mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 18:13:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			370 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			370 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// 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
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
 | 
						|
	"gopkg.in/yaml.v3"
 | 
						|
)
 | 
						|
 | 
						|
const indentation = "  "
 | 
						|
 | 
						|
func renderMappingNode(node *yaml.Node, indent string) (result string) {
 | 
						|
	result = "{\n"
 | 
						|
	innerIndent := indent + indentation
 | 
						|
	for i := 0; i < len(node.Content); i += 2 {
 | 
						|
		// first print the key
 | 
						|
		key := node.Content[i].Value
 | 
						|
		result += fmt.Sprintf("%s\"%+v\": ", innerIndent, key)
 | 
						|
		// then the value
 | 
						|
		value := node.Content[i+1]
 | 
						|
		switch value.Kind {
 | 
						|
		case yaml.ScalarNode:
 | 
						|
			result += "\"" + value.Value + "\""
 | 
						|
		case yaml.MappingNode:
 | 
						|
			result += renderMappingNode(value, innerIndent)
 | 
						|
		case yaml.SequenceNode:
 | 
						|
			result += renderSequenceNode(value, innerIndent)
 | 
						|
		default:
 | 
						|
			result += fmt.Sprintf("???MapItem(Key:%+v, Value:%T)", value, value)
 | 
						|
		}
 | 
						|
		if i < len(node.Content)-2 {
 | 
						|
			result += ","
 | 
						|
		}
 | 
						|
		result += "\n"
 | 
						|
	}
 | 
						|
 | 
						|
	result += indent + "}"
 | 
						|
	return result
 | 
						|
}
 | 
						|
 | 
						|
func renderSequenceNode(node *yaml.Node, indent string) (result string) {
 | 
						|
	result = "[\n"
 | 
						|
	innerIndent := indent + indentation
 | 
						|
	for i := 0; i < len(node.Content); i++ {
 | 
						|
		item := node.Content[i]
 | 
						|
		switch item.Kind {
 | 
						|
		case yaml.ScalarNode:
 | 
						|
			result += innerIndent + "\"" + item.Value + "\""
 | 
						|
		case yaml.MappingNode:
 | 
						|
			result += innerIndent + renderMappingNode(item, innerIndent) + ""
 | 
						|
		default:
 | 
						|
			result += innerIndent + fmt.Sprintf("???ArrayItem(%+v)", item)
 | 
						|
		}
 | 
						|
		if i < len(node.Content)-1 {
 | 
						|
			result += ","
 | 
						|
		}
 | 
						|
		result += "\n"
 | 
						|
	}
 | 
						|
	result += indent + "]"
 | 
						|
	return result
 | 
						|
}
 | 
						|
 | 
						|
func renderStringArray(array []string, indent string) (result string) {
 | 
						|
	result = "[\n"
 | 
						|
	innerIndent := indent + indentation
 | 
						|
	for i, item := range array {
 | 
						|
		result += innerIndent + "\"" + item + "\""
 | 
						|
		if i < len(array)-1 {
 | 
						|
			result += ","
 | 
						|
		}
 | 
						|
		result += "\n"
 | 
						|
	}
 | 
						|
	result += indent + "]"
 | 
						|
	return result
 | 
						|
}
 | 
						|
 | 
						|
// Render renders a yaml.Node as JSON
 | 
						|
func Render(node *yaml.Node) string {
 | 
						|
	if node.Kind == yaml.DocumentNode {
 | 
						|
		if len(node.Content) == 1 {
 | 
						|
			return Render(node.Content[0])
 | 
						|
		}
 | 
						|
	} else if node.Kind == yaml.MappingNode {
 | 
						|
		return renderMappingNode(node, "") + "\n"
 | 
						|
	} else if node.Kind == yaml.SequenceNode {
 | 
						|
		return renderSequenceNode(node, "") + "\n"
 | 
						|
	}
 | 
						|
	return ""
 | 
						|
}
 | 
						|
 | 
						|
