/* * Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ @file:Suppress("DEPRECATION_ERROR") @file:OptIn(ExperimentalSerializationApi::class) package kotlinx.serialization.internal import kotlinx.serialization.* import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* import kotlin.native.concurrent.* @SharedImmutable private val NULL = Any() private const val deprecationMessage = "This class is used only by the plugin in generated code and should not be used directly. Use corresponding factory functions instead" @PublishedApi internal sealed class KeyValueSerializer( protected val keySerializer: KSerializer, protected val valueSerializer: KSerializer ) : KSerializer { protected abstract val R.key: K protected abstract val R.value: V protected abstract fun toResult(key: K, value: V): R override fun serialize(encoder: Encoder, value: R) { val structuredEncoder = encoder.beginStructure(descriptor) structuredEncoder.encodeSerializableElement(descriptor, 0, keySerializer, value.key) structuredEncoder.encodeSerializableElement(descriptor, 1, valueSerializer, value.value) structuredEncoder.endStructure(descriptor) } override fun deserialize(decoder: Decoder): R { val composite = decoder.beginStructure(descriptor) if (composite.decodeSequentially()) { val key = composite.decodeSerializableElement(descriptor, 0, keySerializer) val value = composite.decodeSerializableElement(descriptor, 1, valueSerializer) return toResult(key, value) } var key: Any? = NULL var value: Any? = NULL mainLoop@ while (true) { when (val idx = composite.decodeElementIndex(descriptor)) { CompositeDecoder.DECODE_DONE -> { break@mainLoop } 0 -> { key = composite.decodeSerializableElement(descriptor, 0, keySerializer) } 1 -> { value = composite.decodeSerializableElement(descriptor, 1, valueSerializer) } else -> throw SerializationException("Invalid index: $idx") } } composite.endStructure(descriptor) if (key === NULL) throw SerializationException("Element 'key' is missing") if (value === NULL) throw SerializationException("Element 'value' is missing") @Suppress("UNCHECKED_CAST") return toResult(key as K, value as V) } } @PublishedApi @Suppress("EXTENSION_SHADOWED_BY_MEMBER") internal class MapEntrySerializer( keySerializer: KSerializer, valueSerializer: KSerializer ) : KeyValueSerializer>(keySerializer, valueSerializer) { private data class MapEntry(override val key: K, override val value: V) : Map.Entry /* * Kind 'MAP' because it is represented in a map-like manner with "key: value" serialized directly */ override val descriptor: SerialDescriptor = buildSerialDescriptor("kotlin.collections.Map.Entry", StructureKind.MAP) { element("key", keySerializer.descriptor) element("value", valueSerializer.descriptor) } override val Map.Entry.key: K get() = this.key override val Map.Entry.value: V get() = this.value override fun toResult(key: K, value: V): Map.Entry = MapEntry(key, value) } @PublishedApi internal class PairSerializer( keySerializer: KSerializer, valueSerializer: KSerializer ) : KeyValueSerializer>(keySerializer, valueSerializer) { override val descriptor: SerialDescriptor = buildClassSerialDescriptor("kotlin.Pair") { element("first", keySerializer.descriptor) element("second", valueSerializer.descriptor) } override val Pair.key: K get() = this.first override val Pair.value: V get() = this.second override fun toResult(key: K, value: V): Pair = key to value } @PublishedApi internal class TripleSerializer( private val aSerializer: KSerializer, private val bSerializer: KSerializer, private val cSerializer: KSerializer ) : KSerializer> { override val descriptor: SerialDescriptor = buildClassSerialDescriptor("kotlin.Triple") { element("first", aSerializer.descriptor) element("second", bSerializer.descriptor) element("third", cSerializer.descriptor) } override fun serialize(encoder: Encoder, value: Triple) { val structuredEncoder = encoder.beginStructure(descriptor) structuredEncoder.encodeSerializableElement(descriptor, 0, aSerializer, value.first) structuredEncoder.encodeSerializableElement(descriptor, 1, bSerializer, value.second) structuredEncoder.encodeSerializableElement(descriptor, 2, cSerializer, value.third) structuredEncoder.endStructure(descriptor) } override fun deserialize(decoder: Decoder): Triple { val composite = decoder.beginStructure(descriptor) if (composite.decodeSequentially()) { return decodeSequentially(composite) } return decodeStructure(composite) } private fun decodeSequentially(composite: CompositeDecoder): Triple { val a = composite.decodeSerializableElement(descriptor, 0, aSerializer) val b = composite.decodeSerializableElement(descriptor, 1, bSerializer) val c = composite.decodeSerializableElement(descriptor, 2, cSerializer) composite.endStructure(descriptor) return Triple(a, b, c) } private fun decodeStructure(composite: CompositeDecoder): Triple { var a: Any? = NULL var b: Any? = NULL var c: Any? = NULL mainLoop@ while (true) { when (val index = composite.decodeElementIndex(descriptor)) { CompositeDecoder.DECODE_DONE -> { break@mainLoop } 0 -> { a = composite.decodeSerializableElement(descriptor, 0, aSerializer) } 1 -> { b = composite.decodeSerializableElement(descriptor, 1, bSerializer) } 2 -> { c = composite.decodeSerializableElement(descriptor, 2, cSerializer) } else -> throw SerializationException("Unexpected index $index") } } composite.endStructure(descriptor) if (a === NULL) throw SerializationException("Element 'first' is missing") if (b === NULL) throw SerializationException("Element 'second' is missing") if (c === NULL) throw SerializationException("Element 'third' is missing") @Suppress("UNCHECKED_CAST") return Triple(a as A, b as B, c as C) } }