Skip to content

build: carry proto comments into generated docs via --include_source_info#225

Merged
iainmcgin merged 4 commits into
mainfrom
fix/protoc-include-source-info
Jul 13, 2026
Merged

build: carry proto comments into generated docs via --include_source_info#225
iainmcgin merged 4 commits into
mainfrom
fix/protoc-include-source-info

Conversation

@iainmcgin

Copy link
Copy Markdown
Collaborator

Fixes #222.

connectrpc-build invoked protoc with --include_imports but not --include_source_info, so the resulting FileDescriptorSet carried no SourceCodeInfo and proto comments never reached the generated Rust documentation. This adds the flag, matching buf's default behavior (and prost-build's), and updates Config::descriptor_set docs to note that precompiled sets need --include_source_info on the caller's own protoc invocation to get generated docs.

One deliberate companion change: the set written by Config::emit_descriptor_set now has SourceCodeInfo stripped for the protoc and buf sources. Reflection never needs source info, and passing it through would have grown every embedded descriptor blob (source info is commonly a multiple of the semantic descriptor payload) and leaked proto comments into shipped binaries and reflection responses. Precompiled sets are still written through byte-for-byte, which doubles as the escape hatch for anyone who wants source info in the emitted set. The strip's decode→re-encode round trip preserves unknown fields (custom options), verified against buffa 0.8.1's __buffa_unknown_fields retention.

The regression test compiles a proto with distinctive message and field comments through the real protoc pipeline, asserts both surface as /// doc comments, and asserts the emitted descriptor set is source-info-free while retaining the file and message. Verified the test fails without the flag. This is the first unit test in the crate that requires protoc on PATH; CONTRIBUTING already lists protoc v27+ as a prerequisite and the CI Test job installs it.

…ed sets

protoc was invoked without --include_source_info, so descriptor sets
carried no SourceCodeInfo and proto comments never reached the generated
Rust documentation (#222). Pass the flag, matching buf's default
behavior, and document that precompiled descriptor sets need the flag on
their own protoc invocation to get generated docs.

Since reflection never needs source info, the set written by
Config::emit_descriptor_set now has SourceCodeInfo stripped for the
protoc and buf sources, keeping embedded descriptor bytes lean and proto
comments out of shipped binaries. Precompiled sets are still written
through byte-for-byte.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
@iainmcgin iainmcgin marked this pull request as ready for review July 9, 2026 18:14
iainmcgin added 2 commits July 9, 2026 11:36
Service and method comments were emitted into #[doc] attributes with no
Markdown sanitization, so a proto comment containing a code fence,
bracketed text, or a bare URL could break a downstream consumer's
cargo doc (broken-intra-doc-links, invalid-html-tags, bare-urls under
-D warnings) or be compiled as a doctest by cargo test --doc. buffa
already sanitizes message and field comments; this ports its sanitizer
(as of buffa v0.8.1) for the service/method path, with hardenings on
top: fences without a language annotation default to text, unterminated
fences are closed, and fence open/close detection follows CommonMark
(matching tick counts, no info string on closers, 4+-space-indented
markers are code, not fences).

find_comment now also preserves blank lines and continuation
indentation instead of flattening every comment into a single run-on
block, so paragraph breaks and indented examples survive into the
generated docs. Checked-in generated code is regenerated accordingly.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
Sanitizing the prose of a service or method comment is not enough: a code
fence in a proto comment is handed to rustdoc as-is, and rustdoc compiles
it as a doctest in the *consuming* crate, where the example has no imports
and names proto types rather than Rust ones.

Classifying which fences rustdoc considers Rust turns out to be a trap. An
explicit `rust` keeps a block Rust even beside an unknown word
(`rust,noplayground`), error-code tokens (`compile_fail,E0277`) and
`{class=...}` attributes keep it Rust too, and the verdict is
order-dependent. Of the attributes, only a bare `ignore` reliably stops
compilation: `no_run` still type-checks, `should_panic` runs,
`compile_fail` merely inverts the verdict, and `ignore-<target>` is read as
a target list that *replaces* a plain `ignore`, so the block still compiles
everywhere else.

So don't classify. Drop any `ignore-<target>` token and ensure a bare
`ignore` on every fence. The author's language annotation survives, so a
`rust` fence is still syntax-highlighted as `rust,ignore`; an unannotated
fence becomes `text`, since rustdoc highlights nothing but Rust and
guessing a language would buy no rendering benefit.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
rustdoc's markdown parser compiles a ~~~ block exactly like a ``` one, so
a tilde fence in a proto comment was still reaching the consuming crate's
cargo test --doc. Recognize both fence characters, and require a closer to
match the opener's character and run length.

Also tighten what counts as a marker at all: only 0-3 spaces may precede
it (4+ spaces or a tab is indented code, and any other leading whitespace
is prose), only spaces or tabs may trail a closer, and a backtick fence's
info string may not contain a backtick. Reading a non-fence as a fence is
not harmless — it "closes" a fence rustdoc never opened, leaving the run
rustdoc does treat as an opener unguarded.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
@iainmcgin iainmcgin requested a review from rpb-ant July 12, 2026 18:24
@iainmcgin iainmcgin enabled auto-merge July 12, 2026 18:24
@iainmcgin iainmcgin requested a review from azdagron July 13, 2026 16:12
@iainmcgin iainmcgin added this pull request to the merge queue Jul 13, 2026
Merged via the queue into main with commit b8e132f Jul 13, 2026
14 checks passed
@iainmcgin iainmcgin deleted the fix/protoc-include-source-info branch July 13, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

connectrpc-build drops proto comments in protoc mode

2 participants