package io.gitlab.jfronny.gson.compile.processor.adapter; import com.squareup.javapoet.*; import io.gitlab.jfronny.gson.compile.processor.Cl; import io.gitlab.jfronny.gson.compile.processor.core.TypeHelper; import javax.lang.model.type.TypeMirror; import java.lang.reflect.ParameterizedType; import java.util.Iterator; import java.util.List; public abstract class AdapterAdapter.Hydrated> extends Adapter { public abstract class Hydrated extends Adapter.Hydrated { @Override public void generateWrite(Runnable writeGet) { code.add("$L.write(", getAdapter()); writeGet.run(); code.add(", writer);\n"); } @Override public void generateRead() { code.add("$L.read(reader)", getAdapter()); } private String getAdapter() { for (FieldSpec spec : klazz.fieldSpecs) { if (spec.name.equals(adapterName)) return adapterName; } return createAdapter(adapterName); } protected abstract String createAdapter(String name); protected void appendFieldTypeToken(boolean allowClassType) { TypeName typeName = TypeName.get(type); if (TypeHelper.isComplexType(type, typeUtils)) { TypeName typeTokenType = ParameterizedTypeName.get(Cl.TYPE_TOKEN, typeName); List typeParams = TypeHelper.getGenericTypes(type); if (typeParams.isEmpty()) { code.add("new $T() {}", typeTokenType); } else { code.add("($T) $T.getParameterized($T.class, ", typeTokenType, Cl.TYPE_TOKEN, typeUtils.erasure(type)); for (Iterator iterator = typeParams.iterator(); iterator.hasNext(); ) { TypeMirror typeParam = iterator.next(); int typeIndex = typeVariables.indexOf(TypeVariableName.get(typeParam.toString())); code.add("(($T)typeToken.getType()).getActualTypeArguments()[$L]", ParameterizedType.class, typeIndex); if (iterator.hasNext()) { code.add(", "); } } code.add(")"); } } else if (TypeHelper.isGenericType(type)) { TypeName typeTokenType = ParameterizedTypeName.get(Cl.TYPE_TOKEN, typeName); int typeIndex = typeVariables.indexOf(TypeVariableName.get(type.toString())); code.add("($T) $T.get((($T)typeToken.getType()).getActualTypeArguments()[$L])", typeTokenType, Cl.TYPE_TOKEN, ParameterizedType.class, typeIndex); } else { if (allowClassType) { code.add("$T.class", typeName); } else { code.add("TypeToken.get($T.class)", typeName); } } } } }