or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

any-message-operations.mdbytestring-extensions.mddsl-infrastructure.mdextension-field-access.mdindex.md

extension-field-access.mddocs/

0

# Extension Field Access

1

2

Operator overloads for intuitive extension field access on extendable messages and builders, providing get, set, and contains operations with full type safety.

3

4

## Capabilities

5

6

### Setting Extension Values

7

8

Sets the current value of a protocol buffer extension in a message builder.

9

10

```kotlin { .api }

11

/**

12

* Sets the current value of the proto extension in this builder

13

* @param extension the extension field to set

14

* @param value the value to set for the extension

15

*/

16

operator fun <

17

M : GeneratedMessage.ExtendableMessage<M>,

18

B : GeneratedMessage.ExtendableBuilder<M, B>,

19

T : Any

20

> B.set(extension: ExtensionLite<M, T>, value: T)

21

```

22

23

**Usage Example:**

24

25

```kotlin

26

import com.google.protobuf.kotlin.set

27

// Assuming you have generated message classes with extensions

28

29

val builder = MyExtendableMessage.newBuilder()

30

31

// Set extension value using bracket notation

32

builder[myStringExtension] = "Hello, Extensions!"

33

builder[myIntExtension] = 42

34

builder[myBoolExtension] = true

35

36

val message = builder.build()

37

```

38

39

### Getting Extension Values

40

41

Gets the current value of a protocol buffer extension from a message or builder.

42

43

```kotlin { .api }

44

/**

45

* Gets the current value of the proto extension

46

* @param extension the extension field to get

47

* @return the current value of the extension

48

*/

49

operator fun <

50

M : GeneratedMessage.ExtendableMessage<M>,

51

MorBT : GeneratedMessage.ExtendableMessageOrBuilder<M>,

52

T : Any

53

> MorBT.get(extension: ExtensionLite<M, T>): T

54

```

55

56

**Usage Example:**

57

58

```kotlin

59

import com.google.protobuf.kotlin.get

60

61

// From a built message

62

val message: MyExtendableMessage = // ... some message with extensions

63

val stringValue = message[myStringExtension]

64

val intValue = message[myIntExtension]

65

val boolValue = message[myBoolExtension]

66

67

// From a builder

68

val builder = MyExtendableMessage.newBuilder()

69

builder[myStringExtension] = "test"

70

val currentValue = builder[myStringExtension] // "test"

71

```

72

73

### Checking Extension Presence

74

75

Returns true if the specified extension is set on a message or builder.

76

77

```kotlin { .api }

78

/**

79

* Returns true if the specified extension is set on this builder

80

* @param extension the extension field to check

81

* @return true if the extension is set, false otherwise

82

*/

83

operator fun <

84

M : GeneratedMessage.ExtendableMessage<M>,

85

MorBT : GeneratedMessage.ExtendableMessageOrBuilder<M>

86

> MorBT.contains(extension: ExtensionLite<M, *>): Boolean

87

```

88

89

**Usage Example:**

90

91

```kotlin

92

import com.google.protobuf.kotlin.contains

93

94

val message: MyExtendableMessage = // ... some message

95

val builder = MyExtendableMessage.newBuilder()

96

97

// Check if extension is set

98

if (myStringExtension in message) {

99

println("String extension is set: ${message[myStringExtension]}")

100

} else {

101

println("String extension is not set")

102

}

103

104

// Check before accessing to avoid exceptions

105

if (myOptionalExtension in builder) {

106

val value = builder[myOptionalExtension]

107

// Use value safely

108

}

109

```

110

111

## Complete Usage Patterns

112

113

### Working with Extension Fields

114

115

