private ListBuffer genWriteFieldValueObject()

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;
    }