or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

any-message.mdenum-support.mdfield-annotations.mdindex.mdmessage-framework.mdproto-adapters.mdprotobuf-io.mdtime-types.md

any-message.mddocs/

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.