AutoValueParcelExtension extends AutoValueExtension { @Override public String generateClass(Context context, String className, String classToExtend, boolean isFinal) { ProcessingEnvironment env = context.processingEnvironment(); TypeName autoValueType = TypeName.get(env.getTypeUtils().erasure(context.autoValueClass().asType())); ImmutableList<Property> properties = readProperties(context); if (!validateProperties(env, properties)) { return null; } ImmutableMap<TypeMirror, FieldSpec> typeAdapters = getTypeAdapters(properties); TypeName type = ClassName.get(context.packageName(), className); TypeSpec.Builder subclass = TypeSpec.classBuilder(className) .addModifiers(FINAL) .addMethod(generateConstructor(properties)) .addMethod(generateWriteToParcel(env, properties, typeAdapters)); GeneratedAnnotations.generatedAnnotation(env.getElementUtils(), env.getSourceVersion()) .map( annotation -> AnnotationSpec.builder(ClassName.get(annotation)) .addMember("value", "$S", getClass().getName()) .build()) .ifPresent(subclass::addAnnotation); if (!typeAdapters.isEmpty()) { for (FieldSpec field : typeAdapters.values()) { subclass.addField(field); } } subclass.addField(generateCreator(env, autoValueType, properties, type, typeAdapters)); ClassName superClass = ClassName.get(context.packageName(), classToExtend); List<? extends TypeParameterElement> tpes = context.autoValueClass().getTypeParameters(); if (tpes.isEmpty()) { subclass.superclass(superClass); } else { TypeName[] superTypeVariables = new TypeName[tpes.size()]; for (int i = 0, tpesSize = tpes.size(); i < tpesSize; i++) { TypeParameterElement tpe = tpes.get(i); subclass.addTypeVariable(TypeVariableName.get(tpe)); superTypeVariables[i] = TypeVariableName.get(tpe.getSimpleName().toString()); } subclass.superclass(ParameterizedTypeName.get(superClass, superTypeVariables)); } if (needsContentDescriptor(context)) { subclass.addMethod(generateDescribeContents()); } JavaFile javaFile = JavaFile.builder(context.packageName(), subclass.build()).build(); return javaFile.toString(); }  @Override IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment); @Override boolean applicable(Context context); @Override boolean mustBeFinal(Context context); @Override Set<String> consumeProperties(Context context); @Override Set<ExecutableElement> consumeMethods(Context context); @Override String generateClass(Context context, String className, String classToExtend,
                              boolean isFinal);  }
@Test public void throwsForNonParcelableProperty() throws Exception { TypeElement type = elements.getTypeElement(SampleTypeWithNonSerializable.class.getCanonicalName()); AutoValueExtension.Context context = createContext(type); processingEnvironment.setOption(AutoValueParcelExtension.FAIL_EXPLOSIVELY, "true"); try { extension.generateClass(context, "Test_AnnotatedType", "SampleTypeWithNonSerializable", true); fail(); } catch (AutoValueParcelException e) {} }
@Test public void acceptsParcelableProperties() throws Exception { TypeElement type = elements.getTypeElement(SampleTypeWithParcelable.class.getCanonicalName()); AutoValueExtension.Context context = createContext(type); String generated = extension.generateClass(context, "Test_TypeWithParcelable", "SampleTypeWithParcelable", true); assertThat(generated).isNotNull(); }