Skip to content

Commit 02e1c29

Browse files
committed
regen
1 parent 27c7acb commit 02e1c29

1 file changed

Lines changed: 48 additions & 11 deletions

File tree

pkg/codegen/schema_merge.go

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -713,11 +713,13 @@ func mergeOpenapiSchemas(s1, s2 *base.Schema) (*base.Schema, error) {
713713
// Required. We merge these.
714714
result.Required = append(s1.Required, s2.Required...)
715715

716-
// We merge all properties. When both schemas declare a property with
717-
// the same name, the typed declaration wins over an untyped one
718-
// (which usually only carries annotations like example or
719-
// description). Without this, the later schema silently overwrote
720-
// the earlier one and any type/enum/constraint it carried was lost.
716+
// We merge all properties. When both schemas declare a property
717+
// with the same name, an annotation-only override (carrying only
718+
// fields like `example` or `description`) must not overwrite a
719+
// sibling that actually shapes the Go type. Otherwise we keep the
720+
// previous "s2 wins" behavior, since both sides genuinely shape
721+
// the type and the second declaration is the more specific one in
722+
// an allOf chain.
721723
//
722724
// We deliberately pick one of the original SchemaProxies rather
723725
// than fabricating a merged proxy via CreateSchemaProxy: downstream
@@ -735,13 +737,9 @@ func mergeOpenapiSchemas(s1, s2 *base.Schema) (*base.Schema, error) {
735737
}
736738

737739
if existing, exists := result.Properties.Get(k); exists {
738-
if len(getSchemaType(existing.Schema())) == 0 && len(getSchemaType(v.Schema())) > 0 {
739-
result.Properties.Set(k, v)
740+
if isAnnotationOnlySchema(v.Schema()) && !isAnnotationOnlySchema(existing.Schema()) {
741+
continue
740742
}
741-
// Otherwise the existing (s1's) property keeps its place;
742-
// either it already has a type and we don't want to drop it,
743-
// or neither side has a type and the choice is moot.
744-
continue
745743
}
746744
result.Properties.Set(k, v)
747745
}
@@ -809,6 +807,45 @@ func getSchemaType(schema *base.Schema) []string {
809807
return nil
810808
}
811809

810+
// isAnnotationOnlySchema reports whether a schema has no fields that
811+
// influence the generated Go type. Schemas like `{ example: cancelled }`
812+
// or `{ description: "..." }` are annotation-only and must not be
813+
// allowed to overwrite a sibling declaration that actually carries a
814+
// type, enum, or sub-schema in an allOf merge.
815+
func isAnnotationOnlySchema(s *base.Schema) bool {
816+
if s == nil {
817+
return true
818+
}
819+
if len(s.Type) > 0 {
820+
return false
821+
}
822+
if len(s.AllOf) > 0 || len(s.OneOf) > 0 || len(s.AnyOf) > 0 {
823+
return false
824+
}
825+
if s.If != nil || s.Then != nil || s.Else != nil || s.Not != nil {
826+
return false
827+
}
828+
if s.Properties != nil && s.Properties.Len() > 0 {
829+
return false
830+
}
831+
if s.PatternProperties != nil && s.PatternProperties.Len() > 0 {
832+
return false
833+
}
834+
if s.Items != nil {
835+
return false
836+
}
837+
if len(s.Enum) > 0 {
838+
return false
839+
}
840+
if s.AdditionalProperties != nil {
841+
return false
842+
}
843+
if s.Const != nil {
844+
return false
845+
}
846+
return true
847+
}
848+
812849
// mergeNullable merges two nullable pointers using a union (more permissive) approach.
813850
// If either is true, the result is true. If both are false or nil, the result is nil.
814851
// This allows merging schemas where one specifies nullable and another doesn't.

0 commit comments

Comments
 (0)