• 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      *   interface Parent<T> {
125      *     T bar();
126      *   }
127      *
128      *  {@code @AutoValue abstract class Foo implements Parent<String> {...}}
129      * </pre>
130      *
131      * ...then the type of the {@code bar} property in {@code Foo} is actually {@code String}, but
132      * the {@code ExecutableElement} will be the the method in {@code Parent}, whose return type is
133      * {@code T}.
134      */
properties()135     Map<String, ExecutableElement> properties();
136 
137     /**
138      * Returns the properties to be generated by AutoValue, with their types. Each key is a property
139      * name, and the corresponding value is the type of that property. The order of the map entries
140      * is the same as the order of the {@code @AutoValue} properties.
141      *
142      * <p>For example, if property {@code bar} is defined by {@code abstract String getBar()} then
143      * this map will have an entry mapping {@code "bar"} to the {@code TypeMirror} for {@code
144      * String}.
145      *
146      * <p>For compatibility reasons, this method has a default implementation that throws an
147      * exception. The AutoValue processor supplies an implementation that behaves as documented.
148      */
propertyTypes()149     default Map<String, TypeMirror> propertyTypes() {
150       throw new UnsupportedOperationException();
151     }
152 
153     /**
154      * Returns the complete set of abstract methods defined in or inherited by the
155      * {@code @AutoValue} class. This includes all methods that define properties (like {@code
156      * abstract String getBar()}), any abstract {@code toBuilder()} method, and any other abstract
157      * method even if it has been consumed by this or another Extension.
158      */
abstractMethods()159     Set<ExecutableElement> abstractMethods();
160 
161     /**
162      * Returns a representation of the {@code Builder} associated with the {@code @AutoValue} class,
163      * if there is one.
164      *
165      * <p>This method returns {@link Optional#empty()} if called from within the {@link #applicable}
166      * method. If an Extension needs {@code Builder} information to decide whether it is applicable,
167      * it should return {@code true} from the {@link #applicable} method and then return {@code
168      * null} from the {@link #generateClass} method if it does not need to generate a class after
169      * all.
170      *
171      * <p>The default implementation of this method returns {@link Optional#empty()} for
172      * compatibility with extensions which may have implemented this interface themselves.
173      */
builder()174     default Optional<BuilderContext> builder() {
175       return Optional.empty();
176     }
177   }
178 
179   /**
180    * Represents a {@code Builder} associated with an {@code @AutoValue} class.
181    */
182   public interface BuilderContext {
183     /**
184      * Returns the {@code @AutoValue.Builder} interface or abstract class that this object
185      * represents.
186      */
builderType()187     TypeElement builderType();
188 
189     /**
190      * Returns abstract no-argument methods in the {@code @AutoValue} class that return the builder
191      * type.
192      *
193      * <p>Consider a class like this:
194      * <pre>
195      *   {@code @AutoValue} abstract class Foo {
196      *     abstract String bar();
197      *
198      *     abstract Builder toBuilder();
199      *
200      *     ...
201      *     {@code @AutoValue.Builder}
202      *     abstract static class Builder {...}
203      *   }
204      * </pre>
205      *
206      * <p>Here {@code toBuilderMethods()} will return a set containing the method
207      * {@code Foo.toBuilder()}.
208      */
toBuilderMethods()209     Set<ExecutableElement> toBuilderMethods();
210 
211     /**
212      * Returns static no-argument methods in the {@code @AutoValue} class that return the builder
213      * type.
214      *
215      * <p>Consider a class like this:
216      * <pre>
217      *   {@code @AutoValue} abstract class Foo {
218      *     abstract String bar();
219      *
220      *     static Builder builder() {
221      *       return new AutoValue_Foo.Builder()
222      *           .setBar("default bar");
223      *     }
224      *
225      *     {@code @AutoValue.Builder}
226      *     abstract class Builder {
227      *       abstract Builder setBar(String x);
228      *       abstract Foo build();
229      *     }
230      *   }
231      * </pre>
232      *
233      * <p>Here {@code builderMethods()} will return a set containing the method
234      * {@code Foo.builder()}. Generated code should usually call this method in preference to
235      * constructing {@code AutoValue_Foo.Builder()} directly, because this method can establish
236      * default values for properties, as it does here.
237      */
builderMethods()238     Set<ExecutableElement> builderMethods();
239 
240     /**
241      * Returns the method {@code build()} in the builder class, if it exists and returns the
242      * {@code @AutoValue} type. This is the method that generated code for
243      * {@code @AutoValue class Foo} should call in order to get an instance of {@code Foo} from its
244      * builder. The returned method is called {@code build()}; if the builder uses some other name
245      * then extensions have no good way to guess how they should build.
246      *
247      * <p>A common convention is for {@code build()} to be a concrete method in the
248      * {@code @AutoValue.Builder} class, which calls an abstract method {@code autoBuild()} that is
249      * implemented in the generated subclass. The {@code build()} method can then do validation,
250      * defaulting, and so on.
251      */
buildMethod()252     Optional<ExecutableElement> buildMethod();
253 
254     /**
255      * Returns the abstract build method. If the {@code @AutoValue} class is {@code Foo}, this is an
256      * abstract no-argument method in the builder class that returns {@code Foo}. This might be
257      * called {@code build()}, or, following a common convention, it might be called
258      * {@code autoBuild()} and used in the implementation of a {@code build()} method that is
259      * defined in the builder class.
260      *
261      * <p>Extensions should call the {@code build()} method in preference to this one. But they
262      * should override this one if they want to customize build-time behaviour.
263      */
autoBuildMethod()264     ExecutableElement autoBuildMethod();
265 
266     /**
267      * Returns a map from property names to the corresponding setters. A property may have more than
268      * one setter. For example, an {@code ImmutableList<String>} might be set by
269      * {@code setFoo(ImmutableList<String>)} and {@code setFoo(String[])}.
270      */
setters()271     Map<String, Set<ExecutableElement>> setters();
272 
273     /**
274      * Returns a map from property names to property builders. For example, if there is a property
275      * {@code foo} defined by {@code abstract ImmutableList<String> foo();} or
276      * {@code abstract ImmutableList<String> getFoo();} in the {@code @AutoValue} class,
277      * then there can potentially be a builder defined by
278      * {@code abstract ImmutableList.Builder<String> fooBuilder();} in the
279      * {@code @AutoValue.Builder} class. This map would then map {@code "foo"} to the
280      * {@link ExecutableElement} representing {@code fooBuilder()}.
281      */
propertyBuilders()282     Map<String, ExecutableElement> propertyBuilders();
283   }
284 
285   /**
286    * Indicates to an annotation processor environment supporting incremental annotation processing
287    * (currently a feature specific to Gradle starting with version 4.8) the incremental type of an
288    * Extension.
289    *
290    * <p>The constants for this enum are ordered by increasing performance (but also constraints).
291    *
292    * @see <a
293    *     href="https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing">Gradle
294    *     documentation of its incremental annotation processing</a>
295    */
296   public enum IncrementalExtensionType {
297     /**
298      * The incrementality of this extension is unknown, or it is neither aggregating nor isolating.
299      */
300     UNKNOWN,
301 
302     /**
303      * This extension is <i>aggregating</i>, meaning that it may generate outputs based on several
304      * annotated input classes and it respects the constraints imposed on aggregating processors.
305      * It is unusual for AutoValue extensions to be aggregating.
306      *
307      * @see <a
308      *     href="https://docs.gradle.org/current/userguide/java_plugin.html#aggregating_annotation_processors">Gradle
309      *     definition of aggregating processors</a>
310      */
311     AGGREGATING,
312 
313     /**
314      * This extension is <i>isolating</i>, meaning roughly that its output depends on the
315      * {@code @AutoValue} class and its dependencies, but not on other {@code @AutoValue} classes
316      * that might be compiled at the same time. The constraints that an isolating extension must
317      * respect are the same as those that Gradle imposes on an isolating annotation processor.
318      *
319      * @see <a
320      *     href="https://docs.gradle.org/current/userguide/java_plugin.html#isolating_annotation_processors">Gradle
321      *     definition of isolating processors</a>
322      */
323     ISOLATING
324   }
325 
326   /**
327    * Determines the incremental type of this Extension.
328    *
329    * <p>The {@link ProcessingEnvironment} can be used, among other things, to obtain the processor
330    * options, using {@link ProcessingEnvironment#getOptions()}.
331    *
332    * <p>The actual incremental type of the AutoValue processor as a whole will be the loosest
333    * incremental types of the Extensions present in the annotation processor path. The default
334    * returned value is {@link IncrementalExtensionType#UNKNOWN}, which will disable incremental
335    * annotation processing entirely.
336    */
incrementalType(ProcessingEnvironment processingEnvironment)337   public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {
338     return IncrementalExtensionType.UNKNOWN;
339   }
340 
341   /**
342    * Analogous to {@link Processor#getSupportedOptions()}, here to allow extensions to report their
343    * own.
344    *
345    * <p>By default, if the extension class is annotated with {@link SupportedOptions}, this will
346    * return a set with the strings in the annotation. If the class is not so annotated, an empty set
347    * is returned.
348    *
349    * @return the set of options recognized by this extension or an empty set if none
350    * @see SupportedOptions
351    */
getSupportedOptions()352   public Set<String> getSupportedOptions() {
353     SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class);
354     if (so == null) {
355       return ImmutableSet.of();
356     } else {
357       return ImmutableSet.copyOf(so.value());
358     }
359   }
360 
361   /**
362    * Determines whether this Extension applies to the given context. If an Extension returns {@code
363    * false} for a given class, it will not be called again during the processing of that class. An
364    * Extension can return {@code true} and still choose not to generate any code for the class, by
365    * returning {@code null} from {@link #generateClass}. That is often a more flexible approach.
366    *
367    * @param context The Context of the code generation for this class.
368    */
applicable(Context context)369   public boolean applicable(Context context) {
370     return false;
371   }
372 
373   /**
374    * Denotes that the class generated by this Extension must be the final class in the inheritance
375    * hierarchy. Only one Extension may be the final class, so this should be used sparingly.
376    *
377    * @param context the Context of the code generation for this class.
378    */
mustBeFinal(Context context)379   public boolean mustBeFinal(Context context) {
380     return false;
381   }
382 
383   /**
384    * Returns a possibly empty set of property names that this Extension intends to implement. This
385    * will prevent AutoValue from generating an implementation, and remove the supplied properties
386    * from builders, constructors, {@code toString}, {@code equals}, and {@code hashCode}. The
387    * default set returned by this method is empty.
388    *
389    * <p>Each returned string must be one of the property names in {@link Context#properties()}.
390    *
391    * <p>Returning a property name from this method is equivalent to returning the property's getter
392    * method from {@link #consumeMethods}.
393    *
394    * <p>For example, Android's {@code Parcelable} interface includes a <a
395    * href="http://developer.android.com/reference/android/os/Parcelable.html#describeContents()">method</a>
396    * {@code int describeContents()}. Since this is an abstract method with no parameters, by default
397    * AutoValue will consider that it defines an {@code int} property called {@code
398    * describeContents}. If an {@code @AutoValue} class implements {@code Parcelable} and does not
399    * provide an implementation of this method, by default its implementation will include {@code
400    * describeContents} in builders, constructors, and so on. But an {@code AutoValueExtension} that
401    * understands {@code Parcelable} can instead provide a useful implementation and return a set
402    * containing {@code "describeContents"}. Then {@code describeContents} will be omitted from
403    * builders and the rest.
404    *
405    * @param context the Context of the code generation for this class.
406    */
consumeProperties(Context context)407   public Set<String> consumeProperties(Context context) {
408     return ImmutableSet.of();
409   }
410 
411   /**
412    * Returns a possible empty set of abstract methods that this Extension intends to implement. This
413    * will prevent AutoValue from generating an implementation, in cases where it would have, and it
414    * will also avoid warnings about abstract methods that AutoValue doesn't expect. The default set
415    * returned by this method is empty.
416    *
417    * <p>Each returned method must be one of the abstract methods in {@link
418    * Context#abstractMethods()}.
419    *
420    * <p>For example, Android's {@code Parcelable} interface includes a <a
421    * href="http://developer.android.com/reference/android/os/Parcelable.html#writeToParcel(android.os.Parcel,
422    * int)">method</a> {@code void writeToParcel(Parcel, int)}. Normally AutoValue would not know
423    * what to do with that abstract method. But an {@code AutoValueExtension} that understands {@code
424    * Parcelable} can provide a useful implementation and return the {@code writeToParcel} method
425    * here. That will prevent a warning about the method from AutoValue.
426    *
427    * @param context the Context of the code generation for this class.
428    */
consumeMethods(Context context)429   public Set<ExecutableElement> consumeMethods(Context context) {
430     return ImmutableSet.of();
431   }
432 
433   /**
434    * Returns the generated source code of the class named {@code className} to extend {@code
435    * classToExtend}, or {@code null} if this extension does not generate a class in the hierarchy.
436    * If there is a generated class, it should be final if {@code isFinal} is true; otherwise it
437    * should be abstract. The returned string should be a complete Java class definition of the class
438    * {@code className} in the package {@link Context#packageName() context.packageName()}.
439    *
440    * <p>The returned string will typically look like this:
441    *
442    * <pre>{@code
443    * package <package>;
444    * ...
445    * <finalOrAbstract> class <className> extends <classToExtend> {
446    *   // Constructor
447    *   <className>(<constructorParameters>) {
448    *     super(<constructorParameterNames>);
449    *     ...
450    *   }
451    *   ...
452    * }}</pre>
453    *
454    * <p>Here, {@code <package>} is {@link Context#packageName()}; {@code <finalOrAbstract>} is the
455    * keyword {@code final} if {@code isFinal} is true or {@code abstract} otherwise; and {@code
456    * <className>} and {@code <classToExtend>} are the values of this method's parameters of the same
457    * name. The {@code <constructorParameters>} and {@code <constructorParameterNames>} are typically
458    * derived from {@link Context#propertyTypes()}.
459    *
460    * @param context The {@link Context} of the code generation for this class.
461    * @param className The simple name of the resulting class. The returned code will be written to a
462    *     file named accordingly.
463    * @param classToExtend The simple name of the direct parent of the generated class. This could be
464    *     the AutoValue generated class, or a class generated as the result of another Extension.
465    * @param isFinal True if this class is the last class in the chain, meaning it should be marked
466    *     as final. Otherwise it should be marked as abstract.
467    * @return The source code of the generated class, or {@code null} if this extension does not
468    *     generate a class in the hierarchy.
469    */
generateClass( Context context, String className, String classToExtend, boolean isFinal)470   public abstract String generateClass(
471       Context context, String className, String classToExtend, boolean isFinal);
472 }
473