Upgrade dependent version: github.com/open-policy-agent/opa (#5315)

Upgrade dependent version: github.com/open-policy-agent/opa v0.18.0 -> v0.45.0

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>

Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
hongzhouzi
2022-10-31 10:58:55 +08:00
committed by GitHub
parent 668fca1773
commit ef03b1e3df
363 changed files with 277341 additions and 13544 deletions

View File

@@ -0,0 +1,37 @@
package ast
func arg2map(defs ArgumentDefinitionList, args ArgumentList, vars map[string]interface{}) map[string]interface{} {
result := map[string]interface{}{}
var err error
for _, argDef := range defs {
var val interface{}
var hasValue bool
if argValue := args.ForName(argDef.Name); argValue != nil {
if argValue.Value.Kind == Variable {
val, hasValue = vars[argValue.Value.Raw]
} else {
val, err = argValue.Value.Value(vars)
if err != nil {
panic(err)
}
hasValue = true
}
}
if !hasValue && argDef.DefaultValue != nil {
val, err = argDef.DefaultValue.Value(vars)
if err != nil {
panic(err)
}
hasValue = true
}
if hasValue {
result[argDef.Name] = val
}
}
return result
}

View File

@@ -0,0 +1,148 @@
package ast
type FieldList []*FieldDefinition
func (l FieldList) ForName(name string) *FieldDefinition {
for _, it := range l {
if it.Name == name {
return it
}
}
return nil
}
type EnumValueList []*EnumValueDefinition
func (l EnumValueList) ForName(name string) *EnumValueDefinition {
for _, it := range l {
if it.Name == name {
return it
}
}
return nil
}
type DirectiveList []*Directive
func (l DirectiveList) ForName(name string) *Directive {
for _, it := range l {
if it.Name == name {
return it
}
}
return nil
}
func (l DirectiveList) ForNames(name string) []*Directive {
resp := []*Directive{}
for _, it := range l {
if it.Name == name {
resp = append(resp, it)
}
}
return resp
}
type OperationList []*OperationDefinition
func (l OperationList) ForName(name string) *OperationDefinition {
if name == "" && len(l) == 1 {
return l[0]
}
for _, it := range l {
if it.Name == name {
return it
}
}
return nil
}
type FragmentDefinitionList []*FragmentDefinition
func (l FragmentDefinitionList) ForName(name string) *FragmentDefinition {
for _, it := range l {
if it.Name == name {
return it
}
}
return nil
}
type VariableDefinitionList []*VariableDefinition
func (l VariableDefinitionList) ForName(name string) *VariableDefinition {
for _, it := range l {
if it.Variable == name {
return it
}
}
return nil
}
type ArgumentList []*Argument
func (l ArgumentList) ForName(name string) *Argument {
for _, it := range l {
if it.Name == name {
return it
}
}
return nil
}
type ArgumentDefinitionList []*ArgumentDefinition
func (l ArgumentDefinitionList) ForName(name string) *ArgumentDefinition {
for _, it := range l {
if it.Name == name {
return it
}
}
return nil
}
type SchemaDefinitionList []*SchemaDefinition
type DirectiveDefinitionList []*DirectiveDefinition
func (l DirectiveDefinitionList) ForName(name string) *DirectiveDefinition {
for _, it := range l {
if it.Name == name {
return it
}
}
return nil
}
type DefinitionList []*Definition
func (l DefinitionList) ForName(name string) *Definition {
for _, it := range l {
if it.Name == name {
return it
}
}
return nil
}
type OperationTypeDefinitionList []*OperationTypeDefinition
func (l OperationTypeDefinitionList) ForType(name string) *OperationTypeDefinition {
for _, it := range l {
if it.Type == name {
return it
}
}
return nil
}
type ChildValueList []*ChildValue
func (v ChildValueList) ForName(name string) *Value {
for _, f := range v {
if f.Name == name {
return f.Value
}
}
return nil
}

View File

@@ -0,0 +1,216 @@
package ast
import (
"encoding/json"
)
func UnmarshalSelectionSet(b []byte) (SelectionSet, error) {
var tmp []json.RawMessage
if err := json.Unmarshal(b, &tmp); err != nil {
return nil, err
}
var result = make([]Selection, 0)
for _, item := range tmp {
var field Field
if err := json.Unmarshal(item, &field); err == nil {
result = append(result, &field)
continue
}
var fragmentSpread FragmentSpread
if err := json.Unmarshal(item, &fragmentSpread); err == nil {
result = append(result, &fragmentSpread)
continue
}
var inlineFragment InlineFragment
if err := json.Unmarshal(item, &inlineFragment); err == nil {
result = append(result, &inlineFragment)
continue
}
}
return result, nil
}
func (f *FragmentDefinition) UnmarshalJSON(b []byte) error {
var tmp map[string]json.RawMessage
if err := json.Unmarshal(b, &tmp); err != nil {
return err
}
for k := range tmp {
switch k {
case "Name":
err := json.Unmarshal(tmp[k], &f.Name)
if err != nil {
return err
}
case "VariableDefinition":
err := json.Unmarshal(tmp[k], &f.VariableDefinition)
if err != nil {
return err
}
case "TypeCondition":
err := json.Unmarshal(tmp[k], &f.TypeCondition)
if err != nil {
return err
}
case "Directives":
err := json.Unmarshal(tmp[k], &f.Directives)
if err != nil {
return err
}
case "SelectionSet":
ss, err := UnmarshalSelectionSet(tmp[k])
if err != nil {
return err
}
f.SelectionSet = ss
case "Definition":
err := json.Unmarshal(tmp[k], &f.Definition)
if err != nil {
return err
}
case "Position":
err := json.Unmarshal(tmp[k], &f.Position)
if err != nil {
return err
}
}
}
return nil
}
func (f *InlineFragment) UnmarshalJSON(b []byte) error {
var tmp map[string]json.RawMessage
if err := json.Unmarshal(b, &tmp); err != nil {
return err
}
for k := range tmp {
switch k {
case "TypeCondition":
err := json.Unmarshal(tmp[k], &f.TypeCondition)
if err != nil {
return err
}
case "Directives":
err := json.Unmarshal(tmp[k], &f.Directives)
if err != nil {
return err
}
case "SelectionSet":
ss, err := UnmarshalSelectionSet(tmp[k])
if err != nil {
return err
}
f.SelectionSet = ss
case "ObjectDefinition":
err := json.Unmarshal(tmp[k], &f.ObjectDefinition)
if err != nil {
return err
}
case "Position":
err := json.Unmarshal(tmp[k], &f.Position)
if err != nil {
return err
}
}
}
return nil
}
func (f *OperationDefinition) UnmarshalJSON(b []byte) error {
var tmp map[string]json.RawMessage
if err := json.Unmarshal(b, &tmp); err != nil {
return err
}
for k := range tmp {
switch k {
case "Operation":
err := json.Unmarshal(tmp[k], &f.Operation)
if err != nil {
return err
}
case "Name":
err := json.Unmarshal(tmp[k], &f.Name)
if err != nil {
return err
}
case "VariableDefinitions":
err := json.Unmarshal(tmp[k], &f.VariableDefinitions)
if err != nil {
return err
}
case "Directives":
err := json.Unmarshal(tmp[k], &f.Directives)
if err != nil {
return err
}
case "SelectionSet":
ss, err := UnmarshalSelectionSet(tmp[k])
if err != nil {
return err
}
f.SelectionSet = ss
case "Position":
err := json.Unmarshal(tmp[k], &f.Position)
if err != nil {
return err
}
}
}
return nil
}
func (f *Field) UnmarshalJSON(b []byte) error {
var tmp map[string]json.RawMessage
if err := json.Unmarshal(b, &tmp); err != nil {
return err
}
for k := range tmp {
switch k {
case "Alias":
err := json.Unmarshal(tmp[k], &f.Alias)
if err != nil {
return err
}
case "Name":
err := json.Unmarshal(tmp[k], &f.Name)
if err != nil {
return err
}
case "Arguments":
err := json.Unmarshal(tmp[k], &f.Arguments)
if err != nil {
return err
}
case "Directives":
err := json.Unmarshal(tmp[k], &f.Directives)
if err != nil {
return err
}
case "SelectionSet":
ss, err := UnmarshalSelectionSet(tmp[k])
if err != nil {
return err
}
f.SelectionSet = ss
case "Position":
err := json.Unmarshal(tmp[k], &f.Position)
if err != nil {
return err
}
case "Definition":
err := json.Unmarshal(tmp[k], &f.Definition)
if err != nil {
return err
}
case "ObjectDefinition":
err := json.Unmarshal(tmp[k], &f.ObjectDefinition)
if err != nil {
return err
}
}
}
return nil
}

View File

@@ -0,0 +1,94 @@
package ast
type DefinitionKind string
const (
Scalar DefinitionKind = "SCALAR"
Object DefinitionKind = "OBJECT"
Interface DefinitionKind = "INTERFACE"
Union DefinitionKind = "UNION"
Enum DefinitionKind = "ENUM"
InputObject DefinitionKind = "INPUT_OBJECT"
)
// Definition is the core type definition object, it includes all of the definable types
// but does *not* cover schema or directives.
//
// @vektah: Javascript implementation has different types for all of these, but they are
// more similar than different and don't define any behaviour. I think this style of
// "some hot" struct works better, at least for go.
//
// Type extensions are also represented by this same struct.
type Definition struct {
Kind DefinitionKind
Description string
Name string
Directives DirectiveList
Interfaces []string // object and input object
Fields FieldList // object and input object
Types []string // union
EnumValues EnumValueList // enum
Position *Position `dump:"-"`
BuiltIn bool `dump:"-"`
}
func (d *Definition) IsLeafType() bool {
return d.Kind == Enum || d.Kind == Scalar
}
func (d *Definition) IsAbstractType() bool {
return d.Kind == Interface || d.Kind == Union
}
func (d *Definition) IsCompositeType() bool {
return d.Kind == Object || d.Kind == Interface || d.Kind == Union
}
func (d *Definition) IsInputType() bool {
return d.Kind == Scalar || d.Kind == Enum || d.Kind == InputObject
}
func (d *Definition) OneOf(types ...string) bool {
for _, t := range types {
if d.Name == t {
return true
}
}
return false
}
type FieldDefinition struct {
Description string
Name string
Arguments ArgumentDefinitionList // only for objects
DefaultValue *Value // only for input objects
Type *Type
Directives DirectiveList
Position *Position `dump:"-"`
}
type ArgumentDefinition struct {
Description string
Name string
DefaultValue *Value
Type *Type
Directives DirectiveList
Position *Position `dump:"-"`
}
type EnumValueDefinition struct {
Description string
Name string
Directives DirectiveList
Position *Position `dump:"-"`
}
type DirectiveDefinition struct {
Description string
Name string
Arguments ArgumentDefinitionList
Locations []DirectiveLocation
IsRepeatable bool
Position *Position `dump:"-"`
}

View File

@@ -0,0 +1,43 @@
package ast
type DirectiveLocation string
const (
// Executable
LocationQuery DirectiveLocation = `QUERY`
LocationMutation DirectiveLocation = `MUTATION`
LocationSubscription DirectiveLocation = `SUBSCRIPTION`
LocationField DirectiveLocation = `FIELD`
LocationFragmentDefinition DirectiveLocation = `FRAGMENT_DEFINITION`
LocationFragmentSpread DirectiveLocation = `FRAGMENT_SPREAD`
LocationInlineFragment DirectiveLocation = `INLINE_FRAGMENT`
// Type System
LocationSchema DirectiveLocation = `SCHEMA`
LocationScalar DirectiveLocation = `SCALAR`
LocationObject DirectiveLocation = `OBJECT`
LocationFieldDefinition DirectiveLocation = `FIELD_DEFINITION`
LocationArgumentDefinition DirectiveLocation = `ARGUMENT_DEFINITION`
LocationInterface DirectiveLocation = `INTERFACE`
LocationUnion DirectiveLocation = `UNION`
LocationEnum DirectiveLocation = `ENUM`
LocationEnumValue DirectiveLocation = `ENUM_VALUE`
LocationInputObject DirectiveLocation = `INPUT_OBJECT`
LocationInputFieldDefinition DirectiveLocation = `INPUT_FIELD_DEFINITION`
LocationVariableDefinition DirectiveLocation = `VARIABLE_DEFINITION`
)
type Directive struct {
Name string
Arguments ArgumentList
Position *Position `dump:"-"`
// Requires validation
ParentDefinition *Definition
Definition *DirectiveDefinition
Location DirectiveLocation
}
func (d *Directive) ArgumentMap(vars map[string]interface{}) map[string]interface{} {
return arg2map(d.Definition.Arguments, d.Arguments, vars)
}

View File

@@ -0,0 +1,79 @@
package ast
type QueryDocument struct {
Operations OperationList
Fragments FragmentDefinitionList
Position *Position `dump:"-"`
}
type SchemaDocument struct {
Schema SchemaDefinitionList
SchemaExtension SchemaDefinitionList
Directives DirectiveDefinitionList
Definitions DefinitionList
Extensions DefinitionList
Position *Position `dump:"-"`
}
func (d *SchemaDocument) Merge(other *SchemaDocument) {
d.Schema = append(d.Schema, other.Schema...)
d.SchemaExtension = append(d.SchemaExtension, other.SchemaExtension...)
d.Directives = append(d.Directives, other.Directives...)
d.Definitions = append(d.Definitions, other.Definitions...)
d.Extensions = append(d.Extensions, other.Extensions...)
}
type Schema struct {
Query *Definition
Mutation *Definition
Subscription *Definition
Types map[string]*Definition
Directives map[string]*DirectiveDefinition
PossibleTypes map[string][]*Definition
Implements map[string][]*Definition
Description string
}
// AddTypes is the helper to add types definition to the schema
func (s *Schema) AddTypes(defs ...*Definition) {
if s.Types == nil {
s.Types = make(map[string]*Definition)
}
for _, def := range defs {
s.Types[def.Name] = def
}
}
func (s *Schema) AddPossibleType(name string, def *Definition) {
s.PossibleTypes[name] = append(s.PossibleTypes[name], def)
}
// GetPossibleTypes will enumerate all the definitions for a given interface or union
func (s *Schema) GetPossibleTypes(def *Definition) []*Definition {
return s.PossibleTypes[def.Name]
}
func (s *Schema) AddImplements(name string, iface *Definition) {
s.Implements[name] = append(s.Implements[name], iface)
}
// GetImplements returns all the interface and union definitions that the given definition satisfies
func (s *Schema) GetImplements(def *Definition) []*Definition {
return s.Implements[def.Name]
}
type SchemaDefinition struct {
Description string
Directives DirectiveList
OperationTypes OperationTypeDefinitionList
Position *Position `dump:"-"`
}
type OperationTypeDefinition struct {
Operation Operation
Type string
Position *Position `dump:"-"`
}

View File

@@ -0,0 +1,159 @@
package ast
import (
"bytes"
"fmt"
"reflect"
"strconv"
"strings"
)
// Dump turns ast into a stable string format for assertions in tests
func Dump(i interface{}) string {
v := reflect.ValueOf(i)
d := dumper{Buffer: &bytes.Buffer{}}
d.dump(v)
return d.String()
}
type dumper struct {
*bytes.Buffer
indent int
}
type Dumpable interface {
Dump() string
}
func (d *dumper) dump(v reflect.Value) {
if dumpable, isDumpable := v.Interface().(Dumpable); isDumpable {
d.WriteString(dumpable.Dump())
return
}
switch v.Kind() {
case reflect.Bool:
if v.Bool() {
d.WriteString("true")
} else {
d.WriteString("false")
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
d.WriteString(fmt.Sprintf("%d", v.Int()))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
d.WriteString(fmt.Sprintf("%d", v.Uint()))
case reflect.Float32, reflect.Float64:
d.WriteString(fmt.Sprintf("%.2f", v.Float()))
case reflect.String:
if v.Type().Name() != "string" {
d.WriteString(v.Type().Name() + "(" + strconv.Quote(v.String()) + ")")
} else {
d.WriteString(strconv.Quote(v.String()))
}
case reflect.Array, reflect.Slice:
d.dumpArray(v)
case reflect.Interface, reflect.Ptr:
d.dumpPtr(v)
case reflect.Struct:
d.dumpStruct(v)
default:
panic(fmt.Errorf("unsupported kind: %s\n buf: %s", v.Kind().String(), d.String()))
}
}
func (d *dumper) writeIndent() {
d.Buffer.WriteString(strings.Repeat(" ", d.indent))
}
func (d *dumper) nl() {
d.Buffer.WriteByte('\n')
d.writeIndent()
}
func typeName(t reflect.Type) string {
if t.Kind() == reflect.Ptr {
return typeName(t.Elem())
}
return t.Name()
}
func (d *dumper) dumpArray(v reflect.Value) {
d.WriteString("[" + typeName(v.Type().Elem()) + "]")
for i := 0; i < v.Len(); i++ {
d.nl()
d.WriteString("- ")
d.indent++
d.dump(v.Index(i))
d.indent--
}
}
func (d *dumper) dumpStruct(v reflect.Value) {
d.WriteString("<" + v.Type().Name() + ">")
d.indent++
typ := v.Type()
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
if typ.Field(i).Tag.Get("dump") == "-" {
continue
}
if isZero(f) {
continue
}
d.nl()
d.WriteString(typ.Field(i).Name)
d.WriteString(": ")
d.dump(v.Field(i))
}
d.indent--
}
func isZero(v reflect.Value) bool {
switch v.Kind() {
case reflect.Ptr, reflect.Interface:
return v.IsNil()
case reflect.Func, reflect.Map:
return v.IsNil()
case reflect.Array, reflect.Slice:
if v.IsNil() {
return true
}
z := true
for i := 0; i < v.Len(); i++ {
z = z && isZero(v.Index(i))
}
return z
case reflect.Struct:
z := true
for i := 0; i < v.NumField(); i++ {
z = z && isZero(v.Field(i))
}
return z
case reflect.String:
return v.String() == ""
}
// Compare other types directly:
return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()))
}
func (d *dumper) dumpPtr(v reflect.Value) {
if v.IsNil() {
d.WriteString("nil")
return
}
d.dump(v.Elem())
}

