2023-04-20 10:11:12 +02:00
|
|
|
package it.cavallium.datagen.plugin.classgen;
|
2023-01-21 01:15:05 +01:00
|
|
|
|
|
|
|
import com.squareup.javapoet.ClassName;
|
|
|
|
import com.squareup.javapoet.MethodSpec;
|
|
|
|
import com.squareup.javapoet.ParameterSpec;
|
|
|
|
import com.squareup.javapoet.ParameterizedTypeName;
|
|
|
|
import com.squareup.javapoet.TypeSpec;
|
|
|
|
import com.squareup.javapoet.TypeSpec.Builder;
|
2023-04-20 10:11:12 +02:00
|
|
|
import it.cavallium.datagen.DataSerializer;
|
|
|
|
import it.cavallium.datagen.NotSerializableException;
|
|
|
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedTypeNullable;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedTypeNullableFixed;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedTypeNullableVersioned;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
2023-03-03 00:13:36 +01:00
|
|
|
import it.cavallium.stream.SafeDataInput;
|
|
|
|
import it.cavallium.stream.SafeDataOutput;
|
2023-01-21 01:15:05 +01:00
|
|
|
import java.util.Objects;
|
|
|
|
import java.util.stream.Stream;
|
|
|
|
import javax.lang.model.element.Modifier;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
|
|
|
|
public class GenSerializerNullableX extends ClassGenerator {
|
|
|
|
|
|
|
|
public GenSerializerNullableX(ClassGeneratorParams params) {
|
|
|
|
super(params);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Stream<GeneratedClass> generateClasses() {
|
|
|
|
return dataModel.getVersionsSet().parallelStream().flatMap(this::generateVersionClasses);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Stream<GeneratedClass> generateVersionClasses(ComputedVersion version) {
|
|
|
|
return dataModel
|
|
|
|
.getNullableTypesComputed(version)
|
2023-01-21 23:58:56 +01:00
|
|
|
.filter(type -> (
|
|
|
|
(type instanceof ComputedTypeNullableVersioned versioned && versioned.getVersion().equals(version))
|
|
|
|
|| type instanceof ComputedTypeNullableFixed))
|
|
|
|
.map(type -> generateTypeVersioned(version, type));
|
2023-01-21 01:15:05 +01:00
|
|
|
}
|
|
|
|
|
2023-01-21 23:58:56 +01:00
|
|
|
private GeneratedClass generateTypeVersioned(ComputedVersion version, ComputedTypeNullable typeNullable) {
|
2023-01-21 01:15:05 +01:00
|
|
|
ClassName serializerClassName = typeNullable.getJSerializerName(basePackageName);
|
|
|
|
var typeNullableClassName = typeNullable.getJTypeName(basePackageName);
|
|
|
|
|
|
|
|
var classBuilder = TypeSpec.classBuilder(serializerClassName.simpleName());
|
|
|
|
|
|
|
|
classBuilder.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
|
|
|
|
|
|
|
classBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(DataSerializer.class), typeNullableClassName));
|
|
|
|
|
|
|
|
generateSerialize(version, typeNullable, classBuilder);
|
|
|
|
|
|
|
|
generateDeserialize(version, typeNullable, classBuilder);
|
|
|
|
|
|
|
|
return new GeneratedClass(serializerClassName.packageName(), classBuilder);
|
|
|
|
}
|
|
|
|
|
2023-01-21 23:58:56 +01:00
|
|
|
private void generateSerialize(ComputedVersion version, ComputedTypeNullable typeNullable, Builder classBuilder) {
|
2023-01-21 01:15:05 +01:00
|
|
|
var method = MethodSpec.methodBuilder("serialize");
|
|
|
|
|
|
|
|
var base = typeNullable.getBase();
|
|
|
|
var baseTypeName = base.getJTypeName(basePackageName);
|
|
|
|
var baseSerializerInstance = base.getJSerializerInstance(basePackageName);
|
|
|
|
|
|
|
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
|
|
|
|
2023-03-03 00:13:36 +01:00
|
|
|
method.addParameter(ParameterSpec.builder(SafeDataOutput.class, "out").build());
|
2023-01-21 01:15:05 +01:00
|
|
|
method.addParameter(ParameterSpec
|
|
|
|
.builder(typeNullable.getJTypeName(basePackageName), "data")
|
|
|
|
.addAnnotation(NotNull.class)
|
|
|
|
.build());
|
|
|
|
|
2023-01-22 12:39:54 +01:00
|
|
|
if (generateOldSerializers || version.isCurrent()) {
|
2023-01-21 01:15:05 +01:00
|
|
|
method.addStatement("$T.requireNonNull(data)", Objects.class);
|
|
|
|
method.addCode("\n");
|
2023-01-22 12:39:54 +01:00
|
|
|
method.addStatement("boolean notEmpty = data.getNullable() != null");
|
2023-01-21 01:15:05 +01:00
|
|
|
method.addStatement("out.writeBoolean(notEmpty)");
|
|
|
|
method.beginControlFlow("if (notEmpty)");
|
|
|
|
method.addStatement("$T.$N.serialize(out, ($T) data.getNullable())",
|
|
|
|
baseSerializerInstance.className(),
|
|
|
|
baseSerializerInstance.fieldName(),
|
|
|
|
baseTypeName
|
|
|
|
);
|
|
|
|
method.endControlFlow();
|
|
|
|
} else {
|
|
|
|
method.addStatement("throw new $T()", NotSerializableException.class);
|
|
|
|
}
|
|
|
|
|
|
|
|
classBuilder.addMethod(method.build());
|
|
|
|
}
|
|
|
|
|
2023-01-21 23:58:56 +01:00
|
|
|
private void generateDeserialize(ComputedVersion version, ComputedTypeNullable typeNullable, Builder classBuilder) {
|
2023-01-21 01:15:05 +01:00
|
|
|
var method = MethodSpec.methodBuilder("deserialize");
|
|
|
|
|
|
|
|
var base = typeNullable.getBase();
|
|
|
|
var baseTypeName = base.getJTypeName(basePackageName);
|
|
|
|
var baseSerializerInstance = base.getJSerializerInstance(basePackageName);
|
|
|
|
|
|
|
|
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
|
|
|
|
|
|
|
var typeNullableClassName = typeNullable.getJTypeName(basePackageName);
|
|
|
|
method.returns(typeNullableClassName);
|
|
|
|
method.addAnnotation(NotNull.class);
|
|
|
|
|
2023-03-03 00:13:36 +01:00
|
|
|
method.addParameter(ParameterSpec.builder(SafeDataInput.class, "in").build());
|
2023-01-21 01:15:05 +01:00
|
|
|
|
|
|
|
method.addStatement("return in.readBoolean() ? new $T(($T) $T.$N.deserialize(in)) : $T.empty()",
|
|
|
|
typeNullableClassName,
|
|
|
|
baseTypeName,
|
|
|
|
baseSerializerInstance.className(),
|
|
|
|
baseSerializerInstance.fieldName(),
|
|
|
|
typeNullableClassName
|
|
|
|
);
|
|
|
|
|
|
|
|
classBuilder.addMethod(method.build());
|
|
|
|
}
|
|
|
|
}
|