1 package kotlinx.serialization.json
2 
3 import kotlinx.serialization.*
4 import kotlinx.serialization.modules.*
5 import kotlinx.serialization.descriptors.*
6 
7 /**
8  * Configuration of the current [Json] instance available through [Json.configuration]
9  * and configured with [JsonBuilder] constructor.
10  *
11  * Can be used for debug purposes and for custom Json-specific serializers
12  * via [JsonEncoder] and [JsonDecoder].
13  *
14  * Standalone configuration object is meaningless and can nor be used outside the
15  * [Json], neither new [Json] instance can be created from it.
16  *
17  * Detailed description of each property is available in [JsonBuilder] class.
18  */
19 public class JsonConfiguration @OptIn(ExperimentalSerializationApi::class) internal constructor(
20     public val encodeDefaults: Boolean = false,
21     public val ignoreUnknownKeys: Boolean = false,
22     public val isLenient: Boolean = false,
23     public val allowStructuredMapKeys: Boolean = false,
24     public val prettyPrint: Boolean = false,
25     @ExperimentalSerializationApi
26     public val explicitNulls: Boolean = true,
27     @ExperimentalSerializationApi
28     public val prettyPrintIndent: String = "    ",
29     public val coerceInputValues: Boolean = false,
30     public val useArrayPolymorphism: Boolean = false,
31     public val classDiscriminator: String = "type",
32     public val allowSpecialFloatingPointValues: Boolean = false,
33     public val useAlternativeNames: Boolean = true,
34     @ExperimentalSerializationApi
35     public val namingStrategy: JsonNamingStrategy? = null,
36     @ExperimentalSerializationApi
37     public val decodeEnumsCaseInsensitive: Boolean = false,
38     @ExperimentalSerializationApi
39     public val allowTrailingComma: Boolean = false,
40     @ExperimentalSerializationApi
41     public var classDiscriminatorMode: ClassDiscriminatorMode = ClassDiscriminatorMode.POLYMORPHIC,
42 ) {
43 
44     /** @suppress Dokka **/
45     @OptIn(ExperimentalSerializationApi::class)
toStringnull46     override fun toString(): String {
47         return "JsonConfiguration(encodeDefaults=$encodeDefaults, ignoreUnknownKeys=$ignoreUnknownKeys, isLenient=$isLenient, " +
48                 "allowStructuredMapKeys=$allowStructuredMapKeys, prettyPrint=$prettyPrint, explicitNulls=$explicitNulls, " +
49                 "prettyPrintIndent='$prettyPrintIndent', coerceInputValues=$coerceInputValues, useArrayPolymorphism=$useArrayPolymorphism, " +
50                 "classDiscriminator='$classDiscriminator', allowSpecialFloatingPointValues=$allowSpecialFloatingPointValues, " +
51                 "useAlternativeNames=$useAlternativeNames, namingStrategy=$namingStrategy, decodeEnumsCaseInsensitive=$decodeEnumsCaseInsensitive, " +
52                 "allowTrailingComma=$allowTrailingComma, classDiscriminatorMode=$classDiscriminatorMode)"
53     }
54 }
55 
56 /**
57  * Defines which classes and objects should have their serial name included in the json as so-called class discriminator.
58  *
59  * Class discriminator is a JSON field added by kotlinx.serialization that has [JsonBuilder.classDiscriminator] as a key (`type` by default),
60  * and class' serial name as a value (fully-qualified name by default, can be changed with [SerialName] annotation).
61  *
62  * Class discriminator is important for serializing and deserializing [polymorphic class hierarchies](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#sealed-classes).
63  * Default [ClassDiscriminatorMode.POLYMORPHIC] mode adds discriminator only to polymorphic classes.
64  * This behavior can be changed to match various JSON schemas.
65  *
66  * @see JsonBuilder.classDiscriminator
67  * @see JsonBuilder.classDiscriminatorMode
68  * @see Polymorphic
69  * @see PolymorphicSerializer
70  */
71 public enum class ClassDiscriminatorMode {
72     /**
73      * Never include class discriminator in the output.
74      *
75      * This mode is generally intended to produce JSON for consumption by third-party libraries.
76      * kotlinx.serialization is unable to deserialize [polymorphic classes][POLYMORPHIC] without class discriminators,
77      * so it is impossible to deserialize JSON produced in this mode if a data model has polymorphic classes.
78      */
79     NONE,
80 
81     /**
82      * Include class discriminators whenever possible.
83      *
84      * Given that class discriminator is added as a JSON field, adding class discriminator is possible
85      * when the resulting JSON is a json object — i.e., for Kotlin classes, `object`s, and interfaces.
86      * More specifically, discriminator is added to the output of serializers which descriptors
87      * have a [kind][SerialDescriptor.kind] of either [StructureKind.CLASS] or [StructureKind.OBJECT].
88      *
89      * This mode is generally intended to produce JSON for consumption by third-party libraries.
90      * Given that [JsonBuilder.classDiscriminatorMode] does not affect deserialization, kotlinx.serialization
91      * does not expect every object to have discriminator, which may trigger deserialization errors.
92      * If you experience such problems, refrain from using [ALL_JSON_OBJECTS] or use [JsonBuilder.ignoreUnknownKeys].
93      *
94      * In the example:
95      * ```
96      * @Serializable class Plain(val p: String)
97      * @Serializable sealed class Base
98      * @Serializable object Impl: Base()
99      *
100      * @Serializable class All(val p: Plain, val b: Base, val i: Impl)
101      * ```
102      * setting [JsonBuilder.classDiscriminatorMode] to [ClassDiscriminatorMode.ALL_JSON_OBJECTS] adds
103      * class discriminator to `All.p`, `All.b`, `All.i`, and to `All` object itself.
104      */
105     ALL_JSON_OBJECTS,
106 
107     /**
108      * Include class discriminators for polymorphic classes.
109      *
110      * Sealed classes, abstract classes, and interfaces are polymorphic classes by definition.
111      * Open classes can be polymorphic if they are serializable with [PolymorphicSerializer]
112      * and properly registered in the [SerializersModule].
113      * See [kotlinx.serialization polymorphism guide](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#sealed-classes) for details.
114      *
115      * Note that implementations of polymorphic classes (e.g., sealed class inheritors) are not polymorphic classes from kotlinx.serialization standpoint.
116      * This means that this mode adds class discriminators only if a statically known type of the property is a base class or interface.
117      *
118      * In the example:
119      * ```
120      * @Serializable class Plain(val p: String)
121      * @Serializable sealed class Base
122      * @Serializable object Impl: Base()
123      *
124      * @Serializable class All(val p: Plain, val b: Base, val i: Impl)
125      * ```
126      * setting [JsonBuilder.classDiscriminatorMode] to [ClassDiscriminatorMode.POLYMORPHIC] adds
127      * class discriminator to `All.b`, but leaves `All.p` and `All.i` intact.
128      *
129      * @see SerializersModule
130      * @see SerializersModuleBuilder
131      * @see PolymorphicModuleBuilder
132      */
133     POLYMORPHIC,
134 }
135