Serializing a nested sealed class in Kotlin

68 views Asked by At

I am trying to serialize a nested sealed class. Here is an example

@Serializable
sealed class Base {
    @SerialName("concrete_property")
    val concreteProperty: String = "concrete property of base"
    @SerialName("abstract_property")
    val abstractProperty: String

    @Serializable
    @SerialName("subclass")
    data class Subclass (
        override abstractProperty: String
        @SerialName("subclass_concrete_property")
        val subclassConcreteProperty: String
    ) : Base()

    @Serializable
    @SerialName("subclass2")
    data class Subclass2 (
        override abstractProperty: String
        @SerialName("subclass_other_concrete_property")
        val subclassOtherConcreteProperty: String
    ) : Base()
}

Then for example what I would like to happen is:

val baseInstance = Base.Subclass(abstractProperty = "abstp", subclassConcreteProperty = "sclassp")

print(
      Json{
        encodeDefaults = true // can check https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#concrete-properties-in-a-base-class
      }.encodeToString(base) 
)

// Result: {"abstractProperty": "abstp", "abstract_property": "abstp", "subclassConcreteProperty": "sclassp", "concreteProperty":"concrete property of base", }

The issue I am currently facing lies in the @SerialName of abstractProperty. Is there a way to make serialzer take one from base class so it is abstract_property instead of abstractProperty.

Of course I understand that I can add @SerialName in the subclass explicitly but I really don't want to repeat this code yet again. I assume I will have many subclasses with the same @SerialName for this abstract property.

1

There are 1 answers

0
Jorn On

The way to do this without specifying anything but @Serializable for subclasses is to use a sealed supertype.

If you can't or won't do that, you'll have to specify @SerialName for each supported subclass. Which is logical, because how should the compiler plugin know about arbitrary subclasses if you don't mark them?

It's all explained at length in the documentation.