1 /*
<lambda>null2  * Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.serialization
6 
7 import kotlinx.serialization.builtins.nullable
8 import kotlinx.serialization.internal.cast
9 import kotlinx.serialization.internal.createCache
10 import kotlinx.serialization.internal.createParametrizedCache
11 import kotlinx.serialization.modules.EmptySerializersModule
12 import kotlin.native.concurrent.ThreadLocal
13 import kotlin.reflect.KClass
14 import kotlin.reflect.KType
15 
16 
17 /**
18  * Cache for non-null non-parametrized and non-contextual serializers.
19  */
20 @ThreadLocal
21 private val SERIALIZERS_CACHE = createCache { it.serializerOrNull() }
22 
23 /**
24  * Cache for nullable non-parametrized and non-contextual serializers.
25  */
26 @ThreadLocal
<lambda>null27 private val SERIALIZERS_CACHE_NULLABLE = createCache<Any?> { it.serializerOrNull()?.nullable?.cast() }
28 
29 /**
30  * Cache for non-null parametrized and non-contextual serializers.
31  */
32 @ThreadLocal
typesnull33 private val PARAMETRIZED_SERIALIZERS_CACHE = createParametrizedCache { clazz, types ->
34     val serializers = EmptySerializersModule().serializersForParameters(types, true)!!
35     clazz.parametrizedSerializerOrNull(serializers) { types[0].classifier }
36 }
37 
38 /**
39  * Cache for nullable parametrized and non-contextual serializers.
40  */
41 @ThreadLocal
typesnull42 private val PARAMETRIZED_SERIALIZERS_CACHE_NULLABLE = createParametrizedCache<Any?> { clazz, types ->
43     val serializers = EmptySerializersModule().serializersForParameters(types, true)!!
44     clazz.parametrizedSerializerOrNull(serializers) { types[0].classifier }?.nullable?.cast()
45 }
46 
47 /**
48  * Find cacheable serializer in the cache.
49  * If serializer is cacheable but missed in cache - it will be created, placed into the cache and returned.
50  */
findCachedSerializernull51 internal fun findCachedSerializer(clazz: KClass<Any>, isNullable: Boolean): KSerializer<Any?>? {
52     return if (!isNullable) {
53         SERIALIZERS_CACHE.get(clazz)?.cast()
54     } else {
55         SERIALIZERS_CACHE_NULLABLE.get(clazz)
56     }
57 }
58 
59 /**
60  * Find cacheable parametrized serializer in the cache.
61  * If serializer is cacheable but missed in cache - it will be created, placed into the cache and returned.
62  */
findParametrizedCachedSerializernull63 internal fun findParametrizedCachedSerializer(
64     clazz: KClass<Any>,
65     types: List<KType>,
66     isNullable: Boolean
67 ): Result<KSerializer<Any?>?> {
68     return if (!isNullable) {
69         @Suppress("UNCHECKED_CAST")
70         PARAMETRIZED_SERIALIZERS_CACHE.get(clazz, types) as Result<KSerializer<Any?>?>
71     } else {
72         PARAMETRIZED_SERIALIZERS_CACHE_NULLABLE.get(clazz, types)
73     }
74 }
75