1 /*
2 * Copyright (C) 2020 Square, Inc.
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 * https://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 com.squareup.moshi.kotlin.codegen.apt
17
18 import com.squareup.kotlinpoet.TypeSpec
19 import com.squareup.kotlinpoet.metadata.specs.ClassInspector
20 import com.squareup.kotlinpoet.metadata.specs.toTypeSpec
21 import com.squareup.kotlinpoet.metadata.toKmClass
22 import kotlinx.metadata.KmClass
23 import java.util.TreeMap
24 import javax.lang.model.element.TypeElement
25
26 /** KmClass doesn't implement equality natively. */
<lambda>null27 private val KmClassComparator = compareBy<KmClass> { it.name }
28
29 /**
30 * This cached API over [ClassInspector] that caches certain lookups Moshi does potentially multiple
31 * times. This is useful mostly because it avoids duplicate reloads in cases like common base
32 * classes, common enclosing types, etc.
33 */
34 internal class MoshiCachedClassInspector(private val classInspector: ClassInspector) {
35 private val elementToSpecCache = mutableMapOf<TypeElement, TypeSpec>()
36 private val kmClassToSpecCache = TreeMap<KmClass, TypeSpec>(KmClassComparator)
37 private val metadataToKmClassCache = mutableMapOf<Metadata, KmClass>()
38
toKmClassnull39 fun toKmClass(metadata: Metadata): KmClass {
40 return metadataToKmClassCache.getOrPut(metadata) {
41 metadata.toKmClass()
42 }
43 }
44
toTypeSpecnull45 fun toTypeSpec(kmClass: KmClass): TypeSpec {
46 return kmClassToSpecCache.getOrPut(kmClass) {
47 kmClass.toTypeSpec(classInspector)
48 }
49 }
50
toTypeSpecnull51 fun toTypeSpec(element: TypeElement): TypeSpec {
52 return elementToSpecCache.getOrPut(element) {
53 toTypeSpec(toKmClass(element.metadata))
54 }
55 }
56 }
57