Skip to content

Resolve reference links in every emitted string; scrub plain-text fields - #49

Merged
delphyne merged 1 commit into
mainfrom
fix/description-markdown-handling
Oct 13, 2026
Merged

delphyne merged 1 commit into
mainfrom
fix/description-markdown-handling

Conversation

@delphyne

@delphyne delphyne commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Every string the plugin emits is now classified as CommonMark (description) or plain text (summary, title, OAuth scope descriptions) and handled consistently, whether it comes from a proto comment or an engine.protoc.openapi annotation.

Before:

  • Reference links ([Widget], [Service.Method]) were only resolved when referenceLinkTarget was set, which is off by default. Unresolved ones only logged a warning, and the default logLevel=ERROR hid it.
  • Annotation text bypassed both resolution and scrubbing.
  • Comments kept the leading space of every // line.

Changes

  • Comments: read through protoc-utils' cleaned Comment (dedented, Markdown preserved) instead of raw leadingComments.
  • Resolution: new compile/Descriptions.kt (on JsonContext) uses protoc-utils-markdown (Keep Markdown in cleaned comments; add protoc-utils-markdown for shared reference links protoc-utils#14) to resolve references in every description, summary, and title against every file in the request.
    • A resolved reference links to its operation, tag, or schema, per referenceLinkTarget.
    • Elements with no anchor in the document render as inline code, without a failure: RPCs without an HTTP binding, services that aren't tagged, types not in components/schemas, and any schema under Swagger UI.
    • Anchor availability is decided per document. The collector is now seeded before annotation layers are merged, so annotation text sees the final schema set.
  • New options, matching protoc-gen-markdown:
    • resolveReferenceLinksMode: NONE / WARN / FAIL_ON_INVALID (default). FAIL_ON_INVALID sets CodeGeneratorResponse.error listing every bad reference.
    • referenceLink=<label>=<URL> (repeatable). A URL without a scheme gets https://, because protoc reserves : in --openapi_out.
  • Plain text: annotation summaries, titles, and OAuth scope descriptions are scrubbed. Comment-derived summaries keep their first-sentence logic. Code spans in summaries now flatten to bare text instead of "quoted".
  • Fix: SecurityScheme.description was dropped and is now emitted.
  • ReferenceLinkResolver.kt is removed; operationIdFor and primaryTagFor moved to Descriptions.kt.

⚠️ Breaking change

Unresolved or ambiguous reference links now fail the run by default. Set resolveReferenceLinksMode=WARN to keep the previous behavior. This needs a major version bump.

Output changes

Golden diffs fall into three groups:

  • Multi-line descriptions lose the leading space on continuation lines.
  • Summaries drop quote marks around former code spans.
  • complete now has the security scheme description. CompleteTest now honors UPDATE_GOLDENS like the other suites.

Dependencies

Requires protoc-utils 1.1.0 (engine-public/protoc-utils#14) to be released first.

Test plan

  • ./gradlew check against a locally published protoc-utils: all suites pass, with regenerated goldens reviewed
  • New referenceLinkResolution suite covers:
    • FAIL_ON_INVALID aggregate error, with one unresolved and one ambiguous reference
    • WARN with REDOC and SWAGGER_UI
    • NONE
    • [text][label] with referenceLink
    • an imported type
    • an unmapped RPC
    • annotation descriptions, summaries, and titles
    • dedented lists
  • Native image built with publishToMavenLocal
  • The Partner API docs build runs strict mode in both dialects. Across about 2,000 emitted strings per document, an audit found no bare [Name] references, no leading-space continuations, no Markdown in plain-text fields, and no dangling anchors.

🤖 Generated with Claude Code

…fields

Comments were emitted raw: reference links were only resolved when
referenceLinkTarget was set, never failed the build, and annotation text
bypassed both resolution and scrubbing. Comment text also kept the leading
space of every `// ` line.

- Read comments through protoc-utils' cleaned Comment, which dedents them.
- Resolve references with protoc-utils-markdown in every description,
  summary, and title, from comments and annotations alike, against every
  file in the request. Elements with no anchor in the document render as
  code instead of failing.
- Add resolveReferenceLinksMode (NONE / WARN / FAIL_ON_INVALID, default
  FAIL_ON_INVALID) and referenceLink=<label>=<URL> overrides, matching
  protoc-gen-markdown.
- Scrub Markdown from plain-text fields: annotation summaries, titles, and
  OAuth scope descriptions.
- Emit SecurityScheme.description, which was dropped.

BREAKING CHANGE: unresolved or ambiguous reference links now fail the run by
default; set resolveReferenceLinksMode=WARN to keep the previous behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@delphyne
delphyne requested a review from a team October 8, 2026 17:27

@ezweave ezweave left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: I read through it and it looks good, I'd like to see the output against our protos before we go live.

@delphyne
delphyne merged commit 274bc4e into main Oct 13, 2026
5 of 7 checks passed
@delphyne
delphyne deleted the fix/description-markdown-handling branch October 13, 2026 14:20
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.

3 participants