CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-squareup-wire--wire-runtime

Runtime support library for Wire-generated Protocol Buffer classes in Kotlin multiplatform applications

Pending
Overview
Eval results
Files

any-message.mddocs/

Any Message Support

Support for google.protobuf.Any messages allowing type-safe packing and unpacking of arbitrary protocol buffer messages. AnyMessage provides a way to embed any message type within another message.

Capabilities

AnyMessage Class

Wire implementation of google.protobuf.Any for wrapping arbitrary protobuf messages.

/**
 * Wire implementation of google.protobuf.Any type
 * @param typeUrl Type identifier (e.g., "type.googleapis.com/package.MessageName")
 * @param value Serialized message data
 */
class AnyMessage(
    val typeUrl: String,
    val value: ByteString = ByteString.EMPTY
) : Message<AnyMessage, Nothing> {
    
    /** Unpack to specific type, throws if type mismatch */
    fun <T> unpack(adapter: ProtoAdapter<T>): T
    
    /** Unpack to specific type, returns null if type mismatch */
    fun <T> unpackOrNull(adapter: ProtoAdapter<T>): T?
    
    /** Create copy with modified fields */
    fun copy(
        typeUrl: String = this.typeUrl,
        value: ByteString = this.value
    ): AnyMessage
    
    companion object {
        /** Pack any message into AnyMessage */
        fun pack(message: Message<*, *>): AnyMessage
        
        /** Built-in adapter for AnyMessage */
        @JvmField
        val ADAPTER: ProtoAdapter<AnyMessage>
    }
}

Usage Examples:

import com.squareup.wire.*

// Create messages to pack
val person = Person.Builder()
    .name("Alice")
    .age(30)
    .build()

val address = Address.Builder()
    .street("123 Main St")
    .city("Springfield")
    .build()

// Pack messages into Any
val anyPerson: AnyMessage = AnyMessage.pack(person)
val anyAddress: AnyMessage = AnyMessage.pack(address)

println(anyPerson.typeUrl) // "type.googleapis.com/com.example.Person"
println(anyAddress.typeUrl) // "type.googleapis.com/com.example.Address"

// Unpack with type checking
val unpackedPerson: Person = anyPerson.unpack(Person.ADAPTER)
val unpackedAddress: Address = anyAddress.unpack(Address.ADAPTER)

// Safe unpacking (returns null if type mismatch)
val maybePerson: Person? = anyAddress.unpackOrNull(Person.ADAPTER) // null
val maybeAddress: Address? = anyAddress.unpackOrNull(Address.ADAPTER) // Address instance

// Type mismatch throws exception
try {
    val wrongType: Address = anyPerson.unpack(Address.ADAPTER)
} catch (e: IllegalStateException) {
    println("Type mismatch: ${e.message}")
}

// Use in container messages
class Container(
    @field:WireField(tag = 1, adapter = "com.squareup.wire.AnyMessage#ADAPTER")
    val payload: AnyMessage?,
    
    unknownFields: ByteString = ByteString.EMPTY
) : Message<Container, Container.Builder>(ADAPTER, unknownFields) {
    
    // Helper methods for type-safe access
    fun getPersonPayload(): Person? = payload?.unpackOrNull(Person.ADAPTER)
    fun getAddressPayload(): Address? = payload?.unpackOrNull(Address.ADAPTER)
}

// Create container with different payload types
val containerWithPerson = Container.Builder()
    .payload(AnyMessage.pack(person))
    .build()

val containerWithAddress = Container.Builder()
    .payload(AnyMessage.pack(address))
    .build()

// Process containers generically
fun processContainer(container: Container) {
    val payload = container.payload ?: return
    
    when {
        payload.typeUrl.endsWith("Person") -> {
            val person = payload.unpack(Person.ADAPTER)
            println("Processing person: ${person.name}")
        }
        payload.typeUrl.endsWith("Address") -> {
            val address = payload.unpack(Address.ADAPTER)
            println("Processing address: ${address.street}")
        }
        else -> {
            println("Unknown payload type: ${payload.typeUrl}")
        }
    }
}

Type URL Format

Type URLs follow the format: type.googleapis.com/package.MessageName

  • Domain: Usually type.googleapis.com for Google types
  • Package: Protocol buffer package name with dots
  • Message: Message type name

Wire automatically generates appropriate type URLs for all messages with typeUrl support.

Install with Tessl CLI

npx tessl i tessl/maven-com-squareup-wire--wire-runtime

docs

any-message.md

enum-support.md

field-annotations.md

index.md

message-framework.md

proto-adapters.md

protobuf-io.md

time-types.md

tile.json