1 /*
2  * Copyright 2023 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 
17 package androidx.appsearch.compiler.annotationwrapper;
18 
19 import static androidx.appsearch.compiler.IntrospectionHelper.DOCUMENT_ANNOTATION_CLASS;
20 
21 import androidx.appsearch.compiler.IntrospectionHelper;
22 
23 import com.squareup.javapoet.ClassName;
24 
25 import org.jspecify.annotations.NonNull;
26 import org.jspecify.annotations.Nullable;
27 
28 import java.util.Arrays;
29 
30 import javax.lang.model.element.AnnotationMirror;
31 import javax.lang.model.type.TypeMirror;
32 
33 /**
34  * An annotation for a metadata property e.g. {@code @Document.Id}.
35  */
36 public enum MetadataPropertyAnnotation implements PropertyAnnotation {
37     ID(
38             /* simpleClassName= */"Id",
39             /* genericDocGetterName= */ "getId",
40             /* genericDocSetterName= */"setId"),
41     NAMESPACE(
42             /* simpleClassName= */"Namespace",
43             /* genericDocGetterName= */ "getNamespace",
44             /* genericDocSetterName= */"setNamespace"),
45     CREATION_TIMESTAMP_MILLIS(
46             /* simpleClassName= */"CreationTimestampMillis",
47             /* genericDocGetterName= */ "getCreationTimestampMillis",
48             /* genericDocSetterName= */"setCreationTimestampMillis"),
49     TTL_MILLIS(
50             /* simpleClassName= */"TtlMillis",
51             /* genericDocGetterName= */ "getTtlMillis",
52             /* genericDocSetterName= */"setTtlMillis"),
53     SCORE(
54             /* simpleClassName= */"Score",
55             /* genericDocGetterName= */ "getScore",
56             /* genericDocSetterName= */"setScore");
57 
58     /**
59      * Attempts to parse an {@link AnnotationMirror} into a {@link MetadataPropertyAnnotation},
60      * or null.
61      */
tryParse( @onNull AnnotationMirror annotation)62     public static @Nullable MetadataPropertyAnnotation tryParse(
63             @NonNull AnnotationMirror annotation) {
64         String qualifiedClassName = annotation.getAnnotationType().toString();
65         return Arrays.stream(values())
66                 .filter(val -> val.getClassName().canonicalName().equals(qualifiedClassName))
67                 .findFirst()
68                 .orElse(null);
69     }
70 
71     @SuppressWarnings("ImmutableEnumChecker") // ClassName is an immutable third-party type
72     private final @NonNull ClassName mClassName;
73 
74     private final @NonNull String mGenericDocGetterName;
75 
76     private final @NonNull String mGenericDocSetterName;
77 
MetadataPropertyAnnotation( @onNull String simpleClassName, @NonNull String genericDocGetterName, @NonNull String genericDocSetterName)78     MetadataPropertyAnnotation(
79             @NonNull String simpleClassName,
80             @NonNull String genericDocGetterName,
81             @NonNull String genericDocSetterName) {
82         mClassName = DOCUMENT_ANNOTATION_CLASS.nestedClass(simpleClassName);
83         mGenericDocGetterName = genericDocGetterName;
84         mGenericDocSetterName = genericDocSetterName;
85     }
86 
87     @Override
getClassName()88     public @NonNull ClassName getClassName() {
89         return mClassName;
90     }
91 
92 
93     @Override
getPropertyKind()94     public PropertyAnnotation.@NonNull Kind getPropertyKind() {
95         return Kind.METADATA_PROPERTY;
96     }
97 
98     @Override
getUnderlyingTypeWithinGenericDoc( @onNull IntrospectionHelper helper)99     public @NonNull TypeMirror getUnderlyingTypeWithinGenericDoc(
100             @NonNull IntrospectionHelper helper) {
101         switch (this) {
102             case ID: // fall-through
103             case NAMESPACE:
104                 return helper.stringType;
105             case CREATION_TIMESTAMP_MILLIS: // fall-through
106             case TTL_MILLIS:
107                 return helper.longPrimitiveType;
108             case SCORE:
109                 return helper.intPrimitiveType;
110             default:
111                 throw new IllegalStateException("Unhandled metadata property annotation: " + this);
112         }
113     }
114 
115     @Override
getGenericDocGetterName()116     public @NonNull String getGenericDocGetterName() {
117         return mGenericDocGetterName;
118     }
119 
120 
121     @Override
getGenericDocSetterName()122     public @NonNull String getGenericDocSetterName() {
123         return mGenericDocSetterName;
124     }
125 }
126 
127