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