View File

@@ -0,0 +1,38 @@
package ast
type FragmentSpread struct {
Name string
Directives DirectiveList
// Require validation
ObjectDefinition *Definition
Definition *FragmentDefinition
Position *Position `dump:"-"`
}
type InlineFragment struct {
TypeCondition string
Directives DirectiveList
SelectionSet SelectionSet
// Require validation
ObjectDefinition *Definition
Position *Position `dump:"-"`
}
type FragmentDefinition struct {
Name string
// Note: fragment variable definitions are experimental and may be changed
// or removed in the future.
VariableDefinition VariableDefinitionList
TypeCondition string
Directives DirectiveList
SelectionSet SelectionSet
// Require validation
Definition *Definition
Position *Position `dump:"-"`
}

View File

@@ -0,0 +1,30 @@
package ast
type Operation string
const (
Query Operation = "query"
Mutation Operation = "mutation"
Subscription Operation = "subscription"
)
type OperationDefinition struct {
Operation Operation
Name string
VariableDefinitions VariableDefinitionList
Directives DirectiveList
SelectionSet SelectionSet
Position *Position `dump:"-"`
}
type VariableDefinition struct {
Variable string
Type *Type
DefaultValue *Value
Directives DirectiveList
Position *Position `dump:"-"`
// Requires validation
Definition *Definition
Used bool `dump:"-"`
}

