Class AutoValueExtension
- java.lang.Object
-
- com.google.auto.value.extension.AutoValueExtension
-
- Direct Known Subclasses:
MemoizeExtension,SerializableAutoValueExtension,ToPrettyStringExtension
public abstract class AutoValueExtension extends Object
An AutoValueExtension allows for extra functionality to be created during the generation of an AutoValue class.Extensions are discovered at compile time using the
ServiceLoaderAPIs, allowing them to run without any additional annotations. To be found byServiceLoader, an extension class must be public with a public no-arg constructor, and its fully-qualified name must appear in a file calledMETA-INF/services/com.google.auto.value.extension.AutoValueExtensionin a jar that is on the compiler's-classpathor-processorpath.When the AutoValue processor runs for a class
Foo, it will ask each Extension whether it is applicable. Suppose two Extensions reply that they are. Then the processor will generate the AutoValue logic in a direct subclass ofFoo, and it will ask the first Extension to generate a subclass of that, and the second Extension to generate a subclass of the subclass. So we might have this hierarchy:@AutoValue abstract class Foo {...} // the hand-written class abstract class $$AutoValue_Foo extends Foo {...} // generated by AutoValue processor abstract class $AutoValue_Foo extends $$AutoValue_Foo {...} // generated by first Extension final class AutoValue_Foo extends $AutoValue_Foo {...} // generated by second Extension(The exact naming scheme illustrated here is not fixed and should not be relied on.)
If an Extension needs its generated class to be the final class in the inheritance hierarchy, its
mustBeFinal(Context)method returns true. Only one Extension can return true for a given context. Only generated classes that will be the final class in the inheritance hierarchy can be declared final. All others should be declared abstract.The first generated class in the hierarchy will always be the one generated by the AutoValue processor and the last one will always be the one generated by the Extension that
mustBeFinal, if any. Other than that, the order of the classes in the hierarchy is unspecified. The last class in the hierarchy isAutoValue_Fooand that is the one that theFooclass will reference, for example withnew AutoValue_Foo(...).Each Extension must also be sure to generate a constructor with arguments corresponding to all properties in
AutoValueExtension.Context.propertyTypes(), in order, and to call the superclass constructor with the same arguments. This constructor must have at least package visibility.Because the class generated by the AutoValue processor is at the top of the generated hierarchy, Extensions can override its methods, for example
hashCode(),toString(), or the implementations of the variousbar()property methods.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceAutoValueExtension.BuilderContextRepresents aBuilderassociated with an@AutoValueclass.static interfaceAutoValueExtension.ContextThe context of the generation cycle.static classAutoValueExtension.IncrementalExtensionTypeIndicates to an annotation processor environment supporting incremental annotation processing (currently a feature specific to Gradle starting with version 4.8) the incremental type of an Extension.
-
Constructor Summary
Constructors Constructor Description AutoValueExtension()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description booleanapplicable(AutoValueExtension.Context context)Determines whether this Extension applies to the given context.Set<ExecutableElement>consumeBuilderMethods(AutoValueExtension.Context context)Returns a possibly empty set of abstract methods that this Extension intends to implement.Set<ExecutableElement>consumeMethods(AutoValueExtension.Context context)Returns a possibly empty set of abstract methods that this Extension intends to implement.Set<String>consumeProperties(AutoValueExtension.Context context)Returns a possibly empty set of property names that this Extension intends to implement.abstract StringgenerateClass(AutoValueExtension.Context context, String className, String classToExtend, boolean isFinal)Returns the generated source code of the class namedclassNameto extendclassToExtend, ornullif this extension does not generate a class in the hierarchy.Set<String>getSupportedOptions()Analogous toProcessor.getSupportedOptions(), here to allow extensions to report their own.AutoValueExtension.IncrementalExtensionTypeincrementalType(ProcessingEnvironment processingEnvironment)Determines the incremental type of this Extension.booleanmustBeFinal(AutoValueExtension.Context context)Denotes that the class generated by this Extension must be the final class in the inheritance hierarchy.
-
-
-
Method Detail
-
incrementalType
public AutoValueExtension.IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment)
Determines the incremental type of this Extension.The
ProcessingEnvironmentcan be used, among other things, to obtain the processor options, usingProcessingEnvironment.getOptions().The actual incremental type of the AutoValue processor as a whole will be the loosest incremental types of the Extensions present in the annotation processor path. The default returned value is
AutoValueExtension.IncrementalExtensionType.UNKNOWN, which will disable incremental annotation processing entirely.
-
getSupportedOptions
public Set<String> getSupportedOptions()
Analogous toProcessor.getSupportedOptions(), here to allow extensions to report their own.By default, if the extension class is annotated with
SupportedOptions, this will return a set with the strings in the annotation. If the class is not so annotated, an empty set is returned.- Returns:
- the set of options recognized by this extension or an empty set if none
- See Also:
SupportedOptions
-
applicable
public boolean applicable(AutoValueExtension.Context context)
Determines whether this Extension applies to the given context. If an Extension returnsfalsefor a given class, it will not be called again during the processing of that class. An Extension can returntrueand still choose not to generate any code for the class, by returningnullfromgenerateClass(com.google.auto.value.extension.AutoValueExtension.Context, java.lang.String, java.lang.String, boolean). That is often a more flexible approach.- Parameters:
context- The Context of the code generation for this class.
-
mustBeFinal
public boolean mustBeFinal(AutoValueExtension.Context context)
Denotes that the class generated by this Extension must be the final class in the inheritance hierarchy. Only one Extension may be the final class, so this should be used sparingly.- Parameters:
context- the Context of the code generation for this class.
-
consumeProperties
public Set<String> consumeProperties(AutoValueExtension.Context context)
Returns a possibly empty set of property names that this Extension intends to implement. This will prevent AutoValue from generating an implementation, and remove the supplied properties from builders, constructors,toString,equals, andhashCode. The default set returned by this method is empty.Each returned string must be one of the property names in
AutoValueExtension.Context.properties().Returning a property name from this method is equivalent to returning the property's getter method from
consumeMethods(com.google.auto.value.extension.AutoValueExtension.Context).For example, Android's
Parcelableinterface includes a methodint describeContents(). Since this is an abstract method with no parameters, by default AutoValue will consider that it defines anintproperty calleddescribeContents. If an@AutoValueclass implementsParcelableand does not provide an implementation of this method, by default its implementation will includedescribeContentsin builders, constructors, and so on. But anAutoValueExtensionthat understandsParcelablecan instead provide a useful implementation and return a set containing"describeContents". ThendescribeContentswill be omitted from builders and the rest.- Parameters:
context- the Context of the code generation for this class.
-
consumeMethods
public Set<ExecutableElement> consumeMethods(AutoValueExtension.Context context)
Returns a possibly empty set of abstract methods that this Extension intends to implement. This will prevent AutoValue from generating an implementation, in cases where it would have, and it will also avoid complaints about abstract methods that AutoValue doesn't expect. The default set returned by this method is empty.Each returned method must be one of the abstract methods in
AutoValueExtension.Context.abstractMethods().For example, Android's
Parcelableinterface includes a methodvoid writeToParcel(Parcel, int). Normally AutoValue would not know what to do with that abstract method. But anAutoValueExtensionthat understandsParcelablecan provide a useful implementation and return thewriteToParcelmethod here. That will prevent a warning about the method from AutoValue.- Parameters:
context- the Context of the code generation for this class.
-
consumeBuilderMethods
public Set<ExecutableElement> consumeBuilderMethods(AutoValueExtension.Context context)
Returns a possibly empty set of abstract methods that this Extension intends to implement. This will prevent AutoValue from generating an implementation, in cases where it would have, and it will also avoid complaints about abstract methods that AutoValue doesn't expect. The default set returned by this method is empty.Each returned method must be one of the abstract methods in
AutoValueExtension.Context.builderAbstractMethods().- Parameters:
context- the Context of the code generation for this class.
-
generateClass
public abstract String generateClass(AutoValueExtension.Context context, String className, String classToExtend, boolean isFinal)
Returns the generated source code of the class namedclassNameto extendclassToExtend, ornullif this extension does not generate a class in the hierarchy. If there is a generated class, it should be final ifisFinalis true; otherwise it should be abstract. The returned string should be a complete Java class definition of the classclassNamein the packagecontext.packageName().The returned string will typically look like this:
package <package>; ... <finalOrAbstract> class <className> extends <classToExtend> { // Constructor <className>(<constructorParameters>) { super(<constructorParameterNames>); ... } ... }Here,
<package>isAutoValueExtension.Context.packageName();<finalOrAbstract>is the keywordfinalifisFinalis true orabstractotherwise; and<className>and<classToExtend>are the values of this method's parameters of the same name. The<constructorParameters>and<constructorParameterNames>are typically derived fromAutoValueExtension.Context.propertyTypes().An extension can also generate a subclass of the nested
Builderclass if there is one. In that case, it should check ifAutoValueExtension.BuilderContext.toBuilderMethods()is empty. If not, theBuildersubclass should include a "copy constructor", like this:... <finalOrAbstract> class <className> extends <classToExtend> { ... static class Builder extends <classToExtend>.Builder { Builder() {} Builder(<autoValueClass> copyFrom) { super(copyFrom); } ... } }Here,
<autoValueClass>isAutoValueExtension.Context.autoValueClass().}- Parameters:
context- TheAutoValueExtension.Contextof the code generation for this class.className- The simple name of the resulting class. The returned code will be written to a file named accordingly.classToExtend- The simple name of the direct parent of the generated class. This could be the AutoValue generated class, or a class generated as the result of another Extension.isFinal- True if this class is the last class in the chain, meaning it should be marked as final. Otherwise it should be marked as abstract.- Returns:
- The source code of the generated class, or
nullif this extension does not generate a class in the hierarchy.
-
-