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 public val explicitNulls: Boolean = true, 26 @ExperimentalSerializationApi 27 public val prettyPrintIndent: String = " ", 28 public val coerceInputValues: Boolean = false, 29 public val useArrayPolymorphism: Boolean = false, 30 public val classDiscriminator: String = "type", 31 public val allowSpecialFloatingPointValues: Boolean = false, 32 public val useAlternativeNames: Boolean = true, 33 @ExperimentalSerializationApi 34 public val namingStrategy: JsonNamingStrategy? = null, 35 @ExperimentalSerializationApi 36 public val decodeEnumsCaseInsensitive: Boolean = false, 37 @ExperimentalSerializationApi 38 public val allowTrailingComma: Boolean = false, 39 @ExperimentalSerializationApi 40 public val allowComments: Boolean = false, 41 @ExperimentalSerializationApi 42 @set:Deprecated( 43 "JsonConfiguration is not meant to be mutable, and will be made read-only in a future release. " + 44 "The `Json(from = ...) {}` copy builder should be used instead.", 45 level = DeprecationLevel.ERROR 46 ) 47 public var classDiscriminatorMode: ClassDiscriminatorMode = ClassDiscriminatorMode.POLYMORPHIC, 48 ) { 49 50 /** @suppress Dokka **/ 51 @OptIn(ExperimentalSerializationApi::class) toStringnull52 override fun toString(): String { 53 return "JsonConfiguration(encodeDefaults=$encodeDefaults, ignoreUnknownKeys=$ignoreUnknownKeys, isLenient=$isLenient, " + 54 "allowStructuredMapKeys=$allowStructuredMapKeys, prettyPrint=$prettyPrint, explicitNulls=$explicitNulls, " + 55 "prettyPrintIndent='$prettyPrintIndent', coerceInputValues=$coerceInputValues, useArrayPolymorphism=$useArrayPolymorphism, " + 56 "classDiscriminator='$classDiscriminator', allowSpecialFloatingPointValues=$allowSpecialFloatingPointValues, " + 57 "useAlternativeNames=$useAlternativeNames, namingStrategy=$namingStrategy, decodeEnumsCaseInsensitive=$decodeEnumsCaseInsensitive, " + 58 "allowTrailingComma=$allowTrailingComma, allowComments=$allowComments, classDiscriminatorMode=$classDiscriminatorMode)" 59 } 60 } 61 62 /** 63 * Defines which classes and objects should have their serial name included in the json as so-called class discriminator. 64 * 65 * Class discriminator is a JSON field added by kotlinx.serialization that has [JsonBuilder.classDiscriminator] as a key (`type` by default), 66 * and class' serial name as a value (fully qualified name by default, can be changed with [SerialName] annotation). 67 * 68 * Class discriminator is important for serializing and deserializing [polymorphic class hierarchies](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#sealed-classes). 69 * Default [ClassDiscriminatorMode.POLYMORPHIC] mode adds discriminator only to polymorphic classes. 70 * This behavior can be changed to match various JSON schemas. 71 * 72 * @see JsonBuilder.classDiscriminator 73 * @see JsonBuilder.classDiscriminatorMode 74 * @see Polymorphic 75 * @see PolymorphicSerializer 76 */ 77 public enum class ClassDiscriminatorMode { 78 /** 79 * Never include class discriminator in the output. 80 * 81 * This mode is generally intended to produce JSON for consumption by third-party libraries. 82 * kotlinx.serialization is unable to deserialize [polymorphic classes][POLYMORPHIC] without class discriminators, 83 * so it is impossible to deserialize JSON produced in this mode if a data model has polymorphic classes. 84 */ 85 NONE, 86 87 /** 88 * Include class discriminators whenever possible. 89 * 90 * Given that class discriminator is added as a JSON field, adding class discriminator is possible 91 * when the resulting JSON is a json object — i.e., for Kotlin classes, `object`s, and interfaces. 92 * More specifically, discriminator is added to the output of serializers which descriptors 93 * have a [kind][SerialDescriptor.kind] of either [StructureKind.CLASS] or [StructureKind.OBJECT]. 94 * 95 * This mode is generally intended to produce JSON for consumption by third-party libraries. 96 * Given that [JsonBuilder.classDiscriminatorMode] does not affect deserialization, kotlinx.serialization 97 * does not expect every object to have discriminator, which may trigger deserialization errors. 98 * If you experience such problems, refrain from using [ALL_JSON_OBJECTS] or use [JsonBuilder.ignoreUnknownKeys]. 99 * 100 * In the example: 101 * ``` 102 * @Serializable class Plain(val p: String) 103 * @Serializable sealed class Base 104 * @Serializable object Impl: Base() 105 * 106 * @Serializable class All(val p: Plain, val b: Base, val i: Impl) 107 * ``` 108 * setting [JsonBuilder.classDiscriminatorMode] to [ClassDiscriminatorMode.ALL_JSON_OBJECTS] adds 109 * class discriminator to `All.p`, `All.b`, `All.i`, and to `All` object itself. 110 */ 111 ALL_JSON_OBJECTS, 112 113 /** 114 * Include class discriminators for polymorphic classes. 115 * 116 * Sealed classes, abstract classes, and interfaces are polymorphic classes by definition. 117 * Open classes can be polymorphic if they are serializable with [PolymorphicSerializer] 118 * and properly registered in the [SerializersModule]. 119 * See [kotlinx.serialization polymorphism guide](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#sealed-classes) for details. 120 * 121 * Note that implementations of polymorphic classes (e.g., sealed class inheritors) are not polymorphic classes from kotlinx.serialization standpoint. 122 * This means that this mode adds class discriminators only if a statically known type of the property is a base class or interface. 123 * 124 * In the example: 125 * ``` 126 * @Serializable class Plain(val p: String) 127 * @Serializable sealed class Base 128 * @Serializable object Impl: Base() 129 * 130 * @Serializable class All(val p: Plain, val b: Base, val i: Impl) 131 * ``` 132 * setting [JsonBuilder.classDiscriminatorMode] to [ClassDiscriminatorMode.POLYMORPHIC] adds 133 * class discriminator to `All.b`, but leaves `All.p` and `All.i` intact. 134 * 135 * @see SerializersModule 136 * @see SerializersModuleBuilder 137 * @see PolymorphicModuleBuilder 138 */ 139 POLYMORPHIC, 140 } 141