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