• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 package com.google.auto.value;
15 
16 import java.lang.annotation.Annotation;
17 import java.lang.annotation.ElementType;
18 import java.lang.annotation.Retention;
19 import java.lang.annotation.RetentionPolicy;
20 import java.lang.annotation.Target;
21 
22 /**
23  * Specifies that <a href="https://github.com/google/auto/tree/main/value">AutoValue</a> should
24  * generate an implementation class for the annotated abstract class, implementing the standard
25  * {@link Object} methods like {@link Object#equals equals} to have conventional value semantics. A
26  * simple example:
27  *
28  * <pre>
29  *
30  *   {@code @}AutoValue
31  *   abstract class Person {
32  *     static Person create(String name, int id) {
33  *       return new AutoValue_Person(name, id);
34  *     }
35  *
36  *     abstract String name();
37  *     abstract int id();
38  *   }</pre>
39  *
40  * @see <a href="https://github.com/google/auto/tree/main/value">AutoValue User's Guide</a>
41  * @author Éamonn McManus
42  * @author Kevin Bourrillion
43  */
44 @Retention(RetentionPolicy.CLASS)
45 @Target(ElementType.TYPE)
46 public @interface AutoValue {
47 
48   /**
49    * Specifies that AutoValue should generate an implementation of the annotated class or interface,
50    * to serve as a <i>builder</i> for the value-type class it is nested within. As a simple example,
51    * here is an alternative way to write the {@code Person} class mentioned in the {@link AutoValue}
52    * example:
53    *
54    * <pre>
55    *
56    *   {@code @}AutoValue
57    *   abstract class Person {
58    *     static Builder builder() {
59    *       return new AutoValue_Person.Builder();
60    *     }
61    *
62    *     abstract String name();
63    *     abstract int id();
64    *
65    *     {@code @}AutoValue.Builder
66    *     interface Builder {
67    *       Builder name(String x);
68    *       Builder id(int x);
69    *       Person build();
70    *     }
71    *   }</pre>
72    *
73    * @author Éamonn McManus
74    */
75   @Retention(RetentionPolicy.CLASS)
76   @Target(ElementType.TYPE)
77   public @interface Builder {}
78 
79   /**
80    * Specifies that AutoValue should copy any annotations from the annotated element to the
81    * generated class. This annotation supports classes and methods.
82    *
83    * <p>The following annotations are excluded:
84    *
85    * <ol>
86    *   <li>AutoValue and its nested annotations;
87    *   <li>any annotation appearing in the {@link AutoValue.CopyAnnotations#exclude} field;
88    *   <li>any class annotation which is itself annotated with the {@link
89    *       java.lang.annotation.Inherited} meta-annotation.
90    * </ol>
91    *
92    * <p>For historical reasons, annotations are always copied from an {@code @AutoValue} property
93    * method to its implementation, unless {@code @CopyAnnotations} is present and explicitly
94    * {@linkplain CopyAnnotations#exclude excludes} that annotation. But annotations are not copied
95    * from the {@code @AutoValue} class itself to its implementation unless {@code @CopyAnnotations}
96    * is present.
97    *
98    * <p>If you want to copy annotations from your {@literal @}AutoValue-annotated class's methods to
99    * the generated fields in the AutoValue_... implementation, annotate your method
100    * with {@literal @}AutoValue.CopyAnnotations. For example, if Example.java is:<pre>
101    *
102    *   {@code @}Immutable
103    *   {@code @}AutoValue
104    *   abstract class Example {
105    *     {@code @}CopyAnnotations
106    *     {@code @}SuppressWarnings("Immutable") // justification ...
107    *     abstract Object getObject();
108    *     // other details ...
109    *   }</pre>
110    *
111    * <p>Then AutoValue will generate the following AutoValue_Example.java:<pre>
112    *
113    *   final class AutoValue_Example extends Example {
114    *     {@code @}SuppressWarnings("Immutable")
115    *     private final Object object;
116    *
117    *     {@code @}SuppressWarnings("Immutable")
118    *     {@code @}Override
119    *     Object getObject() {
120    *       return object;
121    *     }
122    *
123    *     // other details ...
124    *   }</pre>
125    *
126    * <p>When the <i>type</i> of an {@code @AutoValue} property method has annotations, those are
127    * part of the type, so by default they are copied to the implementation of the method. But if
128    * a type annotation is mentioned in {@code exclude} then it is not copied.
129    *
130    * <p>For example, suppose {@code @Confidential} is a
131    * {@link java.lang.annotation.ElementType#TYPE_USE TYPE_USE} annotation:
132    *
133    * <pre>
134    *
135    *   {@code @}AutoValue
136    *   abstract class Person {
137    *     static Person create({@code @}Confidential String name, int id) {
138    *       return new AutoValue_Person(name, id);
139    *     }
140    *
141    *     abstract {@code @}Confidential String name();
142    *     abstract int id();
143    *   }</pre>
144    *
145    * Then the implementation of the {@code name()} method will also have return type
146    * {@code @Confidential String}. But if {@code name()} were written like this...
147    *
148    * <pre>
149    *
150    *     {@code @AutoValue.CopyAnnotations(exclude = Confidential.class)}
151    *     abstract {@code @}Confidential String name();</pre>
152    *
153    * <p>...then the implementation of {@code name()} would have return type {@code String} without
154    * the annotation.
155    *
156    * @author Carmi Grushko
157    */
158   @Retention(RetentionPolicy.CLASS)
159   @Target({ElementType.TYPE, ElementType.METHOD})
160   public @interface CopyAnnotations {
exclude()161     Class<? extends Annotation>[] exclude() default {};
162   }
163 }
164