or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

builtins.mdcore-api.mddescriptors.mdencoding.mdindex.mdmodules.md

descriptors.mddocs/

0

# Descriptors System

1

2

The descriptors system provides structural metadata and introspection capabilities for serializable types. It enables format implementations to understand the structure of serializable classes without relying on reflection.

3

4

## Core Descriptor Interface

5

6

### SerialDescriptor

7

8

The main interface for describing the structure and metadata of serializable types.

9

10

```kotlin { .api }

11

interface SerialDescriptor {

12

val serialName: String

13

val kind: SerialKind

14

val elementsCount: Int

15

val annotations: List<Annotation>

16

val isNullable: Boolean

17

18

fun getElementName(index: Int): String

19

fun getElementIndex(name: String): Int

20

fun getElementAnnotations(index: Int): List<Annotation>

21

fun getElementDescriptor(index: Int): SerialDescriptor

22

fun isElementOptional(index: Int): Boolean

23

}

24

```

25

26

**Properties:**

27

- `serialName`: Unique name identifying the serializable class

28

- `kind`: The kind of serializable structure (class, list, map, etc.)

29

- `elementsCount`: Number of elements/properties in the descriptor

30

- `annotations`: Annotations applied to the class

31

- `isNullable`: Whether the type can be null

32

33

**Methods:**

34

- `getElementName(index)`: Gets the name of the element at the given index

35

- `getElementIndex(name)`: Gets the index of the element with the given name

36

- `getElementAnnotations(index)`: Gets annotations for the element at the given index

37

- `getElementDescriptor(index)`: Gets the nested descriptor for the element at the given index

38

- `isElementOptional(index)`: Checks if the element at the given index is optional

39

40

## Serial Kinds

41

42

Serial kinds categorize different types of serializable structures.

43

44

### Base SerialKind

45

46

```kotlin { .api }

47

sealed class SerialKind {

48

object ENUM : SerialKind()

49

object CONTEXTUAL : SerialKind()

50

}

51

```

52

53

### PrimitiveKind

54

55

Represents primitive types.

56

57

```kotlin { .api }

58

sealed class PrimitiveKind : SerialKind() {

59

object BOOLEAN : PrimitiveKind()

60

object BYTE : PrimitiveKind()

61

object CHAR : PrimitiveKind()

62

object SHORT : PrimitiveKind()

63

object INT : PrimitiveKind()

64

object LONG : PrimitiveKind()

65

object FLOAT : PrimitiveKind()

66

object DOUBLE : PrimitiveKind()

67

object STRING : PrimitiveKind()

68

}

69

```

70

71

### StructureKind

72

73

Represents structured types.

74

75

```kotlin { .api }

76

sealed class StructureKind : SerialKind() {

77

object CLASS : StructureKind()

78

object LIST : StructureKind()

79

object MAP : StructureKind()

80

object OBJECT : StructureKind()

81

}

82

```

83

84

### PolymorphicKind

85

86

Represents polymorphic types.

87

88

```kotlin { .api }

89

@ExperimentalSerializationApi

90

sealed class PolymorphicKind : SerialKind() {

91

object SEALED : PolymorphicKind()

92

object OPEN : PolymorphicKind()

93

}

94

```

95

96

## Descriptor Builder Functions

97

98

### buildClassSerialDescriptor

99

100

Creates a descriptor for class-like structures.

101

102

```kotlin { .api }

103

fun buildClassSerialDescriptor(

104

serialName: String,

105

vararg typeParameters: SerialDescriptor,

106

builderAction: ClassSerialDescriptorBuilder.() -> Unit = {}

107

): SerialDescriptor

108

```

109

110

**Usage:**

111

```kotlin

112

val userDescriptor = buildClassSerialDescriptor("User") {

113

element<String>("name")

114

element<String>("email")

115

element<Int>("age", isOptional = true)

116

}

117

```

118

119

### buildSerialDescriptor

120

121

Creates a generic descriptor with a specified kind.

122

123

```kotlin { .api }

124

fun buildSerialDescriptor(

125

serialName: String,

126

kind: SerialKind,

127

vararg typeParameters: SerialDescriptor,

128

builder: SerialDescriptorBuilder.() -> Unit = {}

129

): SerialDescriptor

130

```

131

132

### Collection Descriptor Builders

133

134

```kotlin { .api }

135

@ExperimentalSerializationApi

136

fun listSerialDescriptor(elementDescriptor: SerialDescriptor): SerialDescriptor

137

138

@ExperimentalSerializationApi

139

inline fun <reified T> listSerialDescriptor(): SerialDescriptor

140

141

@ExperimentalSerializationApi

142

fun mapSerialDescriptor(

143

keyDescriptor: SerialDescriptor,

144

valueDescriptor: SerialDescriptor

145

): SerialDescriptor

146

147

@ExperimentalSerializationApi

148

inline fun <reified K, reified V> mapSerialDescriptor(): SerialDescriptor

149

150

@ExperimentalSerializationApi

151

fun setSerialDescriptor(elementDescriptor: SerialDescriptor): SerialDescriptor

152

153

@ExperimentalSerializationApi

154

inline fun <reified T> setSerialDescriptor(): SerialDescriptor

155

```