func (object *SchemaNumber) nodeValue() *yaml.Node {
 | 
						|
	if object.Integer != nil {
 | 
						|
		return nodeForInt64(*object.Integer)
 | 
						|
	} else if object.Float != nil {
 | 
						|
		return nodeForFloat64(*object.Float)
 | 
						|
	} else {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (object *SchemaOrBoolean) nodeValue() *yaml.Node {
 | 
						|
	if object.Schema != nil {
 | 
						|
		return object.Schema.nodeValue()
 | 
						|
	} else if object.Boolean != nil {
 | 
						|
		return nodeForBoolean(*object.Boolean)
 | 
						|
	} else {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func nodeForStringArray(array []string) *yaml.Node {
 | 
						|
	content := make([]*yaml.Node, 0)
 | 
						|
	for _, item := range array {
 | 
						|
		content = append(content, nodeForString(item))
 | 
						|
	}
 | 
						|
	return nodeForSequence(content)
 | 
						|
}
 | 
						|
 | 
						|
func nodeForSchemaArray(array []*Schema) *yaml.Node {
 | 
						|
	content := make([]*yaml.Node, 0)
 | 
						|
	for _, item := range array {
 | 
						|
		content = append(content, item.nodeValue())
 | 
						|
	}
 | 
						|
	return nodeForSequence(content)
 | 
						|
}
 | 
						|
 | 
						|
func (object *StringOrStringArray) nodeValue() *yaml.Node {
 | 
						|
	if object.String != nil {
 | 
						|
		return nodeForString(*object.String)
 | 
						|
	} else if object.StringArray != nil {
 | 
						|
		return nodeForStringArray(*(object.StringArray))
 | 
						|
	} else {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (object *SchemaOrStringArray) nodeValue() *yaml.Node {
 | 
						|
	if object.Schema != nil {
 | 
						|
		return object.Schema.nodeValue()
 | 
						|
	} else if object.StringArray != nil {
 | 
						|
		return nodeForStringArray(*(object.StringArray))
 | 
						|
	} else {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (object *SchemaOrSchemaArray) nodeValue() *yaml.Node {
 | 
						|
	if object.Schema != nil {
 | 
						|
		return object.Schema.nodeValue()
 | 
						|
	} else if object.SchemaArray != nil {
 | 
						|
		return nodeForSchemaArray(*(object.SchemaArray))
 | 
						|
	} else {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (object *SchemaEnumValue) nodeValue() *yaml.Node {
 | 
						|
	if object.String != nil {
 | 
						|
		return nodeForString(*object.String)
 | 
						|
	} else if object.Bool != nil {
 | 
						|
		return nodeForBoolean(*object.Bool)
 | 
						|
	} else {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func nodeForNamedSchemaArray(array *[]*NamedSchema) *yaml.Node {
 | 
						|
	content := make([]*yaml.Node, 0)
 | 
						|
	for _, pair := range *(array) {
 | 
						|
		content = appendPair(content, pair.Name, pair.Value.nodeValue())
 | 
						|
	}
 | 
						|
	return nodeForMapping(content)
 | 
						|
}
 | 
						|
 | 
						|
func nodeForNamedSchemaOrStringArray(array *[]*NamedSchemaOrStringArray) *yaml.Node {
 | 
						|
	content := make([]*yaml.Node, 0)
 | 
						|
	for _, pair := range *(array) {
 | 
						|
		content = appendPair(content, pair.Name, pair.Value.nodeValue())
 | 
						|
	}
 | 
						|
	return nodeForMapping(content)
 | 
						|
}
 | 
						|
 | 
						|
func nodeForSchemaEnumArray(array *[]SchemaEnumValue) *yaml.Node {
 | 
						|
	content := make([]*yaml.Node, 0)
 | 
						|
	for _, item := range *array {
 | 
						|
		content = append(content, item.nodeValue())
 | 
						|
	}
 | 
						|
	return nodeForSequence(content)
 | 
						|
}
 | 
						|
 | 
						|
func nodeForMapping(content []*yaml.Node) *yaml.Node {
 | 
						|
	return &yaml.Node{
 | 
						|
		Kind:    yaml.MappingNode,
 | 
						|
		Content: content,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func nodeForSequence(content []*yaml.Node) *yaml.Node {
 | 
						|
	return &yaml.Node{
 | 
						|
		Kind:    yaml.SequenceNode,
 | 
						|
		Content: content,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func nodeForString(value string) *yaml.Node {
 | 
						|
	return &yaml.Node{
 | 
						|
		Kind:  yaml.ScalarNode,
 | 
						|
		Tag:   "!!str",
 | 
						|
		Value: value,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func nodeForBoolean(value bool) *yaml.Node {
 | 
						|
	return &yaml.Node{
 | 
						|
		Kind:  yaml.ScalarNode,
 | 
						|
		Tag:   "!!bool",
 | 
						|
		Value: fmt.Sprintf("%t", value),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func nodeForInt64(value int64) *yaml.Node {
 | 
						|
	return &yaml.Node{
 | 
						|
		Kind:  yaml.ScalarNode,
 | 
						|
		Tag:   "!!int",
 | 
						|
		Value: fmt.Sprintf("%d", value),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func nodeForFloat64(value float64) *yaml.Node {
 | 
						|
	return &yaml.Node{
 | 
						|
		Kind:  yaml.ScalarNode,
 | 
						|
		Tag:   "!!float",
 | 
						|
		Value: fmt.Sprintf("%f", value),
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func appendPair(nodes []*yaml.Node, name string, value *yaml.Node) []*yaml.Node {
 | 
						|
	nodes = append(nodes, nodeForString(name))
 | 
						|
	nodes = append(nodes, value)
 | 
						|
	return nodes
 | 
						|
}
 | 
						|
 | 
						|
func (schema *Schema) nodeValue() *yaml.Node {
 | 
						|
	n := &yaml.Node{Kind: yaml.MappingNode}
 | 
						|
	content := make([]*yaml.Node, 0)
 | 
						|
	if schema.Title != nil {
 | 
						|
		content = appendPair(content, "title", nodeForString(*schema.Title))
 | 
						|
	}
 | 
						|
	if schema.ID != nil {
 | 
						|
		content = appendPair(content, "id", nodeForString(*schema.ID))
 | 
						|
	}
 | 
						|
	if schema.Schema != nil {
 | 
						|
		content = appendPair(content, "$schema", nodeForString(*schema.Schema))
 | 
						|
	}
 | 
						|
	if schema.Type != nil {
 | 
						|
		content = appendPair(content, "type", schema.Type.nodeValue())
 | 
						|
	}
 | 
						|
	if schema.Items != nil {
 | 
						|
		content = appendPair(content, "items", schema.Items.nodeValue())
 | 
						|
	}
 | 
						|
	if schema.Description != nil {
 | 
						|
		content = appendPair(content, "description", nodeForString(*schema.Description))
 | 
						|
	}
 | 
						|
	if schema.Required != nil {
 | 
						|
		content = appendPair(content, "required", nodeForStringArray(*schema.Required))
 | 
						|
	}
 | 
						|
	if schema.AdditionalProperties != nil {
 | 
						|
		content = appendPair(content, "additionalProperties", schema.AdditionalProperties.nodeValue())
 | 
						|
	}
 | 
						|
	if schema.PatternProperties != nil {
 | 
						|
		content = appendPair(content, "patternProperties", nodeForNamedSchemaArray(schema.PatternProperties))
 | 
						|
	}
 | 
						|
	if schema.Properties != nil {
 | 
						|
		content = appendPair(content, "properties", nodeForNamedSchemaArray(schema.Properties))
 | 
						|
	}
 | 
						|
	if schema.Dependencies != nil {
 | 
						|
		content = appendPair(content, "dependencies", nodeForNamedSchemaOrStringArray(schema.Dependencies))
 | 
						|
	}
 | 
						|
	if schema.Ref != nil {
 | 
						|
		content = appendPair(content, "$ref", nodeForString(*schema.Ref))
 | 
						|
	}
 | 
						|
	if schema.MultipleOf != nil {
 | 
						|
		content = appendPair(content, "multipleOf", schema.MultipleOf.nodeValue())
 | 
						|
	}
 | 
						|
	if schema.Maximum != nil {
 | 
						|
		content = appendPair(content, "maximum", schema.Maximum.nodeValue())
 | 
						|
	}
 | 
						|
	if schema.ExclusiveMaximum != nil {
 | 
						|
		content = appendPair(content, "exclusiveMaximum", nodeForBoolean(*schema.ExclusiveMaximum))
 | 
						|
	}
 | 
						|
	if schema.Minimum != nil {
 | 
						|
		content = appendPair(content, "minimum", schema.Minimum.nodeValue())
 | 
						|
	}
 | 
						|
	if schema.ExclusiveMinimum != nil {
 | 
						|
		content = appendPair(content, "exclusiveMinimum", nodeForBoolean(*schema.ExclusiveMinimum))
 | 
						|
	}
 | 
						|
	if schema.MaxLength != nil {
 | 
						|
		content = appendPair(content, "maxLength", nodeForInt64(*schema.MaxLength))
 | 
						|
	}
 | 
						|
	if schema.MinLength != nil {
 | 
						|
		content = appendPair(content, "minLength", nodeForInt64(*schema.MinLength))
 | 
						|
	}
 | 
						|
	if schema.Pattern != nil {
 | 
						|
		content = appendPair(content, "pattern", nodeForString(*schema.Pattern))
 | 
						|
	}
 | 
						|
	if schema.AdditionalItems != nil {
 | 
						|
		content = appendPair(content, "additionalItems", schema.AdditionalItems.nodeValue())
 | 
						|
	}
 | 
						|
	if schema.MaxItems != nil {
 | 
						|
		content = appendPair(content, "maxItems", nodeForInt64(*schema.MaxItems))
 | 
						|
	}
 | 
						|
	if schema.MinItems != nil {
 | 
						|
		content = appendPair(content, "minItems", nodeForInt64(*schema.MinItems))
 | 
						|
	}
 | 
						|
	if schema.UniqueItems != nil {
 | 
						|
		content = appendPair(content, "uniqueItems", nodeForBoolean(*schema.UniqueItems))
 | 
						|
	}
 | 
						|
	if schema.MaxProperties != nil {
 | 
						|
		content = appendPair(content, "maxProperties", nodeForInt64(*schema.MaxProperties))
 | 
						|
	}
 | 
						|
	if schema.MinProperties != nil {
 | 
						|
		content = appendPair(content, "minProperties", nodeForInt64(*schema.MinProperties))
 | 
						|
	}
 | 
						|
	if schema.Enumeration != nil {
 | 
						|
		content = appendPair(content, "enum", nodeForSchemaEnumArray(schema.Enumeration))
 | 
						|
	}
 | 
						|
	if schema.AllOf != nil {
 | 
						|
		content = appendPair(content, "allOf", nodeForSchemaArray(*schema.AllOf))
 | 
						|
	}
 | 
						|
	if schema.AnyOf != nil {
 | 
						|
		content = appendPair(content, "anyOf", nodeForSchemaArray(*schema.AnyOf))
 | 
						|
	}
 | 
						|
	if schema.OneOf != nil {
 | 
						|
		content = appendPair(content, "oneOf", nodeForSchemaArray(*schema.OneOf))
 | 
						|
	}
 | 
						|
	if schema.Not != nil {
 | 
						|
		content = appendPair(content, "not", schema.Not.nodeValue())
 | 
						|
	}
 | 
						|
	if schema.Definitions != nil {
 | 
						|
		content = appendPair(content, "definitions", nodeForNamedSchemaArray(schema.Definitions))
 | 
						|
	}
 | 
						|
	if schema.Default != nil {
 | 
						|
		// m = append(m, yaml.MapItem{Key: "default", Value: *schema.Default})
 | 
						|
	}
 | 
						|
	if schema.Format != nil {
 | 
						|
		content = appendPair(content, "format", nodeForString(*schema.Format))
 | 
						|
	}
 | 
						|
	n.Content = content
 | 
						|
	return n
 | 
						|
}
 | 
						|
 | 
						|
// JSONString returns a json representation of a schema.
 | 
						|
func (schema *Schema) JSONString() string {
 | 
						|
	node := schema.nodeValue()
 | 
						|
	return Render(node)
 | 
						|
}
 |