or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

buffer-operations.mdcli-tool.mdindex.mdschema-compilation.md

schema-compilation.mddocs/

0

# Schema Compilation

1

2

Compile protocol buffer schema files (.proto) into optimized JavaScript read/write functions. The compilation system generates highly optimized code for encoding and decoding specific protobuf schemas.

3

4

## Compilation Functions

5

6

### Runtime Compilation

7

8

Compile a parsed protocol buffer schema into executable functions:

9

10

```typescript { .api }

11

/**

12

* Compile a protobuf schema into read/write functions

13

* @param proto - Parsed protobuf schema object

14

* @returns Object containing generated read and write functions

15

*/

16

function compile(proto: object): Record<string, Function>;

17

```

18

19

### Code Generation

20

21

Generate raw JavaScript/TypeScript code from a protobuf schema:

22

23

```typescript { .api }

24

interface CompileOptions {

25

dev?: boolean; // Include development features and comments

26

legacy?: boolean; // Generate CommonJS instead of ESM

27

noRead?: boolean; // Skip generating read functions

28

noWrite?: boolean; // Skip generating write functions

29

}

30

31

/**

32

* Compile a protobuf schema into raw JavaScript code

33

* @param proto - Parsed protobuf schema object

34

* @param options - Compilation options

35

* @returns Generated JavaScript code as string

36

*/

37

function compileRaw(proto: object, options?: CompileOptions): string;

38

```

39

40

## Schema Input Format

41

42

The compilation functions expect a parsed protobuf schema object (typically from `resolve-protobuf-schema`):

43

44

```typescript { .api }

45

interface ProtoSchema {

46

name?: string;

47

syntax?: number; // Protocol buffer version (2 or 3)

48

fields?: ProtoField[];

49

messages?: ProtoSchema[];

50

enums?: ProtoEnum[];

51

extensions?: any;

52

}

53

54

interface ProtoField {

55

name: string;

56

type: string;

57

tag: number;

58

repeated?: boolean;

59

required?: boolean;

60

optional?: boolean;

61

oneof?: string;

62

map?: {

63

from: string; // Key type

64

to: string; // Value type

65

};

66

options?: {

67

packed?: string; // "true" or "false"

68

default?: string;

69

jstype?: string; // "JS_STRING" for string representation

70

};

71

}

72

73

interface ProtoEnum {

74

name: string;

75

values: Record<string, { value: number }>;

76

}

77

```

78

79

## Generated Function Pattern

80

81

For each message type in the schema, the compiler generates corresponding read and write functions:

82

83

```typescript { .api }

84

// Generated read function signature

85

type ReadFunction<T> = (pbf: Pbf, end?: number) => T;

86

87

// Generated write function signature

88

type WriteFunction<T> = (obj: T, pbf: Pbf) => void;

89

90

// Example generated functions for a "Person" message

91

interface GeneratedFunctions {

92

readPerson: ReadFunction<Person>;

93

writePerson: WriteFunction<Person>;

94

}

95

```

96

97

## Usage Examples

98

99

### Basic Schema Compilation

100

101

```typescript

102

import { compile } from "pbf/compile";

103

import schema from "protocol-buffers-schema";

104

import fs from "fs";

105

106

// Parse .proto file

107

const proto = schema.parse(fs.readFileSync("person.proto"));

108

109

// Compile to functions

110

const { readPerson, writePerson } = compile(proto);

111

112

// Use generated functions

113

const person = readPerson(new Pbf(buffer));

114

const pbf = new Pbf();

115

writePerson(person, pbf);

116

const encoded = pbf.finish();

117

```

118

119

### Code Generation

120

121

```typescript

122

import { compileRaw } from "pbf/compile";

123

import schema from "protocol-buffers-schema";

124

import fs from "fs";

125

126

// Parse .proto file

127

const proto = schema.parse(fs.readFileSync("person.proto"));

128

129

// Generate JavaScript code

130

const jsCode = compileRaw(proto);

131

132

// Write to file

133

fs.writeFileSync("person.js", jsCode);

134

```

135

136

### Compilation Options