156

157

**Usage:**

158

```kotlin

159

val stringListDescriptor = listSerialDescriptor(String.serializer().descriptor)

160

val intStringMapDescriptor = mapSerialDescriptor(

161

Int.serializer().descriptor,

162

String.serializer().descriptor

163

)

164

```

165

166

## Descriptor Builder Classes

167

168

### SerialDescriptorBuilder

169

170

Base builder for creating descriptors.

171

172

```kotlin { .api }

173

abstract class SerialDescriptorBuilder {

174

abstract fun element(

175

elementName: String,

176

descriptor: SerialDescriptor,

177

annotations: List<Annotation> = emptyList(),

178

isOptional: Boolean = false

179

)

180

181

inline fun <reified T> element(

182

elementName: String,

183

serializer: KSerializer<T> = serializer(),

184

annotations: List<Annotation> = emptyList(),

185

isOptional: Boolean = false

186

)

187

}

188

```

189

190

### ClassSerialDescriptorBuilder

191

192

Specialized builder for class descriptors.

193

194

```kotlin { .api }

195

class ClassSerialDescriptorBuilder(serialName: String) : SerialDescriptorBuilder() {

196

override fun element(

197

elementName: String,

198

descriptor: SerialDescriptor,

199

annotations: List<Annotation>,

200

isOptional: Boolean

201

)

202

}

203

```

204

205

**Usage:**

206

```kotlin

207

val descriptor = buildClassSerialDescriptor("Person") {

208

element<String>("firstName")

209

element<String>("lastName")

210

element<Int>("age", isOptional = true)

211

element("address", Address.serializer().descriptor, isOptional = true)

212

}

213

```

214

215

## Predefined Descriptors

216

217

### Primitive Descriptors

218

219

```kotlin { .api }

220

val BOOLEAN_DESCRIPTOR: SerialDescriptor

221

val BYTE_DESCRIPTOR: SerialDescriptor

222

val CHAR_DESCRIPTOR: SerialDescriptor

223

val SHORT_DESCRIPTOR: SerialDescriptor

224

val INT_DESCRIPTOR: SerialDescriptor

225

val LONG_DESCRIPTOR: SerialDescriptor

226

val FLOAT_DESCRIPTOR: SerialDescriptor

227

val DOUBLE_DESCRIPTOR: SerialDescriptor

228

val STRING_DESCRIPTOR: SerialDescriptor

229

val UNIT_DESCRIPTOR: SerialDescriptor

230

```

231

232

## Descriptor Annotations

233

234

### @ContextAware

235

236

Marks descriptors that require serialization context.

237

238

```kotlin { .api }

239

@Target(AnnotationTarget.CLASS)

240

annotation class ContextAware

241

```

242

243

## Descriptor Utilities

244

245

### Inline Descriptors

246

247

For inline value classes and primitive wrappers.

248

249

```kotlin { .api }

250

fun SerialDescriptor.getInlinedSerializer(): KSerializer<*>?

251

fun buildInlineDescriptor(

252

inlineSerializerName: String,

253

inlineValueDescriptor: SerialDescriptor

254

): SerialDescriptor

255

```

256

257

### Descriptor Equality and Hashing

258

259

```kotlin { .api }

260

fun SerialDescriptor.hashCodeImpl(): Int

261

fun SerialDescriptor.equalsImpl(other: SerialDescriptor): Boolean

262

```

263

264

## Usage Examples

265

266

### Custom Descriptor Creation

267

268

```kotlin

269

// Creating a descriptor for a custom data structure

270

val customDescriptor = buildClassSerialDescriptor("CustomData") {

271

element<String>("id")

272

element<List<String>>("tags")

273

element<Map<String, Any>>("metadata", isOptional = true)

274

}

275

276

// Using the descriptor to understand structure

277

println("Serial name: ${customDescriptor.serialName}")

278

println("Kind: ${customDescriptor.kind}")

279

println("Elements count: ${customDescriptor.elementsCount}")

280

281

// Using extension properties

282

for ((index, elementDescriptor) in customDescriptor.elementDescriptors.withIndex()) {

283

val elementName = customDescriptor.getElementName(index)

284

val isOptional = customDescriptor.isElementOptional(index)

285

286

println("Element $index: $elementName (${elementDescriptor.serialName}) - Optional: $isOptional")

287

}

288

289

// Iterate over element names

290

for (elementName in customDescriptor.elementNames) {

291

val index = customDescriptor.getElementIndex(elementName)

292

println("Element '$elementName' is at index $index")

293

}

294

```

295

296

### Working with Collections

297

298

```kotlin

299

// Descriptor for List<User>

300

val userListDescriptor = listSerialDescriptor(User.serializer().descriptor)

301

302

// Descriptor for Map<String, User>

303

val userMapDescriptor = mapSerialDescriptor(

304

String.serializer().descriptor,

305

User.serializer().descriptor

306

)

307

308

// Check descriptor properties

309

println("List kind: ${userListDescriptor.kind}") // StructureKind.LIST

310

println("Map kind: ${userMapDescriptor.kind}") // StructureKind.MAP

311

```