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.descriptors.*
9 import kotlinx.serialization.modules.*
10 import kotlinx.serialization.internal.*
11 
12 /**
13  * A skeleton implementation of both [Encoder] and [CompositeEncoder] that can be used
14  * for simple formats and for testability purpose.
15  * Most of the `encode*` methods have default implementation that delegates `encodeValue(value: Any)`.
16  * See [Encoder] documentation for information about each particular `encode*` method.
17  */
18 @ExperimentalSerializationApi
19 public abstract class AbstractEncoder : Encoder, CompositeEncoder {
20 
beginStructurenull21     override fun beginStructure(descriptor: SerialDescriptor): CompositeEncoder = this
22 
23     override fun endStructure(descriptor: SerialDescriptor) {}
24 
25     /**
26      * Invoked before writing an element that is part of the structure to determine whether it should be encoded.
27      * Element information can be obtained from the [descriptor] by the given [index].
28      *
29      * @return `true` if the value should be encoded, false otherwise
30      */
encodeElementnull31     public open fun encodeElement(descriptor: SerialDescriptor, index: Int): Boolean = true
32 
33     /**
34      * Invoked to encode a value when specialized `encode*` method was not overridden.
35      */
36     public open fun encodeValue(value: Any): Unit =
37         throw SerializationException("Non-serializable ${value::class} is not supported by ${this::class} encoder")
38 
39     override fun encodeNull() {
40         throw SerializationException("'null' is not supported by default")
41     }
42 
encodeBooleannull43     override fun encodeBoolean(value: Boolean): Unit = encodeValue(value)
44     override fun encodeByte(value: Byte): Unit = encodeValue(value)
45     override fun encodeShort(value: Short): Unit = encodeValue(value)
46     override fun encodeInt(value: Int): Unit = encodeValue(value)
47     override fun encodeLong(value: Long): Unit = encodeValue(value)
48     override fun encodeFloat(value: Float): Unit = encodeValue(value)
49     override fun encodeDouble(value: Double): Unit = encodeValue(value)
50     override fun encodeChar(value: Char): Unit = encodeValue(value)
51     override fun encodeString(value: String): Unit = encodeValue(value)
52     override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int): Unit = encodeValue(index)
53 
54     override fun encodeInline(descriptor: SerialDescriptor): Encoder = this
55 
56     // Delegating implementation of CompositeEncoder
57     final override fun encodeBooleanElement(descriptor: SerialDescriptor, index: Int, value: Boolean) { if (encodeElement(descriptor, index)) encodeBoolean(value) }
encodeByteElementnull58     final override fun encodeByteElement(descriptor: SerialDescriptor, index: Int, value: Byte) { if (encodeElement(descriptor, index)) encodeByte(value) }
encodeShortElementnull59     final override fun encodeShortElement(descriptor: SerialDescriptor, index: Int, value: Short) { if (encodeElement(descriptor, index)) encodeShort(value) }
encodeIntElementnull60     final override fun encodeIntElement(descriptor: SerialDescriptor, index: Int, value: Int) { if (encodeElement(descriptor, index)) encodeInt(value) }
encodeLongElementnull61     final override fun encodeLongElement(descriptor: SerialDescriptor, index: Int, value: Long) { if (encodeElement(descriptor, index)) encodeLong(value) }
encodeFloatElementnull62     final override fun encodeFloatElement(descriptor: SerialDescriptor, index: Int, value: Float) { if (encodeElement(descriptor, index)) encodeFloat(value) }
encodeDoubleElementnull63     final override fun encodeDoubleElement(descriptor: SerialDescriptor, index: Int, value: Double) { if (encodeElement(descriptor, index)) encodeDouble(value) }
encodeCharElementnull64     final override fun encodeCharElement(descriptor: SerialDescriptor, index: Int, value: Char) { if (encodeElement(descriptor, index)) encodeChar(value) }
encodeStringElementnull65     final override fun encodeStringElement(descriptor: SerialDescriptor, index: Int, value: String) { if (encodeElement(descriptor, index)) encodeString(value) }
66 
encodeInlineElementnull67     final override fun encodeInlineElement(
68         descriptor: SerialDescriptor,
69         index: Int
70     ): Encoder =
71         if (encodeElement(descriptor, index)) encodeInline(descriptor.getElementDescriptor(index)) else NoOpEncoder
72 
73     override fun <T : Any?> encodeSerializableElement(
74         descriptor: SerialDescriptor,
75         index: Int,
76         serializer: SerializationStrategy<T>,
77         value: T
78     ) {
79         if (encodeElement(descriptor, index))
80             encodeSerializableValue(serializer, value)
81     }
82 
encodeNullableSerializableElementnull83     override fun <T : Any> encodeNullableSerializableElement(
84         descriptor: SerialDescriptor,
85         index: Int,
86         serializer: SerializationStrategy<T>,
87         value: T?
88     ) {
89         if (encodeElement(descriptor, index))
90             encodeNullableSerializableValue(serializer, value)
91     }
92 }
93