5
5
package kotlinx.serialization.descriptors
6
6
7
7
import kotlinx.serialization.*
8
+ import kotlinx.serialization.builtins.*
8
9
import kotlinx.serialization.encoding.*
9
10
10
11
/* *
11
12
* 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,
13
14
* meaning that one type can have multiple descriptors that have completely different structure.
14
15
*
15
16
* For example, the class `class Color(val rgb: Int)` can have multiple serializable representations,
@@ -25,19 +26,19 @@ import kotlinx.serialization.encoding.*
25
26
* For generic types, the actual type substitution is omitted from the string representation and the name
26
27
* identifies the family of the serializers without type substitutions. However, type substitution is accounted
27
28
* 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.
29
30
* [serialName] is typically used to specify the type of the target class during serialization of polymorphic and sealed
30
31
* 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 .
32
33
* * 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]
34
35
* and [serial annotations][getElementAnnotations].
35
36
*
36
37
* ### Usages
37
38
* There are two general usages of the descriptors: THE serialization process and serialization introspection.
38
39
*
39
40
* #### 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.
41
42
* When asking for a next element, the serializer provides an expected descriptor to the decoder, and,
42
43
* based on the descriptor content, decoder decides how to parse its input.
43
44
* 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.*
59
60
* the range from zero to [elementsCount] and represent and index of the property in this class.
60
61
* Consequently, primitives do not have children and their element count is zero.
61
62
*
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
63
64
* have one element (`T`, maps have two, one for keys and one for values), but potentially unlimited
64
65
* 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.
66
67
*
67
68
* 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
69
70
* 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
71
72
* by the maximal number of collection/map elements.
72
73
*
73
74
* ### Thread-safety and mutability
@@ -76,7 +77,6 @@ import kotlinx.serialization.encoding.*
76
77
* ### Equality and caching
77
78
* Serial descriptor can be used as a unique identifier for format-specific data or schemas and
78
79
* this implies the following restrictions on its `equals` and `hashCode`:
79
- * *
80
80
*
81
81
* An [equals] implementation should use both [serialName] and elements structure.
82
82
* Comparing [elementDescriptors] directly is discouraged,
@@ -100,8 +100,8 @@ import kotlinx.serialization.encoding.*
100
100
* [hashCode] implementation should use the same properties for computing the result.
101
101
*
102
102
* ### 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.
105
105
*
106
106
* Example:
107
107
* ```
@@ -113,15 +113,29 @@ import kotlinx.serialization.encoding.*
113
113
* )
114
114
*
115
115
* // Descriptor for such class:
116
- * SerialDescriptor ("my.package.Data") {
116
+ * buildClassSerialDescriptor ("my.package.Data") {
117
117
* // intField is deliberately ignored by serializer -- not present in the descriptor as well
118
118
* element<Long>("_longField") // longField is named as _longField
119
119
* element("stringField", listSerialDescriptor<String>())
120
120
* }
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
+ * }
121
129
* ```
122
130
*
123
131
* For a classes that are represented as a single primitive value, [PrimitiveSerialDescriptor] builder function can be used instead.
124
132
*
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
+ *
125
139
* ### Not stable for inheritance
126
140
*
127
141
* `SerialDescriptor` interface is not stable for inheritance in 3rd party libraries, as new methods
0 commit comments