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