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 package androidx.appsearch.compiler.annotationwrapper
17 
18 import androidx.appsearch.compiler.IntrospectionHelper
19 import androidx.appsearch.compiler.ProcessingException
20 import com.google.auto.common.MoreTypes
21 import com.squareup.javapoet.ClassName
22 import com.squareup.javapoet.TypeName
23 import javax.lang.model.element.TypeElement
24 import javax.lang.model.type.TypeMirror
25 
26 /** An instance of the `@Document.LongProperty` annotation. */
27 data class LongPropertyAnnotation(
28     override val name: String,
29     override val isRequired: Boolean,
30 
31     /** Specifies how a property should be indexed. */
32     val indexingType: Int,
33 
34     /**
35      * An optional [androidx.appsearch.app.LongSerializer].
36      *
37      * This is specified in the annotation when the annotated getter/field is of some custom type
38      * that should boil down to a long in the database.
39      *
40      * @see androidx.appsearch.annotation.Document.LongProperty.serializer
41      */
42     val customSerializer: SerializerClass?,
43 ) :
44     DataPropertyAnnotation(
45         className = CLASS_NAME,
46         configClassName = CONFIG_CLASS,
47         genericDocGetterName = "getPropertyLong",
48         genericDocArrayGetterName = "getPropertyLongArray",
49         genericDocSetterName = "setPropertyLong",
50     ) {
51     companion object {
52         val CLASS_NAME: ClassName =
53             IntrospectionHelper.DOCUMENT_ANNOTATION_CLASS.nestedClass("LongProperty")
54 
55         @JvmField
56         val CONFIG_CLASS: ClassName =
57             IntrospectionHelper.APPSEARCH_SCHEMA_CLASS.nestedClass("LongPropertyConfig")
58 
59         private val DEFAULT_SERIALIZER_CLASS: ClassName =
60             CLASS_NAME.nestedClass("DefaultSerializer")
61 
62         /**
63          * @param defaultName The name to use for the annotated property in case the annotation
64          *   params do not mention an explicit name.
65          * @throws ProcessingException If the annotation points to an Illegal serializer class.
66          */
67         @Throws(ProcessingException::class)
parsenull68         fun parse(
69             annotationParams: Map<String, Any?>,
70             defaultName: String
71         ): LongPropertyAnnotation {
72             val name = annotationParams["name"] as String
73             val serializerInAnnotation = annotationParams["serializer"] as TypeMirror
74             val typeName = TypeName.get(serializerInAnnotation).toString()
75             val customSerializer: SerializerClass? =
76                 if (typeName == DEFAULT_SERIALIZER_CLASS.canonicalName()) {
77                     null
78                 } else {
79                     SerializerClass.create(
80                         MoreTypes.asElement(serializerInAnnotation) as TypeElement,
81                         SerializerClass.Kind.LONG_SERIALIZER
82                     )
83                 }
84             return LongPropertyAnnotation(
85                 name = if (name.isEmpty()) defaultName else name,
86                 isRequired = annotationParams["required"] as Boolean,
87                 indexingType = annotationParams["indexingType"] as Int,
88                 customSerializer = customSerializer,
89             )
90         }
91     }
92 
93     override val dataPropertyKind
94         get() = Kind.LONG_PROPERTY
95 
getUnderlyingTypeWithinGenericDocnull96     override fun getUnderlyingTypeWithinGenericDoc(helper: IntrospectionHelper): TypeMirror =
97         helper.longPrimitiveType
98 }
99