Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions protoc-gen-openapiv2/internal/genopenapi/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -2043,6 +2043,65 @@ func applyTemplate(p param) (*openapiSwaggerObject, error) {
// Find all the service's messages and enumerations that are defined (recursively)
// and write request, response and other custom (but referenced) types out as definition objects.
findServicesMessagesAndEnumerations(p.Services, p.reg, messages, streamingMessages, enums, requestResponseRefs)

// Build a set of messages/enums that are actually referenced in this file
// we should only consider naming collisions for types that are actually used
referencedNames := make(map[string]bool)

// Add all messages from the current file being processed
for _, msg := range p.Messages {
referencedNames[msg.FQMN()] = true
}

// Add all messages that are referenced (iterate over values to get FQMN, not keys)
for _, msg := range messages {
referencedNames[msg.FQMN()] = true
}

// Add all enums that are referenced
for _, enum := range enums {
referencedNames[enum.FQEN()] = true
}

// Add all method names
for _, svc := range p.Services {
for _, meth := range svc.Methods {
referencedNames[meth.FQMN()] = true
}
}

// Get all names from the registry
allFQMNs := p.reg.GetAllFQMNs()
allFQENs := p.reg.GetAllFQENs()
allFQMethNs := p.reg.GetAllFQMethNs()
allNames := append(append(allFQMNs, allFQENs...), allFQMethNs...)

// Filter: EXCLUDE names that are from a DIFFERENT package AND are NOT referenced
// This way we keep all names from the current package, and all referenced names from other packages
currentPackage := p.File.GetPackage()
filteredNames := make([]string, 0, len(allNames))
for _, name := range allNames {
// Determine the package of this name
// Names are like ".package.Type" or ".package.subpackage.Type"
// We want to extract the top-level package
parts := strings.Split(strings.TrimPrefix(name, "."), ".")
if len(parts) == 0 {
continue
}
namePackage := parts[0]

// Include if: (1) from current package, OR (2) actually referenced, OR (3) from google.*/grpc.* packages
if namePackage == currentPackage || referencedNames[name] || namePackage == "google" || namePackage == "grpc" {
filteredNames = append(filteredNames, name)
}
}

// Clear and recompute the naming cache based only on names that are actually in scope
registriesSeenMutex.Lock()
resolvedNames := resolveFullyQualifiedNameToOpenAPINames(filteredNames, p.reg.GetOpenAPINamingStrategy())
registriesSeen[p.reg] = resolvedNames
registriesSeenMutex.Unlock()

if err := renderMessagesAsDefinition(messages, s.Definitions, p.reg, customRefs, nil); err != nil {
return nil, err
}
Expand Down
Loading