• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.auto.value.extension;
17 
18 import com.google.common.collect.ImmutableSet;
19 import java.util.Map;
20 import java.util.Optional;
21 import java.util.Set;
22 import javax.annotation.processing.ProcessingEnvironment;
23 import javax.annotation.processing.Processor;
24 import javax.annotation.processing.SupportedOptions;
25 import javax.lang.model.element.ExecutableElement;
26 import javax.lang.model.element.TypeElement;
27 import javax.lang.model.type.TypeMirror;
28 
29 /**
30  * An AutoValueExtension allows for extra functionality to be created during the generation of an
31  * AutoValue class.
32  *
33  * <p>Extensions are discovered at compile time using the {@link java.util.ServiceLoader} APIs,
34  * allowing them to run without any additional annotations. To be found by {@code ServiceLoader}, an
35  * extension class must be public with a public no-arg constructor, and its fully-qualified name
36  * must appear in a file called {@code
37  * META-INF/services/com.google.auto.value.extension.AutoValueExtension} in a jar that is on the
38  * compiler's {@code -classpath} or {@code -processorpath}.
39  *
40  * <p>When the AutoValue processor runs for a class {@code Foo}, it will ask each Extension whether
41  * it is {@linkplain #applicable applicable}. Suppose two Extensions reply that they are. Then
42  * the processor will generate the AutoValue logic in a direct subclass of {@code Foo}, and it
43  * will ask the first Extension to generate a subclass of that, and the second Extension to generate
44  * a subclass of the subclass. So we might have this hierarchy:
45  *
46  * <pre>
47  * &#64;AutoValue abstract class Foo {...}                          // the hand-written class
48  * abstract class $$AutoValue_Foo extends Foo {...}             // generated by AutoValue processor
49  * abstract class $AutoValue_Foo extends $$AutoValue_Foo {...}  // generated by first Extension
50  * final class AutoValue_Foo extends $AutoValue_Foo {...}       // generated by second Extension
51  * </pre>
52  *
53  * <p>(The exact naming scheme illustrated here is not fixed and should not be relied on.)
54  *
55  * <p>If an Extension needs its generated class to be the final class in the inheritance hierarchy,
56  * its {@link #mustBeFinal(Context)} method returns true. Only one Extension can return true for a
57  * given context. Only generated classes that will be the final class in the inheritance hierarchy
58  * can be declared final. All others should be declared abstract.
59  *
60  * <p>The first generated class in the hierarchy will always be the one generated by the AutoValue
61  * processor and the last one will always be the one generated by the Extension that {@code
62  * mustBeFinal}, if any. Other than that, the order of the classes in the hierarchy is unspecified.
63  * The last class in the hierarchy is {@code AutoValue_Foo} and that is the one that the
64  * {@code Foo} class will reference, for example with {@code new AutoValue_Foo(...)}.
65  *
66  * <p>Each Extension must also be sure to generate a constructor with arguments corresponding to all
67  * properties in {@link com.google.auto.value.extension.AutoValueExtension.Context#propertyTypes()},
68  * in order, and to call the superclass constructor with the same arguments. This constructor must
69  * have at least package visibility.
70  *
71  * <p>Because the class generated by the AutoValue processor is at the top of the generated
72  * hierarchy, Extensions can override its methods, for example {@code hashCode()},
73  * {@code toString()}, or the implementations of the various {@code bar()} property methods.
74  */
75 public abstract class AutoValueExtension {
76 
77   /** The context of the generation cycle. */
78   public interface Context {
79 
80     /**
81      * Returns the processing environment of this generation cycle. This can be used, among other
82      * things, to produce compilation warnings or errors, using {@link
83      * ProcessingEnvironment#getMessager()}.
84      */
processingEnvironment()85     ProcessingEnvironment processingEnvironment();
86 
87     /** Returns the package name of the classes to be generated. */
packageName()88     String packageName();
89 
90     /**
91      * Returns the annotated class that this generation cycle is based on.
92      *
93      * <p>Given {@code @AutoValue public class Foo {...}}, this will be {@code Foo}.
94      */
autoValueClass()95     TypeElement autoValueClass();
96 
97     /**
98      * The fully-qualified name of the last class in the {@code AutoValue} hierarchy. For an
99      * {@code @AutoValue} class {@code foo.bar.Baz}, this will be {@code foo.bar.AutoValue_Baz}.
100      * The class may be generated by an extension, which will be the current extension if the
101      * {@code isFinal} parameter to {@link AutoValueExtension#generateClass} is true and the
102      * returned string is not {@code null}.
103      *
104      * <p>For compatibility reasons, this method has a default implementation that throws an
105      * exception. The AutoValue processor supplies an implementation that behaves as documented.
106      */
finalAutoValueClassName()107     default String finalAutoValueClassName() {
108       throw new UnsupportedOperationException();
109     }
110 
111     /**
112      * Returns the ordered collection of properties to be generated by AutoValue. Each key is a
113      * property name, and the corresponding value is the getter method for that property. For
114      * example, if property {@code bar} is defined by {@code abstract String getBar()} then this map
115      * will have an entry mapping {@code "bar"} to the {@code ExecutableElement} for {@code
116      * getBar()}.
117      *
118      * <p>To determine the type of a property, it is best to use {@link #propertyTypes()} rather
119      * than looking at the return type of the {@link ExecutableElement} in this map. The reason is
120      * that the final type of the property might be different because of type variables. For
121      * example, if you have...
122      *
123      * <pre>
124      *   {@code interface Parent<T>} {
125      *     T bar();
126      *   }
127      *  {@code @AutoValue abstract class Foo implements Parent<String> {...}}</pre>
128      *
129      * ...then the type of the {@code bar} property in {@code Foo} is actually {@code String}, but
130      * the {@code ExecutableElement} will be the the method in {@code Parent}, whose return type is
131      * {@code T}.
132      */
properties()133     Map<String, ExecutableElement> properties();
134 
135     /**
136      * Returns the properties to be generated by AutoValue, with their types. Each key is a property
137      * name, and the corresponding value is the type of that property. The order of the map entries
138      * is the same as the order of the {@code @AutoValue} properties.
139      *
140      * <p>For example, if property {@code bar} is defined by {@code abstract String getBar()} then
141      * this map will have an entry mapping {@code "bar"} to the {@code TypeMirror} for {@code
142      * String}.
143      *
144      * <p>For compatibility reasons, this method has a default implementation that throws an
145      * exception. The AutoValue processor supplies an implementation that behaves as documented.
146      */
propertyTypes()147     default Map<String, TypeMirror> propertyTypes() {
148       throw new UnsupportedOperationException();
149     }
150 
151     /**
152      * Returns the complete set of abstract methods defined in or inherited by the
153      * {@code @AutoValue} class. This includes all methods that define properties (like {@code
154      * abstract String getBar()}), any abstract {@code toBuilder()} method, and any other abstract
155      * method even if it has been consumed by this or another Extension.
156      */
abstractMethods()157     Set<ExecutableElement> abstractMethods();
158 
159     /**
160      * Returns a representation of the {@code Builder} associated with the {@code @AutoValue} class,
161      * if there is one.
162      *
163      * <p>This method returns {@link Optional#empty()} if called from within the {@link #applicable}
164      * method. If an Extension needs {@code Builder} information to decide whether it is applicable,
165      * it should return {@code true} from the {@link #applicable} method and then return {@code
166      * null} from the {@link #generateClass} method if it does not need to generate a class after
167      * all.
168      *
169      * <p>The default implementation of this method returns {@link Optional#empty()} for
170      * compatibility with extensions which may have implemented this interface themselves.
171      */
builder()172     default Optional<BuilderContext> builder() {
173       return Optional.empty();
174     }
175   }
176 
177   /**
178    * Represents a {@code Builder} associated with an {@code @AutoValue} class.
179    */
180   public interface BuilderContext {
181     /**
182      * Returns the {@code @AutoValue.Builder} interface or abstract class that this object
183      * represents.
184      */
builderType()185     TypeElement builderType();
186 
187     /**
188      * Returns abstract no-argument methods in the {@code @AutoValue} class that return the builder
189      * type.
190      *
191      * <p>Consider a class like this:
192      * <pre>
193      *   {@code @AutoValue} abstract class Foo {
194      *     abstract String bar();
195      *
196      *     abstract Builder toBuilder();
197      *
198      *     ...
199      *     {@code @AutoValue.Builder}
200      *     abstract static class Builder {...}
201      *   }
202      * </pre>
203      *
204      * <p>Here {@code toBuilderMethods()} will return a set containing the method
205      * {@code Foo.toBuilder()}.
206      */
toBuilderMethods()207     Set<ExecutableElement> toBuilderMethods();
208 
209     /**
210      * Returns static no-argument methods in the {@code @AutoValue} class that return the builder
211      * type.
212      *
213      * <p>Consider a class like this:
214      * <pre>
215      *   {@code @AutoValue} abstract class Foo {
216      *     abstract String bar();
217      *
218      *     static Builder builder() {
219      *       return new AutoValue_Foo.Builder()
220      *           .setBar("default bar");
221      *     }
222      *
223      *     {@code @AutoValue.Builder}
224      *     abstract class Builder {
225      *       abstract Builder setBar(String x);
226      *       abstract Foo build();
227      *     }
228      *   }
229      * </pre>
230      *
231      * <p>Here {@code builderMethods()} will return a set containing the method
232      * {@code Foo.builder()}. Generated code should usually call this method in preference to
233      * constructing {@code AutoValue_Foo.Builder()} directly, because this method can establish
234      * default values for properties, as it does here.
235      */
builderMethods()236     Set<ExecutableElement> builderMethods();
237 
238     /**
239      * Returns the method {@code build()} in the builder class, if it exists and returns the
240      * {@code @AutoValue} type. This is the method that generated code for
241      * {@code @AutoValue class Foo} should call in order to get an instance of {@code Foo} from its
242      * builder. The returned method is called {@code build()}; if the builder uses some other name
243      * then extensions have no good way to guess how they should build.
244      *
245      * <p>A common convention is for {@code build()} to be a concrete method in the
246      * {@code @AutoValue.Builder} class, which calls an abstract method {@code autoBuild()} that is
247      * implemented in the generated subclass. The {@code build()} method can then do validation,
248      * defaulting, and so on.
249      */
buildMethod()250     Optional<ExecutableElement> buildMethod();
251 
252     /**
253      * Returns the abstract build method. If the {@code @AutoValue} class is {@code Foo}, this is an
254      * abstract no-argument method in the builder class that returns {@code Foo}. This might be
255      * called {@code build()}, or, following a common convention, it might be called
256      * {@code autoBuild()} and used in the implementation of a {@code build()} method that is
257      * defined in the builder class.
258      *
259      * <p>Extensions should call the {@code build()} method in preference to this one. But they
260      * should override this one if they want to customize build-time behaviour.
261      */
autoBuildMethod()262     ExecutableElement autoBuildMethod();
263 
264     /**
265      * Returns a map from property names to the corresponding setters. A property may have more than
266      * one setter. For example, an {@code ImmutableList<String>} might be set by
267      * {@code setFoo(ImmutableList<String>)} and {@code setFoo(String[])}.
268      */
setters()269     Map<String, Set<ExecutableElement>> setters();
270 
271     /**
272      * Returns a map from property names to property builders. For example, if there is a property
273      * {@code foo} defined by {@code abstract ImmutableList<String> foo();} or
274      * {@code abstract ImmutableList<String> getFoo();} in the {@code @AutoValue} class,
275      * then there can potentially be a builder defined by
276      * {@code abstract ImmutableList.Builder<String> fooBuilder();} in the
277      * {@code @AutoValue.Builder} class. This map would then map {@code "foo"} to the
278      * {@link ExecutableElement} representing {@code fooBuilder()}.
279      */
propertyBuilders()280     Map<String, ExecutableElement> propertyBuilders();
281   }
282 
283   /**
284    * Indicates to an annotation processor environment supporting incremental annotation processing
285    * (currently a feature specific to Gradle starting with version 4.8) the incremental type of an
286    * Extension.
287    *
288    * <p>The constants for this enum are ordered by increasing performance (but also constraints).
289    *
290    * @see <a
291    *     href="https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing">Gradle
292    *     documentation of its incremental annotation processing</a>
293    */
294   public enum IncrementalExtensionType {
295     /**
296      * The incrementality of this extension is unknown, or it is neither aggregating nor isolating.
297      */
298     UNKNOWN,
299 
300     /**
301      * This extension is <i>aggregating</i>, meaning that it may generate outputs based on several
302      * annotated input classes and it respects the constraints imposed on aggregating processors.
303      * It is unusual for AutoValue extensions to be aggregating.
304      *
305      * @see <a
306      *     href="https://docs.gradle.org/current/userguide/java_plugin.html#aggregating_annotation_processors">Gradle
307      *     definition of aggregating processors</a>
308      */
309     AGGREGATING,
310 
311     /**
312      * This extension is <i>isolating</i>, meaning roughly that its output depends on the
313      * {@code @AutoValue} class and its dependencies, but not on other {@code @AutoValue} classes
314      * that might be compiled at the same time. The constraints that an isolating extension must
315      * respect are the same as those that Gradle imposes on an isolating annotation processor.
316      *
317      * @see <a
318      *     href="https://docs.gradle.org/current/userguide/java_plugin.html#isolating_annotation_processors">Gradle
319      *     definition of isolating processors</a>
320      */
321     ISOLATING
322   }
323 
324   /**
325    * Determines the incremental type of this Extension.
326    *
327    * <p>The {@link ProcessingEnvironment} can be used, among other things, to obtain the processor
328    * options, using {@link ProcessingEnvironment#getOptions()}.
329    *
330    * <p>The actual incremental type of the AutoValue processor as a whole will be the loosest
331    * incremental types of the Extensions present in the annotation processor path. The default
332    * returned value is {@link IncrementalExtensionType#UNKNOWN}, which will disable incremental
333    * annotation processing entirely.
334    */
incrementalType(ProcessingEnvironment processingEnvironment)335   public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {
336     return IncrementalExtensionType.UNKNOWN;
337   }
338 
339   /**
340    * Analogous to {@link Processor#getSupportedOptions()}, here to allow extensions to report their
341    * own.
342    *
343    * <p>By default, if the extension class is annotated with {@link SupportedOptions}, this will
344    * return a set with the strings in the annotation. If the class is not so annotated, an empty set
345    * is returned.
346    *
347    * @return the set of options recognized by this extension or an empty set if none
348    * @see SupportedOptions
349    */
getSupportedOptions()350   public Set<String> getSupportedOptions() {
351     SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class);
352     if (so == null) {
353       return ImmutableSet.of();
354     } else {
355       return ImmutableSet.copyOf(so.value());
356     }
357   }
358 
359   /**
360    * Determines whether this Extension applies to the given context. If an Extension returns {@code
361    * false} for a given class, it will not be called again during the processing of that class. An
362    * Extension can return {@code true} and still choose not to generate any code for the class, by
363    * returning {@code null} from {@link #generateClass}. That is often a more flexible approach.
364    *
365    * @param context The Context of the code generation for this class.
366    */
applicable(Context context)367   public boolean applicable(Context context) {
368     return false;
369   }
370 
371   /**
372    * Denotes that the class generated by this Extension must be the final class in the inheritance
373    * hierarchy. Only one Extension may be the final class, so this should be used sparingly.
374    *
375    * @param context the Context of the code generation for this class.
376    */
mustBeFinal(Context context)377   public boolean mustBeFinal(Context context) {
378     return false;
379   }
380 
381   /**
382    * Returns a possibly empty set of property names that this Extension intends to implement. This
383    * will prevent AutoValue from generating an implementation, and remove the supplied properties
384    * from builders, constructors, {@code toString}, {@code equals}, and {@code hashCode}. The
385    * default set returned by this method is empty.
386    *
387    * <p>Each returned string must be one of the property names in {@link Context#properties()}.
388    *
389    * <p>Returning a property name from this method is equivalent to returning the property's getter
390    * method from {@link #consumeMethods}.
391    *
392    * <p>For example, Android's {@code Parcelable} interface includes a <a
393    * href="http://developer.android.com/reference/android/os/Parcelable.html#describeContents()">method</a>
394    * {@code int describeContents()}. Since this is an abstract method with no parameters, by default
395    * AutoValue will consider that it defines an {@code int} property called {@code
396    * describeContents}. If an {@code @AutoValue} class implements {@code Parcelable} and does not
397    * provide an implementation of this method, by default its implementation will include {@code
398    * describeContents} in builders, constructors, and so on. But an {@code AutoValueExtension} that
399    * understands {@code Parcelable} can instead provide a useful implementation and return a set
400    * containing {@code "describeContents"}. Then {@code describeContents} will be omitted from
401    * builders and the rest.
402    *
403    * @param context the Context of the code generation for this class.
404    */
consumeProperties(Context context)405   public Set<String> consumeProperties(Context context) {
406     return ImmutableSet.of();
407   }
408 
409   /**
410    * Returns a possible empty set of abstract methods that this Extension intends to implement. This
411    * will prevent AutoValue from generating an implementation, in cases where it would have, and it
412    * will also avoid warnings about abstract methods that AutoValue doesn't expect. The default set
413    * returned by this method is empty.
414    *
415    * <p>Each returned method must be one of the abstract methods in {@link
416    * Context#abstractMethods()}.
417    *
418    * <p>For example, Android's {@code Parcelable} interface includes a <a
419    * href="http://developer.android.com/reference/android/os/Parcelable.html#writeToParcel(android.os.Parcel,int)">method</a>
420    * {@code void writeToParcel(Parcel, int)}. Normally AutoValue would not know what to do with that
421    * abstract method. But an {@code AutoValueExtension} that understands {@code Parcelable} can
422    * provide a useful implementation and return the {@code writeToParcel} method here. That will
423    * prevent a warning about the method from AutoValue.
424    *
425    * @param context the Context of the code generation for this class.
426    */
consumeMethods(Context context)427   public Set<ExecutableElement> consumeMethods(Context context) {
428     return ImmutableSet.of();
429   }
430 
431   /**
432    * Returns the generated source code of the class named {@code className} to extend {@code
433    * classToExtend}, or {@code null} if this extension does not generate a class in the hierarchy.
434    * If there is a generated class, it should be final if {@code isFinal} is true; otherwise it
435    * should be abstract. The returned string should be a complete Java class definition of the class
436    * {@code className} in the package {@link Context#packageName() context.packageName()}.
437    *
438    * <p>The returned string will typically look like this:
439    *
440    * <pre>{@code
441    * package <package>;
442    * ...
443    * <finalOrAbstract> class <className> extends <classToExtend> {
444    *   // Constructor
445    *   <className>(<constructorParameters>) {
446    *     super(<constructorParameterNames>);
447    *     ...
448    *   }
449    *   ...
450    * }}</pre>
451    *
452    * <p>Here, {@code <package>} is {@link Context#packageName()}; {@code <finalOrAbstract>} is the
453    * keyword {@code final} if {@code isFinal} is true or {@code abstract} otherwise; and {@code
454    * <className>} and {@code <classToExtend>} are the values of this method's parameters of the same
455    * name. The {@code <constructorParameters>} and {@code <constructorParameterNames>} are typically
456    * derived from {@link Context#propertyTypes()}.
457    *
458    * @param context The {@link Context} of the code generation for this class.
459    * @param className The simple name of the resulting class. The returned code will be written to a
460    *     file named accordingly.
461    * @param classToExtend The simple name of the direct parent of the generated class. This could be
462    *     the AutoValue generated class, or a class generated as the result of another Extension.
463    * @param isFinal True if this class is the last class in the chain, meaning it should be marked
464    *     as final. Otherwise it should be marked as abstract.
465    * @return The source code of the generated class, or {@code null} if this extension does not
466    *     generate a class in the hierarchy.
467    */
generateClass( Context context, String className, String classToExtend, boolean isFinal)468   public abstract String generateClass(
469       Context context, String className, String classToExtend, boolean isFinal);
470 }
471