@@ -27,6 +27,7 @@ import kotlinx.serialization.encoding.AbstractDecoder
27
27
import kotlinx.serialization.encoding.CompositeDecoder
28
28
import kotlinx.serialization.encoding.CompositeDecoder.Companion.DECODE_DONE
29
29
import kotlinx.serialization.encoding.CompositeDecoder.Companion.UNKNOWN_NAME
30
+ import kotlinx.serialization.encoding.Decoder
30
31
import kotlinx.serialization.modules.SerializersModule
31
32
import org.bson.AbstractBsonReader
32
33
import org.bson.BsonInvalidOperationException
@@ -36,6 +37,10 @@ import org.bson.BsonType
36
37
import org.bson.BsonValue
37
38
import org.bson.codecs.BsonValueCodec
38
39
import org.bson.codecs.DecoderContext
40
+ import org.bson.codecs.kotlinx.BsonDecoder.Companion.createBsonArrayDecoder
41
+ import org.bson.codecs.kotlinx.BsonDecoder.Companion.createBsonDocumentDecoder
42
+ import org.bson.codecs.kotlinx.BsonDecoder.Companion.createBsonMapDecoder
43
+ import org.bson.codecs.kotlinx.BsonDecoder.Companion.createBsonPolymorphicDecoder
39
44
import org.bson.internal.NumberCodecHelper
40
45
import org.bson.internal.StringCodecHelper
41
46
import org.bson.types.ObjectId
@@ -45,34 +50,93 @@ import org.bson.types.ObjectId
45
50
*
46
51
* For custom serialization handlers
47
52
*/
48
- public sealed interface BsonDecoder {
53
+ @ExperimentalSerializationApi
54
+ internal sealed interface BsonDecoder : Decoder , CompositeDecoder {
55
+
56
+ /* * Factory helper for creating concrete BsonDecoder implementations */
57
+ companion object {
58
+
59
+ @Suppress(" SwallowedException" )
60
+ private val hasJsonDecoder: Boolean by lazy {
61
+ try {
62
+ Class .forName(" kotlinx.serialization.json.JsonDecoder" )
63
+ true
64
+ } catch (e: ClassNotFoundException ) {
65
+ false
66
+ }
67
+ }
68
+
69
+ fun createBsonDecoder (
70
+ reader : AbstractBsonReader ,
71
+ serializersModule : SerializersModule ,
72
+ configuration : BsonConfiguration
73
+ ): BsonDecoder {
74
+ return if (hasJsonDecoder) JsonBsonDecoderImpl (reader, serializersModule, configuration)
75
+ else BsonDecoderImpl (reader, serializersModule, configuration)
76
+ }
77
+
78
+ fun createBsonArrayDecoder (
79
+ descriptor : SerialDescriptor ,
80
+ reader : AbstractBsonReader ,
81
+ serializersModule : SerializersModule ,
82
+ configuration : BsonConfiguration
83
+ ): BsonArrayDecoder {
84
+ return if (hasJsonDecoder) JsonBsonArrayDecoder (descriptor, reader, serializersModule, configuration)
85
+ else BsonArrayDecoder (descriptor, reader, serializersModule, configuration)
86
+ }
87
+
88
+ fun createBsonDocumentDecoder (
89
+ descriptor : SerialDescriptor ,
90
+ reader : AbstractBsonReader ,
91
+ serializersModule : SerializersModule ,
92
+ configuration : BsonConfiguration
93
+ ): BsonDocumentDecoder {
94
+ return if (hasJsonDecoder) JsonBsonDocumentDecoder (descriptor, reader, serializersModule, configuration)
95
+ else BsonDocumentDecoder (descriptor, reader, serializersModule, configuration)
96
+ }
97
+
98
+ fun createBsonPolymorphicDecoder (
99
+ descriptor : SerialDescriptor ,
100
+ reader : AbstractBsonReader ,
101
+ serializersModule : SerializersModule ,
102
+ configuration : BsonConfiguration
103
+ ): BsonPolymorphicDecoder {
104
+ return if (hasJsonDecoder) JsonBsonPolymorphicDecoder (descriptor, reader, serializersModule, configuration)
105
+ else BsonPolymorphicDecoder (descriptor, reader, serializersModule, configuration)
106
+ }
107
+
108
+ fun createBsonMapDecoder (
109
+ descriptor : SerialDescriptor ,
110
+ reader : AbstractBsonReader ,
111
+ serializersModule : SerializersModule ,
112
+ configuration : BsonConfiguration
113
+ ): BsonMapDecoder {
114
+ return if (hasJsonDecoder) JsonBsonMapDecoder (descriptor, reader, serializersModule, configuration)
115
+ else BsonMapDecoder (descriptor, reader, serializersModule, configuration)
116
+ }
117
+ }
49
118
50
119
/* * @return the decoded ObjectId */
51
- public fun decodeObjectId (): ObjectId
120
+ fun decodeObjectId (): ObjectId
52
121
/* * @return the decoded BsonValue */
53
- public fun decodeBsonValue (): BsonValue
54
-
55
- /* * @return the BsonReader */
56
- public fun reader (): BsonReader
122
+ fun decodeBsonValue (): BsonValue
57
123
}
58
124
59
- @ExperimentalSerializationApi
60
- internal open class DefaultBsonDecoder (
61
- internal val reader : AbstractBsonReader ,
125
+ @OptIn( ExperimentalSerializationApi :: class )
126
+ internal sealed class AbstractBsonDecoder (
127
+ val reader : AbstractBsonReader ,
62
128
override val serializersModule : SerializersModule ,
63
- internal val configuration : BsonConfiguration
129
+ val configuration : BsonConfiguration
64
130
) : BsonDecoder, AbstractDecoder() {
65
131
66
- private data class ElementMetadata (val name : String , val nullable : Boolean , var processed : Boolean = false )
67
- private var elementsMetadata: Array <ElementMetadata >? = null
68
- private var currentIndex: Int = UNKNOWN_INDEX
69
-
70
132
companion object {
71
- val validKeyKinds = setOf ( PrimitiveKind . STRING , PrimitiveKind . CHAR , SerialKind . ENUM )
133
+
72
134
val bsonValueCodec = BsonValueCodec ()
73
135
const val UNKNOWN_INDEX = - 10
136
+ val validKeyKinds = setOf (PrimitiveKind .STRING , PrimitiveKind .CHAR , SerialKind .ENUM )
137
+
74
138
fun validateCurrentBsonType (
75
- reader : AbstractBsonReader ,
139
+ reader : BsonReader ,
76
140
expectedType : BsonType ,
77
141
descriptor : SerialDescriptor ,
78
142
actualType : (descriptor: SerialDescriptor ) -> String = { it.kind.toString() }
@@ -87,6 +151,10 @@ internal open class DefaultBsonDecoder(
87
151
}
88
152
}
89
153
154
+ private data class ElementMetadata (val name : String , val nullable : Boolean , var processed : Boolean = false )
155
+ private var elementsMetadata: Array <ElementMetadata >? = null
156
+ private var currentIndex: Int = UNKNOWN_INDEX
157
+
90
158
private fun initElementMetadata (descriptor : SerialDescriptor ) {
91
159
if (this .elementsMetadata != null ) return
92
160
val elementsMetadata =
@@ -134,14 +202,13 @@ internal open class DefaultBsonDecoder(
134
202
? : UNKNOWN_NAME
135
203
}
136
204
137
- @Suppress(" ReturnCount" )
138
205
override fun beginStructure (descriptor : SerialDescriptor ): CompositeDecoder {
139
206
return when (descriptor.kind) {
140
- is StructureKind . LIST -> BsonArrayDecoder (descriptor, reader, serializersModule, configuration)
141
- is PolymorphicKind -> PolymorphicDecoder (descriptor, reader, serializersModule, configuration)
207
+ is PolymorphicKind -> createBsonPolymorphicDecoder (descriptor, reader, serializersModule, configuration)
208
+ is StructureKind . LIST -> createBsonArrayDecoder (descriptor, reader, serializersModule, configuration)
142
209
is StructureKind .CLASS ,
143
- StructureKind .OBJECT -> BsonDocumentDecoder (descriptor, reader, serializersModule, configuration)
144
- is StructureKind .MAP -> MapDecoder (descriptor, reader, serializersModule, configuration)
210
+ StructureKind .OBJECT -> createBsonDocumentDecoder (descriptor, reader, serializersModule, configuration)
211
+ is StructureKind .MAP -> createBsonMapDecoder (descriptor, reader, serializersModule, configuration)
145
212
else -> throw SerializationException (" Primitives are not supported at top-level" )
146
213
}
147
214
}
@@ -152,18 +219,15 @@ internal open class DefaultBsonDecoder(
152
219
is StructureKind .MAP ,
153
220
StructureKind .CLASS ,
154
221
StructureKind .OBJECT -> reader.readEndDocument()
155
- else -> super .endStructure(descriptor)
222
+ else -> {}
156
223
}
157
224
}
158
225
159
226
override fun decodeByte (): Byte = NumberCodecHelper .decodeByte(reader)
160
-
161
227
override fun decodeChar (): Char = StringCodecHelper .decodeChar(reader)
162
228
override fun decodeFloat (): Float = NumberCodecHelper .decodeFloat(reader)
163
-
164
229
override fun decodeShort (): Short = NumberCodecHelper .decodeShort(reader)
165
230
override fun decodeBoolean (): Boolean = reader.readBoolean()
166
-
167
231
override fun decodeDouble (): Double = NumberCodecHelper .decodeDouble(reader)
168
232
override fun decodeInt (): Int = NumberCodecHelper .decodeInt(reader)
169
233
override fun decodeLong (): Long = NumberCodecHelper .decodeLong(reader)
@@ -183,7 +247,6 @@ internal open class DefaultBsonDecoder(
183
247
184
248
override fun decodeObjectId (): ObjectId = readOrThrow({ reader.readObjectId() }, BsonType .OBJECT_ID )
185
249
override fun decodeBsonValue (): BsonValue = bsonValueCodec.decode(reader, DecoderContext .builder().build())
186
- override fun reader (): BsonReader = reader
187
250
188
251
private inline fun <T > readOrThrow (action : () -> T , bsonType : BsonType ): T {
189
252
return try {
@@ -197,13 +260,20 @@ internal open class DefaultBsonDecoder(
197
260
}
198
261
}
199
262
200
- @OptIn(ExperimentalSerializationApi ::class )
201
- private class BsonArrayDecoder (
263
+ /* * The default Bson Decoder implementation */
264
+ internal open class BsonDecoderImpl (
265
+ reader : AbstractBsonReader ,
266
+ serializersModule : SerializersModule ,
267
+ configuration : BsonConfiguration
268
+ ) : AbstractBsonDecoder(reader, serializersModule, configuration)
269
+
270
+ /* * The Bson array decoder */
271
+ internal open class BsonArrayDecoder (
202
272
descriptor : SerialDescriptor ,
203
273
reader : AbstractBsonReader ,
204
274
serializersModule : SerializersModule ,
205
275
configuration : BsonConfiguration
206
- ) : DefaultBsonDecoder (reader, serializersModule, configuration) {
276
+ ) : AbstractBsonDecoder (reader, serializersModule, configuration) {
207
277
208
278
init {
209
279
validateCurrentBsonType(reader, BsonType .ARRAY , descriptor)
@@ -218,13 +288,29 @@ private class BsonArrayDecoder(
218
288
}
219
289
}
220
290
291
+ /* * The Bson document decoder */
221
292
@OptIn(ExperimentalSerializationApi ::class )
222
- private class PolymorphicDecoder (
293
+ internal open class BsonDocumentDecoder (
223
294
descriptor : SerialDescriptor ,
224
295
reader : AbstractBsonReader ,
225
296
serializersModule : SerializersModule ,
226
297
configuration : BsonConfiguration
227
- ) : DefaultBsonDecoder(reader, serializersModule, configuration) {
298
+ ) : AbstractBsonDecoder(reader, serializersModule, configuration) {
299
+
300
+ init {
301
+ validateCurrentBsonType(reader, BsonType .DOCUMENT , descriptor) { it.serialName }
302
+ reader.readStartDocument()
303
+ }
304
+ }
305
+
306
+ /* * The Bson polymorphic class decoder */
307
+ @OptIn(ExperimentalSerializationApi ::class )
308
+ internal open class BsonPolymorphicDecoder (
309
+ descriptor : SerialDescriptor ,
310
+ reader : AbstractBsonReader ,
311
+ serializersModule : SerializersModule ,
312
+ configuration : BsonConfiguration
313
+ ) : AbstractBsonDecoder(reader, serializersModule, configuration) {
228
314
private var index = 0
229
315
private var mark: BsonReaderMark ?
230
316
@@ -239,7 +325,7 @@ private class PolymorphicDecoder(
239
325
it.reset()
240
326
mark = null
241
327
}
242
- return deserializer.deserialize(DefaultBsonDecoder (reader, serializersModule, configuration))
328
+ return deserializer.deserialize(BsonDecoder .createBsonDecoder (reader, serializersModule, configuration))
243
329
}
244
330
245
331
override fun decodeElementIndex (descriptor : SerialDescriptor ): Int {
@@ -266,27 +352,14 @@ private class PolymorphicDecoder(
266
352
}
267
353
}
268
354
355
+ /* * The Bson map decoder */
269
356
@OptIn(ExperimentalSerializationApi ::class )
270
- private class BsonDocumentDecoder (
271
- descriptor : SerialDescriptor ,
272
- reader : AbstractBsonReader ,
273
- serializersModule : SerializersModule ,
274
- configuration : BsonConfiguration
275
- ) : DefaultBsonDecoder(reader, serializersModule, configuration) {
276
- init {
277
- validateCurrentBsonType(reader, BsonType .DOCUMENT , descriptor) { it.serialName }
278
- reader.readStartDocument()
279
- }
280
- }
281
-
282
- @OptIn(ExperimentalSerializationApi ::class )
283
- private class MapDecoder (
357
+ internal open class BsonMapDecoder (
284
358
descriptor : SerialDescriptor ,
285
359
reader : AbstractBsonReader ,
286
360
serializersModule : SerializersModule ,
287
361
configuration : BsonConfiguration
288
- ) : DefaultBsonDecoder(reader, serializersModule, configuration) {
289
-
362
+ ) : AbstractBsonDecoder(reader, serializersModule, configuration) {
290
363
private var index = 0
291
364
private var isKey = false
292
365
0 commit comments