55package kotlinx.serialization.descriptors
66
77import kotlinx.serialization.*
8+ import kotlinx.serialization.builtins.*
89import kotlinx.serialization.encoding.*
910
1011/* *
1112 * Serial descriptor is an inherent property of [KSerializer] that describes the structure of the serializable type.
12- * The structure of the serializable type is not only the property of the type, but also of the serializer as well,
13+ * The structure of the serializable type is not only the characteristic of the type itself , but also of the serializer as well,
1314 * meaning that one type can have multiple descriptors that have completely different structure.
1415 *
1516 * For example, the class `class Color(val rgb: Int)` can have multiple serializable representations,
@@ -25,19 +26,19 @@ import kotlinx.serialization.encoding.*
2526 * For generic types, the actual type substitution is omitted from the string representation and the name
2627 * identifies the family of the serializers without type substitutions. However, type substitution is accounted
2728 * in [equals] and [hashCode] operations, meaning that descriptors of generic classes with the same name, but different type
28- * parameters , are not equal to each other.
29+ * arguments , are not equal to each other.
2930 * [serialName] is typically used to specify the type of the target class during serialization of polymorphic and sealed
3031 * classes, for observability and diagnostics.
31- * * [Kind][SerialKind] defines what this descriptor represents: primitive, enum, object, collection et cetera .
32+ * * [Kind][SerialKind] defines what this descriptor represents: primitive, enum, object, collection etc .
3233 * * Children elements are represented as serial descriptors as well and define the structure of the type's elements.
33- * * Metadata carries additional potentially useful information, such as [nullability][nullable], [optionality][isElementOptional]
34+ * * Metadata carries additional information, such as [nullability][nullable], [optionality][isElementOptional]
3435 * and [serial annotations][getElementAnnotations].
3536 *
3637 * ### Usages
3738 * There are two general usages of the descriptors: THE serialization process and serialization introspection.
3839 *
3940 * #### Serialization
40- * Serial descriptor is used as bridge between decoders/encoders and serializers.
41+ * Serial descriptor is used as a bridge between decoders/encoders and serializers.
4142 * When asking for a next element, the serializer provides an expected descriptor to the decoder, and,
4243 * based on the descriptor content, decoder decides how to parse its input.
4344 * In JSON, for example, when the encoder is asked to encode the next element and this element
@@ -59,15 +60,15 @@ import kotlinx.serialization.encoding.*
5960 * the range from zero to [elementsCount] and represent and index of the property in this class.
6061 * Consequently, primitives do not have children and their element count is zero.
6162 *
62- * For collections and maps, though, indices does not have fixed bound. Regular collections descriptors usually
63+ * For collections and maps indices don't have fixed bound. Regular collections descriptors usually
6364 * have one element (`T`, maps have two, one for keys and one for values), but potentially unlimited
6465 * number of actual children values. Valid indices range is not known statically
65- * and implementations of descriptor should provide consistent and unbounded names and indices.
66+ * and implementations of such descriptor should provide consistent and unbounded names and indices.
6667 *
6768 * In practice, for regular classes it is allowed to invoke `getElement*(index)` methods
68- * with an index within `0 until elementsCount` range and element at the particular index corresponds to the
69+ * with an index from `0` to [ elementsCount] range and element at the particular index corresponds to the
6970 * serializable property at the given position.
70- * For collections and maps, index parameter for `getElement*(index)` methods is effectively bound
71+ * For collections and maps, index parameter for `getElement*(index)` methods is effectively bounded
7172 * by the maximal number of collection/map elements.
7273 *
7374 * ### Thread-safety and mutability
@@ -76,7 +77,6 @@ import kotlinx.serialization.encoding.*
7677 * ### Equality and caching
7778 * Serial descriptor can be used as a unique identifier for format-specific data or schemas and
7879 * this implies the following restrictions on its `equals` and `hashCode`:
79- * *
8080 *
8181 * An [equals] implementation should use both [serialName] and elements structure.
8282 * Comparing [elementDescriptors] directly is discouraged,
@@ -100,8 +100,8 @@ import kotlinx.serialization.encoding.*
100100 * [hashCode] implementation should use the same properties for computing the result.
101101 *
102102 * ### User-defined serial descriptors
103- * The best way to define a custom descriptor is to use [SerialDescriptor ] builder function, where
104- * for each serializable property corresponding element is declared.
103+ * The best way to define a custom descriptor is to use [buildClassSerialDescriptor ] builder function, where
104+ * for each serializable property the corresponding element is declared.
105105 *
106106 * Example:
107107 * ```
@@ -113,15 +113,29 @@ import kotlinx.serialization.encoding.*
113113 * )
114114 *
115115 * // Descriptor for such class:
116- * SerialDescriptor ("my.package.Data") {
116+ * buildClassSerialDescriptor ("my.package.Data") {
117117 * // intField is deliberately ignored by serializer -- not present in the descriptor as well
118118 * element<Long>("_longField") // longField is named as _longField
119119 * element("stringField", listSerialDescriptor<String>())
120120 * }
121+ *
122+ * // Example of 'serialize' function for such descriptor
123+ * override fun serialize(encoder: Encoder, value: Data) {
124+ * encoder.encodeStructure(descriptor) {
125+ * encodeLongElement(descriptor, 0, value.longField) // Will be written as "_longField" because descriptor's child at index 0 says so
126+ * encodeSerializableElement(descriptor, 1, ListSerializer(String.serializer()), value.stringList)
127+ * }
128+ * }
121129 * ```
122130 *
123131 * For a classes that are represented as a single primitive value, [PrimitiveSerialDescriptor] builder function can be used instead.
124132 *
133+ * ### Consistency violations
134+ * An implementation of [SerialDescriptor] should be consistent with the implementation of the corresponding [KSerializer].
135+ * Yet it is not type-checked statically, thus making it possible to declare a non-consistent implementations of descriptor and serializer.
136+ * In such cases, the behaviour of an underlying format is unspecified and may lead to both runtime errors and encoding of
137+ * corrupted data that is impossible to decode back.
138+ *
125139 * ### Not stable for inheritance
126140 *
127141 * `SerialDescriptor` interface is not stable for inheritance in 3rd party libraries, as new methods
0 commit comments