or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-messages.mdindex.mdio-wire-format.mdjson-text-format.mdreflection-descriptors.mdutilities.md

json-text-format.mddocs/

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

```