in modules/network-annotation-processor/src/main/java/org/apache/ignite/internal/network/processor/messages/MessageImplGenerator.java [100:264]
public TypeSpec generateMessageImpl(MessageClass message, TypeSpec builderInterface) {
ClassName messageImplClassName = message.implClassName();
processingEnv.getMessager()
.printMessage(Diagnostic.Kind.NOTE, "Generating " + messageImplClassName);
List<ExecutableElement> getters = message.getters();
var fields = new ArrayList<FieldSpec>(getters.size());
var methodImpls = new ArrayList<MethodSpec>(getters.size());
var notNullFieldNames = new HashSet<String>();
var marshallableFieldNames = new HashSet<String>();
// create a field and a getter implementation for every getter in the message interface
for (ExecutableElement getter : getters) {
TypeMirror getterType = getter.getReturnType();
TypeName getterReturnType = TypeName.get(getterType);
String getterName = getter.getSimpleName().toString();
boolean isMarshallable = getter.getAnnotation(Marshallable.class) != null;
if (isMarshallable && !marshallableTypesBlackList.canBeMarshallable(getterType)) {
String error = String.format(
"\"%s\" field is marked as @Marshallable but this type is either directly supported by native serialization "
+ "or is prohibited by a blacklist, remove this annotation from the field",
getterName
);
throw new ProcessingException(error, null, getter);
}
FieldSpec.Builder fieldBuilder = FieldSpec.builder(getterReturnType, getterName)
.addAnnotation(IgniteToStringInclude.class)
.addModifiers(Modifier.PRIVATE);
boolean generateSetter = getter.getAnnotation(WithSetter.class) != null;
if (!isMarshallable && !generateSetter) {
fieldBuilder.addModifiers(Modifier.FINAL);
}
if (requiresNotNullCheck(getter)) {
notNullFieldNames.add(getterName);
}
FieldSpec field = fieldBuilder.build();
fields.add(field);
if (isMarshallable) {
marshallableFieldNames.add(getterName);
String name = getByteArrayFieldName(getterName);
FieldSpec marshallableFieldArray = FieldSpec.builder(BYTE_ARRAY_TYPE, name)
.addModifiers(Modifier.PRIVATE)
.build();
fields.add(marshallableFieldArray);
MethodSpec baGetterImpl = MethodSpec.methodBuilder(name)
.returns(BYTE_ARRAY_TYPE)
.addStatement("return $N", marshallableFieldArray)
.build();
methodImpls.add(baGetterImpl);
}
if (generateSetter) {
MethodSpec setterImpl = MethodSpec.methodBuilder(getterName)
.returns(TypeName.VOID)
.addModifiers(Modifier.PUBLIC)
.addParameter(getterReturnType, getterName)
.addAnnotation(Override.class)
.addStatement("this.$L = $L", getterName, getterName)
.build();
methodImpls.add(setterImpl);
}
MethodSpec getterImpl = MethodSpec.overriding(getter)
.addStatement("return $N", field)
.build();
methodImpls.add(getterImpl);
}
TypeSpec.Builder messageImpl = TypeSpec.classBuilder(messageImplClassName)
.addModifiers(Modifier.PUBLIC)
.addSuperinterface(message.className())
.addFields(fields)
.addMethods(methodImpls)
.addMethod(constructor(fields, notNullFieldNames, marshallableFieldNames));
// group type constant and getter
FieldSpec groupTypeField = FieldSpec.builder(short.class, "GROUP_TYPE")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$L", messageGroup.groupType())
.build();
messageImpl.addField(groupTypeField);
MethodSpec groupTypeMethod = MethodSpec.methodBuilder("groupType")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.returns(short.class)
.addStatement("return $N", groupTypeField)
.build();
messageImpl.addMethod(groupTypeMethod);
// TODO: https://issues.apache.org/jira/browse/IGNITE-17591
MethodSpec toStringMethod = MethodSpec.methodBuilder("toString")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return $T.toString($T.class, this)", S.class, messageImplClassName)
.build();
messageImpl.addMethod(toStringMethod);
// message type constant and getter
FieldSpec messageTypeField = FieldSpec.builder(short.class, "TYPE")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("$L", message.messageType())
.build();
messageImpl.addField(messageTypeField);
MethodSpec messageTypeMethod = MethodSpec.methodBuilder("messageType")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.returns(short.class)
.addStatement("return $N", messageTypeField)
.build();
messageImpl.addMethod(messageTypeMethod);
// equals and hashCode
generateEqualsAndHashCode(messageImpl, message);
var builderName = ClassName.get(message.packageName(), builderInterface.name);
// nested builder interface and static factory method
TypeSpec builder = generateBuilderImpl(message, messageImplClassName, builderName, notNullFieldNames, marshallableFieldNames);
messageImpl.addType(builder);
MethodSpec builderMethod = MethodSpec.methodBuilder("builder")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(builderName)
.addStatement("return new $N()", builder)
.build();
messageImpl.addMethod(builderMethod);
generatePrepareMarshal(messageImpl, message);
generateUnmarshalMethod(messageImpl, message);
messageImpl
.addOriginatingElement(message.element())
.addOriginatingElement(messageGroup.element());
return messageImpl.build();
}