Skip to content

Commit 9854e11

Browse files
committed
json: Use @SerialName of inline polymorphic children
1 parent b31a220 commit 9854e11

File tree

4 files changed

+34
-18
lines changed

4 files changed

+34
-18
lines changed

formats/json-tests/commonTest/src/kotlinx/serialization/features/sealed/SealedInterfacesInlineSerialNameTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class SealedInterfacesInlineSerialNameTest : JsonTestBase() {
3535
@JvmInline
3636
value class Child2(val value: Child2Value) : Parent
3737

38+
// From https://github.com/Kotlin/kotlinx.serialization/issues/2288
3839
@Test
39-
@Ignore // https://github.com/Kotlin/kotlinx.serialization/issues/2288
4040
fun testSealedInterfaceInlineSerialName() {
4141
val messages = listOf(
4242
Child1(Child1Value(1, "one")),

formats/json/commonMain/src/kotlinx/serialization/json/internal/StreamingJsonEncoder.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ internal class StreamingJsonEncoder(
4343
// Forces serializer to wrap all values into quotes
4444
private var forceQuoting: Boolean = false
4545
private var polymorphicDiscriminator: String? = null
46+
private var polymorphicSerialName: String? = null
4647

4748
init {
4849
val i = mode.ordinal
@@ -66,12 +67,12 @@ internal class StreamingJsonEncoder(
6667
}
6768
}
6869

69-
private fun encodeTypeInfo(descriptor: SerialDescriptor) {
70+
private fun encodeTypeInfo(discriminator: String, serialName: String) {
7071
composer.nextItem()
71-
encodeString(polymorphicDiscriminator!!)
72+
encodeString(discriminator)
7273
composer.print(COLON)
7374
composer.space()
74-
encodeString(descriptor.serialName)
75+
encodeString(serialName)
7576
}
7677

7778
override fun beginStructure(descriptor: SerialDescriptor): CompositeEncoder {
@@ -81,9 +82,11 @@ internal class StreamingJsonEncoder(
8182
composer.indent()
8283
}
8384

84-
if (polymorphicDiscriminator != null) {
85-
encodeTypeInfo(descriptor)
85+
val discriminator = polymorphicDiscriminator
86+
if (discriminator != null) {
87+
encodeTypeInfo(discriminator, polymorphicSerialName ?: descriptor.serialName)
8688
polymorphicDiscriminator = null
89+
polymorphicSerialName = null
8790
}
8891

8992
if (mode == newMode) {
@@ -160,6 +163,7 @@ internal class StreamingJsonEncoder(
160163
when {
161164
descriptor.isUnsignedNumber -> StreamingJsonEncoder(composerAs(::ComposerForUnsignedNumbers), json, mode, null)
162165
descriptor.isUnquotedLiteral -> StreamingJsonEncoder(composerAs(::ComposerForUnquotedLiterals), json, mode, null)
166+
polymorphicDiscriminator != null -> apply { polymorphicSerialName = descriptor.serialName }
163167
else -> super.encodeInline(descriptor)
164168
}
165169

formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonDecoder.kt

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ internal fun <T> Json.readPolymorphicJson(
3535

3636
private sealed class AbstractJsonTreeDecoder(
3737
override val json: Json,
38-
open val value: JsonElement
38+
open val value: JsonElement,
39+
protected val polymorphicDiscriminator: String? = null
3940
) : NamedValueDecoder(), JsonDecoder {
4041

4142
override val serializersModule: SerializersModule
@@ -63,7 +64,7 @@ private sealed class AbstractJsonTreeDecoder(
6364
{ JsonTreeMapDecoder(json, cast(currentObject, descriptor)) },
6465
{ JsonTreeListDecoder(json, cast(currentObject, descriptor)) }
6566
)
66-
else -> JsonTreeDecoder(json, cast(currentObject, descriptor))
67+
else -> JsonTreeDecoder(json, cast(currentObject, descriptor), polymorphicDiscriminator)
6768
}
6869
}
6970

@@ -159,11 +160,15 @@ private sealed class AbstractJsonTreeDecoder(
159160

160161
override fun decodeInline(descriptor: SerialDescriptor): Decoder {
161162
return if (currentTagOrNull != null) super.decodeInline(descriptor)
162-
else JsonPrimitiveDecoder(json, value).decodeInline(descriptor)
163+
else JsonPrimitiveDecoder(json, value, polymorphicDiscriminator).decodeInline(descriptor)
163164
}
164165
}
165166

166-
private class JsonPrimitiveDecoder(json: Json, override val value: JsonElement) : AbstractJsonTreeDecoder(json, value) {
167+
private class JsonPrimitiveDecoder(
168+
json: Json,
169+
override val value: JsonElement,
170+
polymorphicDiscriminator: String? = null
171+
) : AbstractJsonTreeDecoder(json, value, polymorphicDiscriminator) {
167172

168173
init {
169174
pushTag(PRIMITIVE_TAG)
@@ -180,9 +185,9 @@ private class JsonPrimitiveDecoder(json: Json, override val value: JsonElement)
180185
private open class JsonTreeDecoder(
181186
json: Json,
182187
override val value: JsonObject,
183-
private val polyDiscriminator: String? = null,
188+
polymorphicDiscriminator: String? = null,
184189
private val polyDescriptor: SerialDescriptor? = null
185-
) : AbstractJsonTreeDecoder(json, value) {
190+
) : AbstractJsonTreeDecoder(json, value, polymorphicDiscriminator) {
186191
private var position = 0
187192
private var forceNull: Boolean = false
188193
/*
@@ -251,7 +256,7 @@ private open class JsonTreeDecoder(
251256
// in endStructure can filter polyDiscriminator out.
252257
if (descriptor === polyDescriptor) {
253258
return JsonTreeDecoder(
254-
json, cast(currentObject(), polyDescriptor), polyDiscriminator, polyDescriptor
259+
json, cast(currentObject(), polyDescriptor), polymorphicDiscriminator, polyDescriptor
255260
)
256261
}
257262

@@ -271,7 +276,7 @@ private open class JsonTreeDecoder(
271276
}
272277

273278
for (key in value.keys) {
274-
if (key !in names && key != polyDiscriminator) {
279+
if (key !in names && key != polymorphicDiscriminator) {
275280
throw UnknownKeyException(key, value.toString())
276281
}
277282
}

formats/json/commonMain/src/kotlinx/serialization/json/internal/TreeJsonEncoder.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ private sealed class AbstractJsonTreeEncoder(
3535
protected val configuration = json.configuration
3636

3737
private var polymorphicDiscriminator: String? = null
38+
private var polymorphicSerialName: String? = null
3839

3940
override fun elementName(descriptor: SerialDescriptor, index: Int): String =
4041
descriptor.getJsonElementName(json, index)
@@ -112,8 +113,12 @@ private sealed class AbstractJsonTreeEncoder(
112113
}
113114

114115
override fun encodeInline(descriptor: SerialDescriptor): Encoder {
115-
return if (currentTagOrNull != null) super.encodeInline(descriptor)
116-
else JsonPrimitiveEncoder(json, nodeConsumer).encodeInline(descriptor)
116+
return if (currentTagOrNull != null) {
117+
if (polymorphicDiscriminator != null) polymorphicSerialName = descriptor.serialName
118+
super.encodeInline(descriptor)
119+
} else {
120+
JsonPrimitiveEncoder(json, nodeConsumer).encodeInline(descriptor)
121+
}
117122
}
118123

119124
@SuppressAnimalSniffer // Long(Integer).toUnsignedString(long)
@@ -148,9 +153,11 @@ private sealed class AbstractJsonTreeEncoder(
148153
else -> JsonTreeEncoder(json, consumer)
149154
}
150155

151-
if (polymorphicDiscriminator != null) {
152-
encoder.putElement(polymorphicDiscriminator!!, JsonPrimitive(descriptor.serialName))
156+
val discriminator = polymorphicDiscriminator
157+
if (discriminator != null) {
158+
encoder.putElement(discriminator, JsonPrimitive(polymorphicSerialName ?: descriptor.serialName))
153159
polymorphicDiscriminator = null
160+
polymorphicSerialName = null
154161
}
155162

156163
return encoder

0 commit comments

Comments
 (0)