Call default/plugin-generated serializer from custom serializer

Hi,

I am trying to use the default serialization lib to serialize a class hierarchy consisting of a super class Matrix and a sub class ColumnVector (ColumnVector is not adding any fields). as I want to be able to instantiate both, I cannot abstract / seal Matrix and therefore can’t use the polymorphic definition in the SerializersModule.

Therefore I’m trying to build a custom serializer that encodes the class I’m using into a separate element of the serialized structure and then appends the serialized object itself.

Is this possible or do I need to manually serialize all the fields of Matrix?
What would I use as type for the SerialDescriptor? Is there a way to access the default/plugin-generated serializer after I defined my own and specified it in the @Serialized(with = ...) annotation?

@Serializable(with = MatrixSerializer::class)
open class Matrix(var m: Array<Array<Complex>> = someDefaultValue) {...}

class ColumnVector(v: Array<Complex>) : Matrix(v.doSth()) { ... }

object MatrixSerializer : KSerializer<Matrix> {
    override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Matrix") {
        element<Boolean>("columnVector")
        element<???????>("m")
    }

    override fun serialize(encoder: Encoder, matrix: Matrix) {
        encoder.encodeStructure(descriptor) {
            encodeBooleanElement(descriptor, 0, matrix is ColumnVector)
            encodeSerializableElement(descriptor, 1, Matrix.serializer???(), matrix)
        }
    }

    override fun deserialize(decoder: Decoder): Matrix {
        TODO("Not yet implemented")
    }
}

Thanks.

Annotate ColumnVector with @Serializable as well. No need to create a custom serializer unless the problem you are facing has been omitted from the post!

1 Like

Thanks for your reply.
I can’t do that as ColumnVector has constructor parameters that are not variables but are just used for calling the constructor of the superclass.

1 Like

It is fairly easy to call a default serializer from a custom serializer. Looking at your question you actually want to access a generated serializer as well. It may be possible to have an private inner object to MatrixSerializer that is annotated with @Serializer(Matrix::class) that you delegate to. In this particular case it’s probably easier to just do it by hand.

As a sidenote, if your matrix is mutable (as it is here) it is not valid to have ColumnVector be a Matrix as it is possible to use matrix to make the ColumnVector no longer a valid matrix.

1 Like