Protocol Buffers definitions

Protobuf formatter

Review a self-contained proto3 definition. Compare its structure, formatted source and JSON data shape without changing its field numbers.

Protobuf formatter

Proto3 source

Result

    Your source stays in this browser. No imports or network requests are made.

    Options

    Single-file proto3 subset. No imports, custom options, compilation or compatibility checks. Editing source resets the root selection.

    Limits: 100,000 UTF-16 characters, 20,000 tokens, 2,000 declarations, 32 levels; 8-second timeout.

    Result is out of date. Exports are disabled.

    A Protobuf formatter helps when a compact service definition hides the field you need to review. A clean layout alone cannot tell you whether a tag is reserved or a referenced message exists. This workbench checks the supported declarations before making their structure available for export.

    Use the tree to distinguish the original field name, its wire number and its resolved type. The JSON Schema view answers a different question: what can the selected message look like as ordinary JSON? Keep the original contract for information that this projection cannot carry.

    Why use this Protobuf formatter?

    Read relationships beside the source

    The Protobuf formatter keeps nested declarations in their original order and displays resolved references with full names. Two messages named Item under different parents remain separate. A recursive link is shown as a reference, so browsing the tree does not expand forever.

    A source document connected to a branching tree with distinct nested message nodes.

    Review a JSON shape before integrating it

    Switch the root message to compare the data shapes a consumer will see. Message definitions share $defs rather than being copied into every field. This makes recursive schemas readable and keeps repeated fields, maps and mutually exclusive contact fields visible during review.

    Two nested types with similar shapes remain separate as they flow into distinct schema definitions.

    Three details that change the review

    01

    Choose the root deliberately

    The first message is the initial JSON Schema root, including when the file also contains enums and services. Choose another fully qualified message in Options. Editing the source resets this selection so a deleted or renamed root cannot silently remain active.

    02

    Separate tree navigation from editing

    Expand or collapse declarations without rerunning the checks. A line link returns to that declaration in the source. Long trees reveal 50 visible entries at a time; copying the structure exports the complete declaration list, including collapsed entries.

    03

    Check freshness before exporting

    Automatic checks wait 350 ms after an edit. Turning them off reveals the main button and enables Ctrl/Cmd + Enter. Source or parameter changes immediately disable exports. Example and Clear show a replacement preview; Undo restores both source and result.

    What the definition reveals

    Whitespace changes, stable field numbers

    Use this proto formatter to normalize indentation to two or four spaces. Tokens inside quoted strings and comments remain intact; fields retain their names, numbers and order. Output is separate from input. The formatted text is parsed again and compared with the original descriptor before it can be exported.

    Field and enum checks

    Message tags must be positive, unique within their message and outside 19000–19999. Reserved names and numeric ranges are checked even when their declaration follows the field. Enums must begin with zero; numeric aliases need allow_alias. These checks cover the current file, not its historical contract.

    A Protobuf schema viewer with resolved types

    The tree includes package, messages, enums, oneof groups, services and RPC declarations. Field types resolve within the same file, including forward and recursive references. An unresolved type stops output generation. Original snake_case names remain visible even when JSON export uses lowerCamelCase.

    A bounded proto to JSON Schema conversion

    The 2020-12 document uses the chosen root and full names in $defs. Repeated fields become arrays, maps become objects and int64 values become strings. Each oneof permits zero or one member, never two. Optional fields remain omittable; this projection does not invent required properties.

    Supported syntax and projection limits

    Explicit proto3, one source file
    Start with syntax = "proto3";. Proto2, Editions, required, groups and extensions are outside this release. All imports are rejected, including well-known types such as Timestamp and Any. Move a self-contained definition into the input or use your project toolchain for dependency-aware validation.
    Options have an explicit scope
    Common file-level code generation options and the supported json_name, packed, deprecated and allow_alias uses are accepted. Custom and aggregate options, validation annotations and CEL rules are rejected. Accepted code generation options are retained in the formatted source, but do not add business constraints to JSON Schema.
    A JSON projection is not a runtime validator
    The output targets common ProtoJSON output forms. It excludes null-as-unset, numeric enum values and permissive numeric-string parsing. Decimal-string patterns do not enforce the full 64-bit range; base64 contentEncoding is an annotation. Review these boundaries before using the schema to reject production data.
    No automatic contract repair
    The tool does not renumber fields, delete reservations or rewrite the input during formatting. It cannot detect whether a removed tag was used by an earlier release. Compilation, Buf lint, generated clients, OpenAPI output and breaking-change checks remain tasks for the project that owns the contract.
    Resource limits are visible
    Each run accepts up to 100,000 UTF-16 characters, 20,000 tokens, 2,000 declarations and 32 nested levels. Outputs are capped at 1,000,000 characters and a worker is stopped after eight seconds. Exceeding a limit produces an error rather than a truncated schema.
    Schema definitions, not message payloads
    Paste .proto declarations, not binary, Base64 or TextFormat data. The result is a source file, a structure report or a JSON Schema, never a decoded payload. Reverse JSON Schema conversion, remote imports, file batches and share links containing source are not available.

    Protobuf formatter questions

    Can field numbering start at zero?

    No. Message field tags start at 1 and end at 536870911. Tags 19000 through 19999 are also unavailable because the implementation reserves them. This differs from enum values: a proto3 enum must start with a zero-valued declaration. The tool checks the two rules separately rather than applying one number rule everywhere.

    Can I leave gaps between field numbers?

    Yes. Tags do not need to be consecutive. A message with fields numbered 1 and 20 is valid if neither conflicts with another field or a reservation. Formatting preserves the gap and the declaration order. Use reserved when a removed field number must not be reused; an empty gap alone does not record that history.

    How do I declare an optional field in proto3?

    Use optional before the field type when you need explicit presence tracking. The tree preserves that distinction. In the exported schema both an ordinary singular field and an optional field may be absent; JSON Schema does not model the generated has-field API or the difference between an unset field and a default value returned by the runtime.

    Why is an int64 value represented as a JSON string?

    A JSON number handled by JavaScript can lose integer precision beyond its safe range. Common ProtoJSON output therefore represents 64-bit integers as decimal strings. The projection follows this shape without converting the value to Number. Its pattern checks the string shape, so checking the exact signed or unsigned range remains a separate responsibility.

    Why does an import fail even when the path is correct?

    A path is resolved relative to a compiler’s configured import roots, not just the text of the declaration. This workbench has no file tree or dependency resolver and rejects every import explicitly. For a project with dependencies, run protoc or Buf with those files and paths. It will not fetch the path or silently skip the declaration.

    Found a definition that should be supported?

    Review the next contract change

    Use the Protobuf formatter to inspect the supported structure, then take the source and its reviewed JSON shape back to your project. Final compilation still belongs with the complete dependency set.