Skip to main content
Version: dev

Schema Metadata

Kotlin schema metadata is used by the KSP-generated xlang serializers. Reuse the Java Fory annotations for schema concepts, and use Kotlin type-use annotations only when you need Kotlin specific integer encoding metadata.

Struct Fields

Annotate Kotlin schema classes with @ForyStruct and constructor properties with @ForyField(id = N):

import org.apache.fory.annotation.ForyField
import org.apache.fory.annotation.ForyStruct
import org.apache.fory.kotlin.Fixed
import org.apache.fory.kotlin.VarInt

@ForyStruct
data class User(
@ForyField(id = 1)
val id: @Fixed UInt,

@ForyField(id = 2)
val score: @VarInt Long,

@ForyField(id = 3)
val tags: List<String>,
)

Use @ForyField(id = 1) on constructor properties. @field:ForyField(id = 1) is also accepted for field-backed properties. Do not use @get:ForyField or @set:ForyField; accessors are not schema fields and the processor rejects them.

Nullability

Use Kotlin ? to describe nullable schema positions. Nullability is preserved inside collections and maps:

@ForyStruct
data class NullabilityExample(
@ForyField(id = 1)
val names: List<String>,

@ForyField(id = 2)
val optionalNames: List<String?>,

@ForyField(id = 3)
val nullableList: List<String>?,
)

Do not use Fory @Nullable in hand-written constructor-based Kotlin structs. The KSP processor reads nullability from Kotlin source and rejects conflicting nullable annotations.

Reference Tracking

Kotlin generated serializers preserve @Ref metadata for fields, list elements, and map values:

import org.apache.fory.annotation.Ref

@ForyStruct
data class Node(
@ForyField(id = 1)
val children: List<@Ref Node>,

@ForyField(id = 2)
@Ref
val parent: Node?,
)

Global reference tracking still comes from the runtime configuration. See Configuration.

Integer Encoding

Kotlin type-use encoding annotations map to Fory xlang integer encodings:

AnnotationValid Kotlin types
@FixedInt, Long, UInt, ULong
@VarIntInt, Long, UInt, ULong
@TaggedLong, ULong

Without an annotation, xlang Int, Long, UInt, and ULong use varint encoding.

Collections And Dense Arrays

Collection declarations carry schema shape, not JVM implementation identity. List<String> is encoded as list<string> and Map<String, Int> is encoded as map<string, int32>.

Dense primitive and unsigned array fields are supported, including BooleanArray, ByteArray, IntArray, LongArray, FloatArray, DoubleArray, UByteArray, UShortArray, UIntArray, and ULongArray. ByteArray is encoded as Fory binary unless the type use is annotated with Java @ArrayType.