REPROTO(1)

πŸ“¦ version 0.3.6, in nixpkgs unstable

✨ NAME ✨

reproto β€” reconstruct .proto source files from compiled protobuf descriptor sets. okay so this is the REPROTO(1) page, bestie, and this tool is lowkey iconic: it takes compiled protobuf descriptor sets and regenerates the original .proto source files with correct syntax, field types, and options. no cap, that's the whole main character energy πŸ’…

🌈 SYNOPSIS 🌈

reproto [OPTIONS] DESCRIPTOR_FILES...

πŸ¦‹ DESCRIPTION πŸ¦‹

reproto reads one or more binary or text-format protobuf descriptor sets and regenerates the original .proto source files with correct syntax, field types, and options. it's giving "uncompile my heart" in the best way possible πŸ˜­πŸ’–

it supports proto2, proto3, and editions syntax, and accepts both .pb (binary FileDescriptorSet) and .textpb (text-format) descriptor files as input. fr fr, all the syntax eras are invited to the party πŸŽ‰

🌸 ARGUMENTS 🌸

  • DESCRIPTOR_FILES β€” One or more descriptor files to process. Accepts binary FileDescriptorSet, binary FileDescriptorProto, #@ prototext-format descriptors, or directories (processed recursively). Any file extension is accepted; .pb and .desc are conventional. Paths are resolved relative to directories given by -I (--desc-root), or relative to the current working directory if -I is not provided. iykyk, the -I thing is the vibe check for path resolution 🧭

πŸ’– OPTIONS πŸ’–

okay bestie, here's the full menu β€” every flag is here, periodt. no skipping the "boring" ones, because they all matter πŸ’–

🧊 Input

  • -I, --desc-root PATH β€” Root for resolving relative DESCRIPTOR_FILES paths and for locating imports (repeatable; like protoc -I). A directory is read as-is; a file is read as a blob, standing for the descriptors embedded in it, one member per FileDescriptorProto found (what protoscan would have extracted). Defaults to the current directory.

πŸŽ€ Output

  • -O, --proto-out DIRECTORY β€” Output directory for generated .proto files (created if absent). Not required when using --schema-db-out, --scoring-html-out, or --dry-run. Defaults to the --schema-db-out stubΒ΄s Β΄protoΒ΄ child when that option is given; --no-proto-out suppresses that default. When --schema-db-out is also given, DIR may not be inside its stub directory unless DIR is that stubΒ΄s immediate Β΄protoΒ΄ child.
  • --no-proto-out β€” Do not write .proto files. Suppresses the -O directory that --schema-db-out otherwise implies; an error if -O is also given.
  • -b, --emit-binary β€” Also write binary descriptor files (.pb) alongside .proto output.
  • --source-info β€” Embed a SourceCodeInfo synthesized from the reconstructed .proto text in binary descriptor output (-b, --schema-db-out). On by default.
  • --dry-run β€” Do not actually create .proto files.

🌱 Variant / Schema

  • --proto-variant FILE β€” Path to a variant specification YAML file. If omitted, $REPROTO_VARIANT is used; otherwise the built-in google.protobuf default applies.
  • --use-variant CHOICE β€” Use the variantΒ΄s embedded copy of a well-known file instead of whatever the input .pb files contain. Accepts: any, empty, timestamp, duration, struct, wrappers, descriptor, all. May be repeated.
  • --keep-descriptor-path β€” Keep the variant descriptor import path as-is (do not rewrite to google/protobuf/descriptor.proto).

