PolymorphicSerializer

class PolymorphicSerializer<T : Any>(val baseClass: KClass<T>) : AbstractPolymorphicSerializer<T>

This class provides support for multiplatform polymorphic serialization for interfaces and abstract classes.

To avoid the most common security pitfalls and reflective lookup (and potential load) of an arbitrary class, all serializable implementations of any polymorphic type must be registered in advance in the scope of base polymorphic type, efficiently preventing unbounded polymorphic serialization of an arbitrary type.

Polymorphic serialization is enabled automatically by default for interfaces and Serializable abstract classes. To enable this feature explicitly on other types, use @SerializableWith(PolymorphicSerializer::class) or Polymorphic annotation on the property.

Usage of the polymorphic serialization can be demonstrated by the following example:

abstract class BaseRequest()
@Serializable
data class RequestA(val id: Int): BaseRequest()
@Serializable
data class RequestB(val s: String): BaseRequest()

abstract class BaseResponse()
@Serializable
data class ResponseC(val payload: Long): BaseResponse()
@Serializable
data class ResponseD(val payload: ByteArray): BaseResponse()

@Serializable
data class Message(
@Polymorphic val request: BaseRequest,
@Polymorphic val response: BaseResponse
)

In this example, both request and response in Message are serializable with PolymorphicSerializer.

BaseRequest and BaseResponse are base classes and they are captured during compile time by the plugin. Yet PolymorphicSerializer for BaseRequest should only allow RequestA and RequestB serializers, and none of the response's serializers.

This is achieved via special registration function in the module:

val requestAndResponseModule = SerializersModule {
polymorphic(BaseRequest::class) {
subclass(RequestA::class)
subclass(RequestB::class)
}
polymorphic(BaseResponse::class) {
subclass(ResponseC::class)
subclass(ResponseD::class)
}
}

See also

Constructors

Link copied to clipboard
fun <T : Any> PolymorphicSerializer(baseClass: KClass<T>)

Functions

Link copied to clipboard
override fun deserialize(decoder: Decoder): T

Deserializes the value of type T using the format that is represented by the given decoder. deserialize method is format-agnostic and operates with a high-level structured Decoder API. As long as most of the formats imply an arbitrary order of properties, deserializer should be able to decode these properties in an arbitrary order and in a format-agnostic way. For that purposes, CompositeDecoder.decodeElementIndex-based loop is used: decoder firstly signals property at which index it is ready to decode and then expects caller to decode property with the given index.

Link copied to clipboard
open fun findPolymorphicSerializerOrNull(decoder: CompositeDecoder, klassName: String?): DeserializationStrategy<out T>?

Lookups an actual serializer for given klassName withing the current base class. May use context from the decoder.

open fun findPolymorphicSerializerOrNull(encoder: Encoder, value: T): SerializationStrategy<T>?

Lookups an actual serializer for given value within the current base class. May use context from the encoder.

Link copied to clipboard
override fun serialize(encoder: Encoder, value: T)

Serializes the value of type T using the format that is represented by the given encoder. serialize method is format-agnostic and operates with a high-level structured Encoder API. Throws SerializationException if value cannot be serialized.

Link copied to clipboard
open override fun toString(): String

Properties

Link copied to clipboard
open override val baseClass: KClass<T>

Base class for all classes that this polymorphic serializer can serialize or deserialize.

Link copied to clipboard
open override val descriptor: SerialDescriptor

Describes the structure of the serializable representation of T, produced by this serializer. Knowing the structure of the descriptor is required to determine the shape of the serialized form (e.g. what elements are encoded as lists and what as primitives) along with its metadata such as alternative names.