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