F0X
04/05/2023, 10:55 PMid
field of an object determines what the other fields are), and I'm having trouble understanding the existing SealedClassSerializer
/`AbstractPolymorphicSerializer`.
When using such a serializer, the fields of the class are directly within the same object as the type
field, as shown in this example:
@Serializable
sealed class Project {
abstract val name: String
}
@Serializable
class OwnedProject(override val name: String, val owner: String) : Project()
fun main() {
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
println(Json.encodeToString(data)) // Serializing data of compile-time type Project
// prints: {"type":"example.examplePoly04.OwnedProject","name":"kotlinx.coroutines","owner":"kotlin"}
// NOT: {"type":"example.examplePoly04.OwnedProject", "value": {"name":"kotlinx.coroutines","owner":"kotlin"}}
}
But I do not see how this is achieved in the code, where serialize
is implemented like this:
public final override fun serialize(encoder: Encoder, value: T) {
val actualSerializer = findPolymorphicSerializer(encoder, value)
encoder.encodeStructure(descriptor) {
encodeStringElement(descriptor, 0, actualSerializer.descriptor.serialName)
encodeSerializableElement(descriptor, 1, actualSerializer.cast(), value)
}
}
To me it looks like this should result in two fields like the alternative I added in the example above, but somehow with this weird descriptor it works:
override val descriptor: SerialDescriptor by lazy(LazyThreadSafetyMode.PUBLICATION) {
buildSerialDescriptor(serialName, PolymorphicKind.SEALED) {
element("type", String.serializer().descriptor)
val elementDescriptor =
buildSerialDescriptor("kotlinx.serialization.Sealed<${baseClass.simpleName}>", SerialKind.CONTEXTUAL) {
// serialName2Serializer is guaranteed to have no duplicates — checked in `init`.
serialName2Serializer.forEach { (name, serializer) ->
element(name, serializer.descriptor)
}
}
element("value", elementDescriptor)
annotations = _annotations
}
}
Why is that and how can I do the same for my own custom serializer, which requires basically the same logic, but isn't based on a class hierarchy?Ben Woodworth
04/07/2023, 7:10 PMF0X
04/21/2023, 8:33 AM