```kotlin

116

import com.google.protobuf.kotlin.*

117

118

fun configureMessage(builder: MyExtendableMessage.Builder) {

119

// Set various extension types

120

builder[userNameExtension] = "john_doe"

121

builder[userAgeExtension] = 25

122

builder[isActiveExtension] = true

123

builder[scoresExtension] = listOf(95, 87, 92)

124

125

// Check what's been set

126

if (userNameExtension in builder) {

127

println("Username: ${builder[userNameExtension]}")

128

}

129

130

if (userAgeExtension in builder) {

131

println("Age: ${builder[userAgeExtension]}")

132

}

133

}

134

135

fun processMessage(message: MyExtendableMessage) {

136

// Safely access extensions

137

val username = if (userNameExtension in message) {

138

message[userNameExtension]

139

} else {

140

"unknown"

141

}

142

143

val age = if (userAgeExtension in message) {

144

message[userAgeExtension]

145

} else {

146

0

147

}

148

149

println("Processing user: $username (age: $age)")

150

}

151

```

152

153

### Extension Field Validation

154

155

```kotlin

156

import com.google.protobuf.kotlin.*

157

158

fun validateExtensions(message: MyExtendableMessage): List<String> {

159

val errors = mutableListOf<String>()

160

161

if (requiredNameExtension !in message) {

162

errors.add("Required name extension is missing")

163

}

164

165

if (emailExtension in message) {

166

val email = message[emailExtension]

167

if (!email.contains("@")) {

168

errors.add("Invalid email format: $email")

169

}

170

}

171

172

if (ageExtension in message) {

173

val age = message[ageExtension]

174

if (age < 0 || age > 150) {

175

errors.add("Invalid age: $age")

176

}

177

}

178

179

return errors

180

}

181

```

182

183

### Builder Pattern with Extensions

184

185

```kotlin

186

import com.google.protobuf.kotlin.*

187

188

class MessageBuilder {

189

private val builder = MyExtendableMessage.newBuilder()

190

191

fun withName(name: String): MessageBuilder {

192

builder[nameExtension] = name

193

return this

194

}

195

196

fun withAge(age: Int): MessageBuilder {

197

builder[ageExtension] = age

198

return this

199

}

200

201

fun withEmail(email: String): MessageBuilder {

202

builder[emailExtension] = email

203

return this

204

}

205

206

fun build(): MyExtendableMessage {

207

// Validation before building

208

require(nameExtension in builder) { "Name is required" }

209

require(ageExtension in builder) { "Age is required" }

210

211

return builder.build()

212

}

213

}

214

215

// Usage

216

val message = MessageBuilder()

217

.withName("Alice")

218

.withAge(30)

219

.withEmail("alice@example.com")

220

.build()

221

```

222

223

### Copying Extensions Between Messages

224

225

```kotlin

226

import com.google.protobuf.kotlin.*

227

228

fun copyExtensions(

229

source: MyExtendableMessage,

230

target: MyExtendableMessage.Builder

231

) {

232

// Copy all known extensions

233

val extensionsToCheck = listOf(

234

nameExtension,

235

ageExtension,

236

emailExtension,

237

isActiveExtension

238

)

239

240

extensionsToCheck.forEach { extension ->

241

if (extension in source) {

242

target[extension] = source[extension]

243

}

244

}

245

}

246

247

// Usage

248

val originalMessage: MyExtendableMessage = // ... some message

249

val newBuilder = MyExtendableMessage.newBuilder()

250

251

copyExtensions(originalMessage, newBuilder)

252

val copiedMessage = newBuilder.build()

253

```

254

255

## Types

256

257

```kotlin { .api }

258

// Imported from Java protobuf library

259

import com.google.protobuf.ExtensionLite

260

import com.google.protobuf.GeneratedMessage.ExtendableMessage

261

import com.google.protobuf.GeneratedMessage.ExtendableBuilder

262

import com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder

263

```

264

265

## Notes

266

267

- These operator functions provide Kotlin-idiomatic access to protocol buffer extensions

268

- The `set` operator works only on builders, not on immutable messages

269

- The `get` and `contains` operators work on both messages and builders

270

- Extension fields must be defined in your `.proto` files and generated by the protocol buffer compiler

271

- Type safety is maintained through generic constraints - you cannot assign the wrong type to an extension field

272

- Always check with `contains` (using `in` operator) before accessing optional extensions to avoid exceptions

273

- These operators are commonly used in DSL builders and when working with protocol buffer messages that support extensions