1 /* <lambda>null2 * Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 @file:Suppress("DEPRECATION_ERROR") 5 @file:OptIn(ExperimentalSerializationApi::class) 6 package kotlinx.serialization.internal 7 8 import kotlinx.serialization.* 9 import kotlinx.serialization.descriptors.* 10 import kotlinx.serialization.encoding.* 11 import kotlin.reflect.* 12 13 @InternalSerializationApi 14 public sealed class AbstractCollectionSerializer<Element, Collection, Builder> : KSerializer<Collection> { 15 protected abstract fun Collection.collectionSize(): Int 16 protected abstract fun Collection.collectionIterator(): Iterator<Element> 17 protected abstract fun builder(): Builder 18 protected abstract fun Builder.builderSize(): Int 19 protected abstract fun Builder.toResult(): Collection 20 protected abstract fun Collection.toBuilder(): Builder 21 protected abstract fun Builder.checkCapacity(size: Int) 22 23 abstract override fun serialize(encoder: Encoder, value: Collection) 24 25 @InternalSerializationApi 26 public fun merge(decoder: Decoder, previous: Collection?): Collection { 27 val builder = previous?.toBuilder() ?: builder() 28 val startIndex = builder.builderSize() 29 val compositeDecoder = decoder.beginStructure(descriptor) 30 if (compositeDecoder.decodeSequentially()) { 31 readAll(compositeDecoder, builder, startIndex, readSize(compositeDecoder, builder)) 32 } else { 33 while (true) { 34 val index = compositeDecoder.decodeElementIndex(descriptor) 35 if (index == CompositeDecoder.DECODE_DONE) break 36 readElement(compositeDecoder, startIndex + index, builder) 37 } 38 } 39 compositeDecoder.endStructure(descriptor) 40 return builder.toResult() 41 } 42 43 override fun deserialize(decoder: Decoder): Collection = merge(decoder, null) 44 45 private fun readSize(decoder: CompositeDecoder, builder: Builder): Int { 46 val size = decoder.decodeCollectionSize(descriptor) 47 builder.checkCapacity(size) 48 return size 49 } 50 51 protected abstract fun readElement(decoder: CompositeDecoder, index: Int, builder: Builder, checkIndex: Boolean = true) 52 53 protected abstract fun readAll(decoder: CompositeDecoder, builder: Builder, startIndex: Int, size: Int) 54 } 55 56 @PublishedApi 57 internal sealed class CollectionLikeSerializer<Element, Collection, Builder>( 58 private val elementSerializer: KSerializer<Element> 59 ) : AbstractCollectionSerializer<Element, Collection, Builder>() { 60 Buildernull61 protected abstract fun Builder.insert(index: Int, element: Element) 62 abstract override val descriptor: SerialDescriptor 63 64 override fun serialize(encoder: Encoder, value: Collection) { 65 val size = value.collectionSize() 66 encoder.encodeCollection(descriptor, size) { 67 val iterator = value.collectionIterator() 68 for (index in 0 until size) 69 encodeSerializableElement(descriptor, index, elementSerializer, iterator.next()) 70 } 71 } 72 readAllnull73 final override fun readAll(decoder: CompositeDecoder, builder: Builder, startIndex: Int, size: Int) { 74 require(size >= 0) { "Size must be known in advance when using READ_ALL" } 75 for (index in 0 until size) 76 readElement(decoder, startIndex + index, builder, checkIndex = false) 77 } 78 readElementnull79 override fun readElement(decoder: CompositeDecoder, index: Int, builder: Builder, checkIndex: Boolean) { 80 builder.insert(index, decoder.decodeSerializableElement(descriptor, index, elementSerializer)) 81 } 82 } 83 84 @InternalSerializationApi // TODO tech debt: it's used in ProtoBuf 85 public sealed class MapLikeSerializer<Key, Value, Collection, Builder : MutableMap<Key, Value>>( 86 public val keySerializer: KSerializer<Key>, 87 public val valueSerializer: KSerializer<Value> 88 ) : AbstractCollectionSerializer<Map.Entry<Key, Value>, Collection, Builder>() { 89 insertKeyValuePairnull90 protected abstract fun Builder.insertKeyValuePair(index: Int, key: Key, value: Value) 91 abstract override val descriptor: SerialDescriptor 92 93 protected final override fun readAll(decoder: CompositeDecoder, builder: Builder, startIndex: Int, size: Int) { 94 require(size >= 0) { "Size must be known in advance when using READ_ALL" } 95 for (index in 0 until size * 2 step 2) 96 readElement(decoder, startIndex + index, builder, checkIndex = false) 97 } 98 readElementnull99 final override fun readElement(decoder: CompositeDecoder, index: Int, builder: Builder, checkIndex: Boolean) { 100 val key: Key = decoder.decodeSerializableElement(descriptor, index, keySerializer) 101 val vIndex = if (checkIndex) { 102 decoder.decodeElementIndex(descriptor).also { 103 require(it == index + 1) { "Value must follow key in a map, index for key: $index, returned index for value: $it" } 104 } 105 } else { 106 index + 1 107 } 108 val value: Value = if (builder.containsKey(key) && valueSerializer.descriptor.kind !is PrimitiveKind) { 109 decoder.decodeSerializableElement(descriptor, vIndex, valueSerializer, builder.getValue(key)) 110 } else { 111 decoder.decodeSerializableElement(descriptor, vIndex, valueSerializer) 112 } 113 builder[key] = value 114 } 115 serializenull116 override fun serialize(encoder: Encoder, value: Collection) { 117 val size = value.collectionSize() 118 encoder.encodeCollection(descriptor, size) { 119 val iterator = value.collectionIterator() 120 var index = 0 121 iterator.forEach { (k, v) -> 122 encodeSerializableElement(descriptor, index++, keySerializer, k) 123 encodeSerializableElement(descriptor, index++, valueSerializer, v) 124 } 125 } 126 } 127 } 128 129 @PublishedApi 130 internal abstract class PrimitiveArrayBuilder<Array> internal constructor() { 131 internal abstract val position: Int ensureCapacitynull132 internal abstract fun ensureCapacity(requiredCapacity: Int = position + 1) 133 internal abstract fun build(): Array 134 } 135 136 /** 137 * Base serializer for all serializers for primitive arrays. 138 * 139 * It exists only to avoid code duplication and should not be used or implemented directly. 140 * Use concrete serializers ([ByteArraySerializer], etc) instead. 141 */ 142 @PublishedApi 143 internal abstract class PrimitiveArraySerializer<Element, Array, Builder 144 : PrimitiveArrayBuilder<Array>> internal constructor( 145 primitiveSerializer: KSerializer<Element> 146 ) : CollectionLikeSerializer<Element, Array, Builder>(primitiveSerializer) { 147 final override val descriptor: SerialDescriptor = PrimitiveArrayDescriptor(primitiveSerializer.descriptor) 148 149 final override fun Builder.builderSize(): Int = position 150 final override fun Builder.toResult(): Array = build() 151 final override fun Builder.checkCapacity(size: Int): Unit = ensureCapacity(size) 152 153 final override fun Array.collectionIterator(): Iterator<Element> = 154 error("This method lead to boxing and must not be used, use writeContents instead") 155 156 final override fun Builder.insert(index: Int, element: Element): Unit = 157 error("This method lead to boxing and must not be used, use Builder.append instead") 158 159 final override fun builder(): Builder = empty().toBuilder() 160 161 protected abstract fun empty(): Array 162 163 abstract override fun readElement( 164 decoder: CompositeDecoder, 165 index: Int, 166 builder: Builder, 167 checkIndex: Boolean 168 ) 169 170 protected abstract fun writeContent(encoder: CompositeEncoder, content: Array, size: Int) 171 172 final override fun serialize(encoder: Encoder, value: Array) { 173 val size = value.collectionSize() 174 encoder.encodeCollection(descriptor, size) { 175 writeContent(this, value, size) 176 } 177 } 178 179 final override fun deserialize(decoder: Decoder): Array = merge(decoder, null) 180 } 181 182 // todo: can be more efficient when array size is know in advance, this one always uses temporary ArrayList as builder 183 @PublishedApi 184 internal class ReferenceArraySerializer<ElementKlass : Any, Element : ElementKlass?>( 185 private val kClass: KClass<ElementKlass>, 186 eSerializer: KSerializer<Element> 187 ) : CollectionLikeSerializer<Element, Array<Element>, ArrayList<Element>>(eSerializer) { 188 override val descriptor: SerialDescriptor = ArrayClassDesc(eSerializer.descriptor) 189 collectionSizenull190 override fun Array<Element>.collectionSize(): Int = size 191 override fun Array<Element>.collectionIterator(): Iterator<Element> = iterator() 192 override fun builder(): ArrayList<Element> = arrayListOf() 193 override fun ArrayList<Element>.builderSize(): Int = size 194 195 @Suppress("UNCHECKED_CAST") 196 override fun ArrayList<Element>.toResult(): Array<Element> = toNativeArrayImpl<ElementKlass, Element>(kClass) 197 198 override fun Array<Element>.toBuilder(): ArrayList<Element> = ArrayList(this.asList()) 199 override fun ArrayList<Element>.checkCapacity(size: Int): Unit = ensureCapacity(size) 200 override fun ArrayList<Element>.insert(index: Int, element: Element) { 201 add(index, element) 202 } 203 } 204 205 @PublishedApi 206 internal abstract class CollectionSerializer<E, C: Collection<E>, B>(element: KSerializer<E>) : CollectionLikeSerializer<E, C, B>(element) { collectionSizenull207 override fun C.collectionSize(): Int = size 208 override fun C.collectionIterator(): Iterator<E> = iterator() 209 } 210 211 @InternalSerializationApi 212 @PublishedApi 213 internal class ArrayListSerializer<E>(element: KSerializer<E>) : CollectionSerializer<E, List<E>, ArrayList<E>>(element) { 214 override val descriptor: SerialDescriptor = ArrayListClassDesc(element.descriptor) 215 216 override fun builder(): ArrayList<E> = arrayListOf() 217 override fun ArrayList<E>.builderSize(): Int = size 218 override fun ArrayList<E>.toResult(): List<E> = this 219 override fun List<E>.toBuilder(): ArrayList<E> = this as? ArrayList<E> ?: ArrayList(this) 220 override fun ArrayList<E>.checkCapacity(size: Int): Unit = ensureCapacity(size) 221 override fun ArrayList<E>.insert(index: Int, element: E) { add(index, element) } 222 } 223 224 @PublishedApi 225 internal class LinkedHashSetSerializer<E>( 226 eSerializer: KSerializer<E> 227 ) : CollectionSerializer<E, Set<E>, LinkedHashSet<E>>(eSerializer) { 228 override val descriptor: SerialDescriptor = LinkedHashSetClassDesc(eSerializer.descriptor) 229 buildernull230 override fun builder(): LinkedHashSet<E> = linkedSetOf() 231 override fun LinkedHashSet<E>.builderSize(): Int = size 232 override fun LinkedHashSet<E>.toResult(): Set<E> = this 233 override fun Set<E>.toBuilder(): LinkedHashSet<E> = this as? LinkedHashSet<E> ?: LinkedHashSet(this) 234 override fun LinkedHashSet<E>.checkCapacity(size: Int) {} insertnull235 override fun LinkedHashSet<E>.insert(index: Int, element: E) { add(element) } 236 } 237 238 @PublishedApi 239 internal class HashSetSerializer<E>( 240 eSerializer: KSerializer<E> 241 ) : CollectionSerializer<E, Set<E>, HashSet<E>>(eSerializer) { 242 override val descriptor: SerialDescriptor = HashSetClassDesc(eSerializer.descriptor) 243 buildernull244 override fun builder(): HashSet<E> = HashSet() 245 override fun HashSet<E>.builderSize(): Int = size 246 override fun HashSet<E>.toResult(): Set<E> = this 247 override fun Set<E>.toBuilder(): HashSet<E> = this as? HashSet<E> ?: HashSet(this) 248 override fun HashSet<E>.checkCapacity(size: Int) {} insertnull249 override fun HashSet<E>.insert(index: Int, element: E) { add(element) } 250 } 251 252 @PublishedApi 253 internal class LinkedHashMapSerializer<K, V>( 254 kSerializer: KSerializer<K>, vSerializer: KSerializer<V> 255 ) : MapLikeSerializer<K, V, Map<K, V>, LinkedHashMap<K, V>>(kSerializer, vSerializer) { 256 257 override val descriptor: SerialDescriptor = LinkedHashMapClassDesc(kSerializer.descriptor, vSerializer.descriptor) collectionSizenull258 override fun Map<K, V>.collectionSize(): Int = size 259 override fun Map<K, V>.collectionIterator(): Iterator<Map.Entry<K, V>> = iterator() 260 override fun builder(): LinkedHashMap<K, V> = LinkedHashMap() 261 override fun LinkedHashMap<K, V>.builderSize(): Int = size * 2 262 override fun LinkedHashMap<K, V>.toResult(): Map<K, V> = this 263 override fun Map<K, V>.toBuilder(): LinkedHashMap<K, V> = this as? LinkedHashMap<K, V> ?: LinkedHashMap(this) 264 override fun LinkedHashMap<K, V>.checkCapacity(size: Int) {} insertKeyValuePairnull265 override fun LinkedHashMap<K, V>.insertKeyValuePair(index: Int, key: K, value: V): Unit = set(key, value) 266 } 267 268 @PublishedApi 269 internal class HashMapSerializer<K, V>( 270 kSerializer: KSerializer<K>, vSerializer: KSerializer<V> 271 ) : MapLikeSerializer<K, V, Map<K, V>, HashMap<K, V>>(kSerializer, vSerializer) { 272 273 override val descriptor: SerialDescriptor = HashMapClassDesc(kSerializer.descriptor, vSerializer.descriptor) 274 override fun Map<K, V>.collectionSize(): Int = size 275 override fun Map<K, V>.collectionIterator(): Iterator<Map.Entry<K, V>> = iterator() 276 override fun builder(): HashMap<K, V> = HashMap() 277 override fun HashMap<K, V>.builderSize(): Int = size * 2 278 override fun HashMap<K, V>.toResult(): Map<K, V> = this 279 override fun Map<K, V>.toBuilder(): HashMap<K, V> = this as? HashMap<K, V> ?: HashMap(this) 280 override fun HashMap<K, V>.checkCapacity(size: Int) {} 281 override fun HashMap<K, V>.insertKeyValuePair(index: Int, key: K, value: V): Unit = set(key, value) 282 } 283