View File

@@ -0,0 +1,67 @@
package ast
import (
"bytes"
"encoding/json"
"fmt"
)
var _ json.Unmarshaler = (*Path)(nil)
type Path []PathElement
type PathElement interface {
isPathElement()
}
var _ PathElement = PathIndex(0)
var _ PathElement = PathName("")
func (path Path) String() string {
var str bytes.Buffer
for i, v := range path {
switch v := v.(type) {
case PathIndex:
str.WriteString(fmt.Sprintf("[%d]", v))
case PathName:
if i != 0 {
str.WriteByte('.')
}
str.WriteString(string(v))
default:
panic(fmt.Sprintf("unknown type: %T", v))
}
}
return str.String()
}
func (path *Path) UnmarshalJSON(b []byte) error {
var vs []interface{}
err := json.Unmarshal(b, &vs)
if err != nil {
return err
}
*path = make([]PathElement, 0, len(vs))
for _, v := range vs {
switch v := v.(type) {
case string:
*path = append(*path, PathName(v))
case int:
*path = append(*path, PathIndex(v))
case float64:
*path = append(*path, PathIndex(int(v)))
default:
return fmt.Errorf("unknown path element type: %T", v)
}
}
return nil
}
type PathIndex int
func (PathIndex) isPathElement() {}
type PathName string
func (PathName) isPathElement() {}

