0
# Code Generation
1
2
Static code generation and compilation utilities for creating optimized protobuf implementations with high-performance encoding, decoding, and validation functions.
3
4
## Capabilities
5
6
### Encoder Generation
7
8
Generates optimized encoding functions for specific message types.
9
10
```javascript { .api }
11
/**
12
* Generates encoder function for message type
13
* @param mtype - Message type to generate encoder for
14
* @returns Generated encoder function
15
*/
16
function encoder(mtype: Type): Codegen;
17
18
interface Codegen {
19
/**
20
* Generated function source code
21
*/
22
source: string;
23
24
/**
25
* Compiled function
26
*/
27
fn: Function;
28
29
/**
30
* Function generation context
31
*/
32
gen: object;
33
}
34
```
35
36
**Usage Examples:**
37
38
```javascript
39
const protobuf = require("protobufjs");
40
41
protobuf.load("schema.proto", function(err, root) {
42
const MessageType = root.lookupType("package.Message");
43
44
// Generate optimized encoder
45
const encoderFn = protobuf.encoder(MessageType);
46
console.log("Generated encoder:", encoderFn.source);
47
48
// Use generated encoder
49
const message = { field1: "value", field2: 42 };
50
const writer = protobuf.Writer.create();
51
encoderFn.fn(message, writer);
52
const buffer = writer.finish();
53
});
54
```
55
56
### Decoder Generation
57
58
Generates optimized decoding functions for specific message types.
59
60
```javascript { .api }
61
/**
62
* Generates decoder function for message type
63
* @param mtype - Message type to generate decoder for
64
* @returns Generated decoder function
65
*/
66
function decoder(mtype: Type): Codegen;
67
```
68
69
**Usage Examples:**
70
71
```javascript
72
// Generate optimized decoder
73
const decoderFn = protobuf.decoder(MessageType);
74
console.log("Generated decoder:", decoderFn.source);
75
76
// Use generated decoder
77
const reader = protobuf.Reader.create(buffer);
78
const decoded = decoderFn.fn(reader, reader.uint32());
79
console.log("Decoded message:", decoded);
80
```
81
82
### Verifier Generation
83
84
Generates validation functions for message types to check data integrity.
85
86
```javascript { .api }
87
/**
88
* Generates verifier function for message type
89
* @param mtype - Message type to generate verifier for
90
* @returns Generated verifier function
91
*/
92
function verifier(mtype: Type): Codegen;
93
```
94
95
**Usage Examples:**
96
97
```javascript
98
// Generate optimized verifier
99
const verifierFn = protobuf.verifier(MessageType);
100
console.log("Generated verifier:", verifierFn.source);
101
102
// Use generated verifier
103
const message = { field1: "invalid-type", field2: "not-a-number" };
104
const error = verifierFn.fn(message);
105
if (error) {
106
console.log("Validation error:", error);
107
} else {
108
console.log("Message is valid");
109
}
110
```
111
112
### Converter Generation
113
114
Generates object conversion functions for transforming between plain objects and message instances.
115
116
```javascript { .api }
117
namespace converter {
118
/**
119
* Generates fromObject converter for message type
120
* @param mtype - Message type to generate converter for
121
* @returns Generated fromObject function
122
*/
123
function fromObject(mtype: Type): Codegen;
124
125
/**
126
* Generates toObject converter for message type
127
* @param mtype - Message type to generate converter for
128
* @returns Generated toObject function
129
*/
130
function toObject(mtype: Type): Codegen;
131
}
132
```
133
134
**Usage Examples:**
135
136
```javascript
137
// Generate object converters
138
const fromObjectFn = protobuf.converter.fromObject(MessageType);
139
const toObjectFn = protobuf.converter.toObject(MessageType);
140
141
console.log("FromObject source:", fromObjectFn.source);
142
console.log("ToObject source:", toObjectFn.source);
143
144
// Use generated converters
145
const plainObject = { field1: "value", field2: "42" };
146
const message = fromObjectFn.fn(plainObject); // Converts string "42" to number
147
148
const options = { longs: String, enums: String };
149
const converted = toObjectFn.fn(message, options);
150
```
151
152
### Code Generation Context
153
154
Context and utilities used during code generation.
155
156
```javascript { .api }
157
interface CodegenContext {
158
/**
159
* Code generation utilities
160
*/
161
gen: {
162
/**
163
* Generates code block
164
* @param format - Format string with placeholders
165
* @param args - Arguments for placeholders
166
* @returns Generated code
167
*/
168
(format: string, ...args: any[]): string;
169
170
/**
171
* Indents code block
172
* @param level - Indentation level
173
* @returns Code generator with indentation
174
*/
175
indent(level: number): Function;
176
177
/**
178
* Creates scope for variable declarations
179
* @param vars - Variable declarations
180
* @returns Scoped code generator
181
*/
182
scope(vars: object): Function;
183
};
184
185
/**
186
* Generated source code
187
*/
188
source: string;
189
190
/**
191
* Compiled function
192
*/
193
fn: Function;
194
}
195
```
196
197
**Usage Examples:**
198
199
```javascript
200
// Access generation context
201
const encoderCode = protobuf.encoder(MessageType);
202
203
// Inspect generated source
204
console.log("Generated encoder source:");
205
console.log(encoderCode.source);
206
207
// Use context for custom generation
208
const customGenerator = encoderCode.gen;
209
const customCode = customGenerator("if (%s !== null) {", "field");
210
console.log("Custom code fragment:", customCode);
211
```
212
213
### Static Code Generation
214
215
Utilities for generating static JavaScript code from protobuf definitions.
216
217
```javascript { .api }
218
interface StaticGeneration {
219
/**
220
* Generates static module code
221
* @param root - Root namespace
222
* @param options - Generation options
223
* @returns Generated module code
224
*/
225
generateModule(root: Root, options?: StaticOptions): string;
226
227
/**
228
* Generates TypeScript definitions
229
* @param root - Root namespace
230
* @param options - Generation options
231
* @returns Generated TypeScript code
232
*/
233
generateTypes(root: Root, options?: StaticOptions): string;
234
}
235
236
interface StaticOptions {
237
/**
238
* Module format (commonjs, es6, amd, etc.)
239
*/
240
wrap?: string;
241
242
/**
243
* Include imports for dependencies
244
*/
245
imports?: string[];
246
247
/**
248
* Target path for imports
249
*/
250
target?: string;
251
252
/**
253
* Create one file per type
254
*/
255
oneFilePerType?: boolean;
256
}
257
```
258
259
**Usage Examples:**
260
261
```javascript
262
// Generate static code
263
protobuf.load("schema.proto", function(err, root) {
264
// Generate CommonJS module
265
const moduleCode = protobuf.util.generateModule(root, {
266
wrap: "commonjs",
267
target: "static"
268
});
269
270
console.log("Generated static module:");
271
console.log(moduleCode);
272
273
// Generate TypeScript definitions
274
const typeCode = protobuf.util.generateTypes(root, {
275
target: "static"
276
});
277
278
console.log("Generated TypeScript definitions:");
279
console.log(typeCode);
280
});
281
```
282
283
### Performance Optimization
284
285
Code generation features for performance optimization.
286
287
```javascript { .api }
288
interface OptimizationFeatures {
289
/**
290
* Inline field encoding/decoding
291
*/
292
inlineFields: boolean;
293
294
/**
295
* Unroll loops for repeated fields
296
*/
297
unrollLoops: boolean;
298
299
/**
300
* Generate specialized functions for common cases
301
*/
302
specialize: boolean;
303
304
/**
305
* Optimize for message size vs speed
306
*/
307
optimizeSize: boolean;
308
}
309
```
310
311
**Usage Examples:**
312
313
```javascript
314
// Performance comparison
315
const standardEncoder = MessageType.encode;
316
const optimizedEncoder = protobuf.encoder(MessageType).fn;
317
318
// Benchmark encoding performance
319
const message = { field1: "test", field2: 42 };
320
const iterations = 100000;
321
322
console.time("Standard encoding");
323
for (let i = 0; i < iterations; i++) {
324
const writer = protobuf.Writer.create();
325
standardEncoder(message, writer);
326
writer.finish();
327
}
328
console.timeEnd("Standard encoding");
329
330
console.time("Optimized encoding");
331
for (let i = 0; i < iterations; i++) {
332
const writer = protobuf.Writer.create();
333
optimizedEncoder(message, writer);
334
writer.finish();
335
}
336
console.timeEnd("Optimized encoding");
337
```
338
339
### Dynamic vs Static Generation
340
341
Comparison and usage patterns for dynamic vs static code generation.
342
343
```javascript { .api }
344
interface GenerationModes {
345
/**
346
* Dynamic generation - runtime code generation
347
*/
348
dynamic: {
349
benefits: ["Smaller bundle size", "Schema flexibility", "Runtime loading"];
350
costs: ["Slower first execution", "Runtime compilation overhead"];
351
};
352
353
/**
354
* Static generation - build-time code generation
355
*/
356
static: {
357
benefits: ["Faster execution", "No runtime compilation", "Better optimization"];
358
costs: ["Larger bundle size", "Build step required", "Less flexibility"];
359
};
360
}
361
```
362
363
**Usage Examples:**
364
365
```javascript
366
// Dynamic generation (runtime)
367
protobuf.load("schema.proto", function(err, root) {
368
const MessageType = root.lookupType("Message");
369
370
// Functions are generated at runtime
371
const message = MessageType.create({ field: "value" });
372
const encoded = MessageType.encode(message).finish();
373
});
374
375
// Static generation (build time)
376
// Use CLI tools to generate static code:
377
// pbjs -t static-module -w commonjs -o generated.js schema.proto
378
// Then use the generated module:
379
380
const generated = require("./generated");
381
const message = new generated.Message({ field: "value" });
382
const encoded = generated.Message.encode(message).finish();
383
```
384
385
### Error Handling in Generated Code
386
387
Error handling patterns in generated encoding/decoding functions.
388
389
```javascript { .api }
390
interface GeneratedErrorHandling {
391
/**
392
* Type validation errors
393
*/
394
typeErrors: {
395
invalidType: string;
396
missingRequired: string;
397
outOfRange: string;
398
};
399
400
/**
401
* Encoding/decoding errors
402
*/
403
processErrors: {
404
bufferUnderflow: string;
405
invalidWireFormat: string;
406
corruptedData: string;
407
};
408
}
409
```
410
411
**Usage Examples:**
412
413
```javascript
414
// Error handling with generated functions
415
const encoderFn = protobuf.encoder(MessageType).fn;
416
const decoderFn = protobuf.decoder(MessageType).fn;
417
418
try {
419
// Encoding with type validation
420
const invalidMessage = { stringField: 12345 }; // Wrong type
421
const writer = protobuf.Writer.create();
422
encoderFn(invalidMessage, writer); // May throw TypeError
423
} catch (err) {
424
console.error("Encoding error:", err.message);
425
}
426
427
try {
428
// Decoding with format validation
429
const corruptedBuffer = new Uint8Array([0xFF, 0xFF, 0xFF]);
430
const reader = protobuf.Reader.create(corruptedBuffer);
431
const decoded = decoderFn(reader, corruptedBuffer.length);
432
} catch (err) {
433
console.error("Decoding error:", err.message);
434
}
435
```
436
437
## Types
438
439
```javascript { .api }
440
interface Codegen {
441
/**
442
* Generated function source code
443
*/
444
source: string;
445
446
/**
447
* Compiled executable function
448
*/
449
fn: Function;
450
451
/**
452
* Code generation context and utilities
453
*/
454
gen: Function;
455
}
456
457
interface StaticOptions {
458
wrap?: string;
459
imports?: string[];
460
target?: string;
461
oneFilePerType?: boolean;
462
keepCase?: boolean;
463
alternateCommentMode?: boolean;
464
}
465
```