@@ -145,8 +145,8 @@ type Schema struct {
145145 PatternProperties Schemas `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
146146 DependentSchemas Schemas `json:"dependentSchemas,omitempty" yaml:"dependentSchemas,omitempty"`
147147 PropertyNames * SchemaRef `json:"propertyNames,omitempty" yaml:"propertyNames,omitempty"`
148- UnevaluatedItems * SchemaRef `json:"unevaluatedItems,omitempty" yaml:"unevaluatedItems,omitempty"`
149- UnevaluatedProperties * SchemaRef `json:"unevaluatedProperties,omitempty" yaml:"unevaluatedProperties,omitempty"`
148+ UnevaluatedItems BoolSchema `json:"unevaluatedItems,omitempty" yaml:"unevaluatedItems,omitempty"`
149+ UnevaluatedProperties BoolSchema `json:"unevaluatedProperties,omitempty" yaml:"unevaluatedProperties,omitempty"`
150150
151151 // JSON Schema 2020-12 conditional keywords
152152 If * SchemaRef `json:"if,omitempty" yaml:"if,omitempty"`
@@ -357,56 +357,61 @@ func (types *Types) UnmarshalJSON(data []byte) error {
357357 return nil
358358}
359359
360- type AdditionalProperties struct {
360+ // BoolSchema represents a JSON Schema keyword that can be either a boolean or a schema object.
361+ // Used for additionalProperties, unevaluatedProperties, and unevaluatedItems.
362+ type BoolSchema struct {
361363 Has * bool
362364 Schema * SchemaRef
363365}
364366
365- // MarshalYAML returns the YAML encoding of AdditionalProperties.
366- func (addProps AdditionalProperties ) MarshalYAML () (any , error ) {
367- if x := addProps .Has ; x != nil {
367+ // AdditionalProperties is a type alias for BoolSchema, kept for backward compatibility.
368+ type AdditionalProperties = BoolSchema
369+
370+ // MarshalYAML returns the YAML encoding of BoolSchema.
371+ func (bs BoolSchema ) MarshalYAML () (any , error ) {
372+ if x := bs .Has ; x != nil {
368373 if * x {
369374 return true , nil
370375 }
371376 return false , nil
372377 }
373- if x := addProps .Schema ; x != nil {
378+ if x := bs .Schema ; x != nil {
374379 return x .MarshalYAML ()
375380 }
376381 return nil , nil
377382}
378383
379- // MarshalJSON returns the JSON encoding of AdditionalProperties .
380- func (addProps AdditionalProperties ) MarshalJSON () ([]byte , error ) {
381- x , err := addProps .MarshalYAML ()
384+ // MarshalJSON returns the JSON encoding of BoolSchema .
385+ func (bs BoolSchema ) MarshalJSON () ([]byte , error ) {
386+ x , err := bs .MarshalYAML ()
382387 if err != nil {
383388 return nil , err
384389 }
385390 return json .Marshal (x )
386391}
387392
388- // UnmarshalJSON sets AdditionalProperties to a copy of data.
389- func (addProps * AdditionalProperties ) UnmarshalJSON (data []byte ) error {
393+ // UnmarshalJSON sets BoolSchema to a copy of data.
394+ func (bs * BoolSchema ) UnmarshalJSON (data []byte ) error {
390395 var x any
391396 if err := json .Unmarshal (data , & x ); err != nil {
392397 return unmarshalError (err )
393398 }
394399 switch y := x .(type ) {
395400 case nil :
396401 case bool :
397- addProps .Has = & y
402+ bs .Has = & y
398403 case map [string ]any :
399404 if len (y ) == 0 {
400- addProps .Schema = & SchemaRef {Value : & Schema {}}
405+ bs .Schema = & SchemaRef {Value : & Schema {}}
401406 } else {
402407 buf := new (bytes.Buffer )
403408 _ = json .NewEncoder (buf ).Encode (y )
404- if err := json .NewDecoder (buf ).Decode (& addProps .Schema ); err != nil {
409+ if err := json .NewDecoder (buf ).Decode (& bs .Schema ); err != nil {
405410 return err
406411 }
407412 }
408413 default :
409- return errors .New ("cannot unmarshal additionalProperties : value must be either a schema object or a boolean" )
414+ return errors .New ("cannot unmarshal: value must be either a schema object or a boolean" )
410415 }
411416 return nil
412417}
@@ -647,11 +652,11 @@ func (schema Schema) MarshalYAML() (any, error) {
647652 if x := schema .PropertyNames ; x != nil {
648653 m ["propertyNames" ] = x
649654 }
650- if x := schema .UnevaluatedItems ; x != nil {
651- m ["unevaluatedItems" ] = x
655+ if x := schema .UnevaluatedItems ; x . Has != nil || x . Schema != nil {
656+ m ["unevaluatedItems" ] = & x
652657 }
653- if x := schema .UnevaluatedProperties ; x != nil {
654- m ["unevaluatedProperties" ] = x
658+ if x := schema .UnevaluatedProperties ; x . Has != nil || x . Schema != nil {
659+ m ["unevaluatedProperties" ] = & x
655660 }
656661 if x := schema .If ; x != nil {
657662 m ["if" ] = x
@@ -923,18 +928,24 @@ func (schema Schema) JSONLookup(token string) (any, error) {
923928 return schema .PropertyNames .Value , nil
924929 }
925930 case "unevaluatedItems" :
926- if schema .UnevaluatedItems != nil {
927- if schema .UnevaluatedItems .Ref != "" {
928- return & Ref {Ref : schema .UnevaluatedItems .Ref }, nil
931+ if ui := schema .UnevaluatedItems .Has ; ui != nil {
932+ return * ui , nil
933+ }
934+ if ui := schema .UnevaluatedItems .Schema ; ui != nil {
935+ if ui .Ref != "" {
936+ return & Ref {Ref : ui .Ref }, nil
929937 }
930- return schema . UnevaluatedItems .Value , nil
938+ return ui .Value , nil
931939 }
932940 case "unevaluatedProperties" :
933- if schema .UnevaluatedProperties != nil {
934- if schema .UnevaluatedProperties .Ref != "" {
935- return & Ref {Ref : schema .UnevaluatedProperties .Ref }, nil
941+ if up := schema .UnevaluatedProperties .Has ; up != nil {
942+ return * up , nil
943+ }
944+ if up := schema .UnevaluatedProperties .Schema ; up != nil {
945+ if up .Ref != "" {
946+ return & Ref {Ref : up .Ref }, nil
936947 }
937- return schema . UnevaluatedProperties .Value , nil
948+ return up .Value , nil
938949 }
939950 case "if" :
940951 if schema .If != nil {
@@ -1340,10 +1351,16 @@ func (schema *Schema) IsEmpty() bool {
13401351 if pn := schema .PropertyNames ; pn != nil && pn .Value != nil && ! pn .Value .IsEmpty () {
13411352 return false
13421353 }
1343- if ui := schema .UnevaluatedItems ; ui != nil && ui .Value != nil && ! ui .Value .IsEmpty () {
1354+ if ui := schema .UnevaluatedItems .Schema ; ui != nil && ui .Value != nil && ! ui .Value .IsEmpty () {
1355+ return false
1356+ }
1357+ if uih := schema .UnevaluatedItems .Has ; uih != nil && ! * uih {
13441358 return false
13451359 }
1346- if up := schema .UnevaluatedProperties ; up != nil && up .Value != nil && ! up .Value .IsEmpty () {
1360+ if up := schema .UnevaluatedProperties .Schema ; up != nil && up .Value != nil && ! up .Value .IsEmpty () {
1361+ return false
1362+ }
1363+ if uph := schema .UnevaluatedProperties .Has ; uph != nil && ! * uph {
13471364 return false
13481365 }
13491366 if len (schema .Examples ) != 0 {
@@ -1676,7 +1693,10 @@ func (schema *Schema) validate(ctx context.Context, stack []*Schema) ([]*Schema,
16761693 return stack , err
16771694 }
16781695 }
1679- if ref := schema .UnevaluatedItems ; ref != nil {
1696+ if schema .UnevaluatedItems .Has != nil && schema .UnevaluatedItems .Schema != nil {
1697+ return stack , errors .New ("unevaluatedItems is set to both boolean and schema" )
1698+ }
1699+ if ref := schema .UnevaluatedItems .Schema ; ref != nil {
16801700 v := ref .Value
16811701 if v == nil {
16821702 return stack , foundUnresolvedRef (ref .Ref )
@@ -1687,7 +1707,10 @@ func (schema *Schema) validate(ctx context.Context, stack []*Schema) ([]*Schema,
16871707 return stack , err
16881708 }
16891709 }
1690- if ref := schema .UnevaluatedProperties ; ref != nil {
1710+ if schema .UnevaluatedProperties .Has != nil && schema .UnevaluatedProperties .Schema != nil {
1711+ return stack , errors .New ("unevaluatedProperties is set to both boolean and schema" )
1712+ }
1713+ if ref := schema .UnevaluatedProperties .Schema ; ref != nil {
16911714 v := ref .Value
16921715 if v == nil {
16931716 return stack , foundUnresolvedRef (ref .Ref )
0 commit comments