View File

@@ -0,0 +1,39 @@
package ast
type SelectionSet []Selection
type Selection interface {
isSelection()
GetPosition() *Position
}
func (*Field) isSelection() {}
func (*FragmentSpread) isSelection() {}
func (*InlineFragment) isSelection() {}
func (s *Field) GetPosition() *Position { return s.Position }
func (s *FragmentSpread) GetPosition() *Position { return s.Position }
func (s *InlineFragment) GetPosition() *Position { return s.Position }
type Field struct {
Alias string
Name string
Arguments ArgumentList
Directives DirectiveList
SelectionSet SelectionSet
Position *Position `dump:"-"`
// Require validation
Definition *FieldDefinition
ObjectDefinition *Definition
}
type Argument struct {
Name string
Value *Value
Position *Position `dump:"-"`
}
func (s *Field) ArgumentMap(vars map[string]interface{}) map[string]interface{} {
return arg2map(s.Definition.Arguments, s.Arguments, vars)
}

View File

@@ -0,0 +1,19 @@
package ast
// Source covers a single *.graphql file
type Source struct {
// Name is the filename of the source
Name string
// Input is the actual contents of the source file
Input string
// BuiltIn indicate whether the source is a part of the specification
BuiltIn bool
}
type Position struct {
Start int // The starting position, in runes, of this token in the input.
End int // The end position, in runes, of this token in the input.
Line int // The line number at the start of this item.
Column int // The column number at the start of this item.
Src *Source // The source document this token belongs to
}

