1 /*
2  * Copyright (C) 2022 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 com.android.libraries.pcc.chronicle.api
18 
19 import kotlin.reflect.KClass
20 
21 /** Collection of [DataTypeDescriptors][DataTypeDescriptor]. */
22 interface DataTypeDescriptorSet {
23   /**
24    * Returns the [DataTypeDescriptor] with the given [name], throws [IllegalArgumentException] if
25    * none is found.
26    */
getnull27   operator fun get(name: String): DataTypeDescriptor =
28     requireNotNull(getOrNull(name)) { "Could not find a DataTypeDescriptor for name: \"$name\"" }
29 
30   /** Returns the [DataTypeDescriptor] with the given [name], or `null` if none is found. */
getOrNullnull31   fun getOrNull(name: String): DataTypeDescriptor?
32 
33   /**
34    * Returns the [FieldType] for a field within the [DataTypeDescriptor] with the given [dtdName],
35    * accessed via the provided [accessPath].
36    */
37   fun findFieldTypeOrThrow(dtdName: String, accessPath: List<String>): FieldType =
38     findFieldTypeOrThrow(get(dtdName), accessPath)
39 
40   /**
41    * Returns the [FieldType] for a field within the given [DataTypeDescriptor] accessed via the
42    * provided [accessPath].
43    */
44   fun findFieldTypeOrThrow(dtd: DataTypeDescriptor, accessPath: List<String>): FieldType
45 
46   /**
47    * Returns the [DataTypeDescriptor] associated with the provided [FieldType].
48    *
49    * If the [FieldType] is a primitive or opaque value (or is yet otherwise unsupported), `null` is
50    * returned.
51    */
52   fun findDataTypeDescriptor(fieldType: FieldType): DataTypeDescriptor?
53 
54   /** Returns the [DataTypeDescriptor] for the given [KClass], or null if one is not known. */
55   fun findDataTypeDescriptor(cls: KClass<*>): DataTypeDescriptor?
56 
57   /**
58    * Returns the [Class] associated with the provided [FieldType].
59    *
60    * If the [FieldType] represents a primitive, array, or list a constant type is returned.
61    *
62    * If it is a [FieldType.Reference] or [FieldType.Nested] type, its name is used to find the
63    * [DataTypeDescriptor.cls] value of the [DataTypeDescriptor] with that name.
64    *
65    * If it's [FieldType.Opaque], its name is used in conjunction with [Class.forName]
66    * - which has a possibility of throwing a [ClassNotFoundException] if the name is not present in
67    * the classloader.
68    *
69    * If it's [FieldType.Nullable], the value of [findClass] for the non-nullable `itemFieldType`
70    * value is returned.
71    *
72    * [IllegalArgumentException] is thrown for [FieldTypes][FieldType] not yet supported for
73    * Cantrips.
74    */
75   fun fieldTypeAsClass(fieldType: FieldType): Class<*>
76 
77   /**
78    * Returns the [Class] associated with the [FieldType] located within the given
79    * [DataTypeDescriptor] accessed via the provided [accessPath].
80    */
81   fun findFieldTypeAsClass(dtd: DataTypeDescriptor, accessPath: List<String>): Class<*> =
82     fieldTypeAsClass(findFieldTypeOrThrow(dtd, accessPath))
83 
84   /** Returns a representation as a regular Set. */
85   fun toSet(): Set<DataTypeDescriptor>
86 }
87