in codegen/src/main/java/com/alibaba/fastjson2/internal/processor/JSONCompiledAnnotationProcessor.java [2025:2320]
private ListBuffer<JCTree.JCStatement> genWriteFieldValueObject(
MethodWriterContext mwc,
AttributeInfo attributeInfo,
int i
) {
ListBuffer<JCTree.JCStatement> stmts = new ListBuffer<>();
String type = attributeInfo.type.toString();
if (type.contains("[")) {
JCTree.JCVariableDecl objectStrVar = defVar("objectStr" + i, ident("String"), defNull());
stmts.append(objectStrVar);
JCTree.JCVariableDecl objectIntVar = defVar("objectInt" + i, 0);
stmts.append(objectIntVar);
JCTree.JCLabeledStatement outerLabel = label("objectOuterLabel" + i);
ListBuffer<JCTree.JCStatement> outerLabelStmts = new ListBuffer<>();
String elemType = ((ArrayType) attributeInfo.type).getComponentType().toString();
JCTree.JCVariableDecl objectVar = defVar("object" + i, arrayIdentType(elemType), genWriteFieldValue(attributeInfo, mwc.object, mwc.beanType));
outerLabelStmts.append(objectVar);
JCTree.JCLabeledStatement innerLabel = label("objectInnerLabel" + i);
ListBuffer<JCTree.JCStatement> innerLabelStmts = new ListBuffer<>();
ListBuffer<JCTree.JCStatement> notNullStmts = new ListBuffer<>();
JCTree.JCVariableDecl objectLongVar = defVar("objectLong" + i, TypeTag.LONG, bitAnd(mwc.contextFeatures, ReferenceDetection.mask));
notNullStmts.append(objectLongVar);
notNullStmts.append(exec(
assign(
objectIntVar,
ternary(
eq(objectLongVar, 0),
literal(0),
ternary(lt(objectLongVar, 0), -1, 1)
)
)
));
notNullStmts.append(defIf(eq(objectIntVar, 0), defBreak(innerLabel)));
ListBuffer<JCTree.JCStatement> eqStmts = new ListBuffer<>();
eqStmts.append(genWriteFieldName(mwc, attributeInfo, i));
eqStmts.append(exec(mwc.jsonWriterMethod("writeReference", literal(".."))));
eqStmts.append(defBreak(outerLabel));
notNullStmts.append(defIf(eq(mwc.object, objectVar), block(eqStmts.toList())));
notNullStmts.append(exec(
assign(
objectStrVar,
method(
mwc.jsonWriter,
"setPath",
field(names._this, fieldWriter(i)),
objectVar
)
)
));
notNullStmts.append(defIf(eq(objectStrVar, defNull()), block(defBreak(innerLabel))));
notNullStmts.append(genWriteFieldName(mwc, attributeInfo, i));
notNullStmts.append(exec(mwc.jsonWriterMethod("writeReference", "..")));
innerLabelStmts.append(defIf(ne(ident(objectVar), defNull()), block(notNullStmts.toList())));
ListBuffer<JCTree.JCStatement> notZeroStmts = new ListBuffer<>();
notZeroStmts.append(genWriteFieldName(mwc, attributeInfo, i));
notZeroStmts.append(exec(mwc.jsonWriterMethod("writeArrayNull")));
JCTree.JCExpression writeAsStringBinary = literal(WriteNulls.mask | NullAsDefaultValue.mask | WriteNullListAsEmpty.mask);
innerLabelStmts.append(defIf(ne(bitAnd(mwc.contextFeatures, writeAsStringBinary), 0), block(notZeroStmts.toList())));
innerLabelStmts.append(defBreak(outerLabel));
innerLabel.body = block(innerLabelStmts.toList());
outerLabelStmts.append(innerLabel);
ListBuffer<JCTree.JCStatement> notEmptyArrayStmts = new ListBuffer<>();
notEmptyArrayStmts.append(genWriteFieldName(mwc, attributeInfo, i));
notEmptyArrayStmts.append(
exec(method(
method(field(names._this, fieldWriter(i)), "getObjectWriter", mwc.jsonWriter, field(arrayIdentType(type), names._class)),
"write",
mwc.jsonWriter,
ident(objectVar),
literal(attributeInfo),
method(objectVar, "getClass"),
literal(0L)
))
);
notEmptyArrayStmts.append(
defIf(
ne(objectIntVar, 0),
exec(mwc.jsonWriterMethod("popPath", objectVar))
)
);
JCTree.JCBinary binary1 = eq(bitAnd(mwc.contextFeatures, NotWriteEmptyArray.mask), 0);
JCTree.JCBinary binary2 = ne(field(objectVar, "length"), 0);
outerLabelStmts.append(defIf(and(binary1, binary2), block(notEmptyArrayStmts.toList())));
outerLabel.body = block(outerLabelStmts.toList());
stmts.append(outerLabel);
} else if (type.contains("java.util.Map<")) {
JCTree.JCLabeledStatement outerLabel = label("objectOuterLabel" + i);
ListBuffer<JCTree.JCStatement> outerLabelStmts = new ListBuffer<>();
JCTree.JCVariableDecl objectStrVar = defVar("objectStr" + i, ident("String"), defNull());
outerLabelStmts.append(objectStrVar);
JCTree.JCVariableDecl objectVar = defVar("object" + i, getFieldValueType(type), genWriteFieldValue(attributeInfo, mwc.object, mwc.beanType));
outerLabelStmts.append(objectVar);
JCTree.JCVariableDecl objectIntVar = defVar("objectInt" + i, TypeTag.INT, literal(0));
outerLabelStmts.append(objectIntVar);
JCTree.JCLabeledStatement innerLabel = label("objectInnerLabel" + i);
ListBuffer<JCTree.JCStatement> notNullStmts = new ListBuffer<>();
notNullStmts.append(defIf(mwc.jsonWriterMethod("isIgnoreNoneSerializable", objectVar), block(defBreak(outerLabel))));
JCTree.JCVariableDecl objectLongVar = defVar("objectLong" + i, TypeTag.LONG, bitAnd(mwc.contextFeatures, ReferenceDetection.mask));
notNullStmts.append(objectLongVar);
notNullStmts.append(exec(
assign(
objectIntVar,
ternary(
eq(objectLongVar, 0),
literal(0),
ternary(lt(objectLongVar, 0), -1, 1)
)
)
));
notNullStmts.append(defIf(eq(objectIntVar, 0), defBreak(innerLabel)));
notNullStmts.append(defIf(eq(mwc.object, objectVar),
block(genWriteFieldName(mwc, attributeInfo, i),
exec(mwc.jsonWriterMethod("writeReference", literal(".."))),
defBreak(outerLabel)), null));
notNullStmts.append(exec(assign(objectStrVar, mwc.jsonWriterMethod("setPath", field(ident(names._this), fieldWriter(i)), ident(objectVar)))));
notNullStmts.append(defIf(eq(objectStrVar, defNull()), defBreak(innerLabel)));
notNullStmts.append(genWriteFieldName(mwc, attributeInfo, i));
notNullStmts.append(exec(mwc.jsonWriterMethod("writeReference", objectStrVar)));
notNullStmts.append(exec(mwc.jsonWriterMethod("popPath", objectVar)));
ListBuffer<JCTree.JCStatement> innerLabelStmts = new ListBuffer<>();
innerLabelStmts.append(defIf(ne(ident(objectVar), defNull()), block(notNullStmts.toList())));
JCTree.JCBinary binary = ne(bitAnd(mwc.contextFeatures, WriteMapNullValue.mask), 0);
innerLabelStmts.append(
defIf(
binary,
block(
genWriteFieldName(mwc, attributeInfo, i),
exec(mwc.jsonWriterMethod("writeNull"))
)
)
);
innerLabelStmts.append(defBreak(outerLabel));
innerLabel.body = block(innerLabelStmts.toList());
outerLabelStmts.append(innerLabel);
outerLabelStmts.append(genWriteFieldName(mwc, attributeInfo, i));
outerLabelStmts.append(
exec(method(
method(
field(names._this, fieldWriter(i)),
"getObjectWriter",
mwc.jsonWriter,
method(objectVar, "getClass")
),
"write",
mwc.jsonWriter, ident(objectVar),
literal(attributeInfo.name),
field(field(names._this, fieldWriter(i)), "fieldType"),
literal(0L))
)
);
outerLabelStmts.append(
defIf(
ne(objectIntVar, 0),
exec(mwc.jsonWriterMethod("popPath", objectVar))
)
);
outerLabel.body = block(outerLabelStmts.toList());
stmts.append(outerLabel);
} else {
String WRITE_NULL_METHOD;
if ("AtomicLongArray".equals(type)
|| "AtomicIntegerArray".equals(type)
|| "Collection.class.isAssignableFrom".equals(type)
|| "isArray".equals(type)) {
WRITE_NULL_METHOD = "writeArrayNull";
} else if ("java.lang.Number".equals(type)) {
WRITE_NULL_METHOD = "writeNumberNull";
} else if ("Boolean".equals(type)) {
WRITE_NULL_METHOD = "writeBooleanNull";
} else if ("String".equals(type)
|| "Appendable".equals(type)
|| "StringBuffer".equals(type)
|| "StringBuilder".equals(type)) {
WRITE_NULL_METHOD = "writeStringNull";
} else {
WRITE_NULL_METHOD = "writeNull";
}
JCTree.JCLabeledStatement outerLabel = label("objectOuterLabel" + i);
ListBuffer<JCTree.JCStatement> outerLabelStmts = new ListBuffer<>();
JCTree.JCVariableDecl objectStrVar = defVar("objectStr" + i, ident("String"), defNull());
outerLabelStmts.append(objectStrVar);
JCTree.JCVariableDecl objectVar = defVar("object" + i, getFieldValueType(type), genWriteFieldValue(attributeInfo, mwc.object, mwc.beanType));
outerLabelStmts.append(objectVar);
JCTree.JCVariableDecl objectIntVar = defVar("objectInt" + i, TypeTag.INT, literal(0));
outerLabelStmts.append(objectIntVar);
JCTree.JCLabeledStatement innerLabel = label("objectInnerLabel" + i);
ListBuffer<JCTree.JCStatement> notNullStmts = new ListBuffer<>();
boolean noneSerializable = false;
if (attributeInfo.type instanceof com.sun.tools.javac.code.Type.ClassType) {
List<com.sun.tools.javac.code.Type> interfacesField = ((com.sun.tools.javac.code.Type.ClassType) attributeInfo.type).interfaces_field;
if (interfacesField == null || interfacesField.stream().noneMatch(f -> "java.io.Serializable".equals(f.toString()))) {
noneSerializable = true;
}
}
if (noneSerializable) {
notNullStmts.append(defIf(mwc.jsonWriterMethod("isIgnoreNoneSerializable", objectVar), defBreak(outerLabel)));
}
JCTree.JCVariableDecl objectLongVar = defVar("objectLong" + i, TypeTag.LONG, bitAnd(mwc.contextFeatures, ReferenceDetection.mask));
notNullStmts.append(objectLongVar);
notNullStmts.append(exec(assign(objectIntVar, ternary(eq(objectLongVar, 0), literal(0), ternary(lt(objectLongVar, 0), -1, 1)))));
notNullStmts.append(defIf(eq(objectIntVar, 0), defBreak(innerLabel)));
notNullStmts.append(defIf(eq(mwc.object, ident(objectVar)),
block(genWriteFieldName(mwc, attributeInfo, i),
exec(mwc.jsonWriterMethod("writeReference", "..")),
defBreak(outerLabel))));
notNullStmts.append(
exec(
assign(
objectStrVar,
method(
mwc.jsonWriter,
"setPath",
field(names._this, fieldWriter(i)),
objectVar
)
)
)
);
notNullStmts.append(defIf(eq(objectStrVar, defNull()), defBreak(innerLabel)));
notNullStmts.append(genWriteFieldName(mwc, attributeInfo, i));
notNullStmts.append(exec(mwc.jsonWriterMethod("writeReference", objectStrVar)));
notNullStmts.append(exec(mwc.jsonWriterMethod("popPath", objectVar)));
ListBuffer<JCTree.JCStatement> innerLabelStmts = new ListBuffer<>();
innerLabelStmts.append(defIf(ne(objectVar, defNull()), block(notNullStmts.toList())));
JCTree.JCBinary binary = ne(bitAnd(mwc.contextFeatures, WriteMapNullValue.mask), 0);
innerLabelStmts.append(defIf(binary,
block(genWriteFieldName(mwc, attributeInfo, i),
exec(mwc.jsonWriterMethod(WRITE_NULL_METHOD))),
null));
innerLabelStmts.append(defBreak(outerLabel));
innerLabel.body = block(innerLabelStmts.toList());
outerLabelStmts.append(innerLabel);
outerLabelStmts.append(genWriteFieldName(mwc, attributeInfo, i));
outerLabelStmts.append(
exec(method(
method(
field(names._this, fieldWriter(i)),
"getObjectWriter",
mwc.jsonWriter,
method(objectVar, "getClass")
),
"write",
mwc.jsonWriter,
ident(objectVar),
literal(attributeInfo.name),
field(field(ident(names._this), fieldWriter(i)), "fieldType"),
literal(0L))
)
);
outerLabelStmts.append(
defIf(
ne(objectIntVar, 0),
exec(mwc.jsonWriterMethod("popPath", objectVar))
)
);
outerLabel.body = block(outerLabelStmts.toList());
stmts.append(outerLabel);
}
return stmts;
}