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