1 /*
2  * Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.serialization.encoding
6 
7 import kotlinx.serialization.*
8 import kotlinx.serialization.builtins.*
9 import kotlinx.serialization.descriptors.*
10 import kotlinx.serialization.modules.*
11 
12 /**
13  * Decoder is a core deserialization primitive that encapsulates the knowledge of the underlying
14  * format and an underlying storage, exposing only structural methods to the deserializer, making it completely
15  * format-agnostic. Deserialization process takes a decoder and asks him for a sequence of primitive elements,
16  * defined by a deserializer serial form, while decoder knows how to retrieve these primitive elements from an actual format
17  * representations.
18  *
19  * Decoder provides high-level API that operates with basic primitive types, collections
20  * and nested structures. Internally, the decoder represents input storage, and operates with its state
21  * and lower level format-specific details.
22  *
23  * To be more specific, serialization asks a decoder for a sequence of "give me an int, give me
24  * a double, give me a list of strings and give me another object that is a nested int", while decoding
25  * transforms this sequence into a format-specific commands such as "parse the part of the string until the next quotation mark
26  * as an int to retrieve an int, parse everything within the next curly braces to retrieve elements of a nested object etc."
27  *
28  * The symmetric interface for the serialization process is [Encoder].
29  *
30  * ### Deserialization. Primitives
31  *
32  * If a class is represented as a single [primitive][PrimitiveKind] value in its serialized form,
33  * then one of the `decode*` methods (e.g. [decodeInt]) can be used directly.
34  *
35  * ### Deserialization. Structured types
36  *
37  * If a class is represented as a structure or has multiple values in its serialized form,
38  * `decode*` methods are not that helpful, because format may not require a strict order of data
39  * (e.g. JSON or XML), do not allow working with collection types or establish structure boundaries.
40  * All these capabilities are delegated to the [CompositeDecoder] interface with a more specific API surface.
41  * To denote a structure start, [beginStructure] should be used.
42  * ```
43  * // Denote the structure start,
44  * val composite = decoder.beginStructure(descriptor)
45  * // Decode all elements within the structure using 'composite'
46  * ...
47  * // Denote the structure end
48  * composite.endStructure(descriptor)
49  * ```
50  *
51  * E.g. if the decoder belongs to JSON format, then [beginStructure] will parse an opening bracket
52  * (`{` or `[`, depending on the descriptor kind), returning the [CompositeDecoder] that is aware of colon separator,
53  * that should be read after each key-value pair, whilst [CompositeDecoder.endStructure] will parse a closing bracket.
54  *
55  * ### Exception guarantees.
56  * For the regular exceptions, such as invalid input, missing control symbols or attributes and unknown symbols,
57  * [SerializationException] can be thrown by any decoder methods. It is recommended to declare a format-specific
58  * subclass of [SerializationException] and throw it.
59  *
60  * ### Format encapsulation
61  *
62  * For example, for the following deserializer:
63  * ```
64  * class StringHolder(val stringValue: String)
65  *
66  * object StringPairDeserializer : DeserializationStrategy<StringHolder> {
67  *    override val descriptor = ...
68  *
69  *    override fun deserializer(decoder: Decoder): StringHolder {
70  *        // Denotes start of the structure, StringHolder is not a "plain" data type
71  *        val composite = decoder.beginStructure(descriptor)
72  *        if (composite.decodeElementIndex(descriptor) != 0)
73  *            throw MissingFieldException("Field 'stringValue' is missing")
74  *        // Decode the nested string value
75  *        val value = composite.decodeStringElement(descriptor, index = 0)
76  *        // Denotes end of the structure
77  *        composite.endStructure(descriptor)
78  *    }
79  * }
80  * ```
81  *
82  * ### Exception safety
83  *
84  * In general, catching [SerializationException] from any of `decode*` methods is not allowed and produces unspecified behaviour.
85  * After thrown exception, current decoder is left in an arbitrary state, no longer suitable for further decoding.
86  *
87  * This deserializer does not know anything about the underlying data and will work with any properly-implemented decoder.
88  * JSON, for example, parses an opening bracket `{` during the `beginStructure` call, checks that the next key
89  * after this bracket is `stringValue` (using the descriptor), returns the value after the colon as string value
90  * and parses closing bracket `}` during the `endStructure`.
91  * XML would do roughly the same, but with different separators and parsing structures, while ProtoBuf
92  * machinery could be completely different.
93  * In any case, all these parsing details are encapsulated by a decoder.
94  *
95  * ### Decoder implementation
96  *
97  * While being strictly typed, an underlying format can transform actual types in the way it wants.
98  * For example, a format can support only string types and encode/decode all primitives in a string form:
99  * ```
100  * StringFormatDecoder : Decoder {
101  *
102  *     ...
103  *     override fun decodeDouble(): Double = decodeString().toDouble()
104  *     override fun decodeInt(): Int = decodeString().toInt()
105  *     ...
106  * }
107  * ```
108  *
109  * ### Not stable for inheritance
110  *
111  * `Decoder` interface is not stable for inheritance in 3rd-party libraries, as new methods
112  * might be added to this interface or contracts of the existing methods can be changed.
113  */
114 public interface Decoder {
115     /**
116      * Context of the current serialization process, including contextual and polymorphic serialization and,
117      * potentially, a format-specific configuration.
118      */
119     public val serializersModule: SerializersModule
120 
121     /**
122      * Returns `true` if the current value in decoder is not null, false otherwise.
123      * This method is usually used to decode potentially nullable data:
124      * ```
125      * // Could be String? deserialize() method
126      * public fun deserialize(decoder: Decoder): String? {
127      *     if (decoder.decodeNotNullMark()) {
128      *         return decoder.decodeString()
129      *     } else {
130      *         return decoder.decodeNull()
131      *     }
132      * }
133      * ```
134      */
135     @ExperimentalSerializationApi
decodeNotNullMarknull136     public fun decodeNotNullMark(): Boolean
137 
138     /**
139      * Decodes the `null` value and returns it.
140      *
141      * It is expected that `decodeNotNullMark` was called
142      * prior to `decodeNull` invocation and the case when it returned `true` was handled.
143      */
144     @ExperimentalSerializationApi
145     public fun decodeNull(): Nothing?
146 
147     /**
148      * Decodes a boolean value.
149      * Corresponding kind is [PrimitiveKind.BOOLEAN].
150      */
151     public fun decodeBoolean(): Boolean
152 
153     /**
154      * Decodes a single byte value.
155      * Corresponding kind is [PrimitiveKind.BYTE].
156      */
157     public fun decodeByte(): Byte
158 
159     /**
160      * Decodes a 16-bit short value.
161      * Corresponding kind is [PrimitiveKind.SHORT].
162      */
163     public fun decodeShort(): Short
164 
165     /**
166      * Decodes a 16-bit unicode character value.
167      * Corresponding kind is [PrimitiveKind.CHAR].
168      */
169     public fun decodeChar(): Char
170 
171     /**
172      * Decodes a 32-bit integer value.
173      * Corresponding kind is [PrimitiveKind.INT].
174      */
175     public fun decodeInt(): Int
176 
177     /**
178      * Decodes a 64-bit integer value.
179      * Corresponding kind is [PrimitiveKind.LONG].
180      */
181     public fun decodeLong(): Long
182 
183     /**
184      * Decodes a 32-bit IEEE 754 floating point value.
185      * Corresponding kind is [PrimitiveKind.FLOAT].
186      */
187     public fun decodeFloat(): Float
188 
189     /**
190      * Decodes a 64-bit IEEE 754 floating point value.
191      * Corresponding kind is [PrimitiveKind.DOUBLE].
192      */
193     public fun decodeDouble(): Double
194 
195     /**
196      * Decodes a string value.
197      * Corresponding kind is [PrimitiveKind.STRING].
198      */
199     public fun decodeString(): String
200 
201     /**
202      * Decodes a enum value and returns its index in [enumDescriptor] elements collection.
203      * Corresponding kind is [SerialKind.ENUM].
204      *
205      * E.g. for the enum `enum class Letters { A, B, C, D }` and
206      * underlying input "C", [decodeEnum] method should return `2` as a result.
207      *
208      * This method does not imply any restrictions on the input format,
209      * the format is free to store the enum by its name, index, ordinal or any other enum representation.
210      */
211     public fun decodeEnum(enumDescriptor: SerialDescriptor): Int
212 
213     /**
214      * Returns [Decoder] for decoding an underlying type of a value class in an inline manner.
215      * [descriptor] describes a target value class.
216      *
217      * Namely, for the `@Serializable @JvmInline value class MyInt(val my: Int)`, the following sequence is used:
218      * ```
219      * thisDecoder.decodeInline(MyInt.serializer().descriptor).decodeInt()
220      * ```
221      *
222      * Current decoder may return any other instance of [Decoder] class, depending on the provided [descriptor].
223      * For example, when this function is called on `Json` decoder with
224      * `UInt.serializer().descriptor`, the returned decoder is able to decode unsigned integers.
225      *
226      * Note that this function returns [Decoder] instead of the [CompositeDecoder]
227      * because value classes always have the single property.
228      *
229      * Calling [Decoder.beginStructure] on returned instance leads to an unspecified behavior and, in general, is prohibited.
230      */
231     public fun decodeInline(descriptor: SerialDescriptor): Decoder
232 
233     /**
234      * Decodes the beginning of the nested structure in a serialized form
235      * and returns [CompositeDecoder] responsible for decoding this very structure.
236      *
237      * Typically, classes, collections and maps are represented as a nested structure in a serialized form.
238      * E.g. the following JSON
239      * ```
240      * {
241      *     "a": 2,
242      *     "b": { "nested": "c" }
243      *     "c": [1, 2, 3],
244      *     "d": null
245      * }
246      * ```
247      * has three nested structures: the very beginning of the data, "b" value and "c" value.
248      */
249     public fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder
250 
251     /**
252      * Decodes the value of type [T] by delegating the decoding process to the given [deserializer].
253      * For example, `decodeInt` call us equivalent to delegating integer decoding to [Int.serializer][Int.Companion.serializer]:
254      * `decodeSerializableValue(IntSerializer)`
255      */
256     public fun <T : Any?> decodeSerializableValue(deserializer: DeserializationStrategy<T>): T =
257         deserializer.deserialize(this)
258 
259     /**
260      * Decodes the nullable value of type [T] by delegating the decoding process to the given [deserializer].
261      */
262     @ExperimentalSerializationApi
263     public fun <T : Any> decodeNullableSerializableValue(deserializer: DeserializationStrategy<T?>): T? = decodeIfNullable(deserializer) {
264         decodeSerializableValue(deserializer)
265     }
266 }
267 
268 @OptIn(ExperimentalSerializationApi::class)
decodeIfNullablenull269 internal inline fun <T : Any> Decoder.decodeIfNullable(deserializer: DeserializationStrategy<T?>, block: () -> T?): T? {
270     val isNullabilitySupported = deserializer.descriptor.isNullable
271     return if (isNullabilitySupported || decodeNotNullMark()) block() else decodeNull()
272 }
273 
274 /**
275  * [CompositeDecoder] is a part of decoding process that is bound to a particular structured part of
276  * the serialized form, described by the serial descriptor passed to [Decoder.beginStructure].
277  *
278  * Typically, for unordered data, [CompositeDecoder] is used by a serializer withing a [decodeElementIndex]-based
279  * loop that decodes all the required data one-by-one in any order and then terminates by calling [endStructure].
280  * Please refer to [decodeElementIndex] for example of such loop.
281  *
282  * All `decode*` methods have `index` and `serialDescriptor` parameters with a strict semantics and constraints:
283  *   * `descriptor` argument is always the same as one used in [Decoder.beginStructure].
284  *   * `index` of the element being decoded. For [sequential][decodeSequentially] decoding, it is always a monotonic
285  *      sequence from `0` to `descriptor.elementsCount` and for indexing-loop it is always an index that [decodeElementIndex]
286  *      has returned from the last call.
287  *
288  * The symmetric interface for the serialization process is [CompositeEncoder].
289  *
290  * ### Not stable for inheritance
291  *
292  * `CompositeDecoder` interface is not stable for inheritance in 3rd party libraries, as new methods
293  * might be added to this interface or contracts of the existing methods can be changed.
294  */
295 public interface CompositeDecoder {
296 
297     /**
298      * Results of [decodeElementIndex] used for decoding control flow.
299      */
300     public companion object {
301         /**
302          * Value returned by [decodeElementIndex] when the underlying input has no more data in the current structure.
303          * When this value is returned, no methods of the decoder should be called but [endStructure].
304          */
305         public const val DECODE_DONE: Int = -1
306 
307         /**
308          * Value returned by [decodeElementIndex] when the format encountered an unknown element
309          * (expected neither by the structure of serial descriptor, nor by the format itself).
310          */
311         public const val UNKNOWN_NAME: Int = -3
312     }
313 
314     /**
315      * Context of the current decoding process, including contextual and polymorphic serialization and,
316      * potentially, a format-specific configuration.
317      */
318     public val serializersModule: SerializersModule
319 
320     /**
321      * Denotes the end of the structure associated with current decoder.
322      * For example, composite decoder of JSON format will expect (and parse)
323      * a closing bracket in the underlying input.
324      */
endStructurenull325     public fun endStructure(descriptor: SerialDescriptor)
326 
327     /**
328      * Checks whether the current decoder supports strictly ordered decoding of the data
329      * without calling to [decodeElementIndex].
330      * If the method returns `true`, the caller might skip [decodeElementIndex] calls
331      * and start invoking `decode*Element` directly, incrementing the index of the element one by one.
332      * This method can be called by serializers (either generated or user-defined) as a performance optimization,
333      * but there is no guarantee that the method will be ever called. Practically, it means that implementations
334      * that may benefit from sequential decoding should also support a regular [decodeElementIndex]-based decoding as well.
335      *
336      * Example of usage:
337      * ```
338      * class MyPair(i: Int, d: Double)
339      *
340      * object MyPairSerializer : KSerializer<MyPair> {
341      *     // ... other methods omitted
342      *
343      *    fun deserialize(decoder: Decoder): MyPair {
344      *        val composite = decoder.beginStructure(descriptor)
345      *        if (composite.decodeSequentially()) {
346      *            val i = composite.decodeIntElement(descriptor, index = 0) // Mind the sequential indexing
347      *            val d = composite.decodeIntElement(descriptor, index = 1)
348      *            composite.endStructure(descriptor)
349      *            return MyPair(i, d)
350      *        } else {
351      *            // Fallback to `decodeElementIndex` loop, refer to its documentation for details
352      *        }
353      *    }
354      * }
355      * ```
356      * This example is a rough equivalent of what serialization plugin generates for serializable pair class.
357      *
358      * Sequential decoding is a performance optimization for formats with strictly ordered schema,
359      * usually binary ones. Regular formats such as JSON or ProtoBuf cannot use this optimization,
360      * because e.g. in the latter example, the same data can be represented both as
361      * `{"i": 1, "d": 1.0}`"` and `{"d": 1.0, "i": 1}` (thus, unordered).
362      */
363     @ExperimentalSerializationApi
364     public fun decodeSequentially(): Boolean = false
365 
366     /**
367      *  Decodes the index of the next element to be decoded.
368      *  Index represents a position of the current element in the serial descriptor element that can be found
369      *  with [SerialDescriptor.getElementIndex].
370      *
371      *  If this method returns non-negative index, the caller should call one of the `decode*Element` methods
372      *  with a resulting index.
373      *  Apart from positive values, this method can return [DECODE_DONE] to indicate that no more elements
374      *  are left or [UNKNOWN_NAME] to indicate that symbol with an unknown name was encountered.
375      *
376      * Example of usage:
377      * ```
378      * class MyPair(i: Int, d: Double)
379      *
380      * object MyPairSerializer : KSerializer<MyPair> {
381      *     // ... other methods omitted
382      *
383      *    fun deserialize(decoder: Decoder): MyPair {
384      *        val composite = decoder.beginStructure(descriptor)
385      *        var i: Int? = null
386      *        var d: Double? = null
387      *        while (true) {
388      *            when (val index = composite.decodeElementIndex(descriptor)) {
389      *                0 -> i = composite.decodeIntElement(descriptor, 0)
390      *                1 -> d = composite.decodeDoubleElement(descriptor, 1)
391      *                DECODE_DONE -> break // Input is over
392      *                else -> error("Unexpected index: $index)
393      *            }
394      *        }
395      *        composite.endStructure(descriptor)
396      *        require(i != null && d != null)
397      *        return MyPair(i, d)
398      *    }
399      * }
400      * ```
401      * This example is a rough equivalent of what serialization plugin generates for serializable pair class.
402      *
403      * The need in such a loop comes from unstructured nature of most serialization formats.
404      * For example, JSON for the following input `{"d": 2.0, "i": 1}`, will first read `d` key with index `1`
405      * and only after `i` with the index `0`.
406      *
407      * A potential implementation of this method for JSON format can be the following:
408      * ```
409      * fun decodeElementIndex(descriptor: SerialDescriptor): Int {
410      *     // Ignore arrays
411      *     val nextKey: String? = myStringJsonParser.nextKey()
412      *     if (nextKey == null) return DECODE_DONE
413      *     return descriptor.getElementIndex(nextKey) // getElementIndex can return UNKNOWN_NAME
414      * }
415      * ```
416      *
417      * If [decodeSequentially] returns `true`, the caller might skip calling this method.
418      */
419     public fun decodeElementIndex(descriptor: SerialDescriptor): Int
420 
421     /**
422      * Method to decode collection size that may be called before the collection decoding.
423      * Collection type includes [Collection], [Map] and [Array] (including primitive arrays).
424      * Method can return `-1` if the size is not known in advance, though for [sequential decoding][decodeSequentially]
425      * knowing precise size is a mandatory requirement.
426      */
427     public fun decodeCollectionSize(descriptor: SerialDescriptor): Int = -1
428 
429     /**
430      * Decodes a boolean value from the underlying input.
431      * The resulting value is associated with the [descriptor] element at the given [index].
432      * The element at the given index should have [PrimitiveKind.BOOLEAN] kind.
433      */
434     public fun decodeBooleanElement(descriptor: SerialDescriptor, index: Int): Boolean
435 
436     /**
437      * Decodes a single byte value from the underlying input.
438      * The resulting value is associated with the [descriptor] element at the given [index].
439      * The element at the given index should have [PrimitiveKind.BYTE] kind.
440      */
441     public fun decodeByteElement(descriptor: SerialDescriptor, index: Int): Byte
442 
443     /**
444      * Decodes a 16-bit unicode character value from the underlying input.
445      * The resulting value is associated with the [descriptor] element at the given [index].
446      * The element at the given index should have [PrimitiveKind.CHAR] kind.
447      */
448     public fun decodeCharElement(descriptor: SerialDescriptor, index: Int): Char
449 
450     /**
451      * Decodes a 16-bit short value from the underlying input.
452      * The resulting value is associated with the [descriptor] element at the given [index].
453      * The element at the given index should have [PrimitiveKind.SHORT] kind.
454      */
455     public fun decodeShortElement(descriptor: SerialDescriptor, index: Int): Short
456 
457     /**
458      * Decodes a 32-bit integer value from the underlying input.
459      * The resulting value is associated with the [descriptor] element at the given [index].
460      * The element at the given index should have [PrimitiveKind.INT] kind.
461      */
462     public fun decodeIntElement(descriptor: SerialDescriptor, index: Int): Int
463 
464     /**
465      * Decodes a 64-bit integer value from the underlying input.
466      * The resulting value is associated with the [descriptor] element at the given [index].
467      * The element at the given index should have [PrimitiveKind.LONG] kind.
468      */
469     public fun decodeLongElement(descriptor: SerialDescriptor, index: Int): Long
470 
471     /**
472      * Decodes a 32-bit IEEE 754 floating point value from the underlying input.
473      * The resulting value is associated with the [descriptor] element at the given [index].
474      * The element at the given index should have [PrimitiveKind.FLOAT] kind.
475      */
476     public fun decodeFloatElement(descriptor: SerialDescriptor, index: Int): Float
477 
478     /**
479      * Decodes a 64-bit IEEE 754 floating point value from the underlying input.
480      * The resulting value is associated with the [descriptor] element at the given [index].
481      * The element at the given index should have [PrimitiveKind.DOUBLE] kind.
482      */
483     public fun decodeDoubleElement(descriptor: SerialDescriptor, index: Int): Double
484 
485     /**
486      * Decodes a string value from the underlying input.
487      * The resulting value is associated with the [descriptor] element at the given [index].
488      * The element at the given index should have [PrimitiveKind.STRING] kind.
489      */
490     public fun decodeStringElement(descriptor: SerialDescriptor, index: Int): String
491 
492     /**
493      * Returns [Decoder] for decoding an underlying type of a value class in an inline manner.
494      * Serializable value class is described by the [child descriptor][SerialDescriptor.getElementDescriptor]
495      * of given [descriptor] at [index].
496      *
497      * Namely, for the `@Serializable @JvmInline value class MyInt(val my: Int)`,
498      * and `@Serializable class MyData(val myInt: MyInt)` the following sequence is used:
499      * ```
500      * thisDecoder.decodeInlineElement(MyData.serializer().descriptor, 0).decodeInt()
501      * ```
502      *
503      * This method provides an opportunity for the optimization to avoid boxing of a carried value
504      * and its invocation should be equivalent to the following:
505      * ```
506      * thisDecoder.decodeSerializableElement(MyData.serializer.descriptor, 0, MyInt.serializer())
507      * ```
508      *
509      * Current decoder may return any other instance of [Decoder] class, depending on the provided descriptor.
510      * For example, when this function is called on `Json` decoder with descriptor that has
511      * `UInt.serializer().descriptor` at the given [index], the returned decoder is able
512      * to decode unsigned integers.
513      *
514      * Note that this function returns [Decoder] instead of the [CompositeDecoder]
515      * because value classes always have the single property.
516      * Calling [Decoder.beginStructure] on returned instance leads to an unspecified behavior and, in general, is prohibited.
517      *
518      * @see Decoder.decodeInline
519      * @see SerialDescriptor.getElementDescriptor
520      */
521     public fun decodeInlineElement(
522         descriptor: SerialDescriptor,
523         index: Int
524     ): Decoder
525 
526     /**
527      * Decodes value of the type [T] with the given [deserializer].
528      *
529      * Implementations of [CompositeDecoder] may use their format-specific deserializers
530      * for particular data types, e.g. handle [ByteArray] specifically if format is binary.
531      *
532      * If value at given [index] was already decoded with previous [decodeSerializableElement] call with the same index,
533      * [previousValue] would contain a previously decoded value.
534      * This parameter can be used to aggregate multiple values of the given property to the only one.
535      * Implementation can safely ignore it and return a new value, effectively using 'the last one wins' strategy,
536      * or apply format-specific aggregating strategies, e.g. appending scattered Protobuf lists to a single one.
537      */
538     public fun <T : Any?> decodeSerializableElement(
539         descriptor: SerialDescriptor,
540         index: Int,
541         deserializer: DeserializationStrategy<T>,
542         previousValue: T? = null
543     ): T
544 
545     /**
546      * Decodes nullable value of the type [T] with the given [deserializer].
547      *
548      * If value at given [index] was already decoded with previous [decodeSerializableElement] call with the same index,
549      * [previousValue] would contain a previously decoded value.
550      * This parameter can be used to aggregate multiple values of the given property to the only one.
551      * Implementation can safely ignore it and return a new value, efficiently using 'the last one wins' strategy,
552      * or apply format-specific aggregating strategies, e.g. appending scattered Protobuf lists to a single one.
553      */
554     @ExperimentalSerializationApi
555     public fun <T : Any> decodeNullableSerializableElement(
556         descriptor: SerialDescriptor,
557         index: Int,
558         deserializer: DeserializationStrategy<T?>,
559         previousValue: T? = null
560     ): T?
561 }
562 
563 /**
564  * Begins a structure, decodes it using the given [block], ends it and returns decoded element.
565  */
566 public inline fun <T> Decoder.decodeStructure(
567     descriptor: SerialDescriptor,
568     crossinline block: CompositeDecoder.() -> T
569 ): T {
570     val composite = beginStructure(descriptor)
571     val result = composite.block()
572     composite.endStructure(descriptor)
573     return result
574 }
575