decodeSequentially

Checks whether the current decoder supports strictly ordered decoding of the data without calling to decodeElementIndex. If the method returns true, the caller might skip decodeElementIndex calls and start invoking decode*Element directly, incrementing the index of the element one by one. This method can be called by serializers (either generated or user-defined) as a performance optimization, but there is no guarantee that the method will be ever called. Practically, it means that implementations that may benefit from sequential decoding should also support a regular decodeElementIndex-based decoding as well.

Example of usage:

class MyPair(i: Int, d: Double)

object MyPairSerializer : KSerializer<MyPair> {
// ... other methods omitted

fun deserialize(decoder: Decoder): MyPair {
val composite = decoder.beginStructure(descriptor)
if (composite.decodeSequentially()) {
val i = composite.decodeIntElement(descriptor, index = 0) // Mind the sequential indexing
val d = composite.decodeIntElement(descriptor, index = 1)
composite.endStructure(descriptor)
return MyPair(i, d)
} else {
// Fallback to `decodeElementIndex` loop, refer to its documentation for details
}
}
}

This example is a rough equivalent of what serialization plugin generates for serializable pair class.

Sequential decoding is a performance optimization for formats with strictly ordered schema, usually binary ones. Regular formats such as JSON or ProtoBuf cannot use this optimization, because e.g. in the latter example, the same data can be represented both as {"i": 1, "d": 1.0}"and {"d": 1.0, "i": 1}` (thus, unordered).