0
# JSON and Text Format
1
2
Bidirectional conversion between protocol buffers and human-readable formats including JSON for web APIs and text format for debugging and configuration files.
3
4
## Capabilities
5
6
### JSON Format Conversion
7
8
High-performance bidirectional conversion between protocol buffers and JSON format with extensive configuration options for field naming, type handling, and compatibility.
9
10
```java { .api }
11
/**
12
* JSON format conversion utilities
13
*/
14
public class JsonFormat {
15
// Static factory methods
16
/** Creates Printer with default configuration */
17
public static Printer printer();
18
19
/** Creates Parser with default configuration */
20
public static Parser parser();
21
22
/**
23
* Converts protobuf messages to JSON format
24
*/
25
public static class Printer {
26
// Configuration methods
27
/** Sets type registry for Any message resolution */
28
public Printer usingTypeRegistry(TypeRegistry typeRegistry);
29
30
/** Includes fields with default values in output */
31
public Printer includingDefaultValueFields();
32
33
/** Preserves original proto field names instead of JSON names */
34
public Printer preservingProtoFieldNames();
35
36
/** Omits insignificant whitespace for compact output */
37
public Printer omittingInsignificantWhitespace();
38
39
/** Prints enum values as integers instead of names */
40
public Printer printingEnumsAsInts();
41
42
/** Sorts map keys in output for deterministic results */
43
public Printer sortingMapKeys();
44
45
// Printing methods
46
/** Prints message to JSON string */
47
public String print(MessageOrBuilder message) throws InvalidProtocolBufferException;
48
49
/** Appends JSON representation to Appendable */
50
public void appendTo(Appendable json, MessageOrBuilder message) throws InvalidProtocolBufferException, IOException;
51
}
52
53
/**
54
* Parses JSON format to protobuf messages
55
*/
56
public static class Parser {
57
// Configuration methods
58
/** Sets type registry for Any message resolution */
59
public Parser usingTypeRegistry(TypeRegistry typeRegistry);
60
61
/** Ignores unknown fields instead of throwing exceptions */
62
public Parser ignoringUnknownFields();
63
64
/** Creates parser builder for advanced configuration */
65
public static Builder newBuilder();
66
67
// Parsing methods
68
/** Merges JSON into message builder */
69
public void merge(String json, Message.Builder builder) throws InvalidProtocolBufferException;
70
71
/** Merges JSON from Readable into message builder */
72
public void merge(Readable json, Message.Builder builder) throws InvalidProtocolBufferException, IOException;
73
74
/**
75
* Builder for configuring JSON parser
76
*/
77
public static class Builder {
78
/** Sets type registry for Any message resolution */
79
public Builder usingTypeRegistry(TypeRegistry typeRegistry);
80
81
/** Ignores unknown fields during parsing */
82
public Builder ignoringUnknownFields();
83
84
/** Builds configured parser */
85
public Parser build();
86
}
87
}
88
}
89
```
90
91
### Text Format Support
92
93
Human-readable text representation for protocol buffers, commonly used for debugging, configuration files, and development workflows.
94
95
```java { .api }
96
/**
97
* Text format parsing and printing support
98
*/
99
public class TextFormat {
100
// Static convenience methods
101
/** Generate short debug string (deprecated, use printer()) */
102
@Deprecated
103
public static String shortDebugString(MessageOrBuilder message);
104
105
/** Get default printer instance */
106
public static Printer printer();
107
108
/** Get debug format printer with special escaping */
109
public static Printer debugFormatPrinter();
110
111
/** Get default parser */
112
public static Parser getParser();
113
114
/** Parse text format into message builder */
115
public static void merge(Readable input, Message.Builder builder) throws IOException;
116
117
/** Parse text format string into message builder */
118
public static void merge(CharSequence input, Message.Builder builder) throws ParseException;
119
120
// Utility methods
121
/** Escape bytes for text format output */
122
public static String escapeBytes(ByteString input);
123
124
/** Escape byte array for text format output */
125
public static String escapeBytes(byte[] input);
126
127
/** Convert unsigned int to string */
128
public static String unsignedToString(int value);
129
130
/** Convert unsigned long to string */
131
public static String unsignedToString(long value);
132
133
/**
134
* Converts protobuf messages to human-readable text format
135
*/
136
public static class Printer {
137
// Configuration methods
138
/** Configure ASCII escaping for non-ASCII characters */
139
public Printer escapingNonAscii(boolean escapeNonAscii);
140
141
/** Set type registry for Any message resolution */
142
public Printer usingTypeRegistry(TypeRegistry typeRegistry);
143
144
/** Set extension registry for extension field resolution */
145
public Printer usingExtensionRegistry(ExtensionRegistryLite extensionRegistry);
146
147
/** Configure single-line output format */
148
public Printer emittingSingleLine(boolean singleLine);
149
150
// Printing methods
151
/** Print message to appendable output */
152
public void print(MessageOrBuilder message, Appendable output) throws IOException;
153
154
/** Print unknown fields to appendable output */
155
public void print(UnknownFieldSet fields, Appendable output) throws IOException;
156
157
/** Print message to string */
158
public String printToString(MessageOrBuilder message);
159
160
/** Print unknown fields to string */
161
public String printToString(UnknownFieldSet fields);
162
163
/** Generate short debug string (single line) */
164
public String shortDebugString(MessageOrBuilder message);
165
166
/** Print individual field value to string */
167
public String printFieldToString(FieldDescriptor field, Object value);
168
}
169
170
/**
171
* Parses text format to protobuf messages
172
*/
173
public static class Parser {
174
// Static factory method
175
/** Creates parser builder for configuration */
176
public static Builder newBuilder();
177
178
// Parsing methods
179
/** Parse text format into message builder */
180
public void merge(Readable input, Message.Builder builder) throws IOException;
181
182
/** Parse text format into message builder with extension registry */
183
public void merge(Readable input, ExtensionRegistryLite extensionRegistry, Message.Builder builder) throws IOException;
184
185
/**
186
* Builder for configuring text format parser
187
*/
188
public static class Builder {
189
/** Set type registry for Any message resolution */
190
public Builder setTypeRegistry(TypeRegistry typeRegistry);
191
192
/** Allow unknown fields during parsing */
193
public Builder setAllowUnknownFields(boolean allowUnknownFields);
194
195
/** Allow unknown extensions during parsing */
196
public Builder setAllowUnknownExtensions(boolean allowUnknownExtensions);
197
198
/** Set policy for handling duplicate singular fields */
199
public Builder setSingularOverwritePolicy(SingularOverwritePolicy policy);
200
201
/** Set recursion limit for nested messages */
202
public Builder setRecursionLimit(int recursionLimit);
203
204
/** Build configured parser */
205
public Parser build();
206
}
207
208
/** Policy for handling duplicate singular field values */
209
public enum SingularOverwritePolicy {
210
/** Allow overwriting (default behavior) */
211
ALLOW_SINGULAR_OVERWRITES,
212
/** Forbid overwriting, throw exception */
213
FORBID_SINGULAR_OVERWRITES
214
}
215
}
216
}
217
```
218
219
### Text Format Utilities
220
221
Additional utilities for working with text format and escaping.
222
223
```java { .api }
224
/**
225
* Text format escaping and utility functions
226
*/
227
public class TextFormatEscaper {
228
/** Escape text for protocol buffer text format */
229
public static String escapeText(String input);
230
231
/** Escape bytes as text for protocol buffer format */
232
public static String escapeBytes(byte[] input);
233
234
/** Unescape text from protocol buffer text format */
235
public static String unescapeText(String input) throws InvalidEscapeSequenceException;
236
237
/** Unescape bytes from protocol buffer text format */
238
public static ByteString unescapeBytes(CharSequence input) throws InvalidEscapeSequenceException;
239
}
240
```
241
242
### Parse Information and Location Tracking
243
244
Classes for tracking parse locations and building parse info trees for advanced text format processing.
245
246
```java { .api }
247
/**
248
* Represents a location in parsed text format
249
*/
250
public class TextFormatParseLocation {
251
/** Get line number (0-based) */
252
public int getLine();
253
254
/** Get column number (0-based) */
255
public int getColumn();
256
257
/** Create location */
258
public static TextFormatParseLocation create(int line, int column);
259
}
260
261
/**
262
* Tree structure containing parse location information
263
*/
264
public class TextFormatParseInfoTree {
265
/** Get parse locations for a field */
266
public List<TextFormatParseLocation> getLocations(FieldDescriptor field);
267
268
/** Get parse location for a field index */
269
public TextFormatParseLocation getLocation(FieldDescriptor field, int index);
270
271
/** Get nested tree for a field */
272
public TextFormatParseInfoTree getNestedTree(FieldDescriptor field, int index);
273
274
/** Builder for constructing parse info trees */
275
public static class Builder {
276
/** Set location for field */
277
public Builder setLocation(FieldDescriptor field, TextFormatParseLocation location);
278
279
/** Set nested tree for field */
280
public Builder setNestedTree(FieldDescriptor field, int index, TextFormatParseInfoTree nestedTree);
281
282
/** Build parse info tree */
283
public TextFormatParseInfoTree build();
284
}
285
}
286
```
287
288
**Usage Examples:**
289
290
```java
291
import com.google.protobuf.util.JsonFormat;
292
import com.google.protobuf.TextFormat;
293
import com.google.protobuf.TypeRegistry;
294
295
// JSON format conversion
296
try {
297
// Convert message to JSON
298
JsonFormat.Printer jsonPrinter = JsonFormat.printer()
299
.includingDefaultValueFields()
300
.preservingProtoFieldNames()
301
.omittingInsignificantWhitespace();
302
303
String json = jsonPrinter.print(myMessage);
304
System.out.println("JSON: " + json);
305
306
// Parse JSON back to message
307
JsonFormat.Parser jsonParser = JsonFormat.parser()
308
.ignoringUnknownFields();
309
310
MyMessage.Builder builder = MyMessage.newBuilder();
311
jsonParser.merge(json, builder);
312
MyMessage parsedMessage = builder.build();
313
314
} catch (InvalidProtocolBufferException e) {
315
System.err.println("JSON conversion error: " + e.getMessage());
316
}
317
318
// Text format conversion
319
try {
320
// Convert message to text format
321
TextFormat.Printer textPrinter = TextFormat.printer()
322
.escapingNonAscii(true)
323
.emittingSingleLine(false);
324
325
String textFormat = textPrinter.printToString(myMessage);
326
System.out.println("Text format:\n" + textFormat);
327
328
// Parse text format back to message
329
TextFormat.Parser textParser = TextFormat.getParser();
330
MyMessage.Builder textBuilder = MyMessage.newBuilder();
331
textParser.merge(textFormat, textBuilder);
332
MyMessage parsedFromText = textBuilder.build();
333
334
} catch (IOException e) {
335
System.err.println("Text format error: " + e.getMessage());
336
}
337
338
// Working with Any messages and type registry
339
TypeRegistry typeRegistry = TypeRegistry.newBuilder()
340
.add(MyMessage.getDescriptor())
341
.add(AnotherMessage.getDescriptor())
342
.build();
343
344
JsonFormat.Printer anyPrinter = JsonFormat.printer()
345
.usingTypeRegistry(typeRegistry)
346
.includingDefaultValueFields();
347
348
// This will properly resolve Any message types
349
String jsonWithAny = anyPrinter.print(messageContainingAny);
350
```
351
352
### JSON Format Specifics
353
354
Key behaviors and mappings for JSON format conversion:
355
356
```java { .api }
357
// JSON field name mapping
358
// Proto field names: user_name, email_address
359
// JSON field names: userName, emailAddress (camelCase by default)
360
361
// Special JSON representations for well-known types:
362
// google.protobuf.Timestamp -> RFC 3339 string: "1972-01-01T10:00:20.021Z"
363
// google.protobuf.Duration -> Duration string: "1.000340012s", "1s"
364
// google.protobuf.Struct -> JSON object: {"key": "value"}
365
// google.protobuf.Value -> JSON value: "string", 123, true, null, [], {}
366
// google.protobuf.ListValue -> JSON array: [1, 2, 3]
367
// google.protobuf.NullValue -> JSON null: null
368
// google.protobuf.Any -> JSON object: {"@type": "type.googleapis.com/MyMessage", "field": "value"}
369
370
// Enum handling:
371
// Default: enum names as strings: "ENUM_VALUE"
372
// With printingEnumsAsInts(): enum numbers: 123
373
374
// Field presence:
375
// Proto3: only non-default values included by default
376
// With includingDefaultValueFields(): all fields included
377
// Proto2: optional fields only included if explicitly set
378
379
// Map fields:
380
// Represented as JSON objects: {"key1": "value1", "key2": "value2"}
381
// With sortingMapKeys(): deterministic key ordering
382
383
// Repeated fields:
384
// Represented as JSON arrays: ["item1", "item2", "item3"]
385
386
// Binary data (bytes fields):
387
// Base64-encoded strings: "SGVsbG8gV29ybGQ="
388
```
389
390
### Text Format Specifics
391
392
Key behaviors and syntax for text format:
393
394
```java { .api }
395
// Text format syntax examples:
396
//
397
// message MyMessage {
398
// string name = 1;
399
// int32 age = 2;
400
// repeated string items = 3;
401
// MyNestedMessage nested = 4;
402
// }
403
//
404
// Text format representation:
405
// name: "John Doe"
406
// age: 30
407
// items: "item1"
408
// items: "item2"
409
// nested {
410
// field: "value"
411
// }
412
413
// String escaping in text format:
414
// Regular strings: "Hello World"
415
// Escaped strings: "Hello \"World\""
416
// Raw strings: R"(Hello "World")"
417
// Bytes: "\x48\x65\x6c\x6c\x6f"
418
419
// Comments in text format:
420
// # This is a comment
421
// name: "value" # End-of-line comment
422
423
// Extension syntax:
424
// [com.example.my_extension]: "value"
425
// [my_extension]: 123
426
427
// Any message syntax:
428
// [type.googleapis.com/MyMessage] {
429
// field: "value"
430
// }
431
```
432
433
### Debug Format
434
435
Special debug format for development and troubleshooting:
436
437
```java { .api }
438
/**
439
* Debug format utilities
440
*/
441
public class DebugFormat {
442
/** Generate single-line debug string */
443
public static String toString(MessageOrBuilder message);
444
445
/** Generate multi-line debug string */
446
public static String toStringMultiline(MessageOrBuilder message);
447
}
448
449
// Debug format output example:
450
// MyMessage{name="John", age=30, items=["a", "b"], nested=MyNested{field="value"}}
451
```
452
453
## Exception Handling
454
455
Common exceptions when working with JSON and text formats:
456
457
```java { .api }
458
// JSON format exceptions
459
try {
460
JsonFormat.printer().print(message);
461
} catch (InvalidProtocolBufferException e) {
462
// Handle JSON conversion errors:
463
// - Unresolvable Any types without type registry
464
// - Invalid enum values
465
// - Required field violations
466
}
467
468
// Text format exceptions
469
try {
470
TextFormat.getParser().merge(input, builder);
471
} catch (IOException e) {
472
// Handle text parsing errors:
473
// - Invalid syntax
474
// - Unknown field names
475
// - Type mismatches
476
// - Malformed escape sequences
477
} catch (ParseException e) {
478
// Handle text format parse errors
479
}
480
```
481
482
**Common error scenarios:**
483
- **JSON**: Missing type registry for Any messages, invalid enum names, malformed timestamps/durations
484
- **Text Format**: Syntax errors, unknown fields, invalid escape sequences, type mismatches
485
- **Both**: Required field violations, recursion limit exceeded, invalid UTF-8 sequences
486
487
## Types
488
489
```java { .api }
490
// Parse exception for text format
491
public class ParseException extends Exception {
492
public ParseException(String message);
493
public ParseException(String message, Throwable cause);
494
}
495
496
// Invalid escape sequence exception
497
public class InvalidEscapeSequenceException extends Exception {
498
public InvalidEscapeSequenceException(String description);
499
}
500
501
// Escaper utility class
502
public class TextFormatEscaper {
503
// Text escaping utilities for custom formatters
504
}
505
506
// Legacy debug format (deprecated)
507
public class LegacyUnredactedTextFormat {
508
// Deprecated - use TextFormat.printer() instead
509
}
510
```