1 /*
2  * Copyright (C) 2017 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.room.processor.cache
18 
19 import androidx.room.compiler.processing.XElement
20 import androidx.room.compiler.processing.XTypeElement
21 import androidx.room.processor.PropertyProcessor
22 import androidx.room.vo.BuiltInConverterFlags
23 import androidx.room.vo.DataClass
24 import androidx.room.vo.EmbeddedProperty
25 import androidx.room.vo.Entity
26 import androidx.room.vo.Warning
27 
28 /**
29  * A cache key can be used to avoid re-processing elements.
30  *
31  * Each context has a cache variable that uses the same backing storage as the Root Context but adds
32  * current adapters and warning suppression list to the key.
33  */
34 class Cache(
35     val parent: Cache?,
36     val converters: Set<XTypeElement>,
37     val suppressedWarnings: Set<Warning>,
38     val builtInConverterFlags: BuiltInConverterFlags
39 ) {
40     val entities: Bucket<EntityKey, Entity> = Bucket(parent?.entities)
41     val dataClasses: Bucket<DataClassKey, DataClass> = Bucket(parent?.dataClasses)
42 
43     inner class Bucket<K, T>(source: Bucket<K, T>?) {
44         private val entries: MutableMap<FullKey<K>, T> = source?.entries ?: mutableMapOf()
45 
getnull46         fun get(key: K, calculate: () -> T): T {
47             val fullKey = FullKey(converters, suppressedWarnings, builtInConverterFlags, key)
48             return entries.getOrPut(fullKey) { calculate() }
49         }
50     }
51 
52     /** Key for Entity cache */
53     data class EntityKey(val element: XElement)
54 
55     /** Key for data class cache */
56     data class DataClassKey(
57         val element: XElement,
58         val scope: PropertyProcessor.BindingScope,
59         val parent: EmbeddedProperty?
60     )
61 
62     /**
63      * Internal key representation with adapters & warnings included.
64      *
65      * Converters are kept in a linked set since the order is important for the TypeAdapterStore.
66      */
67     private data class FullKey<T>(
68         val converters: Set<XTypeElement>,
69         val suppressedWarnings: Set<Warning>,
70         val builtInConverterFlags: BuiltInConverterFlags,
71         val key: T
72     )
73 }
74