137

138

```typescript

139

import { compileRaw } from "pbf/compile";

140

141

// Generate CommonJS module with only write functions

142

const code = compileRaw(proto, {

143

legacy: true, // Use CommonJS exports

144

noRead: true, // Skip read functions

145

dev: false // Production mode

146

});

147

148

// Generate ESM module with development features

149

const devCode = compileRaw(proto, {

150

legacy: false, // Use ESM exports

151

dev: true // Include comments and debug info

152

});

153

```

154

155

### Working with Complex Types

156

157

```typescript

158

// Schema with nested messages and enums

159

const proto = {

160

name: "AddressBook",

161

fields: [

162

{ name: "people", type: "Person", tag: 1, repeated: true }

163

],

164

messages: [

165

{

166

name: "Person",

167

fields: [

168

{ name: "name", type: "string", tag: 1 },

169

{ name: "id", type: "int32", tag: 2 },

170

{ name: "email", type: "string", tag: 3 },

171

{ name: "phones", type: "PhoneNumber", tag: 4, repeated: true },

172

{ name: "type", type: "PhoneType", tag: 5 }

173

]

174

},

175

{

176

name: "PhoneNumber",

177

fields: [

178

{ name: "number", type: "string", tag: 1 },

179

{ name: "type", type: "PhoneType", tag: 2 }

180

]

181

}

182

],

183

enums: [

184

{

185

name: "PhoneType",

186

values: {

187

MOBILE: { value: 0 },

188

HOME: { value: 1 },

189

WORK: { value: 2 }

190

}

191

}

192

]

193

};

194

195

const { readAddressBook, writeAddressBook, readPerson, writePerson, PhoneType } = compile(proto);

196

```

197

198

### Map Field Support

199

200

```typescript

201

// Schema with map fields

202

const proto = {

203

name: "MapExample",

204

fields: [

205

{

206

name: "attributes",

207

type: "map",

208

tag: 1,

209

map: { from: "string", to: "string" }

210

},

211

{

212

name: "counters",

213

type: "map",

214

tag: 2,

215

map: { from: "string", to: "int32" }

216

}

217

]

218

};

219

220

const { readMapExample, writeMapExample } = compile(proto);

221

222

// Usage

223

const data = {

224

attributes: { "color": "red", "size": "large" },

225

counters: { "views": 100, "likes": 25 }

226

};

227

```

228

229

### Packed Fields and Proto3

230

231

```typescript

232

// Proto3 schema with packed repeated fields

233

const proto = {

234

name: "PackedExample",

235

syntax: 3, // Proto3

236

fields: [

237

{

238

name: "numbers",

239

type: "int32",

240

tag: 1,

241

repeated: true,

242

options: { packed: "true" }

243

},

244

{

245

name: "flags",

246

type: "bool",

247

tag: 2,

248

repeated: true,

249

options: { packed: "true" }

250

}

251

]

252

};

253

254

const { readPackedExample, writePackedExample } = compile(proto);

255

```

256

257

### OneOf Fields

258

259

```typescript

260

// Schema with oneof fields

261

const proto = {

262

name: "OneOfExample",

263

fields: [

264

{ name: "name", type: "string", tag: 1 },

265

{ name: "email", type: "string", tag: 2, oneof: "contact" },

266

{ name: "phone", type: "string", tag: 3, oneof: "contact" }

267

]

268

};

269

270

const { readOneOfExample, writeOneOfExample } = compile(proto);

271

272

// Usage - only one field in the oneof group will be set

273

const data1 = { name: "John", email: "john@example.com", contact: "email" };

274

const data2 = { name: "Jane", phone: "555-1234", contact: "phone" };

275

```

276

277

## Error Handling

278

279

The compilation functions may throw errors for invalid schemas:

280

281

```typescript

282

try {

283

const functions = compile(proto);

284

} catch (error) {

285

// Handle compilation errors:

286

// - "Unexpected type: [type]" for unsupported types

287

// - Schema validation errors

288

// - Missing field type definitions

289

console.error("Compilation failed:", error.message);

290

}

291

```