public abstract class AutoValueExtension
extends java.lang.Object
Extensions are discovered at compile time using the ServiceLoader APIs,
allowing them to run without any additional annotations. To be found by ServiceLoader, an
extension class must be public with a public no-arg constructor, and its fully-qualified name
must appear in a file called META-INF/services/com.google.auto.value.extension.AutoValueExtension in a jar that is on the
compiler's -classpath or -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 of Foo, 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 is AutoValue_Foo and that is the one that the
Foo class will reference, for example with new AutoValue_Foo(...).
Each Extension must also be sure to generate a constructor with arguments corresponding to all
properties in AutoValueExtension.Context.properties(), 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 various bar() property methods.
| Modifier and Type | Class and Description |
|---|---|
static interface |
AutoValueExtension.Context
The context of the generation cycle.
|
static class |
AutoValueExtension.IncrementalExtensionType
Indicates 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 and Description |
|---|
AutoValueExtension() |
| Modifier and Type | Method and Description |
|---|---|
boolean |
applicable(AutoValueExtension.Context context)
Determines whether this Extension applies to the given context.
|
java.util.Set<javax.lang.model.element.ExecutableElement> |
consumeMethods(AutoValueExtension.Context context)
Returns a possible empty set of abstract methods that this Extension intends to implement.
|
java.util.Set<java.lang.String> |
consumeProperties(AutoValueExtension.Context context)
Returns a possibly empty set of property names that this Extension intends to implement.
|
abstract java.lang.String |
generateClass(AutoValueExtension.Context context,
java.lang.String className,
java.lang.String classToExtend,
boolean isFinal)
Returns the generated source code of the class named
className to extend classToExtend, or null if this extension does not generate a class in the hierarchy. |
AutoValueExtension.IncrementalExtensionType |
incrementalType(javax.annotation.processing.ProcessingEnvironment processingEnvironment)
Determines the incremental type of this Extension.
|
boolean |
mustBeFinal(AutoValueExtension.Context context)
Denotes that the class generated by this Extension must be the final class in the inheritance
hierarchy.
|
public AutoValueExtension.IncrementalExtensionType incrementalType(javax.annotation.processing.ProcessingEnvironment processingEnvironment)
The ProcessingEnvironment can be used, among other things, to obtain the processor
options, using ProcessingEnvironment.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.
public boolean applicable(AutoValueExtension.Context context)
context - The Context of the code generation for this class.public boolean mustBeFinal(AutoValueExtension.Context context)
context - the Context of the code generation for this class.public java.util.Set<java.lang.String> consumeProperties(AutoValueExtension.Context context)
toString, equals, and hashCode. 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 Parcelable interface includes a method
int describeContents(). Since this is an abstract method with no parameters, by default
AutoValue will consider that it defines an int property called describeContents. If an @AutoValue class implements Parcelable and does not
provide an implementation of this method, by default its implementation will include describeContents in builders, constructors, and so on. But an AutoValueExtension that
understands Parcelable can instead provide a useful implementation and return a set
containing "describeContents". Then describeContents will be omitted from
builders and the rest.
context - the Context of the code generation for this class.public java.util.Set<javax.lang.model.element.ExecutableElement> consumeMethods(AutoValueExtension.Context context)
Each returned method must be one of the abstract methods in AutoValueExtension.Context.abstractMethods().
For example, Android's Parcelable interface includes a method void writeToParcel(Parcel, int). Normally AutoValue would not know
what to do with that abstract method. But an AutoValueExtension that understands Parcelable can provide a useful implementation and return the writeToParcel method
here. That will prevent a warning about the method from AutoValue.
context - the Context of the code generation for this class.public abstract java.lang.String generateClass(AutoValueExtension.Context context, java.lang.String className, java.lang.String classToExtend, boolean isFinal)
className to extend classToExtend, or null if this extension does not generate a class in the hierarchy.
If there is a generated class, it should be final if isFinal is true; otherwise it
should be abstract. The returned string should be a complete Java class definition of the class
className in the package context.packageName().
The returned string will typically look like this:
package <package>;
...
<finalOrAbstract> class <className> extends <classToExtend> {...}
Here, <package> is AutoValueExtension.Context.packageName(); <finalOrAbstract> is the
keyword final if isFinal is true or abstract otherwise; and <className> and <classToExtend> are the values of this method's parameters of the same
name.
context - The AutoValueExtension.Context of 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.null if this extension does not
generate a class in the hierarchy.Copyright © 2018 Google, Inc.. All Rights Reserved.