package io.gitlab.jfronny.gson.compile.processor.adapter; import com.squareup.javapoet.*; import io.gitlab.jfronny.gson.compile.processor.SerializableClass; import io.gitlab.jfronny.gson.compile.processor.adapter.impl.*; import io.gitlab.jfronny.gson.compile.processor.core.value.Property; import javax.annotation.processing.Messager; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic; import java.util.List; import java.util.Set; import java.util.function.Consumer; public class Adapters { public static final List> ADAPTERS = List.of( new DeclaredAdapter(), new PrimitiveAdapter(), new StringAdapter(), new DateAdapter(), new EnumAdapter(), new ArrayAdapter(), new CollectionAdapter(), new MapAdapter(), new OtherSerializableAdapter(), new ReflectAdapter() ); public static void generateRead(Property prop, TypeSpec.Builder klazz, CodeBlock.Builder code, List typeVariables, Set otherAdapters, Messager message) { withAdapter(prop, klazz, code, typeVariables, otherAdapters, message, Adapter.Hydrated::generateRead); } public static void generateWrite(Property prop, TypeSpec.Builder klazz, CodeBlock.Builder code, List typeVariables, Set otherAdapters, Messager message, Runnable writeGet) { withAdapter(prop, klazz, code, typeVariables, otherAdapters, message, adapter -> adapter.generateWrite(writeGet)); } private static void withAdapter(Property prop, TypeSpec.Builder klazz, CodeBlock.Builder code, List typeVariables, Set otherAdapters, Messager message, Consumer.Hydrated> action) { withAdapter(klazz, code, typeVariables, otherAdapters, prop.getType(), prop.getName(), prop.getAnnotations(), prop.getElement(), message, action); } public static void generateRead(TypeSpec.Builder klazz, CodeBlock.Builder code, List typeVariables, Set other, TypeMirror type, String propName, List annotations, Element sourceElement, Messager message) { withAdapter(klazz, code, typeVariables, other, type, propName, annotations, sourceElement, message, Adapter.Hydrated::generateRead); } public static void generateWrite(TypeSpec.Builder klazz, CodeBlock.Builder code, List typeVariables, Set other, TypeMirror type, String propName, List annotations, Element sourceElement, Messager message, Runnable writeGet) { withAdapter(klazz, code, typeVariables, other, type, propName, annotations, sourceElement, message, adapter -> adapter.generateWrite(writeGet)); } private static void withAdapter(TypeSpec.Builder klazz, CodeBlock.Builder code, List typeVariables, Set other, TypeMirror type, String propName, List annotations, Element sourceElement, Messager message, Consumer.Hydrated> action) { for (Adapter adapter : Adapters.ADAPTERS) { Adapter.Hydrated hydrated = adapter.hydrate(klazz, code, typeVariables, other, type, propName, annotations, sourceElement); if (hydrated.applies()) { action.accept(hydrated); return; } } message.printMessage(Diagnostic.Kind.ERROR, "Could not find applicable adapter for property " + propName, sourceElement); } }