1 /*
2 * Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3 */
4
5 @file:Suppress("FunctionName")
6 @file:OptIn(ExperimentalSerializationApi::class)
7
8 package kotlinx.serialization.internal
9
10 import kotlinx.serialization.*
11 import kotlinx.serialization.builtins.*
12 import kotlinx.serialization.descriptors.*
13 import kotlinx.serialization.encoding.*
14 import kotlin.native.concurrent.*
15 import kotlin.reflect.*
16 import kotlin.time.Duration
17
18 @OptIn(ExperimentalUnsignedTypes::class)
19 private val BUILTIN_SERIALIZERS = mapOf(
20 String::class to String.serializer(),
21 Char::class to Char.serializer(),
22 CharArray::class to CharArraySerializer(),
23 Double::class to Double.serializer(),
24 DoubleArray::class to DoubleArraySerializer(),
25 Float::class to Float.serializer(),
26 FloatArray::class to FloatArraySerializer(),
27 Long::class to Long.serializer(),
28 LongArray::class to LongArraySerializer(),
29 ULong::class to ULong.serializer(),
30 ULongArray::class to ULongArraySerializer(),
31 Int::class to Int.serializer(),
32 IntArray::class to IntArraySerializer(),
33 UInt::class to UInt.serializer(),
34 UIntArray::class to UIntArraySerializer(),
35 Short::class to Short.serializer(),
36 ShortArray::class to ShortArraySerializer(),
37 UShort::class to UShort.serializer(),
38 UShortArray::class to UShortArraySerializer(),
39 Byte::class to Byte.serializer(),
40 ByteArray::class to ByteArraySerializer(),
41 UByte::class to UByte.serializer(),
42 UByteArray::class to UByteArraySerializer(),
43 Boolean::class to Boolean.serializer(),
44 BooleanArray::class to BooleanArraySerializer(),
45 Unit::class to Unit.serializer(),
46 Nothing::class to NothingSerializer(),
47 Duration::class to Duration.serializer()
48 )
49
50 internal class PrimitiveSerialDescriptor(
51 override val serialName: String,
52 override val kind: PrimitiveKind
53 ) : SerialDescriptor {
54 override val elementsCount: Int get() = 0
getElementNamenull55 override fun getElementName(index: Int): String = error()
56 override fun getElementIndex(name: String): Int = error()
57 override fun isElementOptional(index: Int): Boolean = error()
58 override fun getElementDescriptor(index: Int): SerialDescriptor = error()
59 override fun getElementAnnotations(index: Int): List<Annotation> = error()
60 override fun toString(): String = "PrimitiveDescriptor($serialName)"
61 override fun equals(other: Any?): Boolean {
62 if (this === other) return true
63 if (other !is PrimitiveSerialDescriptor) return false
64 if (serialName == other.serialName && kind == other.kind) return true
65 return false
66 }
hashCodenull67 override fun hashCode() = serialName.hashCode() + 31 * kind.hashCode()
68 private fun error(): Nothing = throw IllegalStateException("Primitive descriptor does not have elements")
69 }
70
71 internal fun PrimitiveDescriptorSafe(serialName: String, kind: PrimitiveKind): SerialDescriptor {
72 checkName(serialName)
73 return PrimitiveSerialDescriptor(serialName, kind)
74 }
75
checkNamenull76 private fun checkName(serialName: String) {
77 val keys = BUILTIN_SERIALIZERS.keys
78 for (primitive in keys) {
79 val simpleName = primitive.simpleName!!.capitalize()
80 val qualifiedName = "kotlin.$simpleName" // KClass.qualifiedName is not supported in JS
81 if (serialName.equals(qualifiedName, ignoreCase = true) || serialName.equals(simpleName, ignoreCase = true)) {
82 throw IllegalArgumentException("""
83 The name of serial descriptor should uniquely identify associated serializer.
84 For serial name $serialName there already exist ${simpleName.capitalize()}Serializer.
85 Please refer to SerialDescriptor documentation for additional information.
86 """.trimIndent())
87 }
88 }
89 }
90
<lambda>null91 private fun String.capitalize() = replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
92
93 @Suppress("UNCHECKED_CAST")
builtinSerializerOrNullnull94 internal fun <T : Any> KClass<T>.builtinSerializerOrNull(): KSerializer<T>? =
95 BUILTIN_SERIALIZERS[this] as KSerializer<T>?
96
97 @PublishedApi
98 internal object UnitSerializer : KSerializer<Unit> by ObjectSerializer("kotlin.Unit", Unit)
99
100 @PublishedApi
101 internal object BooleanSerializer : KSerializer<Boolean> {
102 override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlin.Boolean", PrimitiveKind.BOOLEAN)
103 override fun serialize(encoder: Encoder, value: Boolean): Unit = encoder.encodeBoolean(value)
104 override fun deserialize(decoder: Decoder): Boolean = decoder.decodeBoolean()
105 }
106
107 @PublishedApi
108 internal object ByteSerializer : KSerializer<Byte> {
109 override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlin.Byte", PrimitiveKind.BYTE)
serializenull110 override fun serialize(encoder: Encoder, value: Byte): Unit = encoder.encodeByte(value)
111 override fun deserialize(decoder: Decoder): Byte = decoder.decodeByte()
112 }
113
114 @PublishedApi
115 internal object ShortSerializer : KSerializer<Short> {
116 override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlin.Short", PrimitiveKind.SHORT)
117 override fun serialize(encoder: Encoder, value: Short): Unit = encoder.encodeShort(value)
118 override fun deserialize(decoder: Decoder): Short = decoder.decodeShort()
119 }
120
121 @PublishedApi
122 internal object IntSerializer : KSerializer<Int> {
123 override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlin.Int", PrimitiveKind.INT)
serializenull124 override fun serialize(encoder: Encoder, value: Int): Unit = encoder.encodeInt(value)
125 override fun deserialize(decoder: Decoder): Int = decoder.decodeInt()
126 }
127
128 @PublishedApi
129 internal object LongSerializer : KSerializer<Long> {
130 override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlin.Long", PrimitiveKind.LONG)
131 override fun serialize(encoder: Encoder, value: Long): Unit = encoder.encodeLong(value)
132 override fun deserialize(decoder: Decoder): Long = decoder.decodeLong()
133 }
134
135 @PublishedApi
136 internal object FloatSerializer : KSerializer<Float> {
137 override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlin.Float", PrimitiveKind.FLOAT)
serializenull138 override fun serialize(encoder: Encoder, value: Float): Unit = encoder.encodeFloat(value)
139 override fun deserialize(decoder: Decoder): Float = decoder.decodeFloat()
140 }
141
142 @PublishedApi
143 internal object DoubleSerializer : KSerializer<Double> {
144 override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlin.Double", PrimitiveKind.DOUBLE)
145 override fun serialize(encoder: Encoder, value: Double): Unit = encoder.encodeDouble(value)
146 override fun deserialize(decoder: Decoder): Double = decoder.decodeDouble()
147 }
148
149 @PublishedApi
150 internal object CharSerializer : KSerializer<Char> {
151 override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlin.Char", PrimitiveKind.CHAR)
serializenull152 override fun serialize(encoder: Encoder, value: Char): Unit = encoder.encodeChar(value)
153 override fun deserialize(decoder: Decoder): Char = decoder.decodeChar()
154 }
155
156 @PublishedApi
157 internal object StringSerializer : KSerializer<String> {
158 override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlin.String", PrimitiveKind.STRING)
159 override fun serialize(encoder: Encoder, value: String): Unit = encoder.encodeString(value)
160 override fun deserialize(decoder: Decoder): String = decoder.decodeString()
161 }
162