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

Provide an API to build serial descriptors for recursive data-structures.

Open qwwdfsad opened this issue 10 months ago • 5 comments

Consider the following class:

data class Node(val data: Int, val nodes: List<Node>)

For that, kotlinx.serialization is able to generate a proper serializer (using the coupling between auto-generated serializer and childSerializers loophole), but there is no public API to write it an external (or custom) serial descriptor/serializer for that.

When solving the similar problem for JsonElement serialization, we ended up with the following:

https://github.com/Kotlin/kotlinx.serialization/blob/776e3c1bb96a0edf6f7dad074920cadc3c9e3b52/formats/json/commonMain/src/kotlinx/serialization/json/JsonElementSerializers.kt#L219-L235

Potentially, we can streamline it, pick a decent name (e.g.: recursive, deferred, nested) and make it public

qwwdfsad avatar Jan 29 '25 20:01 qwwdfsad

In addition it would be good to make sure that the library (and all formats) work correctly with user provided serial descriptor implementations.

In terms of the general solution, it would be good if the solution could be properly self-referential (rather than having lazily generated copies). This may be mainly the documentation of preferring Type::serializer().serialDescriptor.

pdvrieze avatar Jan 29 '25 20:01 pdvrieze

Not sure I follow here, could you please elaborate on the idea?

In addition it would be good to make sure that the library (and all formats) work correctly with user provided serial descriptor implementations.

This part, I think, we'll be extensively covered by tests (and the whole approach is more or less battle-tested with JsonElementSerializer).

it would be good if the solution could be properly self-referential (rather than having lazily generated copies)

The caveat here is that all intermediate serializers have to be aware of that. I.e. the caveat here is that in the following:

// In node serializer class

buildSerialDescriptor {
     element<List<Node>>(...)
}

it is s List serializer that has to be aware its type argument serializer should be retrieved lazily, not our machinery. The same goes for any other parametrized serializer

qwwdfsad avatar Jan 29 '25 21:01 qwwdfsad

I suspect it works already (due to JsonElementSerializer), but some other cases special case specific serializers (AbstractPolymorphicSerializer). In any case, I would see the self-referential aspect as mainly an optimization, hence the idea of just documenting it. I would say that any attempt at caching/lookups would be hard and certainly not worth it if possible at all.

pdvrieze avatar Jan 29 '25 21:01 pdvrieze

👍🏿

Zakonduasabbat avatar Mar 01 '25 10:03 Zakonduasabbat

Ok

Zakonduasabbat avatar Mar 01 '25 10:03 Zakonduasabbat