private void generateAssigners()

in broker-codegen/src/main/java/org/apache/qpid/server/protocol/v1_0/CompositeTypeConstructorGenerator.java [209:342]


    private void generateAssigners(final PrintWriter pw, final TypeElement typeElement)
    {
        Types typeUtils = processingEnv.getTypeUtils();

        final List<AnnotatedField> annotatedFields = new ArrayList<>();
        for (Element element : typeElement.getEnclosedElements())
        {
            if (element instanceof VariableElement && element.getKind() == ElementKind.FIELD)
            {
                boolean annotationFound = false;
                for(AnnotationMirror annotationMirror : element.getAnnotationMirrors())
                {
                    if(annotationMirror.getAnnotationType().toString().equals("org.apache.qpid.server.protocol.v1_0.CompositeTypeField"))
                    {
                        if (annotationFound)
                        {
                            processingEnv.getMessager()
                                         .printMessage(Diagnostic.Kind.ERROR,
                                                       String.format(
                                                               "More than one CompositeTypeField annotations on field '%s.%s'",
                                                               typeElement.getSimpleName(),
                                                               element.getSimpleName()));
                        }
                        annotationFound = true;
                        annotatedFields.add(new AnnotatedField((VariableElement) element, annotationMirror));
                    }
                }
            }
        }

        annotatedFields.sort(Comparator.comparingInt(AnnotatedField::getIndex));

        for (int index = 0; index < annotatedFields.size(); ++index)
        {
            AnnotatedField annotatedField = annotatedFields.get(index);
            final VariableElement variableElement = annotatedField.getVariableElement();
            final String fieldName = stripUnderscore(variableElement.getSimpleName().toString());
            if (annotatedField.getIndex() != index)
            {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,String.format(
                        "Unexpected CompositeTypeField index '%d' is specified on field '%s' of '%s'. Expected %d.",
                        annotatedField.getIndex(),
                        fieldName,
                        typeElement.getSimpleName(),
                        index));
            }

            final String baseIndent = "        ";
            if (variableElement.asType().getKind() == TypeKind.ARRAY)
            {
                final TypeMirror componentType = ((ArrayType) variableElement.asType()).getComponentType();
                final String functionString;
                if (annotatedField.getFactory() != null)
                {
                    functionString = "x -> " + annotatedField.getFactory() + "(x)";
                }
                else if (RESTRICTED_TYPES.contains(componentType))
                {
                    functionString = variableElement.asType().toString() + "::valueOf";
                }
                else
                {
                    functionString = "x -> (" + componentType + ") x";
                }
                pw.println(String.format("        %s %s = fieldValueReader.readArrayValue(%d, \"%s\", %s, %s.class, %s);",
                                             annotatedField.getVariableElement().asType(),
                                             fieldName,
                                             index,
                                             fieldName,
                                             annotatedField.isMandatory(),
                                             componentType,
                                             functionString));
                optionallyWrapInNullCheck(!annotatedField.isMandatory(), pw, baseIndent, fieldName, indent -> {
                    pw.println(indent + "obj." + getSetterName(variableElement) + "(" + fieldName + ");");
                });
            }
            else if (annotatedField.getFactory() != null || RESTRICTED_TYPES.contains(variableElement.asType().toString()))
            {
                String functionName = annotatedField.getFactory() != null ? annotatedField.getFactory() : variableElement.asType().toString() + ".valueOf";
                pw.println(String.format("        Object %s = fieldValueReader.readValue(%d, \"%s\", %s, Object.class);",
                                         fieldName,
                                         index,
                                         fieldName,
                                         annotatedField.isMandatory()));
                optionallyWrapInNullCheck(!annotatedField.isMandatory(), pw, baseIndent, fieldName, indent -> {
                    pw.println(indent + "try");
                    pw.println(indent + "{");
                    pw.println(indent + "    obj." + getSetterName(variableElement) + "(" + functionName + "(" + fieldName + "));");
                    pw.println(indent + "}");
                    pw.println(indent + "catch (RuntimeException e)");
                    pw.println(indent + "{");
                    pw.println(indent + "    Error error = new Error(AmqpError.DECODE_ERROR, \"Could not decode value field '" + fieldName + "' of '" + typeElement.getSimpleName() + "'\");");
                    pw.println(indent + "    throw new AmqpErrorException(error, e);");
                    pw.println(indent + "}");
                });
            }
            else if (typeUtils.isSameType(typeUtils.erasure(variableElement.asType()),
                                          getErasure(processingEnv, "java.util.Map")))
            {
                List<? extends TypeMirror> args = ((DeclaredType) variableElement.asType()).getTypeArguments();
                if (args.size() != 2)
                {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                                                             "Map types must have exactly two type arguments");
                }
                pw.println(String.format("        %s %s = fieldValueReader.readMapValue(%d, \"%s\", %s, %s.class, %s.class);",
                                         annotatedField.getVariableElement().asType(),
                                         fieldName,
                                         index,
                                         fieldName,
                                         annotatedField.isMandatory(),
                                         args.get(0),
                                         args.get(1)));
                optionallyWrapInNullCheck(!annotatedField.isMandatory(), pw, baseIndent, fieldName, indent -> {
                    pw.println(indent + "obj." + getSetterName(variableElement) + "(" + fieldName + ");");
                });
            }
            else
            {
                pw.println(String.format("        %s %s = fieldValueReader.readValue(%d, \"%s\", %s, %s.class);",
                                         annotatedField.getVariableElement().asType(),
                                         fieldName,
                                         index,
                                         fieldName,
                                         annotatedField.isMandatory(),
                                         annotatedField.getVariableElement().asType()));
                optionallyWrapInNullCheck(!annotatedField.isMandatory(), pw, baseIndent, fieldName, indent -> {
                    pw.println(indent + "obj." + getSetterName(variableElement) + "(" + fieldName + ");");
                });
            }

            pw.println();
        }
    }