This page shows how to work with the Kotlin types generated from .proto schemas. For details on what the protoc plugins and the compiler plugin produce, see Schema and codegen.
Building messages
Every generated message has a builder DSL accessed through the extension Companion.invoke operator:
import com.example.HelloRequest
import com.example.invoke
val request = HelloRequest {
name = "kotlinx.rpc"
}
Copying messages
Messages are immutable. Use copy extension to create a modified version:
import com.example.copy
val updated = request.copy {
name = "grpc"
}
Optional fields and clearing
Optional protobuf fields are generated as non-null Kotlin properties. When such a field is absent, the generated property returns the protobuf default value for that field. To check whether the field is actually present, use presence.has<Field>. Generated builders and copy { ... } blocks also provide clear<Field>(), which removes the field from the message instead of assigning its default value.
import com.example.User
import com.example.copy
import com.example.invoke
val original = User {
nickname = "neo"
}
check(original.presence.hasNickname)
check(original.nickname == "neo")
val cleared = original.copy {
clearNickname()
}
check(!cleared.presence.hasNickname)
check(cleared.nickname == "")
// Available only when optionalFieldOrNullGetters is enabled:
check(cleared.nicknameOrNull == null)
Clearing a field affects subsequent serialization as well: once cleared, the field is absent from newly encoded data and stays absent after decode.
Enums
Proto enums become Kotlin sealed types. Unknown values received over the wire are represented as UNRECOGNIZED: