private void processNested()

in java/clickhouse-client/src/main/java/com/epam/deltix/clickhouse/writer/WriterCodecGenerator.java [141:264]


    private void processNested(MethodVisitor methodVisitor,
                               Class<?> nestedClass, String memberName,
                               String memberTypeDescriptor, SqlDataType dbDataType) {
        String internalNestedName = Type.getInternalName(nestedClass);

        List<ColumnDeclaration> columns = ((NestedDataType) dbDataType).getColumns();

        loadMemberValueOnStack(methodVisitor, memberName, memberTypeDescriptor);
        storeNestedMemberValue(methodVisitor);

        loadNestedMemberOnStack(methodVisitor);
        methodVisitor.visitMethodInsn(INVOKESTATIC, CodecUtil.INTERNAL_NAME, CodecUtil.MAKE_LIST_NOT_NULL_NAME, CodecUtil.MAKE_LIST_NOT_NULL_DESC, false);
        storeNestedMemberValue(methodVisitor);

        loadNestedMemberOnStack(methodVisitor);
        // invoke size() method on a `memberName`
        methodVisitor.visitMethodInsn(INVOKEINTERFACE, INTERNAL_LIST_NAME, "size", "()I", true);
        storeSizeOfNestedMemberValue(methodVisitor);

        List<String> arrayDescriptors = new ArrayList<>();
        List<BindDeclaration> nestedBinds;
        if (IntrospectionType.BY_GETTERS == introspectionType)
            nestedBinds = BindHelper.getBindDeclarationsByGetMethods(nestedClass, columns);
        else
            nestedBinds = BindHelper.getBindDeclarationsByFields(nestedClass, columns);

        int currentLocalVarIndex = 7;
        for (BindDeclaration bind : nestedBinds) {
            Class<?> nestedType = BindHelper.memberType.apply(bind);
            String nestedInternalName = Type.getInternalName(nestedType);

            arrayDescriptors.add(String.format("[%s", Type.getDescriptor(nestedType)));

            currentLocalVarIndex = initArray(methodVisitor, nestedType, nestedInternalName, currentLocalVarIndex);
        }

        Label start = new Label();
        Label loop = new Label();

        methodVisitor.visitLabel(start);
        methodVisitor.visitInsn(ICONST_0);
        int tempVarIndex = currentLocalVarIndex;
        // it is 'index' in 'for' loop.
        methodVisitor.visitVarInsn(ISTORE, tempVarIndex);
        localVarSize++;

        methodVisitor.visitLabel(loop);

        // '+ 1' need, because 'this' reference is also local variable.
        int numLocal = tempVarIndex + 1;

        Object[] localVariableTypes = getLocalVarTypes(arrayDescriptors, numLocal);

        methodVisitor.visitFrame(F_FULL, numLocal, localVariableTypes, 0, new Object[]{});

        methodVisitor.visitVarInsn(ILOAD, tempVarIndex);
        loadSizeOfNestedMemberValueOnStack(methodVisitor);
        Label l6 = new Label();
        methodVisitor.visitJumpInsn(IF_ICMPGE, l6);
        Label l7 = new Label();
        methodVisitor.visitLabel(l7);

        currentLocalVarIndex = 7;
        for (BindDeclaration bind : nestedBinds) {
            String nestedName = BindHelper.memberName.apply(bind);
            Class<?> nestedType = BindHelper.memberType.apply(bind);

            String nestedTypeDescriptor = BindHelper.memberDescriptor.apply(bind);

            methodVisitor.visitVarInsn(ALOAD, currentLocalVarIndex++);
            methodVisitor.visitVarInsn(ILOAD, tempVarIndex);

            loadNestedMemberOnStack(methodVisitor);

            methodVisitor.visitVarInsn(ILOAD, tempVarIndex);
            methodVisitor.visitMethodInsn(INVOKEINTERFACE, INTERNAL_LIST_NAME, "get", "(I)Ljava/lang/Object;", true);
            methodVisitor.visitTypeInsn(CHECKCAST, internalNestedName);
            loadNestedMemberValueOnStack(methodVisitor, internalNestedName, nestedName, nestedTypeDescriptor);

            if (!nestedType.isPrimitive())
                methodVisitor.visitInsn(AASTORE);
            else if (nestedType.equals(long.class))
                methodVisitor.visitInsn(LASTORE);
            else if (nestedType.equals(int.class))
                methodVisitor.visitInsn(IASTORE);
            else if (nestedType.equals(short.class))
                methodVisitor.visitInsn(SASTORE);
            else if (nestedType.equals(float.class))
                methodVisitor.visitInsn(FASTORE);
            else if (nestedType.equals(double.class))
                methodVisitor.visitInsn(DASTORE);
            else if (nestedType.equals(byte.class) ||
                    nestedType.equals(boolean.class))
                methodVisitor.visitInsn(BASTORE);

        }

        Label l8 = new Label();
        methodVisitor.visitLabel(l8);
        methodVisitor.visitIincInsn(tempVarIndex, 1);
        methodVisitor.visitJumpInsn(GOTO, loop);
        methodVisitor.visitLabel(l6);
        methodVisitor.visitFrame(F_CHOP, 1, null, 0, null);

        currentLocalVarIndex = 7;
        for (BindDeclaration bind : nestedBinds) {
            Class<?> nestedType = BindHelper.memberType.apply(bind);

            ClickHouseDataType sqlType = CodecUtil.getClickHouseDataType(nestedType);

            loadPsOnStack(methodVisitor);
            loadParameterIndexOnStack(methodVisitor);
            methodVisitor.visitVarInsn(ALOAD, currentLocalVarIndex++);

            String owner = Type.getInternalName(ClickHouseDataType.class);
            String value = sqlType.name();
            String descriptor = Type.getDescriptor(ClickHouseDataType.class);
            methodVisitor.visitFieldInsn(GETSTATIC, owner, value, descriptor);

            methodVisitor.visitMethodInsn(INVOKESTATIC, CodecUtil.INTERNAL_NAME, CodecUtil.PROCESS_ARRAY_NAME, CodecUtil.PROCESS_ARRAY_DESC, false);
            storeParameterIndexValue(methodVisitor);
        }

    }