Runtime support library for Wire-generated Protocol Buffer classes in Kotlin multiplatform applications
npx @tessl/cli install tessl/maven-com-squareup-wire--wire-runtime@4.9.0Wire Runtime provides core functionality for encoding, decoding, and working with Protocol Buffer messages in Kotlin multiplatform applications. It serves as the foundation for Wire-generated protobuf classes, offering cross-platform serialization capabilities, immutable message classes with builders, and efficient binary protobuf data handling.
implementation("com.squareup.wire:wire-runtime:4.9.11")import com.squareup.wire.*
import com.squareup.wire.ProtoAdapter.*
import okio.ByteString
import okio.BufferedSource
import okio.BufferedSinkimport com.squareup.wire.*
import okio.Buffer
// Create a message using generated Wire classes
val person = Person.Builder()
.name("John Doe")
.age(30)
.email("john@example.com")
.build()
// Encode message to binary format
val encoded: ByteArray = person.encode()
val encodedByteString: ByteString = person.encodeByteString()
// Decode message from binary format
val decoded: Person = Person.ADAPTER.decode(encoded)
// Work with protocol buffer I/O directly
val buffer = Buffer()
val writer = ProtoWriter(buffer)
ProtoAdapter.STRING.encodeWithTag(writer, 1, "Hello Wire!")
val reader = ProtoReader(buffer)
val tag = reader.nextTag() // Returns 1
val message = ProtoAdapter.STRING.decode(reader) // Returns "Hello Wire!"Wire Runtime is built around several key architectural components:
ProtoAdapter handles encoding/decoding for each type with built-in adapters for all protobuf typesProtoReader and ProtoWriter provide low-level protocol buffer reading and writingexpect classes, platform-specific implementationsCore message classes and builders that form the foundation of all Wire-generated protocol buffer classes.
abstract class Message<M : Message<M, B>, B : Message.Builder<M, B>>(
adapter: ProtoAdapter<M>,
unknownFields: ByteString
) {
val unknownFields: ByteString
val adapter: ProtoAdapter<M>
abstract fun newBuilder(): B
fun encode(sink: BufferedSink)
fun encode(): ByteArray
fun encodeByteString(): ByteString
}
abstract class Message.Builder<M : Message<M, B>, B : Builder<M, B>> {
fun addUnknownFields(unknownFields: ByteString): Builder<M, B>
fun addUnknownField(tag: Int, fieldEncoding: FieldEncoding, value: Any?): Builder<M, B>
fun clearUnknownFields(): Builder<M, B>
fun buildUnknownFields(): ByteString
abstract fun build(): M
}Low-level reading and writing of protocol buffer wire format data with support for all protobuf field types.
class ProtoReader(source: BufferedSource) {
fun beginMessage(): Long
fun endMessageAndGetUnknownFields(token: Long): ByteString
fun nextTag(): Int
fun peekFieldEncoding(): FieldEncoding?
fun readString(): String
fun readBytes(): ByteString
fun readVarint32(): Int
fun readVarint64(): Long
fun readFixed32(): Int
fun readFixed64(): Long
}
class ProtoWriter(sink: BufferedSink) {
fun writeTag(fieldNumber: Int, fieldEncoding: FieldEncoding)
fun writeString(value: String)
fun writeBytes(value: ByteString)
fun writeVarint32(value: Int)
fun writeVarint64(value: Long)
fun writeFixed32(value: Int)
fun writeFixed64(value: Long)
}Type-safe encoding and decoding adapters for all protocol buffer types, including built-in adapters for scalars, collections, and Google Well-Known Types.
abstract class ProtoAdapter<E>(
fieldEncoding: FieldEncoding,
type: KClass<*>?,
typeUrl: String?,
syntax: Syntax,
identity: E? = null,
sourceFile: String? = null
) {
abstract fun encodedSize(value: E): Int
abstract fun encode(writer: ProtoWriter, value: E)
abstract fun decode(reader: ProtoReader): E
fun encode(value: E): ByteArray
fun decode(bytes: ByteArray): E
fun asPacked(): ProtoAdapter<List<E>>
fun asRepeated(): ProtoAdapter<List<E>>
companion object {
val STRING: ProtoAdapter<String>
val BYTES: ProtoAdapter<ByteString>
val INT32: ProtoAdapter<Int>
val INT64: ProtoAdapter<Long>
val BOOL: ProtoAdapter<Boolean>
val FLOAT: ProtoAdapter<Float>
val DOUBLE: ProtoAdapter<Double>
// ... all built-in adapters
}
}Support for protocol buffer enums with proper value mapping and unknown value handling.
interface WireEnum {
val value: Int
}
abstract class EnumAdapter<E : WireEnum>(
type: KClass<E>,
syntax: Syntax,
identity: E?
) : ProtoAdapter<E> {
protected abstract fun fromValue(value: Int): E?
}Annotations for marking generated message fields with encoding metadata and serialization behavior.
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class WireField(
val tag: Int,
val adapter: String,
val label: Label = Label.OPTIONAL,
val redacted: Boolean = false,
val declaredName: String = "",
val jsonName: String = "",
val oneofName: String = "",
val schemaIndex: Int = -1
)
enum class Label {
REQUIRED, OPTIONAL, REPEATED, ONE_OF, PACKED, OMIT_IDENTITY
}Cross-platform time and duration types that map to Google Well-Known Types.
expect class Duration {
fun getSeconds(): Long
fun getNano(): Int
}
expect class Instant {
fun getEpochSecond(): Long
fun getNano(): Int
}
fun durationOfSeconds(seconds: Long, nano: Long): Duration
fun ofEpochSecond(epochSecond: Long, nano: Long): InstantSupport for google.protobuf.Any messages allowing type-safe packing and unpacking of arbitrary protocol buffer messages.
class AnyMessage(
val typeUrl: String,
val value: ByteString = ByteString.EMPTY
) : Message<AnyMessage, Nothing> {
fun <T> unpack(adapter: ProtoAdapter<T>): T
fun <T> unpackOrNull(adapter: ProtoAdapter<T>): T?
companion object {
fun pack(message: Message<*, *>): AnyMessage
val ADAPTER: ProtoAdapter<AnyMessage>
}
}enum class FieldEncoding(val value: Int) {
VARINT(0),
FIXED64(1),
LENGTH_DELIMITED(2),
FIXED32(5)
}
enum class Syntax {
PROTO_2,
PROTO_3
}