View File

@@ -0,0 +1,68 @@
package ast
func NonNullNamedType(named string, pos *Position) *Type {
return &Type{NamedType: named, NonNull: true, Position: pos}
}
func NamedType(named string, pos *Position) *Type {
return &Type{NamedType: named, NonNull: false, Position: pos}
}
func NonNullListType(elem *Type, pos *Position) *Type {
return &Type{Elem: elem, NonNull: true, Position: pos}
}
func ListType(elem *Type, pos *Position) *Type {
return &Type{Elem: elem, NonNull: false, Position: pos}
}
type Type struct {
NamedType string
Elem *Type
NonNull bool
Position *Position `dump:"-"`
}
func (t *Type) Name() string {
if t.NamedType != "" {
return t.NamedType
}
return t.Elem.Name()
}
func (t *Type) String() string {
nn := ""
if t.NonNull {
nn = "!"
}
if t.NamedType != "" {
return t.NamedType + nn
}
return "[" + t.Elem.String() + "]" + nn
}
func (t *Type) IsCompatible(other *Type) bool {
if t.NamedType != other.NamedType {
return false
}
if t.Elem != nil && other.Elem == nil {
return false
}
if t.Elem != nil && !t.Elem.IsCompatible(other.Elem) {
return false
}
if other.NonNull {
return t.NonNull
}
return true
}
func (t *Type) Dump() string {
return t.String()
}

