private Function createValueConsumer0()

in core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderCreatorASM.java [4254:4597]


    private Function createValueConsumer0(
            Class objectClass,
            FieldReader[] fieldReaderArray,
            boolean bytes
    ) {
        Constructor defaultConstructor = BeanUtils.getDefaultConstructor(objectClass, false);
        if (defaultConstructor == null || !Modifier.isPublic(objectClass.getModifiers())) {
            return null;
        }

        ClassWriter cw = new ClassWriter(
                (e) -> objectClass.getName().equals(e) ? objectClass : null
        );

        String className = (bytes ? "VBACG_" : "VCACG_")
                + seed.incrementAndGet()
                + "_" + fieldReaderArray.length
                + "_" + objectClass.getSimpleName();
        String classNameType;
        String classNameFull;

        Package pkg = ObjectReaderCreatorASM.class.getPackage();
        if (pkg != null) {
            classNameFull = packageName + '.' + className;
            classNameType = classNameFull.replace('.', '/');
        } else {
            classNameType = className;
            classNameFull = className;
        }

        String TYPE_OBJECT = ASMUtils.type(objectClass);
        String DESC_OBJECT = ASMUtils.desc(objectClass);

        cw.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "consumer", "Ljava/util/function/Consumer;");
        cw.visitField(Opcodes.ACC_PUBLIC, "object", DESC_OBJECT);

        cw.visit(
                Opcodes.V1_8,
                Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
                classNameType,
                "java/lang/Object",
                new String[]{
                        bytes ? TYPE_BYTE_ARRAY_VALUE_CONSUMER : TYPE_CHAR_ARRAY_VALUE_CONSUMER
                }
        );

        {
            final int CONSUMER = 1;

            MethodWriter mw = cw.visitMethod(
                    Opcodes.ACC_PUBLIC,
                    "<init>",
                    "(Ljava/util/function/Consumer;)V",
                    32
            );
            mw.aload(THIS);
            mw.invokespecial("java/lang/Object", "<init>", "()V");

            mw.aload(THIS);
            mw.aload(CONSUMER);
            mw.putfield(classNameType, "consumer", "Ljava/util/function/Consumer;");

            mw.return_();
            mw.visitMaxs(3, 3);
        }

        {
            MethodWriter mw = cw.visitMethod(
                    Opcodes.ACC_PUBLIC,
                    "beforeRow",
                    "(I)V",
                    32
            );

            mw.aload(THIS);
            newObject(mw, TYPE_OBJECT, defaultConstructor);
            mw.putfield(classNameType, "object", DESC_OBJECT);

            mw.return_();
            mw.visitMaxs(3, 3);
        }

        {
            MethodWriter mw = cw.visitMethod(
                    Opcodes.ACC_PUBLIC,
                    "afterRow",
                    "(I)V",
                    32
            );

            mw.aload(THIS);
            mw.getfield(classNameType, "consumer", "Ljava/util/function/Consumer;");
            mw.aload(THIS);
            mw.getfield(classNameType, "object", DESC_OBJECT);
            mw.invokeinterface("java/util/function/Consumer", "accept", "(Ljava/lang/Object;)V");

            mw.aload(THIS);
            mw.aconst_null();
            mw.putfield(classNameType, "object", DESC_OBJECT);

            mw.return_();
            mw.visitMaxs(3, 3);
        }

        {
            final int ROW = 1, COLUMN = 2, BYTES = 3, OFF = 4, LEN = 5, CHARSET = 6;

            String methodDesc;
            if (bytes) {
                methodDesc = "(II[BIILjava/nio/charset/Charset;)V";
            } else {
                methodDesc = "(II[CII)V";
            }

            MethodWriter mw = cw.visitMethod(
                    Opcodes.ACC_PUBLIC,
                    "accept",
                    methodDesc,
                    32
            );

            Label switch_ = new Label(), L0_ = new Label(), L1_ = new Label();

            mw.iload(LEN);
            mw.ifne(L0_);
            mw.return_();

            mw.visitLabel(L0_);
            mw.iload(COLUMN);
            mw.ifge(L1_);
            mw.return_();

            mw.visitLabel(L1_);
            mw.iload(COLUMN);
            mw.visitLdcInsn(fieldReaderArray.length);
            mw.if_icmple(switch_);
            mw.return_();

            mw.visitLabel(switch_);

            Label dflt = new Label();
            Label[] labels = new Label[fieldReaderArray.length];
            int[] columns = new int[fieldReaderArray.length];
            for (int i = 0; i < columns.length; i++) {
                columns[i] = i;
                labels[i] = new Label();
            }

            mw.iload(COLUMN);
            mw.visitLookupSwitchInsn(dflt, columns, labels);

            for (int i = 0; i < labels.length; i++) {
                mw.visitLabel(labels[i]);
                FieldReader fieldReader = fieldReaderArray[i];
                Field field = fieldReader.field;
                Class fieldClass = fieldReader.fieldClass;
                Type fieldType = fieldReader.fieldType;

                mw.aload(THIS);
                mw.getfield(classNameType, "object", DESC_OBJECT);

                String DESC_FIELD_CLASS, DESC_METHOD;
                if (fieldType == Integer.class
                        || fieldType == int.class
                        || fieldType == Short.class
                        || fieldType == short.class
                        || fieldType == Byte.class
                        || fieldType == byte.class
                ) {
                    mw.aload(BYTES);
                    mw.iload(OFF);
                    mw.iload(LEN);
                    mw.invokestatic(TYPE_TYPE_UTILS, "parseInt", bytes ? "([BII)I" : "([CII)I");

                    if (fieldType == short.class) {
                        DESC_FIELD_CLASS = "S";
                        DESC_METHOD = "(S)V";
                    } else if (fieldType == Short.class) {
                        mw.invokestatic("java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
                        DESC_FIELD_CLASS = "Ljava/lang/Short;";
                        DESC_METHOD = "(Ljava/lang/Short;)V";
                    } else if (fieldType == byte.class) {
                        DESC_FIELD_CLASS = "B";
                        DESC_METHOD = "(B)V";
                    } else if (fieldType == Byte.class) {
                        mw.invokestatic("java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
                        DESC_FIELD_CLASS = "Ljava/lang/Byte;";
                        DESC_METHOD = "(Ljava/lang/Byte;)V";
                    } else if (fieldType == int.class) {
                        DESC_FIELD_CLASS = "I";
                        DESC_METHOD = "(I)V";
                    } else {
                        mw.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
                        DESC_FIELD_CLASS = "Ljava/lang/Integer;";
                        DESC_METHOD = "(Ljava/lang/Integer;)V";
                    }
                } else if (fieldType == Long.class || fieldType == long.class) {
                    mw.aload(BYTES);
                    mw.iload(OFF);
                    mw.iload(LEN);
                    mw.invokestatic(TYPE_TYPE_UTILS, "parseLong", bytes ? "([BII)J" : "([CII)J");
                    if (fieldType == long.class) {
                        DESC_FIELD_CLASS = "J";
                        DESC_METHOD = "(J)V";
                    } else {
                        mw.invokestatic("java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
                        DESC_FIELD_CLASS = "Ljava/lang/Long;";
                        DESC_METHOD = "(Ljava/lang/Long;)V";
                    }
                } else if (fieldType == Float.class || fieldType == float.class) {
                    mw.aload(BYTES);
                    mw.iload(OFF);
                    mw.iload(LEN);
                    mw.invokestatic(TYPE_TYPE_UTILS, "parseFloat", bytes ? "([BII)F" : "([CII)F");

                    if (fieldType == float.class) {
                        DESC_FIELD_CLASS = "F";
                        DESC_METHOD = "(F)V";
                    } else {
                        mw.invokestatic("java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
                        DESC_FIELD_CLASS = "Ljava/lang/Float;";
                        DESC_METHOD = "(Ljava/lang/Float;)V";
                    }
                } else if (fieldType == Double.class || fieldType == double.class) {
                    mw.aload(BYTES);
                    mw.iload(OFF);
                    mw.iload(LEN);
                    mw.invokestatic(TYPE_TYPE_UTILS, "parseDouble", bytes ? "([BII)D" : "([CII)D");

                    if (fieldType == double.class) {
                        DESC_FIELD_CLASS = "D";
                        DESC_METHOD = "(D)V";
                    } else {
                        mw.invokestatic("java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
                        DESC_FIELD_CLASS = "Ljava/lang/Double;";
                        DESC_METHOD = "(Ljava/lang/Double;)V";
                    }
                } else if (fieldType == Boolean.class || fieldType == boolean.class) {
                    mw.aload(BYTES);
                    mw.iload(OFF);
                    mw.iload(LEN);
                    mw.invokestatic(TYPE_TYPE_UTILS, "parseBoolean", bytes ? "([BII)Ljava/lang/Boolean;" : "([CII)Ljava/lang/Boolean;");

                    if (fieldType == boolean.class) {
                        mw.invokevirtual("java/lang/Boolean", "booleanValue", "()Z");
                        DESC_FIELD_CLASS = "Z";
                        DESC_METHOD = "(Z)V";
                    } else {
                        DESC_FIELD_CLASS = "Ljava/lang/Boolean;";
                        DESC_METHOD = "(Ljava/lang/Boolean;)V";
                    }
                } else if (fieldType == Date.class) {
                    mw.new_("java/util/Date");

                    // long millis = DateUtils.parseMillis(bytes, off, len, charset);
                    mw.dup();
                    mw.aload(BYTES);
                    mw.iload(OFF);
                    mw.iload(LEN);
                    if (bytes) {
                        mw.aload(CHARSET);
                        mw.invokestatic(TYPE_DATE_UTILS, "parseMillis", "([BIILjava/nio/charset/Charset;)J");
                    } else {
                        mw.invokestatic(TYPE_DATE_UTILS, "parseMillis", "([CII)J");
                    }
                    mw.invokespecial("java/util/Date", "<init>", "(J)V");

                    DESC_FIELD_CLASS = "Ljava/util/Date;";
                    DESC_METHOD = "(Ljava/util/Date;)V";
                } else if (fieldType == BigDecimal.class) {
                    mw.aload(BYTES);
                    mw.iload(OFF);
                    mw.iload(LEN);
                    mw.invokestatic(TYPE_TYPE_UTILS, "parseBigDecimal", bytes ? "([BII)Ljava/math/BigDecimal;" : "([CII)Ljava/math/BigDecimal;");

                    DESC_FIELD_CLASS = "Ljava/math/BigDecimal;";
                    DESC_METHOD = "(Ljava/math/BigDecimal;)V";
                } else {
                    mw.new_("java/lang/String");
                    mw.dup();
                    mw.aload(BYTES);
                    mw.iload(OFF);
                    mw.iload(LEN);
                    if (bytes) {
                        mw.aload(CHARSET);
                        mw.invokespecial("java/lang/String", "<init>", "([BIILjava/nio/charset/Charset;)V");
                    } else {
                        mw.invokespecial("java/lang/String", "<init>", "([CII)V");
                    }

                    if (fieldType == String.class) {
                        DESC_FIELD_CLASS = "Ljava/lang/String;";
                        DESC_METHOD = "(Ljava/lang/String;)V";
                    } else {
                        DESC_FIELD_CLASS = ASMUtils.desc(fieldClass);
                        if (fieldClass == char.class) {
                            DESC_METHOD = "(C)V";
                        } else {
                            DESC_METHOD = "(" + DESC_FIELD_CLASS + ")V";
                        }

                        mw.visitLdcInsn(fieldClass);
                        mw.invokestatic(TYPE_TYPE_UTILS, "cast", "(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;");
                        mw.checkcast(ASMUtils.type(fieldClass));
                    }
                }

                if (fieldReader.method != null) {
                    if (fieldReader.method.getReturnType() != void.class) {
                        return null;
                    }

                    mw.invokevirtual(TYPE_OBJECT, fieldReader.method.getName(), DESC_METHOD);
                } else if (field != null) {
                    mw.putfield(TYPE_OBJECT, field.getName(), DESC_FIELD_CLASS);
                } else {
                    return null;
                }
                mw.goto_(dflt);
            }

            mw.visitLabel(dflt);

            mw.return_();
            mw.visitMaxs(3, 3);
        }

        byte[] code = cw.toByteArray();

        try {
            Class<?> consumerClass = classLoader.defineClassPublic(classNameFull, code, 0, code.length);
            Constructor<?> constructor = consumerClass.getConstructor(Consumer.class);
            return (c) -> {
                try {
                    return constructor.newInstance(c);
                } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
                    throw new JSONException("create ByteArrayValueConsumer error", e);
                }
            };
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }