0
# Any Message Support
1
2
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.
3
4
## Capabilities
5
6
### AnyMessage Class
7
8
Wire implementation of google.protobuf.Any for wrapping arbitrary protobuf messages.
9
10
```kotlin { .api }
11
/**
12
* Wire implementation of google.protobuf.Any type
13
* @param typeUrl Type identifier (e.g., "type.googleapis.com/package.MessageName")
14
* @param value Serialized message data
15
*/
16
class AnyMessage(
17
val typeUrl: String,
18
val value: ByteString = ByteString.EMPTY
19
) : Message<AnyMessage, Nothing> {
20
21
/** Unpack to specific type, throws if type mismatch */
22
fun <T> unpack(adapter: ProtoAdapter<T>): T
23
24
/** Unpack to specific type, returns null if type mismatch */
25
fun <T> unpackOrNull(adapter: ProtoAdapter<T>): T?
26
27
/** Create copy with modified fields */
28
fun copy(
29
typeUrl: String = this.typeUrl,
30
value: ByteString = this.value
31
): AnyMessage
32
33
companion object {
34
/** Pack any message into AnyMessage */
35
fun pack(message: Message<*, *>): AnyMessage
36
37
/** Built-in adapter for AnyMessage */
38
@JvmField
39
val ADAPTER: ProtoAdapter<AnyMessage>
40
}
41
}
42
```
43
44
**Usage Examples:**
45
46
```kotlin
47
import com.squareup.wire.*
48
49
// Create messages to pack
50
val person = Person.Builder()
51
.name("Alice")
52
.age(30)
53
.build()
54
55
val address = Address.Builder()
56
.street("123 Main St")
57
.city("Springfield")
58
.build()
59
60
// Pack messages into Any
61
val anyPerson: AnyMessage = AnyMessage.pack(person)
62
val anyAddress: AnyMessage = AnyMessage.pack(address)
63
64
println(anyPerson.typeUrl) // "type.googleapis.com/com.example.Person"
65
println(anyAddress.typeUrl) // "type.googleapis.com/com.example.Address"
66
67
// Unpack with type checking
68
val unpackedPerson: Person = anyPerson.unpack(Person.ADAPTER)
69
val unpackedAddress: Address = anyAddress.unpack(Address.ADAPTER)
70
71
// Safe unpacking (returns null if type mismatch)
72
val maybePerson: Person? = anyAddress.unpackOrNull(Person.ADAPTER) // null
73
val maybeAddress: Address? = anyAddress.unpackOrNull(Address.ADAPTER) // Address instance
74
75
// Type mismatch throws exception
76
try {
77
val wrongType: Address = anyPerson.unpack(Address.ADAPTER)
78
} catch (e: IllegalStateException) {
79
println("Type mismatch: ${e.message}")
80
}
81
82
// Use in container messages
83
class Container(
84
@field:WireField(tag = 1, adapter = "com.squareup.wire.AnyMessage#ADAPTER")
85
val payload: AnyMessage?,
86
87
unknownFields: ByteString = ByteString.EMPTY
88
) : Message<Container, Container.Builder>(ADAPTER, unknownFields) {
89
90
// Helper methods for type-safe access
91
fun getPersonPayload(): Person? = payload?.unpackOrNull(Person.ADAPTER)
92
fun getAddressPayload(): Address? = payload?.unpackOrNull(Address.ADAPTER)
93
}
94
95
// Create container with different payload types
96
val containerWithPerson = Container.Builder()
97
.payload(AnyMessage.pack(person))
98
.build()
99
100
val containerWithAddress = Container.Builder()
101
.payload(AnyMessage.pack(address))
102
.build()
103
104
// Process containers generically
105
fun processContainer(container: Container) {
106
val payload = container.payload ?: return
107
108
when {
109
payload.typeUrl.endsWith("Person") -> {
110
val person = payload.unpack(Person.ADAPTER)
111
println("Processing person: ${person.name}")
112
}
113
payload.typeUrl.endsWith("Address") -> {
114
val address = payload.unpack(Address.ADAPTER)
115
println("Processing address: ${address.street}")
116
}
117
else -> {
118
println("Unknown payload type: ${payload.typeUrl}")
119
}
120
}
121
}
122
```
123
124
## Type URL Format
125
126
Type URLs follow the format: `type.googleapis.com/package.MessageName`
127
128
- **Domain**: Usually `type.googleapis.com` for Google types
129
- **Package**: Protocol buffer package name with dots
130
- **Message**: Message type name
131
132
Wire automatically generates appropriate type URLs for all messages with `typeUrl` support.