// Copyright 2017 Google LLC. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package jsonschema supports the reading, writing, and manipulation // of JSON Schemas. package jsonschema import "gopkg.in/yaml.v3" // The Schema struct models a JSON Schema and, because schemas are // defined hierarchically, contains many references to itself. // All fields are pointers and are nil if the associated values // are not specified. type Schema struct { Schema *string // $schema ID *string // id keyword used for $ref resolution scope Ref *string // $ref, i.e. JSON Pointers // http://json-schema.org/latest/json-schema-validation.html // 5.1. Validation keywords for numeric instances (number and integer) MultipleOf *SchemaNumber Maximum *SchemaNumber ExclusiveMaximum *bool Minimum *SchemaNumber ExclusiveMinimum *bool // 5.2. Validation keywords for strings MaxLength *int64 MinLength *int64 Pattern *string // 5.3. Validation keywords for arrays AdditionalItems *SchemaOrBoolean Items *SchemaOrSchemaArray MaxItems *int64 MinItems *int64 UniqueItems *bool // 5.4. Validation keywords for objects MaxProperties *int64 MinProperties *int64 Required *[]string AdditionalProperties *SchemaOrBoolean Properties *[]*NamedSchema PatternProperties *[]*NamedSchema Dependencies *[]*NamedSchemaOrStringArray // 5.5. Validation keywords for any instance type Enumeration *[]SchemaEnumValue Type *StringOrStringArray AllOf *[]*Schema AnyOf *[]*Schema OneOf *[]*Schema Not *Schema Definitions *[]*NamedSchema // 6. Metadata keywords Title *string Description *string Default *yaml.Node // 7. Semantic validation with "format" Format *string } // These helper structs represent "combination" types that generally can // have values of one type or another. All are used to represent parts // of Schemas. // SchemaNumber represents a value that can be either an Integer or a Float. type SchemaNumber struct { Integer *int64 Float *float64 } // NewSchemaNumberWithInteger creates and returns a new object func NewSchemaNumberWithInteger(i int64) *SchemaNumber { result := &SchemaNumber{} result.Integer = &i return result } // NewSchemaNumberWithFloat creates and returns a new object func NewSchemaNumberWithFloat(f float64) *SchemaNumber { result := &SchemaNumber{} result.Float = &f return result } // SchemaOrBoolean represents a value that can be either a Schema or a Boolean. type SchemaOrBoolean struct { Schema *Schema Boolean *bool } // NewSchemaOrBooleanWithSchema creates and returns a new object func NewSchemaOrBooleanWithSchema(s *Schema) *SchemaOrBoolean { result := &SchemaOrBoolean{} result.Schema = s return result } // NewSchemaOrBooleanWithBoolean creates and returns a new object func NewSchemaOrBooleanWithBoolean(b bool) *SchemaOrBoolean { result := &SchemaOrBoolean{} result.Boolean = &b return result } // StringOrStringArray represents a value that can be either // a String or an Array of Strings. type StringOrStringArray struct { String *string StringArray *[]string } // NewStringOrStringArrayWithString creates and returns a new object func NewStringOrStringArrayWithString(s string) *StringOrStringArray { result := &StringOrStringArray{} result.String = &s return result } // NewStringOrStringArrayWithStringArray creates and returns a new object func NewStringOrStringArrayWithStringArray(a []string) *StringOrStringArray { result := &StringOrStringArray{} result.StringArray = &a return result } // SchemaOrStringArray represents a value that can be either // a Schema or an Array of Strings. type SchemaOrStringArray struct { Schema *Schema StringArray *[]string } // SchemaOrSchemaArray represents a value that can be either // a Schema or an Array of Schemas. type SchemaOrSchemaArray struct { Schema *Schema SchemaArray *[]*Schema } // NewSchemaOrSchemaArrayWithSchema creates and returns a new object func NewSchemaOrSchemaArrayWithSchema(s *Schema) *SchemaOrSchemaArray { result := &SchemaOrSchemaArray{} result.Schema = s return result } // NewSchemaOrSchemaArrayWithSchemaArray creates and returns a new object func NewSchemaOrSchemaArrayWithSchemaArray(a []*Schema) *SchemaOrSchemaArray { result := &SchemaOrSchemaArray{} result.SchemaArray = &a return result } // SchemaEnumValue represents a value that can be part of an // enumeration in a Schema. type SchemaEnumValue struct { String *string Bool *bool } // NamedSchema is a name-value pair that is used to emulate maps // with ordered keys. type NamedSchema struct { Name string Value *Schema } // NewNamedSchema creates and returns a new object func NewNamedSchema(name string, value *Schema) *NamedSchema { return &NamedSchema{Name: name, Value: value} } // NamedSchemaOrStringArray is a name-value pair that is used // to emulate maps with ordered keys. type NamedSchemaOrStringArray struct { Name string Value *SchemaOrStringArray } // Access named subschemas by name func namedSchemaArrayElementWithName(array *[]*NamedSchema, name string) *Schema { if array == nil { return nil } for _, pair := range *array { if pair.Name == name { return pair.Value } } return nil } // PropertyWithName returns the selected element. func (s *Schema) PropertyWithName(name string) *Schema { return namedSchemaArrayElementWithName(s.Properties, name) } // PatternPropertyWithName returns the selected element. func (s *Schema) PatternPropertyWithName(name string) *Schema { return namedSchemaArrayElementWithName(s.PatternProperties, name) } // DefinitionWithName returns the selected element. func (s *Schema) DefinitionWithName(name string) *Schema { return namedSchemaArrayElementWithName(s.Definitions, name) } // AddProperty adds a named property. func (s *Schema) AddProperty(name string, property *Schema) { *s.Properties = append(*s.Properties, NewNamedSchema(name, property)) }