Skip to content

Commit

Permalink
fix: field name collision (#184)
Browse files Browse the repository at this point in the history
  • Loading branch information
byashimov authored Nov 19, 2024
1 parent 3257514 commit 1b3b015
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 50 deletions.
43 changes: 36 additions & 7 deletions generator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/kelseyhightower/envconfig"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v3"
)
Expand Down Expand Up @@ -525,19 +526,47 @@ func writeStruct(f *jen.File, s *Schema) error {
return nil
}

// fmtStruct returns anynonous struct
// reInvertSnakeCase snake case name pattern reversed
var reInvertSnakeCase = regexp.MustCompile("[^a-zA-Z0-9_]+")

// fmtStruct returns anonymous struct
func fmtStruct(s *Schema) *jen.Statement {
fields := make([]jen.Code, 0, len(s.Properties))
for _, k := range s.propertyNames {
p := s.Properties[k]
field := jen.Id(customCamelCase(k)).Add(getType(p))
tag := k
// Sorts field names
// Resolves field name collision when a new more conventional JSON name replaces an existing field
jsonNames := maps.Keys(s.Properties)
sort.Slice(jsonNames, func(i, j int) bool {
return reInvertSnakeCase.ReplaceAllString(jsonNames[i], "") > reInvertSnakeCase.ReplaceAllString(jsonNames[j], "")
})

// Resolves collisions
uniqueNames := make(map[string]string, len(jsonNames))
for _, jsonName := range jsonNames {
p := s.Properties[jsonName]
goName := customCamelCase(jsonName)
if exist, ok := uniqueNames[goName]; ok {
log.Warn().Msgf("Field collision: %q overrides %q", p.path(), exist)
}
// WARNING: This is a hack to avoid name collisions in Go fields
// overrides duplicate fields
uniqueNames[goName] = jsonName
}

fields := make([]jen.Code, 0, len(uniqueNames))
for _, goName := range sortedKeys(uniqueNames) {
jsonName := uniqueNames[goName]
p := s.Properties[jsonName]

// Adds json tags
tag := jsonName
if !p.required {
tag += ",omitempty"
}

field = field.Tag(map[string]string{"json": strings.ReplaceAll(tag, `\`, "")})
// Some fields have special characters escaped in the name
tag = strings.ReplaceAll(tag, `\`, "")

field := jen.Id(goName).Add(getType(p))
field = field.Tag(map[string]string{"json": tag})

// Adds a comment if it's not equal to the field name
if p.Description != "" && p.Description != p.CamelName {
Expand Down
11 changes: 11 additions & 0 deletions generator/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,17 @@ func (s *Schema) level() int {
return level
}

func (s *Schema) path() string {
path := []string{s.name}
p := s.parent
for p != nil {
path = append(path, p.name)
p = p.parent
}
slices.Reverse(path)
return strings.Join(path, "/")
}

// isAnonymous returns true when a struct should be rendered anonymous to reduce scope noise
func (s *Schema) isAnonymous() bool {
return s.hasCollision && s.isObject() && s.level() > 3
Expand Down
5 changes: 0 additions & 5 deletions handler/kafkamirrormaker/kafkamirrormaker.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion handler/user/user.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 0 additions & 37 deletions openapi_patch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,43 +65,6 @@ components:
properties:
integration_type:
$ref: "#/components/schemas/ServiceCreateRequestBody/properties/service_integrations/items/properties/integration_type"
ServiceKafkaMirrorMakerCreateReplicationFlowRequestBody:
properties:
topics.blacklist:
type: array
items:
type: string
ServiceKafkaMirrorMakerGetReplicationFlowResponse:
properties:
replication_flow:
properties:
topics.blacklist:
type: array
items:
type: string
ServiceKafkaMirrorMakerGetReplicationFlowsResponse:
properties:
replication_flows:
items:
properties:
topics.blacklist:
type: array
items:
type: string
ServiceKafkaMirrorMakerPatchReplicationFlowRequestBody:
properties:
topics.blacklist:
type: array
items:
type: string
ServiceKafkaMirrorMakerPatchReplicationFlowResponse:
properties:
replication_flow:
properties:
topics.blacklist:
type: array
items:
type: string
ServiceGetResponse:
properties:
service:
Expand Down

0 comments on commit 1b3b015

Please sign in to comment.