View File

@@ -0,0 +1,120 @@
package ast
import (
"fmt"
"strconv"
"strings"
)
type ValueKind int
const (
Variable ValueKind = iota
IntValue
FloatValue
StringValue
BlockValue
BooleanValue
NullValue
EnumValue
ListValue
ObjectValue
)
type Value struct {
Raw string
Children ChildValueList
Kind ValueKind
Position *Position `dump:"-"`
// Require validation
Definition *Definition
VariableDefinition *VariableDefinition
ExpectedType *Type
}
type ChildValue struct {
Name string
Value *Value
Position *Position `dump:"-"`
}
func (v *Value) Value(vars map[string]interface{}) (interface{}, error) {
if v == nil {
return nil, nil
}
switch v.Kind {
case Variable:
if value, ok := vars[v.Raw]; ok {
return value, nil
}
if v.VariableDefinition != nil && v.VariableDefinition.DefaultValue != nil {
return v.VariableDefinition.DefaultValue.Value(vars)
}
return nil, nil
case IntValue:
return strconv.ParseInt(v.Raw, 10, 64)
case FloatValue:
return strconv.ParseFloat(v.Raw, 64)
case StringValue, BlockValue, EnumValue:
return v.Raw, nil
case BooleanValue:
return strconv.ParseBool(v.Raw)
case NullValue:
return nil, nil
case ListValue:
var val []interface{}
for _, elem := range v.Children {
elemVal, err := elem.Value.Value(vars)
if err != nil {
return val, err
}
val = append(val, elemVal)
}
return val, nil
case ObjectValue:
val := map[string]interface{}{}
for _, elem := range v.Children {
elemVal, err := elem.Value.Value(vars)
if err != nil {
return val, err
}
val[elem.Name] = elemVal
}
return val, nil
default:
panic(fmt.Errorf("unknown value kind %d", v.Kind))
}
}
func (v *Value) String() string {
if v == nil {
return "<nil>"
}
switch v.Kind {
case Variable:
return "$" + v.Raw
case IntValue, FloatValue, EnumValue, BooleanValue, NullValue:
return v.Raw
case StringValue, BlockValue:
return strconv.Quote(v.Raw)
case ListValue:
var val []string
for _, elem := range v.Children {
val = append(val, elem.Value.String())
}
return "[" + strings.Join(val, ",") + "]"
case ObjectValue:
var val []string
for _, elem := range v.Children {
val = append(val, elem.Name+":"+elem.Value.String())
}
return "{" + strings.Join(val, ",") + "}"
default:
panic(fmt.Errorf("unknown value kind %d", v.Kind))
}
}
func (v *Value) Dump() string {
return v.String()
}