fix(protoc-gen-openapiv2): fix naming cache for multi-file generation#6315
Conversation
Properly fixes grpc-ecosystem#6274 (panic) without causing grpc-ecosystem#6308 (naming mismatch). Replaces the reverted approach from PR grpc-ecosystem#6275. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
franchb
left a comment
There was a problem hiding this comment.
Code Review
Overview
This PR fixes a race condition/ordering bug in the OpenAPI v2 generator when processing multiple proto files. The fix restructures applyTemplate() to initialize the naming cache before renderServices() is called, ensuring all subsequent lookups use consistent naming.
Strengths
✅ Root cause fix - Addresses execution order rather than patching symptoms
✅ Clear architecture - Pre-scanning to build cache before usage is sound
✅ Excellent test coverage - Both regression scenarios are tested
✅ Well-documented - Good explanatory comments throughout
✅ Follows conventions - Matches existing code patterns and style
Code Quality Observations
1. Edge case verification (template.go:572-594)
The cycle detection in collectNestedTypeFQNs looks correct - it only recurses into messages since enums don't have children. Good pattern.
2. Error handling consistency (template.go:563-566)
if statusMsg, err := reg.LookupMsg("google.rpc", "Status"); err == nil {
collectNestedTypeFQNs(statusMsg, reg, refs)
}The error is silently ignored, which matches the existing pattern at lines 2225-2230. Consider adding a debug log for troubleshooting, but not blocking.
3. Test helper duplication (generator_test.go:2191-2227)
The new requireGenerateWithNamingStrategy helper is nearly identical to requireGenerate. Minor suggestion: could refactor to use optional parameters or a config struct to reduce duplication.
Performance
- Adds one additional O(n) scan pass over services/messages
- For typical protobuf definitions, overhead is negligible
- Actually improves performance by avoiding mid-execution cache rebuilds
Test Coverage
Excellent coverage with realistic scenarios:
TestGenerateMergeFilesWithBodyAndPathParams- validates #6274 panic fixTestGenerateMultiFileNamingConsistency- validates #6308 $ref consistency- Tests verify correctness, not just "no panic"
Recommendation
✅ Approve - Well-crafted fix that properly addresses the root cause. Ready to merge once CI passes.
🤖 Reviewed with Claude Code
|
Thanks for your PR, @codeout-ssol, any chance you could try and build the plugin from this PR to confirm that this is not causing your panic? Thanks! |
|
Note: I have successfully executed the script from the GitHub issue link here and observed no errors during the process. |
|
Thanks @franchb, sounds good enough to me! |
…sages (grpc-ecosystem#6366) Fix two bugs in collectReferencedNamesForCache() introduced by PR grpc-ecosystem#6315 that caused a panic ("can't resolve OpenAPI ref from typename") when a service method returned a message containing another message with an enum field, particularly with multi-component package names like "example.v1". Bug 1: Message FQMNs were pre-populated in the refs map before scanning services, causing collectNestedTypeFQNs to short-circuit on already-visited entries and miss nested enum types. Bug 2: The package filter compared only the first dot-component (e.g. "example") against the full package name (e.g. "example.v1"), which always failed for multi-component packages. Fixes grpc-ecosystem#6366 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sages (grpc-ecosystem#6366) Fix two bugs in collectReferencedNamesForCache() introduced by PR grpc-ecosystem#6315 that caused a panic ("can't resolve OpenAPI ref from typename") when a service method returned a message containing another message with an enum field, particularly with multi-component package names like "example.v1". Bug 1: Message FQMNs were pre-populated in the refs map before scanning services, causing collectNestedTypeFQNs to short-circuit on already-visited entries and miss nested enum types. Bug 2: The package filter compared only the first dot-component (e.g. "example") against the full package name (e.g. "example.v1"), which always failed for multi-component packages. Fixes grpc-ecosystem#6366 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sages (#6366) (#6367) Fix two bugs in collectReferencedNamesForCache() introduced by PR #6315 that caused a panic ("can't resolve OpenAPI ref from typename") when a service method returned a message containing another message with an enum field, particularly with multi-component package names like "example.v1". Bug 1: Message FQMNs were pre-populated in the refs map before scanning services, causing collectNestedTypeFQNs to short-circuit on already-visited entries and miss nested enum types. Bug 2: The package filter compared only the first dot-component (e.g. "example") against the full package name (e.g. "example.v1"), which always failed for multi-component packages. Fixes #6366 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Properly fixes #6274 (panic when processing multiple proto files) without causing #6308 (naming inconsistency regression).
This replaces the approach from PR #6275 which was reverted.
Root Cause
The fundamental issue was execution order in
applyTemplate():renderServices()was called first, using/building the cache for$refgenerationrenderMessagesAsDefinition()used the NEW filtered cache for definitions$refand definition names could mismatchSolution
Move cache initialization BEFORE
renderServices():Changes
collectReferencedNamesForCache()- scans services/messages without using cachecollectNestedTypeFQNs()- recursively collects nested type FQNsapplyTemplate()to initialize cache beforerenderServices()Test Plan
TestGenerateMergeFilesWithBodyAndPathParams- tests protoc-gen-openapiv2 panics when generating OpenAPI for services with messages in separate files (Protobuf Edition 2023) #6274 scenario (no panic)TestGenerateMultiFileNamingConsistency- tests$refand definition name mismatch forgoogle.rpc.Statuswhen processing multiple proto files with nestedStatustype #6308 scenario ($ref matches definition)🤖 Generated with Claude Code