πŸ”Ž Filtering

  • -s, --seed TEXT β€” FQDN or path pattern to treat as an output root. FQDN (needs a prefix): desc:my.pkg.MyMsg, file:foo.proto (the FDP named foo.proto). Path (bare, or path: prefix): foo.pb (every FDP in that physical file), matched against the -I-relative path. Glob (either form): one *.proto (one level), borg/** (recursive).
  • -p, --prune TEXT β€” FQDN or path pattern to exclude from output. FQDN (needs a prefix): desc:my.pkg.MyMsg, file:foo.proto (the FDP named foo.proto). Path (bare, or path: prefix): foo.pb (that physical file, never loaded), matched against the -I-relative path. Glob (either form): one *.proto (one level), borg/** (recursive).
  • -C, --filter-config FILE β€” Path to a YAML file with "seed:"/"prune:" lists of FQDNs or path patterns (same syntax as -s/--seed and -p/--prune). Merged with any -s/-p flags given on the command line.

🎨 Rendering

  • --force-proto2-output β€” Force all output to proto2 syntax, regardless of the input syntax. Without this flag, output syntax matches the input (polyglot mode).
  • --force-proto2-for-editions β€” Translate editions-syntax files to proto2 in output and binary descriptors, the schema DB included. Symmetric with --force-proto2-output but limited to editions files only. Use this for readers that do not support editions, such as prost-reflect.
  • --redact-comments β€” Redact comments from reconstructed .proto files.
  • --redact-orphans β€” Redact orphans from reconstructed .proto files.
  • --go-root TEXT β€” Force go_package option in reconstructed .proto files.

πŸ› οΈ Advanced

  • --schema-db-out FILE β€” Write the schema DB to FILE (must end in .desc). Writes FILE (FileDescriptorSet of all loaded FDPs), FILE-stem/hopcroft.rkyv (compiled scoring graph), and FILE-stem/index.rkyv (lazy-loading FDS index). If -O is also given, it may not be inside FILE-stem unless it is exactly FILE-stem/proto.
  • --emit-scoring-yaml β€” Write per-file scoring-graph YAML files alongside .proto output under --proto-out.
  • --emit-extension-ranges β€” Record each messageΒ΄s extension ranges in the scoring graph, so that an unknown field number inside a declared range is not counted against the type.
  • --scoring-html-out FILE β€” Write scoring-graph HTML visualisations to FILE; requires --schema-db-out.
  • --with-leaf-nodes β€” Include leaf (wire-type sink) nodes in --scoring-html-out graphs (hidden by default).
  • --hide TEXT β€” FQDN or glob pattern to hide from --scoring-html-out graphs (same syntax as --prune). Matched nodes and their incident edges are dropped from the HTML; no effect on the schema DB.
  • --debug β€” Print detailed debug information (development only).
  • --fdp-plugin PATH β€” Python file executed as a transformation hook on every FileDescriptorProto reproto parses, before anything reads it. Must define fdp_plugin(fdp), which mutates fdp in place. Called more than once per input file, so it must be deterministic; it must not read reproto state.
  • --keep-duplicates β€” Do not prune files whose symbols conflict with already-loaded files (legacy behaviour; by default conflicting files are silently pruned and a warning is emitted).

🩺 Diagnostics

  • --detailed-warnings β€” Print every warning occurrence immediately as it is emitted (default: squash repeated warnings and show a count summary at the end).
  • --quiet, -q β€” Suppress progress messages and warnings. Errors are always printed.
  • --debug-fqdn β€” Print detailed information about FQDNs (development only).

🎁 Other

  • --emit-descriptor β€” Write descriptor.proto to the output directory (default: on).
  • --version β€” Print version and exit.
  • --help β€” Show a help message and exit.

🌿 ENVIRONMENT 🌿

  • REPROTO_VARIANT β€” Path to a variant YAML file used when --proto-variant is not given.
  • REPROTO_GEN_MAN β€” When set to a directory, write the man pages of reproto and reproto-instantiate-schema into it and exit.
  • _REPROTO_COMPLETE β€” When set to bash_source, zsh_source or fish_source, print the completion script for that shell and exit. The scripts set it to bash_complete, zsh_complete or fish_complete to get the candidates.

⚠️ NOTES ⚠️

bestie, important vibe check: reproto does not support multi-file FileDescriptorSet inputs (i.e. .pb files produced with protoc --include_imports). Each .pb file must contain exactly one FileDescriptorProto. Pass all .pb files together on the command line and let reproto resolve cross-file imports. no cap, this one matters πŸ’€

πŸ§ͺ EXAMPLES πŸ§ͺ

🧸 Reconstruct a descriptor set

Compile each .proto to its own descriptor set (without --include_imports), then pass all .pb files to reproto:

protoc --descriptor_set_out=phone_number.pb --proto_path=. phone_number.proto
protoc --descriptor_set_out=address_book.pb --proto_path=. address_book.proto
reproto --use-variant descriptor -I . -O out/ phone_number.pb address_book.pb

✨ Selective output (one message and its dependencies)

reproto --use-variant descriptor -I . -O out/ --seed desc:.tutorial.Person \
  phone_number.pb address_book.pb

πŸ¦‹ Using the embedded descriptor variant

The --use-variant descriptor flag supplies descriptor.proto from the built-in variant bundle, so no separate descriptor .pb is needed:

reproto --use-variant descriptor -I . -O out/ phone_number.pb address_book.pb

🐚 Enable shell completion

Packages usually install the scripts. Otherwise, in bash, zsh or fish:

source <(_REPROTO_COMPLETE=bash_source reproto)
source <(_REPROTO_COMPLETE=zsh_source reproto)
_REPROTO_COMPLETE=fish_source reproto | source

πŸ‘€ SEE ALSO πŸ‘€

protoc(1), prototext(1) β€” go say hi to the cousins πŸ‘‹


mwah πŸ’‹ that's the whole reproto 0.3.6 moment, dated 2026, on page REPROTO(1) β€” now go reconstruct something iconic ✨🫢

πŸ“¦ where this page comes from