kotlinx.serialization icon indicating copy to clipboard operation
kotlinx.serialization copied to clipboard

Consider unifying serial names of SealedClassSerializer and PolymorphicClassSerializer

Open sandwwraith opened this issue 1 month ago • 1 comments

Currently they have different formats:

interface X

@Serializable
sealed interface Y

@Test
fun names() {
    println(serializer<X>().descriptor.serialName) // kotlinx.serialization.Polymorphic<X>
    println(serializer<Y>().descriptor.serialName) // kotlinx.serialization.features.DefaultPolymorphicSerializerTest.Y
}

Moreover, X's name is not affected by @SerialName (https://github.com/Kotlin/kotlinx.serialization/blob/45976024789fce101b650f3fe5546dd30362658a/core/commonMain/src/kotlinx/serialization/descriptors/ContextAware.kt#L94).

Changing it would bring uniformity in exception messages, but it is a potential breaking change.

sandwwraith avatar Nov 04 '25 07:11 sandwwraith

Looking at this, the naming of X is not at all different from the case of any use of PolymorphicSerializer. This serializer needs to have a different name than the base type (if it itself is also serializable - something the polymorphicserializer does not know). As polymorphicSerializer only works on base classes (and does not require or use their serializability) it has little choice to use the class/type name. Unfortunately it only uses the class name (not FQN) so it is hardly unique.

Then considering SealedSerializer it uses the same pattern, but then it is initialized in the companion of the sealed base with the name of the sealed interface/class.

Interestingly the code refuses to run for an empty abstract class X if it is not @Serializable. But if it is @Serializable the name is still not taken into account.

In principle a consistent/coherent approach between the two forms of polymorphic serialization would be desirable, but it would be a (potentially significant) incompatible change (these are the base serializers so I don't think it would break XML format's wire format - only the concrete types are used in this case). Other formats may however use the name information in serialization.

Ideally a change like this would be configurable, and have a deprecation period to change the behaviour. I'm not sure how feasible this is though as the only way it would work would be some sort of global configuration option that is then used in the creation/initialisation of the relevant serial descriptors.

From a practical perspective, it is not clear how feasible it is how to even have a consistent naming system. It would very likely be of the form "kotlinx.serialization.Polymorphic<FullClassNameOrSerialName>", where for debugging the class name would potentially even be clearer than the serial name. While in some cases the serial name could be used, there are likely cases where the serializer is constructed without this information (do we want to try to look up the serial name of a dynamically created polymorphic serializer? Is that even feasible?).

pdvrieze avatar Nov 04 '25 19:11 pdvrieze