1 /*
2  * Copyright (C) 2021 The Android Open Source Project
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.android.car.internal.util;
17 
18 import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
19 import static java.lang.annotation.ElementType.CONSTRUCTOR;
20 import static java.lang.annotation.ElementType.FIELD;
21 import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
22 import static java.lang.annotation.ElementType.METHOD;
23 import static java.lang.annotation.ElementType.PARAMETER;
24 import static java.lang.annotation.ElementType.TYPE;
25 
26 import android.annotation.IntDef;
27 import android.annotation.Nullable;
28 import android.annotation.StringDef;
29 import android.os.Parcelable;
30 
31 import java.lang.annotation.ElementType;
32 import java.lang.annotation.Retention;
33 import java.lang.annotation.RetentionPolicy;
34 import java.lang.annotation.Target;
35 
36 /**
37  * {@code com.android.internal.util.DataClass} replacement for car-lib.
38  *
39  * @hide
40  */
41 @Retention(RetentionPolicy.SOURCE)
42 @Target(ElementType.TYPE)
43 public @interface DataClass {
44 
45     /**
46      * Generates {@link Parcelable#writeToParcel}, {@link Parcelable#describeContents} and a
47      * {@link Parcelable.Creator}.
48      *
49      * Can be implicitly requested by adding "implements Parcelable" to class signature
50      *
51      * You can provide custom parceling logic by using a {@link ParcelWith} annotation with a
52      * custom {@link Parcelling} subclass.
53      *
54      * Alternatively, for one-off customizations you can declare methods like:
55      * {@code void parcelFieldName(Parcel dest, int flags)}
56      * {@code static FieldType unparcelFieldName(Parcel in)}
57      *
58      * @hide
59      */
genParcelable()60     boolean genParcelable() default false;
61 
62     /**
63      * Generates a simple "parcelable" .aidl file alongside the original .java file
64      *
65      * If not explicitly requested/suppressed, is on iff {@link #genParcelable} is on
66      */
genAidl()67     boolean genAidl() default false;
68 
69     /**
70      * Generates getters for each field.
71      *
72      * You can request for getter to lazily initialize your field by declaring a method like:
73      * {@code FieldType lazyInitFieldName()}
74      *
75      * You can request for the lazy initialization to be thread safe my marking the field volatile.
76      */
genGetters()77     boolean genGetters() default true;
78 
79     /**
80      * {@link #genGetters} with @hide
81      */
genHiddenGetters()82     boolean genHiddenGetters() default false;
83 
84     /**
85      * Generates setters for each field.
86      */
genSetters()87     boolean genSetters() default false;
88 
89     /**
90      * {@link #genSetters} with @hide
91      */
genHiddenSetters()92     boolean genHiddenSetters() default false;
93 
94     /**
95      * Generates a public constructor with each field initialized from a parameter and optionally
96      * some user-defined state validation at the end.
97      *
98      * Uses field {@link Nullable nullability}/default value presence to determine optional
99      * parameters.
100      *
101      * Requesting a {@link #genBuilder} suppresses public constructor generation by default.
102      *
103      * You receive a callback at the end of constructor call by declaring the method:
104      * {@code void onConstructed()}
105      * This is the place to put any custom validation logic.
106      */
genConstructor()107     boolean genConstructor() default true;
108 
109     /**
110      * {@link #genConstructor} with @hide
111      */
genHiddenConstructor()112     boolean genHiddenConstructor() default false;
113 
114     /**
115      * Generates a Builder for your class.
116      *
117      * Uses a package-private constructor under the hood, so same rules hold as for
118      * {@link #genConstructor()}
119      */
genBuilder()120     boolean genBuilder() default false;
121 
122     /**
123      * {@link #genBuilder} with @hide
124      */
genHiddenBuilder()125     boolean genHiddenBuilder() default false;
126 
127     /**
128      * Generates a structural {@link Object#equals} + {@link Object#hashCode}.
129      *
130      * You can customize individual fields' logic by declaring methods like:
131      * {@link boolean fieldNameEquals(ClassName otherInstance)}
132      * {@link boolean fieldNameEquals(FieldType otherValue)}
133      * {@link int fieldNameHashCode()}
134      */
genEqualsHashCode()135     boolean genEqualsHashCode() default false;
136 
137     /**
138      * Generates a structural {@link Object#toString}.
139      *
140      * You can customize individual fields' logic by declaring methods like:
141      * {@link String fieldNameToString()}
142      */
genToString()143     boolean genToString() default false;
144 
145     /**
146      * Generates a utility method that takes a {@link PerObjectFieldAction per-field callback}
147      * and calls it once for each field with its name and value.
148      *
149      * If some fields are of primitive types, and additional overload is generated that takes
150      * multiple callbacks, specialized for used primitive types to avoid auto-boxing, e.g.
151      * {@link PerIntFieldAction}.
152      */
genForEachField()153     boolean genForEachField() default false;
154 
155     /**
156      * Generates a constructor that copies the given instance of the same class.
157      */
genCopyConstructor()158     boolean genCopyConstructor() default false;
159 
160     /**
161      * {@link #genCopyConstructor} with @hide
162      */
genHiddenCopyConstructor()163     boolean genHiddenCopyConstructor() default false;
164 
165     /**
166      * Generates constant annotations({@link IntDef}/{@link StringDef}) for any constant groups
167      * with common prefix.
168      * The annotation names are based on the common prefix.
169      *
170      * For int constants this additionally generates the corresponding static *ToString method and
171      * uses it in {@link Object#toString}.
172      *
173      * Additionally, any fields you annotate with the generated constants will be automatically
174      * validated in constructor.
175      *
176      * Int constants specified as hex(0x..) are considered to be flags, which is taken into account
177      * for in their *ToString and validation.
178      *
179      * You can optionally override the name of the generated annotation by annotating each constant
180      * with the desired annotation name.
181      *
182      * Unless suppressed, is implied by presence of constants with common prefix.
183      */
genConstDefs()184     boolean genConstDefs() default true;
185 
186     /**
187      * {@link #genConstDefs} with @hide
188      */
genHiddenConstDefs()189     boolean genHiddenConstDefs() default false;
190 
191 
192     /**
193      * Allows specifying custom parcelling logic based on reusable
194      * {@link Parcelling} implementations
195      */
196     @Retention(RetentionPolicy.SOURCE)
197     @Target(FIELD)
198     @interface ParcelWith {
value()199         Class<? extends Parcelling> value();
200     }
201 
202     /**
203      * Allows specifying a singular name for a builder's plural field name e.g. 'name' for 'mNames'
204      * Used for Builder's {@code addName(String name)} methods
205      */
206     @Retention(RetentionPolicy.SOURCE)
207     @Target(FIELD)
208     @interface PluralOf {
value()209         String value();
210     }
211 
212     /**
213      * Marks that any annotations following it are applicable to each element of the
214      * collection/array, as opposed to itself.
215      */
216     @Retention(RetentionPolicy.SOURCE)
217     @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
218     @interface Each {}
219 
220     /**
221      * @deprecated to be used by code generator exclusively
222      */
223     @Deprecated
224     @Retention(RetentionPolicy.SOURCE)
225     @Target({METHOD})
226     @interface Generated {
time()227         long time();
codegenVersion()228         String codegenVersion();
sourceFile()229         String sourceFile();
inputSignatures()230         String inputSignatures() default "";
231 
232         /**
233          * @deprecated to be used by code generator exclusively
234          */
235         @Deprecated
236         @Retention(RetentionPolicy.SOURCE)
237         @Target({FIELD, METHOD, ANNOTATION_TYPE, CONSTRUCTOR, TYPE})
238         @interface Member {}
239     }
240 
241     /**
242      * Opt out of generating {@link #genConstDefs IntDef/StringDef}s for annotated constant
243      */
244     @Retention(RetentionPolicy.SOURCE)
245     @Target({FIELD})
246     @interface SuppressConstDefsGeneration {}
247 
248     /**
249      * A class-level annotation to suppress methods' generation by name
250      */
251     @Retention(RetentionPolicy.SOURCE)
252     @Target({TYPE})
253     @interface Suppress {
value()254         String[] value();
255     }
256 
257     /**
258      * Mark that the field should have a {@link Nullable} argument for its setter.
259      */
260     @Retention(RetentionPolicy.SOURCE)
261     @Target({FIELD})
262     @interface MaySetToNull {}
263 
264     /**
265      * Callback used by {@link #genForEachField}.
266      *
267      * @param <THIS> The enclosing data class instance.
268      *              Can be used to try and avoid capturing values from outside of the lambda,
269      *              minimizing allocations.
270      */
271     interface PerObjectFieldAction<THIS> {
acceptObject(THIS self, String fieldName, Object fieldValue)272         void acceptObject(THIS self, String fieldName, Object fieldValue);
273     }
274 
275     /**
276      * A specialization of {@link PerObjectFieldAction} called exclusively for int fields to avoid
277      * boxing.
278      *
279      * @param <THIS> The enclosing data class instance.
280      */
281     interface PerIntFieldAction<THIS> {
acceptInt(THIS self, String fieldName, int fieldValue)282         void acceptInt(THIS self, String fieldName, int fieldValue);
283     }
284 }
285