@@ -27,6 +27,7 @@ import kotlinx.serialization.encoding.AbstractDecoder
2727import kotlinx.serialization.encoding.CompositeDecoder
2828import kotlinx.serialization.encoding.CompositeDecoder.Companion.DECODE_DONE
2929import kotlinx.serialization.encoding.CompositeDecoder.Companion.UNKNOWN_NAME
30+ import kotlinx.serialization.encoding.Decoder
3031import kotlinx.serialization.modules.SerializersModule
3132import org.bson.AbstractBsonReader
3233import org.bson.BsonInvalidOperationException
@@ -36,6 +37,10 @@ import org.bson.BsonType
3637import org.bson.BsonValue
3738import org.bson.codecs.BsonValueCodec
3839import 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
3944import org.bson.internal.NumberCodecHelper
4045import org.bson.internal.StringCodecHelper
4146import org.bson.types.ObjectId
@@ -45,34 +50,93 @@ import org.bson.types.ObjectId
4550 *
4651 * For custom serialization handlers
4752 */
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+ }
49118
50119 /* * @return the decoded ObjectId */
51- public fun decodeObjectId (): ObjectId
120+ fun decodeObjectId (): ObjectId
52121 /* * @return the decoded BsonValue */
53- public fun decodeBsonValue (): BsonValue
54-
55- /* * @return the BsonReader */
56- public fun reader (): BsonReader
122+ fun decodeBsonValue (): BsonValue
57123}
58124
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 ,
62128 override val serializersModule : SerializersModule ,
63- internal val configuration : BsonConfiguration
129+ val configuration : BsonConfiguration
64130) : BsonDecoder, AbstractDecoder() {
65131
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-
70132 companion object {
71- val validKeyKinds = setOf ( PrimitiveKind . STRING , PrimitiveKind . CHAR , SerialKind . ENUM )
133+
72134 val bsonValueCodec = BsonValueCodec ()
73135 const val UNKNOWN_INDEX = - 10
136+ val validKeyKinds = setOf (PrimitiveKind .STRING , PrimitiveKind .CHAR , SerialKind .ENUM )
137+
74138 fun validateCurrentBsonType (
75- reader : AbstractBsonReader ,
139+ reader : BsonReader ,
76140 expectedType : BsonType ,
77141 descriptor : SerialDescriptor ,
78142 actualType : (descriptor: SerialDescriptor ) -> String = { it.kind.toString() }
@@ -87,6 +151,10 @@ internal open class DefaultBsonDecoder(
87151 }
88152 }
89153
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+
90158 private fun initElementMetadata (descriptor : SerialDescriptor ) {
91159 if (this .elementsMetadata != null ) return
92160 val elementsMetadata =
@@ -134,14 +202,13 @@ internal open class DefaultBsonDecoder(
134202 ? : UNKNOWN_NAME
135203 }
136204
137- @Suppress(" ReturnCount" )
138205 override fun beginStructure (descriptor : SerialDescriptor ): CompositeDecoder {
139206 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)
142209 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)
145212 else -> throw SerializationException (" Primitives are not supported at top-level" )
146213 }
147214 }
@@ -152,18 +219,15 @@ internal open class DefaultBsonDecoder(
152219 is StructureKind .MAP ,
153220 StructureKind .CLASS ,
154221 StructureKind .OBJECT -> reader.readEndDocument()
155- else -> super .endStructure(descriptor)
222+ else -> {}
156223 }
157224 }
158225
159226 override fun decodeByte (): Byte = NumberCodecHelper .decodeByte(reader)
160-
161227 override fun decodeChar (): Char = StringCodecHelper .decodeChar(reader)
162228 override fun decodeFloat (): Float = NumberCodecHelper .decodeFloat(reader)
163-
164229 override fun decodeShort (): Short = NumberCodecHelper .decodeShort(reader)
165230 override fun decodeBoolean (): Boolean = reader.readBoolean()
166-
167231 override fun decodeDouble (): Double = NumberCodecHelper .decodeDouble(reader)
168232 override fun decodeInt (): Int = NumberCodecHelper .decodeInt(reader)
169233 override fun decodeLong (): Long = NumberCodecHelper .decodeLong(reader)
@@ -183,7 +247,6 @@ internal open class DefaultBsonDecoder(
183247
184248 override fun decodeObjectId (): ObjectId = readOrThrow({ reader.readObjectId() }, BsonType .OBJECT_ID )
185249 override fun decodeBsonValue (): BsonValue = bsonValueCodec.decode(reader, DecoderContext .builder().build())
186- override fun reader (): BsonReader = reader
187250
188251 private inline fun <T > readOrThrow (action : () -> T , bsonType : BsonType ): T {
189252 return try {
@@ -197,13 +260,20 @@ internal open class DefaultBsonDecoder(
197260 }
198261}
199262
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 (
202272 descriptor : SerialDescriptor ,
203273 reader : AbstractBsonReader ,
204274 serializersModule : SerializersModule ,
205275 configuration : BsonConfiguration
206- ) : DefaultBsonDecoder (reader, serializersModule, configuration) {
276+ ) : AbstractBsonDecoder (reader, serializersModule, configuration) {
207277
208278 init {
209279 validateCurrentBsonType(reader, BsonType .ARRAY , descriptor)
@@ -218,13 +288,29 @@ private class BsonArrayDecoder(
218288 }
219289}
220290
291+ /* * The Bson document decoder */
221292@OptIn(ExperimentalSerializationApi ::class )
222- private class PolymorphicDecoder (
293+ internal open class BsonDocumentDecoder (
223294 descriptor : SerialDescriptor ,
224295 reader : AbstractBsonReader ,
225296 serializersModule : SerializersModule ,
226297 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) {
228314 private var index = 0
229315 private var mark: BsonReaderMark ?
230316
@@ -239,7 +325,7 @@ private class PolymorphicDecoder(
239325 it.reset()
240326 mark = null
241327 }
242- return deserializer.deserialize(DefaultBsonDecoder (reader, serializersModule, configuration))
328+ return deserializer.deserialize(BsonDecoder .createBsonDecoder (reader, serializersModule, configuration))
243329 }
244330
245331 override fun decodeElementIndex (descriptor : SerialDescriptor ): Int {
@@ -266,27 +352,14 @@ private class PolymorphicDecoder(
266352 }
267353}
268354
355+ /* * The Bson map decoder */
269356@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 (
284358 descriptor : SerialDescriptor ,
285359 reader : AbstractBsonReader ,
286360 serializersModule : SerializersModule ,
287361 configuration : BsonConfiguration
288- ) : DefaultBsonDecoder(reader, serializersModule, configuration) {
289-
362+ ) : AbstractBsonDecoder(reader, serializersModule, configuration) {
290363 private var index = 0
291364 private var isKey = false
292365
0 commit comments