aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/graphql-go/graphql/language
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2018-07-19 14:15:50 +0200
committerMichael Muré <batolettre@gmail.com>2018-07-19 14:15:50 +0200
commita2a50f3de0c428c5a61e6a449191be3c4ded86ac (patch)
tree5ecf4f5f1f26933b42a606b741963fa5f66c85aa /vendor/github.com/graphql-go/graphql/language
parent25fb88d7497b00bbe3dda540efde22ffd3de6e49 (diff)
downloadgit-bug-a2a50f3de0c428c5a61e6a449191be3c4ded86ac.tar.gz
webui: add a primitive graphql handler
Diffstat (limited to 'vendor/github.com/graphql-go/graphql/language')
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/arguments.go33
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/definitions.go247
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/directives.go33
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/document.go31
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/location.go22
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/name.go31
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/node.go45
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/selections.go144
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/type_definitions.go529
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/types.go106
-rw-r--r--vendor/github.com/graphql-go/graphql/language/ast/values.go305
-rw-r--r--vendor/github.com/graphql-go/graphql/language/kinds/kinds.go59
-rw-r--r--vendor/github.com/graphql-go/graphql/language/lexer/lexer.go656
-rw-r--r--vendor/github.com/graphql-go/graphql/language/location/location.go35
-rw-r--r--vendor/github.com/graphql-go/graphql/language/parser/parser.go1636
-rw-r--r--vendor/github.com/graphql-go/graphql/language/printer/printer.go821
-rw-r--r--vendor/github.com/graphql-go/graphql/language/source/source.go20
-rw-r--r--vendor/github.com/graphql-go/graphql/language/typeInfo/type_info.go11
-rw-r--r--vendor/github.com/graphql-go/graphql/language/visitor/visitor.go873
19 files changed, 5637 insertions, 0 deletions
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/arguments.go b/vendor/github.com/graphql-go/graphql/language/ast/arguments.go
new file mode 100644
index 00000000..5f7ef0d2
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/arguments.go
@@ -0,0 +1,33 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/kinds"
+)
+
+// Argument implements Node
+type Argument struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Value Value
+}
+
+func NewArgument(arg *Argument) *Argument {
+ if arg == nil {
+ arg = &Argument{}
+ }
+ return &Argument{
+ Kind: kinds.Argument,
+ Loc: arg.Loc,
+ Name: arg.Name,
+ Value: arg.Value,
+ }
+}
+
+func (arg *Argument) GetKind() string {
+ return arg.Kind
+}
+
+func (arg *Argument) GetLoc() *Location {
+ return arg.Loc
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/definitions.go b/vendor/github.com/graphql-go/graphql/language/ast/definitions.go
new file mode 100644
index 00000000..cd527f0a
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/definitions.go
@@ -0,0 +1,247 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/kinds"
+)
+
+type Definition interface {
+ GetOperation() string
+ GetVariableDefinitions() []*VariableDefinition
+ GetSelectionSet() *SelectionSet
+ GetKind() string
+ GetLoc() *Location
+}
+
+// Ensure that all definition types implements Definition interface
+var _ Definition = (*OperationDefinition)(nil)
+var _ Definition = (*FragmentDefinition)(nil)
+var _ Definition = (TypeSystemDefinition)(nil) // experimental non-spec addition.
+
+// Note: subscription is an experimental non-spec addition.
+const (
+ OperationTypeQuery = "query"
+ OperationTypeMutation = "mutation"
+ OperationTypeSubscription = "subscription"
+)
+
+// OperationDefinition implements Node, Definition
+type OperationDefinition struct {
+ Kind string
+ Loc *Location
+ Operation string
+ Name *Name
+ VariableDefinitions []*VariableDefinition
+ Directives []*Directive
+ SelectionSet *SelectionSet
+}
+
+func NewOperationDefinition(op *OperationDefinition) *OperationDefinition {
+ if op == nil {
+ op = &OperationDefinition{}
+ }
+ return &OperationDefinition{
+ Kind: kinds.OperationDefinition,
+ Loc: op.Loc,
+ Operation: op.Operation,
+ Name: op.Name,
+ VariableDefinitions: op.VariableDefinitions,
+ Directives: op.Directives,
+ SelectionSet: op.SelectionSet,
+ }
+}
+
+func (op *OperationDefinition) GetKind() string {
+ return op.Kind
+}
+
+func (op *OperationDefinition) GetLoc() *Location {
+ return op.Loc
+}
+
+func (op *OperationDefinition) GetOperation() string {
+ return op.Operation
+}
+
+func (op *OperationDefinition) GetName() *Name {
+ return op.Name
+}
+
+func (op *OperationDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return op.VariableDefinitions
+}
+
+func (op *OperationDefinition) GetDirectives() []*Directive {
+ return op.Directives
+}
+
+func (op *OperationDefinition) GetSelectionSet() *SelectionSet {
+ return op.SelectionSet
+}
+
+// FragmentDefinition implements Node, Definition
+type FragmentDefinition struct {
+ Kind string
+ Loc *Location
+ Operation string
+ Name *Name
+ VariableDefinitions []*VariableDefinition
+ TypeCondition *Named
+ Directives []*Directive
+ SelectionSet *SelectionSet
+}
+
+func NewFragmentDefinition(fd *FragmentDefinition) *FragmentDefinition {
+ if fd == nil {
+ fd = &FragmentDefinition{}
+ }
+ return &FragmentDefinition{
+ Kind: kinds.FragmentDefinition,
+ Loc: fd.Loc,
+ Operation: fd.Operation,
+ Name: fd.Name,
+ VariableDefinitions: fd.VariableDefinitions,
+ TypeCondition: fd.TypeCondition,
+ Directives: fd.Directives,
+ SelectionSet: fd.SelectionSet,
+ }
+}
+
+func (fd *FragmentDefinition) GetKind() string {
+ return fd.Kind
+}
+
+func (fd *FragmentDefinition) GetLoc() *Location {
+ return fd.Loc
+}
+
+func (fd *FragmentDefinition) GetOperation() string {
+ return fd.Operation
+}
+
+func (fd *FragmentDefinition) GetName() *Name {
+ return fd.Name
+}
+
+func (fd *FragmentDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return fd.VariableDefinitions
+}
+
+func (fd *FragmentDefinition) GetSelectionSet() *SelectionSet {
+ return fd.SelectionSet
+}
+
+// VariableDefinition implements Node
+type VariableDefinition struct {
+ Kind string
+ Loc *Location
+ Variable *Variable
+ Type Type
+ DefaultValue Value
+}
+
+func NewVariableDefinition(vd *VariableDefinition) *VariableDefinition {
+ if vd == nil {
+ vd = &VariableDefinition{}
+ }
+ return &VariableDefinition{
+ Kind: kinds.VariableDefinition,
+ Loc: vd.Loc,
+ Variable: vd.Variable,
+ Type: vd.Type,
+ DefaultValue: vd.DefaultValue,
+ }
+}
+
+func (vd *VariableDefinition) GetKind() string {
+ return vd.Kind
+}
+
+func (vd *VariableDefinition) GetLoc() *Location {
+ return vd.Loc
+}
+
+// TypeExtensionDefinition implements Node, Definition
+type TypeExtensionDefinition struct {
+ Kind string
+ Loc *Location
+ Definition *ObjectDefinition
+}
+
+func NewTypeExtensionDefinition(def *TypeExtensionDefinition) *TypeExtensionDefinition {
+ if def == nil {
+ def = &TypeExtensionDefinition{}
+ }
+ return &TypeExtensionDefinition{
+ Kind: kinds.TypeExtensionDefinition,
+ Loc: def.Loc,
+ Definition: def.Definition,
+ }
+}
+
+func (def *TypeExtensionDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *TypeExtensionDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *TypeExtensionDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return []*VariableDefinition{}
+}
+
+func (def *TypeExtensionDefinition) GetSelectionSet() *SelectionSet {
+ return &SelectionSet{}
+}
+
+func (def *TypeExtensionDefinition) GetOperation() string {
+ return ""
+}
+
+// DirectiveDefinition implements Node, Definition
+type DirectiveDefinition struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Description *StringValue
+ Arguments []*InputValueDefinition
+ Locations []*Name
+}
+
+func NewDirectiveDefinition(def *DirectiveDefinition) *DirectiveDefinition {
+ if def == nil {
+ def = &DirectiveDefinition{}
+ }
+ return &DirectiveDefinition{
+ Kind: kinds.DirectiveDefinition,
+ Loc: def.Loc,
+ Name: def.Name,
+ Description: def.Description,
+ Arguments: def.Arguments,
+ Locations: def.Locations,
+ }
+}
+
+func (def *DirectiveDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *DirectiveDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *DirectiveDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return []*VariableDefinition{}
+}
+
+func (def *DirectiveDefinition) GetSelectionSet() *SelectionSet {
+ return &SelectionSet{}
+}
+
+func (def *DirectiveDefinition) GetOperation() string {
+ return ""
+}
+
+func (def *DirectiveDefinition) GetDescription() *StringValue {
+ return def.Description
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/directives.go b/vendor/github.com/graphql-go/graphql/language/ast/directives.go
new file mode 100644
index 00000000..0c8a8c0e
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/directives.go
@@ -0,0 +1,33 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/kinds"
+)
+
+// Directive implements Node
+type Directive struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Arguments []*Argument
+}
+
+func NewDirective(dir *Directive) *Directive {
+ if dir == nil {
+ dir = &Directive{}
+ }
+ return &Directive{
+ Kind: kinds.Directive,
+ Loc: dir.Loc,
+ Name: dir.Name,
+ Arguments: dir.Arguments,
+ }
+}
+
+func (dir *Directive) GetKind() string {
+ return dir.Kind
+}
+
+func (dir *Directive) GetLoc() *Location {
+ return dir.Loc
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/document.go b/vendor/github.com/graphql-go/graphql/language/ast/document.go
new file mode 100644
index 00000000..dcb67034
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/document.go
@@ -0,0 +1,31 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/kinds"
+)
+
+// Document implements Node
+type Document struct {
+ Kind string
+ Loc *Location
+ Definitions []Node
+}
+
+func NewDocument(d *Document) *Document {
+ if d == nil {
+ d = &Document{}
+ }
+ return &Document{
+ Kind: kinds.Document,
+ Loc: d.Loc,
+ Definitions: d.Definitions,
+ }
+}
+
+func (node *Document) GetKind() string {
+ return node.Kind
+}
+
+func (node *Document) GetLoc() *Location {
+ return node.Loc
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/location.go b/vendor/github.com/graphql-go/graphql/language/ast/location.go
new file mode 100644
index 00000000..266dc847
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/location.go
@@ -0,0 +1,22 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/source"
+)
+
+type Location struct {
+ Start int
+ End int
+ Source *source.Source
+}
+
+func NewLocation(loc *Location) *Location {
+ if loc == nil {
+ loc = &Location{}
+ }
+ return &Location{
+ Start: loc.Start,
+ End: loc.End,
+ Source: loc.Source,
+ }
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/name.go b/vendor/github.com/graphql-go/graphql/language/ast/name.go
new file mode 100644
index 00000000..00fddbcd
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/name.go
@@ -0,0 +1,31 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/kinds"
+)
+
+// Name implements Node
+type Name struct {
+ Kind string
+ Loc *Location
+ Value string
+}
+
+func NewName(node *Name) *Name {
+ if node == nil {
+ node = &Name{}
+ }
+ return &Name{
+ Kind: kinds.Name,
+ Value: node.Value,
+ Loc: node.Loc,
+ }
+}
+
+func (node *Name) GetKind() string {
+ return node.Kind
+}
+
+func (node *Name) GetLoc() *Location {
+ return node.Loc
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/node.go b/vendor/github.com/graphql-go/graphql/language/ast/node.go
new file mode 100644
index 00000000..cd63a0fc
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/node.go
@@ -0,0 +1,45 @@
+package ast
+
+type Node interface {
+ GetKind() string
+ GetLoc() *Location
+}
+
+// The list of all possible AST node graphql.
+// Ensure that all node types implements Node interface
+var _ Node = (*Name)(nil)
+var _ Node = (*Document)(nil)
+var _ Node = (*OperationDefinition)(nil)
+var _ Node = (*VariableDefinition)(nil)
+var _ Node = (*Variable)(nil)
+var _ Node = (*SelectionSet)(nil)
+var _ Node = (*Field)(nil)
+var _ Node = (*Argument)(nil)
+var _ Node = (*FragmentSpread)(nil)
+var _ Node = (*InlineFragment)(nil)
+var _ Node = (*FragmentDefinition)(nil)
+var _ Node = (*IntValue)(nil)
+var _ Node = (*FloatValue)(nil)
+var _ Node = (*StringValue)(nil)
+var _ Node = (*BooleanValue)(nil)
+var _ Node = (*EnumValue)(nil)
+var _ Node = (*ListValue)(nil)
+var _ Node = (*ObjectValue)(nil)
+var _ Node = (*ObjectField)(nil)
+var _ Node = (*Directive)(nil)
+var _ Node = (*Named)(nil)
+var _ Node = (*List)(nil)
+var _ Node = (*NonNull)(nil)
+var _ Node = (*SchemaDefinition)(nil)
+var _ Node = (*OperationTypeDefinition)(nil)
+var _ Node = (*ScalarDefinition)(nil)
+var _ Node = (*ObjectDefinition)(nil)
+var _ Node = (*FieldDefinition)(nil)
+var _ Node = (*InputValueDefinition)(nil)
+var _ Node = (*InterfaceDefinition)(nil)
+var _ Node = (*UnionDefinition)(nil)
+var _ Node = (*EnumDefinition)(nil)
+var _ Node = (*EnumValueDefinition)(nil)
+var _ Node = (*InputObjectDefinition)(nil)
+var _ Node = (*TypeExtensionDefinition)(nil)
+var _ Node = (*DirectiveDefinition)(nil)
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/selections.go b/vendor/github.com/graphql-go/graphql/language/ast/selections.go
new file mode 100644
index 00000000..0dc0ea12
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/selections.go
@@ -0,0 +1,144 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/kinds"
+)
+
+type Selection interface {
+ GetSelectionSet() *SelectionSet
+}
+
+// Ensure that all definition types implements Selection interface
+var _ Selection = (*Field)(nil)
+var _ Selection = (*FragmentSpread)(nil)
+var _ Selection = (*InlineFragment)(nil)
+
+// Field implements Node, Selection
+type Field struct {
+ Kind string
+ Loc *Location
+ Alias *Name
+ Name *Name
+ Arguments []*Argument
+ Directives []*Directive
+ SelectionSet *SelectionSet
+}
+
+func NewField(f *Field) *Field {
+ if f == nil {
+ f = &Field{}
+ }
+ return &Field{
+ Kind: kinds.Field,
+ Loc: f.Loc,
+ Alias: f.Alias,
+ Name: f.Name,
+ Arguments: f.Arguments,
+ Directives: f.Directives,
+ SelectionSet: f.SelectionSet,
+ }
+}
+
+func (f *Field) GetKind() string {
+ return f.Kind
+}
+
+func (f *Field) GetLoc() *Location {
+ return f.Loc
+}
+
+func (f *Field) GetSelectionSet() *SelectionSet {
+ return f.SelectionSet
+}
+
+// FragmentSpread implements Node, Selection
+type FragmentSpread struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Directives []*Directive
+}
+
+func NewFragmentSpread(fs *FragmentSpread) *FragmentSpread {
+ if fs == nil {
+ fs = &FragmentSpread{}
+ }
+ return &FragmentSpread{
+ Kind: kinds.FragmentSpread,
+ Loc: fs.Loc,
+ Name: fs.Name,
+ Directives: fs.Directives,
+ }
+}
+
+func (fs *FragmentSpread) GetKind() string {
+ return fs.Kind
+}
+
+func (fs *FragmentSpread) GetLoc() *Location {
+ return fs.Loc
+}
+
+func (fs *FragmentSpread) GetSelectionSet() *SelectionSet {
+ return nil
+}
+
+// InlineFragment implements Node, Selection
+type InlineFragment struct {
+ Kind string
+ Loc *Location
+ TypeCondition *Named
+ Directives []*Directive
+ SelectionSet *SelectionSet
+}
+
+func NewInlineFragment(f *InlineFragment) *InlineFragment {
+ if f == nil {
+ f = &InlineFragment{}
+ }
+ return &InlineFragment{
+ Kind: kinds.InlineFragment,
+ Loc: f.Loc,
+ TypeCondition: f.TypeCondition,
+ Directives: f.Directives,
+ SelectionSet: f.SelectionSet,
+ }
+}
+
+func (f *InlineFragment) GetKind() string {
+ return f.Kind
+}
+
+func (f *InlineFragment) GetLoc() *Location {
+ return f.Loc
+}
+
+func (f *InlineFragment) GetSelectionSet() *SelectionSet {
+ return f.SelectionSet
+}
+
+// SelectionSet implements Node
+type SelectionSet struct {
+ Kind string
+ Loc *Location
+ Selections []Selection
+}
+
+func NewSelectionSet(ss *SelectionSet) *SelectionSet {
+ if ss == nil {
+ ss = &SelectionSet{}
+ }
+ return &SelectionSet{
+ Kind: kinds.SelectionSet,
+ Loc: ss.Loc,
+ Selections: ss.Selections,
+ }
+}
+
+func (ss *SelectionSet) GetKind() string {
+ return ss.Kind
+}
+
+func (ss *SelectionSet) GetLoc() *Location {
+ return ss.Loc
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/type_definitions.go b/vendor/github.com/graphql-go/graphql/language/ast/type_definitions.go
new file mode 100644
index 00000000..aefa70ed
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/type_definitions.go
@@ -0,0 +1,529 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/kinds"
+)
+
+// DescribableNode are nodes that have descriptions associated with them.
+type DescribableNode interface {
+ GetDescription() *StringValue
+}
+
+type TypeDefinition interface {
+ DescribableNode
+ GetOperation() string
+ GetVariableDefinitions() []*VariableDefinition
+ GetSelectionSet() *SelectionSet
+ GetKind() string
+ GetLoc() *Location
+}
+
+var _ TypeDefinition = (*ScalarDefinition)(nil)
+var _ TypeDefinition = (*ObjectDefinition)(nil)
+var _ TypeDefinition = (*InterfaceDefinition)(nil)
+var _ TypeDefinition = (*UnionDefinition)(nil)
+var _ TypeDefinition = (*EnumDefinition)(nil)
+var _ TypeDefinition = (*InputObjectDefinition)(nil)
+
+type TypeSystemDefinition interface {
+ GetOperation() string
+ GetVariableDefinitions() []*VariableDefinition
+ GetSelectionSet() *SelectionSet
+ GetKind() string
+ GetLoc() *Location
+}
+
+var _ TypeSystemDefinition = (*SchemaDefinition)(nil)
+var _ TypeSystemDefinition = (TypeDefinition)(nil)
+var _ TypeSystemDefinition = (*TypeExtensionDefinition)(nil)
+var _ TypeSystemDefinition = (*DirectiveDefinition)(nil)
+
+// SchemaDefinition implements Node, Definition
+type SchemaDefinition struct {
+ Kind string
+ Loc *Location
+ Directives []*Directive
+ OperationTypes []*OperationTypeDefinition
+}
+
+func NewSchemaDefinition(def *SchemaDefinition) *SchemaDefinition {
+ if def == nil {
+ def = &SchemaDefinition{}
+ }
+ return &SchemaDefinition{
+ Kind: kinds.SchemaDefinition,
+ Loc: def.Loc,
+ Directives: def.Directives,
+ OperationTypes: def.OperationTypes,
+ }
+}
+
+func (def *SchemaDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *SchemaDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *SchemaDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return []*VariableDefinition{}
+}
+
+func (def *SchemaDefinition) GetSelectionSet() *SelectionSet {
+ return &SelectionSet{}
+}
+
+func (def *SchemaDefinition) GetOperation() string {
+ return ""
+}
+
+// OperationTypeDefinition implements Node, Definition
+type OperationTypeDefinition struct {
+ Kind string
+ Loc *Location
+ Operation string
+ Type *Named
+}
+
+func NewOperationTypeDefinition(def *OperationTypeDefinition) *OperationTypeDefinition {
+ if def == nil {
+ def = &OperationTypeDefinition{}
+ }
+ return &OperationTypeDefinition{
+ Kind: kinds.OperationTypeDefinition,
+ Loc: def.Loc,
+ Operation: def.Operation,
+ Type: def.Type,
+ }
+}
+
+func (def *OperationTypeDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *OperationTypeDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+// ScalarDefinition implements Node, Definition
+type ScalarDefinition struct {
+ Kind string
+ Loc *Location
+ Description *StringValue
+ Name *Name
+ Directives []*Directive
+}
+
+func NewScalarDefinition(def *ScalarDefinition) *ScalarDefinition {
+ if def == nil {
+ def = &ScalarDefinition{}
+ }
+ return &ScalarDefinition{
+ Kind: kinds.ScalarDefinition,
+ Loc: def.Loc,
+ Description: def.Description,
+ Name: def.Name,
+ Directives: def.Directives,
+ }
+}
+
+func (def *ScalarDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *ScalarDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *ScalarDefinition) GetName() *Name {
+ return def.Name
+}
+
+func (def *ScalarDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return []*VariableDefinition{}
+}
+
+func (def *ScalarDefinition) GetSelectionSet() *SelectionSet {
+ return &SelectionSet{}
+}
+
+func (def *ScalarDefinition) GetOperation() string {
+ return ""
+}
+
+func (def *ScalarDefinition) GetDescription() *StringValue {
+ return def.Description
+}
+
+// ObjectDefinition implements Node, Definition
+type ObjectDefinition struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Description *StringValue
+ Interfaces []*Named
+ Directives []*Directive
+ Fields []*FieldDefinition
+}
+
+func NewObjectDefinition(def *ObjectDefinition) *ObjectDefinition {
+ if def == nil {
+ def = &ObjectDefinition{}
+ }
+ return &ObjectDefinition{
+ Kind: kinds.ObjectDefinition,
+ Loc: def.Loc,
+ Name: def.Name,
+ Description: def.Description,
+ Interfaces: def.Interfaces,
+ Directives: def.Directives,
+ Fields: def.Fields,
+ }
+}
+
+func (def *ObjectDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *ObjectDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *ObjectDefinition) GetName() *Name {
+ return def.Name
+}
+
+func (def *ObjectDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return []*VariableDefinition{}
+}
+
+func (def *ObjectDefinition) GetSelectionSet() *SelectionSet {
+ return &SelectionSet{}
+}
+
+func (def *ObjectDefinition) GetOperation() string {
+ return ""
+}
+
+func (def *ObjectDefinition) GetDescription() *StringValue {
+ return def.Description
+}
+
+// FieldDefinition implements Node
+type FieldDefinition struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Description *StringValue
+ Arguments []*InputValueDefinition
+ Type Type
+ Directives []*Directive
+}
+
+func NewFieldDefinition(def *FieldDefinition) *FieldDefinition {
+ if def == nil {
+ def = &FieldDefinition{}
+ }
+ return &FieldDefinition{
+ Kind: kinds.FieldDefinition,
+ Loc: def.Loc,
+ Name: def.Name,
+ Description: def.Description,
+ Arguments: def.Arguments,
+ Type: def.Type,
+ Directives: def.Directives,
+ }
+}
+
+func (def *FieldDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *FieldDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *FieldDefinition) GetDescription() *StringValue {
+ return def.Description
+}
+
+// InputValueDefinition implements Node
+type InputValueDefinition struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Description *StringValue
+ Type Type
+ DefaultValue Value
+ Directives []*Directive
+}
+
+func NewInputValueDefinition(def *InputValueDefinition) *InputValueDefinition {
+ if def == nil {
+ def = &InputValueDefinition{}
+ }
+ return &InputValueDefinition{
+ Kind: kinds.InputValueDefinition,
+ Loc: def.Loc,
+ Name: def.Name,
+ Description: def.Description,
+ Type: def.Type,
+ DefaultValue: def.DefaultValue,
+ Directives: def.Directives,
+ }
+}
+
+func (def *InputValueDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *InputValueDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *InputValueDefinition) GetDescription() *StringValue {
+ return def.Description
+}
+
+// InterfaceDefinition implements Node, Definition
+type InterfaceDefinition struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Description *StringValue
+ Directives []*Directive
+ Fields []*FieldDefinition
+}
+
+func NewInterfaceDefinition(def *InterfaceDefinition) *InterfaceDefinition {
+ if def == nil {
+ def = &InterfaceDefinition{}
+ }
+ return &InterfaceDefinition{
+ Kind: kinds.InterfaceDefinition,
+ Loc: def.Loc,
+ Name: def.Name,
+ Description: def.Description,
+ Directives: def.Directives,
+ Fields: def.Fields,
+ }
+}
+
+func (def *InterfaceDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *InterfaceDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *InterfaceDefinition) GetName() *Name {
+ return def.Name
+}
+
+func (def *InterfaceDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return []*VariableDefinition{}
+}
+
+func (def *InterfaceDefinition) GetSelectionSet() *SelectionSet {
+ return &SelectionSet{}
+}
+
+func (def *InterfaceDefinition) GetOperation() string {
+ return ""
+}
+
+func (def *InterfaceDefinition) GetDescription() *StringValue {
+ return def.Description
+}
+
+// UnionDefinition implements Node, Definition
+type UnionDefinition struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Description *StringValue
+ Directives []*Directive
+ Types []*Named
+}
+
+func NewUnionDefinition(def *UnionDefinition) *UnionDefinition {
+ if def == nil {
+ def = &UnionDefinition{}
+ }
+ return &UnionDefinition{
+ Kind: kinds.UnionDefinition,
+ Loc: def.Loc,
+ Name: def.Name,
+ Description: def.Description,
+ Directives: def.Directives,
+ Types: def.Types,
+ }
+}
+
+func (def *UnionDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *UnionDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *UnionDefinition) GetName() *Name {
+ return def.Name
+}
+
+func (def *UnionDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return []*VariableDefinition{}
+}
+
+func (def *UnionDefinition) GetSelectionSet() *SelectionSet {
+ return &SelectionSet{}
+}
+
+func (def *UnionDefinition) GetOperation() string {
+ return ""
+}
+
+func (def *UnionDefinition) GetDescription() *StringValue {
+ return def.Description
+}
+
+// EnumDefinition implements Node, Definition
+type EnumDefinition struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Description *StringValue
+ Directives []*Directive
+ Values []*EnumValueDefinition
+}
+
+func NewEnumDefinition(def *EnumDefinition) *EnumDefinition {
+ if def == nil {
+ def = &EnumDefinition{}
+ }
+ return &EnumDefinition{
+ Kind: kinds.EnumDefinition,
+ Loc: def.Loc,
+ Name: def.Name,
+ Description: def.Description,
+ Directives: def.Directives,
+ Values: def.Values,
+ }
+}
+
+func (def *EnumDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *EnumDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *EnumDefinition) GetName() *Name {
+ return def.Name
+}
+
+func (def *EnumDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return []*VariableDefinition{}
+}
+
+func (def *EnumDefinition) GetSelectionSet() *SelectionSet {
+ return &SelectionSet{}
+}
+
+func (def *EnumDefinition) GetOperation() string {
+ return ""
+}
+
+func (def *EnumDefinition) GetDescription() *StringValue {
+ return def.Description
+}
+
+// EnumValueDefinition implements Node, Definition
+type EnumValueDefinition struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Description *StringValue
+ Directives []*Directive
+}
+
+func NewEnumValueDefinition(def *EnumValueDefinition) *EnumValueDefinition {
+ if def == nil {
+ def = &EnumValueDefinition{}
+ }
+ return &EnumValueDefinition{
+ Kind: kinds.EnumValueDefinition,
+ Loc: def.Loc,
+ Name: def.Name,
+ Description: def.Description,
+ Directives: def.Directives,
+ }
+}
+
+func (def *EnumValueDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *EnumValueDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *EnumValueDefinition) GetDescription() *StringValue {
+ return def.Description
+}
+
+// InputObjectDefinition implements Node, Definition
+type InputObjectDefinition struct {
+ Kind string
+ Loc *Location
+ Name *Name
+ Description *StringValue
+ Directives []*Directive
+ Fields []*InputValueDefinition
+}
+
+func NewInputObjectDefinition(def *InputObjectDefinition) *InputObjectDefinition {
+ if def == nil {
+ def = &InputObjectDefinition{}
+ }
+ return &InputObjectDefinition{
+ Kind: kinds.InputObjectDefinition,
+ Loc: def.Loc,
+ Name: def.Name,
+ Description: def.Description,
+ Directives: def.Directives,
+ Fields: def.Fields,
+ }
+}
+
+func (def *InputObjectDefinition) GetKind() string {
+ return def.Kind
+}
+
+func (def *InputObjectDefinition) GetLoc() *Location {
+ return def.Loc
+}
+
+func (def *InputObjectDefinition) GetName() *Name {
+ return def.Name
+}
+
+func (def *InputObjectDefinition) GetVariableDefinitions() []*VariableDefinition {
+ return []*VariableDefinition{}
+}
+
+func (def *InputObjectDefinition) GetSelectionSet() *SelectionSet {
+ return &SelectionSet{}
+}
+
+func (def *InputObjectDefinition) GetOperation() string {
+ return ""
+}
+
+func (def *InputObjectDefinition) GetDescription() *StringValue {
+ return def.Description
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/types.go b/vendor/github.com/graphql-go/graphql/language/ast/types.go
new file mode 100644
index 00000000..27f00997
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/types.go
@@ -0,0 +1,106 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/kinds"
+)
+
+type Type interface {
+ GetKind() string
+ GetLoc() *Location
+ String() string
+}
+
+// Ensure that all value types implements Value interface
+var _ Type = (*Named)(nil)
+var _ Type = (*List)(nil)
+var _ Type = (*NonNull)(nil)
+
+// Named implements Node, Type
+type Named struct {
+ Kind string
+ Loc *Location
+ Name *Name
+}
+
+func NewNamed(t *Named) *Named {
+ if t == nil {
+ t = &Named{}
+ }
+ return &Named{
+ Kind: kinds.Named,
+ Loc: t.Loc,
+ Name: t.Name,
+ }
+}
+
+func (t *Named) GetKind() string {
+ return t.Kind
+}
+
+func (t *Named) GetLoc() *Location {
+ return t.Loc
+}
+
+func (t *Named) String() string {
+ return t.GetKind()
+}
+
+// List implements Node, Type
+type List struct {
+ Kind string
+ Loc *Location
+ Type Type
+}
+
+func NewList(t *List) *List {
+ if t == nil {
+ t = &List{}
+ }
+ return &List{
+ Kind: kinds.List,
+ Loc: t.Loc,
+ Type: t.Type,
+ }
+}
+
+func (t *List) GetKind() string {
+ return t.Kind
+}
+
+func (t *List) GetLoc() *Location {
+ return t.Loc
+}
+
+func (t *List) String() string {
+ return t.GetKind()
+}
+
+// NonNull implements Node, Type
+type NonNull struct {
+ Kind string
+ Loc *Location
+ Type Type
+}
+
+func NewNonNull(t *NonNull) *NonNull {
+ if t == nil {
+ t = &NonNull{}
+ }
+ return &NonNull{
+ Kind: kinds.NonNull,
+ Loc: t.Loc,
+ Type: t.Type,
+ }
+}
+
+func (t *NonNull) GetKind() string {
+ return t.Kind
+}
+
+func (t *NonNull) GetLoc() *Location {
+ return t.Loc
+}
+
+func (t *NonNull) String() string {
+ return t.GetKind()
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/ast/values.go b/vendor/github.com/graphql-go/graphql/language/ast/values.go
new file mode 100644
index 00000000..67912bdc
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/ast/values.go
@@ -0,0 +1,305 @@
+package ast
+
+import (
+ "github.com/graphql-go/graphql/language/kinds"
+)
+
+type Value interface {
+ GetValue() interface{}
+ GetKind() string
+ GetLoc() *Location
+}
+
+// Ensure that all value types implements Value interface
+var _ Value = (*Variable)(nil)
+var _ Value = (*IntValue)(nil)
+var _ Value = (*FloatValue)(nil)
+var _ Value = (*StringValue)(nil)
+var _ Value = (*BooleanValue)(nil)
+var _ Value = (*EnumValue)(nil)
+var _ Value = (*ListValue)(nil)
+var _ Value = (*ObjectValue)(nil)
+
+// Variable implements Node, Value
+type Variable struct {
+ Kind string
+ Loc *Location
+ Name *Name
+}
+
+func NewVariable(v *Variable) *Variable {
+ if v == nil {
+ v = &Variable{}
+ }
+ return &Variable{
+ Kind: kinds.Variable,
+ Loc: v.Loc,
+ Name: v.Name,
+ }
+}
+
+func (v *Variable) GetKind() string {
+ return v.Kind
+}
+
+func (v *Variable) GetLoc() *Location {
+ return v.Loc
+}
+
+// GetValue alias to Variable.GetName()
+func (v *Variable) GetValue() interface{} {
+ return v.GetName()
+}
+
+func (v *Variable) GetName() interface{} {
+ return v.Name
+}
+
+// IntValue implements Node, Value
+type IntValue struct {
+ Kind string
+ Loc *Location
+ Value string
+}
+
+func NewIntValue(v *IntValue) *IntValue {
+ if v == nil {
+ v = &IntValue{}
+ }
+ return &IntValue{
+ Kind: kinds.IntValue,
+ Loc: v.Loc,
+ Value: v.Value,
+ }
+}
+
+func (v *IntValue) GetKind() string {
+ return v.Kind
+}
+
+func (v *IntValue) GetLoc() *Location {
+ return v.Loc
+}
+
+func (v *IntValue) GetValue() interface{} {
+ return v.Value
+}
+
+// FloatValue implements Node, Value
+type FloatValue struct {
+ Kind string
+ Loc *Location
+ Value string
+}
+
+func NewFloatValue(v *FloatValue) *FloatValue {
+ if v == nil {
+ v = &FloatValue{}
+ }
+ return &FloatValue{
+ Kind: kinds.FloatValue,
+ Loc: v.Loc,
+ Value: v.Value,
+ }
+}
+
+func (v *FloatValue) GetKind() string {
+ return v.Kind
+}
+
+func (v *FloatValue) GetLoc() *Location {
+ return v.Loc
+}
+
+func (v *FloatValue) GetValue() interface{} {
+ return v.Value
+}
+
+// StringValue implements Node, Value
+type StringValue struct {
+ Kind string
+ Loc *Location
+ Value string
+}
+
+func NewStringValue(v *StringValue) *StringValue {
+ if v == nil {
+ v = &StringValue{}
+ }
+ return &StringValue{
+ Kind: kinds.StringValue,
+ Loc: v.Loc,
+ Value: v.Value,
+ }
+}
+
+func (v *StringValue) GetKind() string {
+ return v.Kind
+}
+
+func (v *StringValue) GetLoc() *Location {
+ return v.Loc
+}
+
+func (v *StringValue) GetValue() interface{} {
+ return v.Value
+}
+
+// BooleanValue implements Node, Value
+type BooleanValue struct {
+ Kind string
+ Loc *Location
+ Value bool
+}
+
+func NewBooleanValue(v *BooleanValue) *BooleanValue {
+ if v == nil {
+ v = &BooleanValue{}
+ }
+ return &BooleanValue{
+ Kind: kinds.BooleanValue,
+ Loc: v.Loc,
+ Value: v.Value,
+ }
+}
+
+func (v *BooleanValue) GetKind() string {
+ return v.Kind
+}
+
+func (v *BooleanValue) GetLoc() *Location {
+ return v.Loc
+}
+
+func (v *BooleanValue) GetValue() interface{} {
+ return v.Value
+}
+
+// EnumValue implements Node, Value
+type EnumValue struct {
+ Kind string
+ Loc *Location
+ Value string
+}
+
+func NewEnumValue(v *EnumValue) *EnumValue {
+ if v == nil {
+ v = &EnumValue{}
+ }
+ return &EnumValue{
+ Kind: kinds.EnumValue,
+ Loc: v.Loc,
+ Value: v.Value,
+ }
+}
+
+func (v *EnumValue) GetKind() string {
+ return v.Kind
+}
+
+func (v *EnumValue) GetLoc() *Location {
+ return v.Loc
+}
+
+func (v *EnumValue) GetValue() interface{} {
+ return v.Value
+}
+
+// ListValue implements Node, Value
+type ListValue struct {
+ Kind string
+ Loc *Location
+ Values []Value
+}
+
+func NewListValue(v *ListValue) *ListValue {
+ if v == nil {
+ v = &ListValue{}
+ }
+ return &ListValue{
+ Kind: kinds.ListValue,
+ Loc: v.Loc,
+ Values: v.Values,
+ }
+}
+
+func (v *ListValue) GetKind() string {
+ return v.Kind
+}
+
+func (v *ListValue) GetLoc() *Location {
+ return v.Loc
+}
+
+// GetValue alias to ListValue.GetValues()
+func (v *ListValue) GetValue() interface{} {
+ return v.GetValues()
+}
+
+func (v *ListValue) GetValues() interface{} {
+ // TODO: verify ObjectValue.GetValue()
+ return v.Values
+}
+
+// ObjectValue implements Node, Value
+type ObjectValue struct {
+ Kind string
+ Loc *Location
+ Fields []*ObjectField
+}
+
+func NewObjectValue(v *ObjectValue) *ObjectValue {
+ if v == nil {
+ v = &ObjectValue{}
+ }
+ return &ObjectValue{
+ Kind: kinds.ObjectValue,
+ Loc: v.Loc,
+ Fields: v.Fields,
+ }
+}
+
+func (v *ObjectValue) GetKind() string {
+ return v.Kind
+}
+
+func (v *ObjectValue) GetLoc() *Location {
+ return v.Loc
+}
+
+func (v *ObjectValue) GetValue() interface{} {
+ // TODO: verify ObjectValue.GetValue()
+ return v.Fields
+}
+
+// ObjectField implements Node, Value
+type ObjectField struct {
+ Kind string
+ Name *Name
+ Loc *Location
+ Value Value
+}
+
+func NewObjectField(f *ObjectField) *ObjectField {
+ if f == nil {
+ f = &ObjectField{}
+ }
+ return &ObjectField{
+ Kind: kinds.ObjectField,
+ Loc: f.Loc,
+ Name: f.Name,
+ Value: f.Value,
+ }
+}
+
+func (f *ObjectField) GetKind() string {
+ return f.Kind
+}
+
+func (f *ObjectField) GetLoc() *Location {
+ return f.Loc
+}
+
+func (f *ObjectField) GetValue() interface{} {
+ return f.Value
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/kinds/kinds.go b/vendor/github.com/graphql-go/graphql/language/kinds/kinds.go
new file mode 100644
index 00000000..40bc994e
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/kinds/kinds.go
@@ -0,0 +1,59 @@
+package kinds
+
+const (
+ // Name
+ Name = "Name"
+
+ // Document
+ Document = "Document"
+ OperationDefinition = "OperationDefinition"
+ VariableDefinition = "VariableDefinition"
+ Variable = "Variable"
+ SelectionSet = "SelectionSet"
+ Field = "Field"
+ Argument = "Argument"
+
+ // Fragments
+ FragmentSpread = "FragmentSpread"
+ InlineFragment = "InlineFragment"
+ FragmentDefinition = "FragmentDefinition"
+
+ // Values
+ IntValue = "IntValue"
+ FloatValue = "FloatValue"
+ StringValue = "StringValue"
+ BooleanValue = "BooleanValue"
+ EnumValue = "EnumValue"
+ ListValue = "ListValue"
+ ObjectValue = "ObjectValue"
+ ObjectField = "ObjectField"
+
+ // Directives
+ Directive = "Directive"
+
+ // Types
+ Named = "Named" // previously NamedType
+ List = "List" // previously ListType
+ NonNull = "NonNull" // previously NonNull
+
+ // Type System Definitions
+ SchemaDefinition = "SchemaDefinition"
+ OperationTypeDefinition = "OperationTypeDefinition"
+
+ // Types Definitions
+ ScalarDefinition = "ScalarDefinition" // previously ScalarTypeDefinition
+ ObjectDefinition = "ObjectDefinition" // previously ObjectTypeDefinition
+ FieldDefinition = "FieldDefinition"
+ InputValueDefinition = "InputValueDefinition"
+ InterfaceDefinition = "InterfaceDefinition" // previously InterfaceTypeDefinition
+ UnionDefinition = "UnionDefinition" // previously UnionTypeDefinition
+ EnumDefinition = "EnumDefinition" // previously EnumTypeDefinition
+ EnumValueDefinition = "EnumValueDefinition"
+ InputObjectDefinition = "InputObjectDefinition" // previously InputObjectTypeDefinition
+
+ // Types Extensions
+ TypeExtensionDefinition = "TypeExtensionDefinition"
+
+ // Directive Definitions
+ DirectiveDefinition = "DirectiveDefinition"
+)
diff --git a/vendor/github.com/graphql-go/graphql/language/lexer/lexer.go b/vendor/github.com/graphql-go/graphql/language/lexer/lexer.go
new file mode 100644
index 00000000..62589f4e
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/lexer/lexer.go
@@ -0,0 +1,656 @@
+package lexer
+
+import (
+ "bytes"
+ "fmt"
+ "regexp"
+ "strings"
+ "unicode/utf8"
+
+ "github.com/graphql-go/graphql/gqlerrors"
+ "github.com/graphql-go/graphql/language/source"
+)
+
+const (
+ EOF = iota + 1
+ BANG
+ DOLLAR
+ PAREN_L
+ PAREN_R
+ SPREAD
+ COLON
+ EQUALS
+ AT
+ BRACKET_L
+ BRACKET_R
+ BRACE_L
+ PIPE
+ BRACE_R
+ NAME
+ INT
+ FLOAT
+ STRING
+ BLOCK_STRING
+)
+
+var TokenKind map[int]int
+var tokenDescription map[int]string
+
+func init() {
+ TokenKind = make(map[int]int)
+ tokenDescription = make(map[int]string)
+ TokenKind[EOF] = EOF
+ TokenKind[BANG] = BANG
+ TokenKind[DOLLAR] = DOLLAR
+ TokenKind[PAREN_L] = PAREN_L
+ TokenKind[PAREN_R] = PAREN_R
+ TokenKind[SPREAD] = SPREAD
+ TokenKind[COLON] = COLON
+ TokenKind[EQUALS] = EQUALS
+ TokenKind[AT] = AT
+ TokenKind[BRACKET_L] = BRACKET_L
+ TokenKind[BRACKET_R] = BRACKET_R
+ TokenKind[BRACE_L] = BRACE_L
+ TokenKind[PIPE] = PIPE
+ TokenKind[BRACE_R] = BRACE_R
+ TokenKind[NAME] = NAME
+ TokenKind[INT] = INT
+ TokenKind[FLOAT] = FLOAT
+ TokenKind[STRING] = STRING
+ TokenKind[BLOCK_STRING] = BLOCK_STRING
+ tokenDescription[TokenKind[EOF]] = "EOF"
+ tokenDescription[TokenKind[BANG]] = "!"
+ tokenDescription[TokenKind[DOLLAR]] = "$"
+ tokenDescription[TokenKind[PAREN_L]] = "("
+ tokenDescription[TokenKind[PAREN_R]] = ")"
+ tokenDescription[TokenKind[SPREAD]] = "..."
+ tokenDescription[TokenKind[COLON]] = ":"
+ tokenDescription[TokenKind[EQUALS]] = "="
+ tokenDescription[TokenKind[AT]] = "@"
+ tokenDescription[TokenKind[BRACKET_L]] = "["
+ tokenDescription[TokenKind[BRACKET_R]] = "]"
+ tokenDescription[TokenKind[BRACE_L]] = "{"
+ tokenDescription[TokenKind[PIPE]] = "|"
+ tokenDescription[TokenKind[BRACE_R]] = "}"
+ tokenDescription[TokenKind[NAME]] = "Name"
+ tokenDescription[TokenKind[INT]] = "Int"
+ tokenDescription[TokenKind[FLOAT]] = "Float"
+ tokenDescription[TokenKind[STRING]] = "String"
+ tokenDescription[TokenKind[BLOCK_STRING]] = "BlockString"
+}
+
+// Token is a representation of a lexed Token. Value only appears for non-punctuation
+// tokens: NAME, INT, FLOAT, and STRING.
+type Token struct {
+ Kind int
+ Start int
+ End int
+ Value string
+}
+
+type Lexer func(resetPosition int) (Token, error)
+
+func Lex(s *source.Source) Lexer {
+ var prevPosition int
+ return func(resetPosition int) (Token, error) {
+ if resetPosition == 0 {
+ resetPosition = prevPosition
+ }
+ token, err := readToken(s, resetPosition)
+ if err != nil {
+ return token, err
+ }
+ prevPosition = token.End
+ return token, nil
+ }
+}
+
+// Reads an alphanumeric + underscore name from the source.
+// [_A-Za-z][_0-9A-Za-z]*
+// position: Points to the byte position in the byte array
+// runePosition: Points to the rune position in the byte array
+func readName(source *source.Source, position, runePosition int) Token {
+ body := source.Body
+ bodyLength := len(body)
+ endByte := position + 1
+ endRune := runePosition + 1
+ for {
+ code, _ := runeAt(body, endByte)
+ if (endByte != bodyLength) &&
+ (code == '_' || // _
+ code >= '0' && code <= '9' || // 0-9
+ code >= 'A' && code <= 'Z' || // A-Z
+ code >= 'a' && code <= 'z') { // a-z
+ endByte++
+ endRune++
+ continue
+ } else {
+ break
+ }
+ }
+ return makeToken(TokenKind[NAME], runePosition, endRune, string(body[position:endByte]))
+}
+
+// Reads a number token from the source file, either a float
+// or an int depending on whether a decimal point appears.
+// Int: -?(0|[1-9][0-9]*)
+// Float: -?(0|[1-9][0-9]*)(\.[0-9]+)?((E|e)(+|-)?[0-9]+)?
+func readNumber(s *source.Source, start int, firstCode rune, codeLength int) (Token, error) {
+ code := firstCode
+ body := s.Body
+ position := start
+ isFloat := false
+ if code == '-' { // -
+ position += codeLength
+ code, codeLength = runeAt(body, position)
+ }
+ if code == '0' { // 0
+ position += codeLength
+ code, codeLength = runeAt(body, position)
+ if code >= '0' && code <= '9' {
+ description := fmt.Sprintf("Invalid number, unexpected digit after 0: %v.", printCharCode(code))
+ return Token{}, gqlerrors.NewSyntaxError(s, position, description)
+ }
+ } else {
+ p, err := readDigits(s, position, code, codeLength)
+ if err != nil {
+ return Token{}, err
+ }
+ position = p
+ code, codeLength = runeAt(body, position)
+ }
+ if code == '.' { // .
+ isFloat = true
+ position += codeLength
+ code, codeLength = runeAt(body, position)
+ p, err := readDigits(s, position, code, codeLength)
+ if err != nil {
+ return Token{}, err
+ }
+ position = p
+ code, codeLength = runeAt(body, position)
+ }
+ if code == 'E' || code == 'e' { // E e
+ isFloat = true
+ position += codeLength
+ code, codeLength = runeAt(body, position)
+ if code == '+' || code == '-' { // + -
+ position += codeLength
+ code, codeLength = runeAt(body, position)
+ }
+ p, err := readDigits(s, position, code, codeLength)
+ if err != nil {
+ return Token{}, err
+ }
+ position = p
+ }
+ kind := TokenKind[INT]
+ if isFloat {
+ kind = TokenKind[FLOAT]
+ }
+
+ return makeToken(kind, start, position, string(body[start:position])), nil
+}
+
+// Returns the new position in the source after reading digits.
+func readDigits(s *source.Source, start int, firstCode rune, codeLength int) (int, error) {
+ body := s.Body
+ position := start
+ code := firstCode
+ if code >= '0' && code <= '9' { // 0 - 9
+ for {
+ if code >= '0' && code <= '9' { // 0 - 9
+ position += codeLength
+ code, codeLength = runeAt(body, position)
+ continue
+ } else {
+ break
+ }
+ }
+ return position, nil
+ }
+ var description string
+ description = fmt.Sprintf("Invalid number, expected digit but got: %v.", printCharCode(code))
+ return position, gqlerrors.NewSyntaxError(s, position, description)
+}
+
+func readString(s *source.Source, start int) (Token, error) {
+ body := s.Body
+ position := start + 1
+ runePosition := start + 1
+ chunkStart := position
+ var code rune
+ var n int
+ var valueBuffer bytes.Buffer
+ for {
+ code, n = runeAt(body, position)
+ if position < len(body) &&
+ // not LineTerminator
+ code != 0x000A && code != 0x000D &&
+ // not Quote (")
+ code != '"' {
+
+ // SourceCharacter
+ if code < 0x0020 && code != 0x0009 {
+ return Token{}, gqlerrors.NewSyntaxError(s, runePosition, fmt.Sprintf(`Invalid character within String: %v.`, printCharCode(code)))
+ }
+ position += n
+ runePosition++
+ if code == '\\' { // \
+ valueBuffer.Write(body[chunkStart : position-1])
+ code, n = runeAt(body, position)
+ switch code {
+ case '"':
+ valueBuffer.WriteRune('"')
+ break
+ case '/':
+ valueBuffer.WriteRune('/')
+ break
+ case '\\':
+ valueBuffer.WriteRune('\\')
+ break
+ case 'b':
+ valueBuffer.WriteRune('\b')
+ break
+ case 'f':
+ valueBuffer.WriteRune('\f')
+ break
+ case 'n':
+ valueBuffer.WriteRune('\n')
+ break
+ case 'r':
+ valueBuffer.WriteRune('\r')
+ break
+ case 't':
+ valueBuffer.WriteRune('\t')
+ break
+ case 'u':
+ // Check if there are at least 4 bytes available
+ if len(body) <= position+4 {
+ return Token{}, gqlerrors.NewSyntaxError(s, runePosition,
+ fmt.Sprintf("Invalid character escape sequence: "+
+ "\\u%v", string(body[position+1:])))
+ }
+ charCode := uniCharCode(
+ rune(body[position+1]),
+ rune(body[position+2]),
+ rune(body[position+3]),
+ rune(body[position+4]),
+ )
+ if charCode < 0 {
+ return Token{}, gqlerrors.NewSyntaxError(s, runePosition,
+ fmt.Sprintf("Invalid character escape sequence: "+
+ "\\u%v", string(body[position+1:position+5])))
+ }
+ valueBuffer.WriteRune(charCode)
+ position += 4
+ runePosition += 4
+ break
+ default:
+ return Token{}, gqlerrors.NewSyntaxError(s, runePosition,
+ fmt.Sprintf(`Invalid character escape sequence: \\%c.`, code))
+ }
+ position += n
+ runePosition++
+ chunkStart = position
+ }
+ continue
+ } else {
+ break
+ }
+ }
+ if code != '"' { // quote (")
+ return Token{}, gqlerrors.NewSyntaxError(s, runePosition, "Unterminated string.")
+ }
+ stringContent := body[chunkStart:position]
+ valueBuffer.Write(stringContent)
+ value := valueBuffer.String()
+ return makeToken(TokenKind[STRING], start, position+1, value), nil
+}
+
+// readBlockString reads a block string token from the source file.
+//
+// """("?"?(\\"""|\\(?!=""")|[^"\\]))*"""
+func readBlockString(s *source.Source, start int) (Token, error) {
+ body := s.Body
+ position := start + 3
+ runePosition := start + 3
+ chunkStart := position
+ var valueBuffer bytes.Buffer
+
+ for {
+ // Stop if we've reached the end of the buffer
+ if position >= len(body) {
+ break
+ }
+
+ code, n := runeAt(body, position)
+
+ // Closing Triple-Quote (""")
+ if code == '"' {
+ x, _ := runeAt(body, position+1)
+ y, _ := runeAt(body, position+2)
+ if x == '"' && y == '"' {
+ stringContent := body[chunkStart:position]
+ valueBuffer.Write(stringContent)
+ value := blockStringValue(valueBuffer.String())
+ return makeToken(TokenKind[BLOCK_STRING], start, position+3, value), nil
+ }
+ }
+
+ // SourceCharacter
+ if code < 0x0020 &&
+ code != 0x0009 &&
+ code != 0x000a &&
+ code != 0x000d {
+ return Token{}, gqlerrors.NewSyntaxError(s, runePosition, fmt.Sprintf(`Invalid character within String: %v.`, printCharCode(code)))
+ }
+
+ // Escape Triple-Quote (\""")
+ if code == '\\' { // \
+ x, _ := runeAt(body, position+1)
+ y, _ := runeAt(body, position+2)
+ z, _ := runeAt(body, position+3)
+ if x == '"' && y == '"' && z == '"' {
+ stringContent := append(body[chunkStart:position], []byte(`"""`)...)
+ valueBuffer.Write(stringContent)
+ position += 4 // account for `"""` characters
+ runePosition += 4 // " " " "
+ chunkStart = position
+ continue
+ }
+ }
+
+ position += n
+ runePosition++
+ }
+
+ return Token{}, gqlerrors.NewSyntaxError(s, runePosition, "Unterminated string.")
+}
+
+var splitLinesRegex = regexp.MustCompile("\r\n|[\n\r]")
+
+// This implements the GraphQL spec's BlockStringValue() static algorithm.
+//
+// Produces the value of a block string from its parsed raw value, similar to
+// Coffeescript's block string, Python's docstring trim or Ruby's strip_heredoc.
+//
+// Spec: http://facebook.github.io/graphql/draft/#BlockStringValue()
+// Heavily borrows from: https://github.com/graphql/graphql-js/blob/8e0c599ceccfa8c40d6edf3b72ee2a71490b10e0/src/language/blockStringValue.js
+func blockStringValue(in string) string {
+ // Expand a block string's raw value into independent lines.
+ lines := splitLinesRegex.Split(in, -1)
+
+ // Remove common indentation from all lines but first
+ commonIndent := -1
+ for i := 1; i < len(lines); i++ {
+ line := lines[i]
+ indent := leadingWhitespaceLen(line)
+ if indent < len(line) && (commonIndent == -1 || indent < commonIndent) {
+ commonIndent = indent
+ if commonIndent == 0 {
+ break
+ }
+ }
+ }
+ if commonIndent > 0 {
+ for i, line := range lines {
+ if commonIndent > len(line) {
+ continue
+ }
+ lines[i] = line[commonIndent:]
+ }
+ }
+
+ // Remove leading blank lines.
+ for {
+ if isBlank := lineIsBlank(lines[0]); !isBlank {
+ break
+ }
+ lines = lines[1:]
+ }
+
+ // Remove trailing blank lines.
+ for {
+ i := len(lines) - 1
+ if isBlank := lineIsBlank(lines[i]); !isBlank {
+ break
+ }
+ lines = append(lines[:i], lines[i+1:]...)
+ }
+
+ // Return a string of the lines joined with U+000A.
+ return strings.Join(lines, "\n")
+}
+
+// leadingWhitespaceLen returns count of whitespace characters on given line.
+func leadingWhitespaceLen(in string) (n int) {
+ for _, ch := range in {
+ if ch == ' ' || ch == '\t' {
+ n++
+ } else {
+ break
+ }
+ }
+ return
+}
+
+// lineIsBlank returns true when given line has no content.
+func lineIsBlank(in string) bool {
+ return leadingWhitespaceLen(in) == len(in)
+}
+
+// Converts four hexidecimal chars to the integer that the
+// string represents. For example, uniCharCode('0','0','0','f')
+// will return 15, and uniCharCode('0','0','f','f') returns 255.
+// Returns a negative number on error, if a char was invalid.
+// This is implemented by noting that char2hex() returns -1 on error,
+// which means the result of ORing the char2hex() will also be negative.
+func uniCharCode(a, b, c, d rune) rune {
+ return rune(char2hex(a)<<12 | char2hex(b)<<8 | char2hex(c)<<4 | char2hex(d))
+}
+
+// Converts a hex character to its integer value.
+// '0' becomes 0, '9' becomes 9
+// 'A' becomes 10, 'F' becomes 15
+// 'a' becomes 10, 'f' becomes 15
+// Returns -1 on error.
+func char2hex(a rune) int {
+ if a >= 48 && a <= 57 { // 0-9
+ return int(a) - 48
+ } else if a >= 65 && a <= 70 { // A-F
+ return int(a) - 55
+ } else if a >= 97 && a <= 102 {
+ // a-f
+ return int(a) - 87
+ }
+ return -1
+}
+
+func makeToken(kind int, start int, end int, value string) Token {
+ return Token{Kind: kind, Start: start, End: end, Value: value}
+}
+
+func printCharCode(code rune) string {
+ // NaN/undefined represents access beyond the end of the file.
+ if code < 0 {
+ return "<EOF>"
+ }
+ // print as ASCII for printable range
+ if code >= 0x0020 && code < 0x007F {
+ return fmt.Sprintf(`"%c"`, code)
+ }
+ // Otherwise print the escaped form. e.g. `"\\u0007"`
+ return fmt.Sprintf(`"\\u%04X"`, code)
+}
+
+func readToken(s *source.Source, fromPosition int) (Token, error) {
+ body := s.Body
+ bodyLength := len(body)
+ position, runePosition := positionAfterWhitespace(body, fromPosition)
+ if position >= bodyLength {
+ return makeToken(TokenKind[EOF], position, position, ""), nil
+ }
+ code, codeLength := runeAt(body, position)
+
+ // SourceCharacter
+ if code < 0x0020 && code != 0x0009 && code != 0x000A && code != 0x000D {
+ return Token{}, gqlerrors.NewSyntaxError(s, runePosition, fmt.Sprintf(`Invalid character %v`, printCharCode(code)))
+ }
+
+ switch code {
+ // !
+ case '!':
+ return makeToken(TokenKind[BANG], position, position+1, ""), nil
+ // $
+ case '$':
+ return makeToken(TokenKind[DOLLAR], position, position+1, ""), nil
+ // (
+ case '(':
+ return makeToken(TokenKind[PAREN_L], position, position+1, ""), nil
+ // )
+ case ')':
+ return makeToken(TokenKind[PAREN_R], position, position+1, ""), nil
+ // .
+ case '.':
+ next1, _ := runeAt(body, position+1)
+ next2, _ := runeAt(body, position+2)
+ if next1 == '.' && next2 == '.' {
+ return makeToken(TokenKind[SPREAD], position, position+3, ""), nil
+ }
+ break
+ // :
+ case ':':
+ return makeToken(TokenKind[COLON], position, position+1, ""), nil
+ // =
+ case '=':
+ return makeToken(TokenKind[EQUALS], position, position+1, ""), nil
+ // @
+ case '@':
+ return makeToken(TokenKind[AT], position, position+1, ""), nil
+ // [
+ case '[':
+ return makeToken(TokenKind[BRACKET_L], position, position+1, ""), nil
+ // ]
+ case ']':
+ return makeToken(TokenKind[BRACKET_R], position, position+1, ""), nil
+ // {
+ case '{':
+ return makeToken(TokenKind[BRACE_L], position, position+1, ""), nil
+ // |
+ case '|':
+ return makeToken(TokenKind[PIPE], position, position+1, ""), nil
+ // }
+ case '}':
+ return makeToken(TokenKind[BRACE_R], position, position+1, ""), nil
+ // A-Z
+ case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':
+ return readName(s, position, runePosition), nil
+ // _
+ // a-z
+ case '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z':
+ return readName(s, position, runePosition), nil
+ // -
+ // 0-9
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ token, err := readNumber(s, position, code, codeLength)
+ if err != nil {
+ return token, err
+ }
+ return token, nil
+ // "
+ case '"':
+ var token Token
+ var err error
+ x, _ := runeAt(body, position+1)
+ y, _ := runeAt(body, position+2)
+ if x == '"' && y == '"' {
+ token, err = readBlockString(s, position)
+ } else {
+ token, err = readString(s, position)
+ }
+ return token, err
+ }
+ description := fmt.Sprintf("Unexpected character %v.", printCharCode(code))
+ return Token{}, gqlerrors.NewSyntaxError(s, runePosition, description)
+}
+
+// Gets the rune from the byte array at given byte position and it's width in bytes
+func runeAt(body []byte, position int) (code rune, charWidth int) {
+ if len(body) <= position {
+ // <EOF>
+ return -1, utf8.RuneError
+ }
+
+ c := body[position]
+ if c < utf8.RuneSelf {
+ return rune(c), 1
+ }
+
+ r, n := utf8.DecodeRune(body[position:])
+ return r, n
+}
+
+// Reads from body starting at startPosition until it finds a non-whitespace
+// or commented character, then returns the position of that character for lexing.
+// lexing.
+// Returns both byte positions and rune position
+func positionAfterWhitespace(body []byte, startPosition int) (position int, runePosition int) {
+ bodyLength := len(body)
+ position = startPosition
+ runePosition = startPosition
+ for {
+ if position < bodyLength {
+ code, n := runeAt(body, position)
+
+ // Skip Ignored
+ if code == 0xFEFF || // BOM
+ // White Space
+ code == 0x0009 || // tab
+ code == 0x0020 || // space
+ // Line Terminator
+ code == 0x000A || // new line
+ code == 0x000D || // carriage return
+ // Comma
+ code == 0x002C {
+ position += n
+ runePosition++
+ } else if code == 35 { // #
+ position += n
+ runePosition++
+ for {
+ code, n := runeAt(body, position)
+ if position < bodyLength &&
+ code != 0 &&
+ // SourceCharacter but not LineTerminator
+ (code > 0x001F || code == 0x0009) && code != 0x000A && code != 0x000D {
+ position += n
+ runePosition++
+ continue
+ } else {
+ break
+ }
+ }
+ } else {
+ break
+ }
+ continue
+ } else {
+ break
+ }
+ }
+ return position, runePosition
+}
+
+func GetTokenDesc(token Token) string {
+ if token.Value == "" {
+ return GetTokenKindDesc(token.Kind)
+ }
+ return fmt.Sprintf("%s \"%s\"", GetTokenKindDesc(token.Kind), token.Value)
+}
+
+func GetTokenKindDesc(kind int) string {
+ return tokenDescription[kind]
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/location/location.go b/vendor/github.com/graphql-go/graphql/language/location/location.go
new file mode 100644
index 00000000..04bbde6e
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/location/location.go
@@ -0,0 +1,35 @@
+package location
+
+import (
+ "regexp"
+
+ "github.com/graphql-go/graphql/language/source"
+)
+
+type SourceLocation struct {
+ Line int `json:"line"`
+ Column int `json:"column"`
+}
+
+func GetLocation(s *source.Source, position int) SourceLocation {
+ body := []byte{}
+ if s != nil {
+ body = s.Body
+ }
+ line := 1
+ column := position + 1
+ lineRegexp := regexp.MustCompile("\r\n|[\n\r]")
+ matches := lineRegexp.FindAllIndex(body, -1)
+ for _, match := range matches {
+ matchIndex := match[0]
+ if matchIndex < position {
+ line++
+ l := len(s.Body[match[0]:match[1]])
+ column = position + 1 - (matchIndex + l)
+ continue
+ } else {
+ break
+ }
+ }
+ return SourceLocation{Line: line, Column: column}
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/parser/parser.go b/vendor/github.com/graphql-go/graphql/language/parser/parser.go
new file mode 100644
index 00000000..32beef37
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/parser/parser.go
@@ -0,0 +1,1636 @@
+package parser
+
+import (
+ "fmt"
+
+ "github.com/graphql-go/graphql/gqlerrors"
+ "github.com/graphql-go/graphql/language/ast"
+ "github.com/graphql-go/graphql/language/lexer"
+ "github.com/graphql-go/graphql/language/source"
+)
+
+type parseFn func(parser *Parser) (interface{}, error)
+
+type ParseOptions struct {
+ NoLocation bool
+ NoSource bool
+}
+
+type ParseParams struct {
+ Source interface{}
+ Options ParseOptions
+}
+
+type Parser struct {
+ LexToken lexer.Lexer
+ Source *source.Source
+ Options ParseOptions
+ PrevEnd int
+ Token lexer.Token
+}
+
+func Parse(p ParseParams) (*ast.Document, error) {
+ var sourceObj *source.Source
+ switch p.Source.(type) {
+ case *source.Source:
+ sourceObj = p.Source.(*source.Source)
+ default:
+ body, _ := p.Source.(string)
+ sourceObj = source.NewSource(&source.Source{Body: []byte(body)})
+ }
+ parser, err := makeParser(sourceObj, p.Options)
+ if err != nil {
+ return nil, err
+ }
+ doc, err := parseDocument(parser)
+ if err != nil {
+ return nil, err
+ }
+ return doc, nil
+}
+
+// TODO: test and expose parseValue as a public
+func parseValue(p ParseParams) (ast.Value, error) {
+ var value ast.Value
+ var sourceObj *source.Source
+ switch p.Source.(type) {
+ case *source.Source:
+ sourceObj = p.Source.(*source.Source)
+ default:
+ body, _ := p.Source.(string)
+ sourceObj = source.NewSource(&source.Source{Body: []byte(body)})
+ }
+ parser, err := makeParser(sourceObj, p.Options)
+ if err != nil {
+ return value, err
+ }
+ value, err = parseValueLiteral(parser, false)
+ if err != nil {
+ return value, err
+ }
+ return value, nil
+}
+
+// Converts a name lex token into a name parse node.
+func parseName(parser *Parser) (*ast.Name, error) {
+ token, err := expect(parser, lexer.TokenKind[lexer.NAME])
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewName(&ast.Name{
+ Value: token.Value,
+ Loc: loc(parser, token.Start),
+ }), nil
+}
+
+func makeParser(s *source.Source, opts ParseOptions) (*Parser, error) {
+ lexToken := lexer.Lex(s)
+ token, err := lexToken(0)
+ if err != nil {
+ return &Parser{}, err
+ }
+ return &Parser{
+ LexToken: lexToken,
+ Source: s,
+ Options: opts,
+ PrevEnd: 0,
+ Token: token,
+ }, nil
+}
+
+/* Implements the parsing rules in the Document section. */
+
+func parseDocument(parser *Parser) (*ast.Document, error) {
+ start := parser.Token.Start
+ var nodes []ast.Node
+ for {
+ if skp, err := skip(parser, lexer.TokenKind[lexer.EOF]); err != nil {
+ return nil, err
+ } else if skp {
+ break
+ }
+ if peek(parser, lexer.TokenKind[lexer.BRACE_L]) {
+ node, err := parseOperationDefinition(parser)
+ if err != nil {
+ return nil, err
+ }
+ nodes = append(nodes, node)
+ } else if peek(parser, lexer.TokenKind[lexer.NAME]) {
+ switch parser.Token.Value {
+ case "query":
+ fallthrough
+ case "mutation":
+ fallthrough
+ case "subscription": // Note: subscription is an experimental non-spec addition.
+ node, err := parseOperationDefinition(parser)
+ if err != nil {
+ return nil, err
+ }
+ nodes = append(nodes, node)
+ case "fragment":
+ node, err := parseFragmentDefinition(parser)
+ if err != nil {
+ return nil, err
+ }
+ nodes = append(nodes, node)
+
+ // Note: the Type System IDL is an experimental non-spec addition.
+ case "schema":
+ fallthrough
+ case "scalar":
+ fallthrough
+ case "type":
+ fallthrough
+ case "interface":
+ fallthrough
+ case "union":
+ fallthrough
+ case "enum":
+ fallthrough
+ case "input":
+ fallthrough
+ case "extend":
+ fallthrough
+ case "directive":
+ node, err := parseTypeSystemDefinition(parser)
+ if err != nil {
+ return nil, err
+ }
+ nodes = append(nodes, node)
+ default:
+ if err := unexpected(parser, lexer.Token{}); err != nil {
+ return nil, err
+ }
+ }
+ } else if peekDescription(parser) {
+ node, err := parseTypeSystemDefinition(parser)
+ if err != nil {
+ return nil, err
+ }
+ nodes = append(nodes, node)
+ } else {
+ if err := unexpected(parser, lexer.Token{}); err != nil {
+ return nil, err
+ }
+ }
+ }
+ return ast.NewDocument(&ast.Document{
+ Loc: loc(parser, start),
+ Definitions: nodes,
+ }), nil
+}
+
+/* Implements the parsing rules in the Operations section. */
+
+/**
+ * OperationDefinition :
+ * - SelectionSet
+ * - OperationType Name? VariableDefinitions? Directives? SelectionSet
+ */
+func parseOperationDefinition(parser *Parser) (*ast.OperationDefinition, error) {
+ start := parser.Token.Start
+ if peek(parser, lexer.TokenKind[lexer.BRACE_L]) {
+ selectionSet, err := parseSelectionSet(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewOperationDefinition(&ast.OperationDefinition{
+ Operation: ast.OperationTypeQuery,
+ Directives: []*ast.Directive{},
+ SelectionSet: selectionSet,
+ Loc: loc(parser, start),
+ }), nil
+ }
+ operation, err := parseOperationType(parser)
+ if err != nil {
+ return nil, err
+ }
+
+ var name *ast.Name
+ if peek(parser, lexer.TokenKind[lexer.NAME]) {
+ name, err = parseName(parser)
+ }
+ variableDefinitions, err := parseVariableDefinitions(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ selectionSet, err := parseSelectionSet(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewOperationDefinition(&ast.OperationDefinition{
+ Operation: operation,
+ Name: name,
+ VariableDefinitions: variableDefinitions,
+ Directives: directives,
+ SelectionSet: selectionSet,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * OperationType : one of query mutation subscription
+ */
+func parseOperationType(parser *Parser) (string, error) {
+ operationToken, err := expect(parser, lexer.TokenKind[lexer.NAME])
+ if err != nil {
+ return "", err
+ }
+ switch operationToken.Value {
+ case ast.OperationTypeQuery:
+ return operationToken.Value, nil
+ case ast.OperationTypeMutation:
+ return operationToken.Value, nil
+ case ast.OperationTypeSubscription:
+ return operationToken.Value, nil
+ default:
+ return "", unexpected(parser, operationToken)
+ }
+}
+
+/**
+ * VariableDefinitions : ( VariableDefinition+ )
+ */
+func parseVariableDefinitions(parser *Parser) ([]*ast.VariableDefinition, error) {
+ variableDefinitions := []*ast.VariableDefinition{}
+ if peek(parser, lexer.TokenKind[lexer.PAREN_L]) {
+ vdefs, err := many(parser, lexer.TokenKind[lexer.PAREN_L], parseVariableDefinition, lexer.TokenKind[lexer.PAREN_R])
+ for _, vdef := range vdefs {
+ if vdef != nil {
+ variableDefinitions = append(variableDefinitions, vdef.(*ast.VariableDefinition))
+ }
+ }
+ if err != nil {
+ return variableDefinitions, err
+ }
+ return variableDefinitions, nil
+ }
+ return variableDefinitions, nil
+}
+
+/**
+ * VariableDefinition : Variable : Type DefaultValue?
+ */
+func parseVariableDefinition(parser *Parser) (interface{}, error) {
+ start := parser.Token.Start
+ variable, err := parseVariable(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expect(parser, lexer.TokenKind[lexer.COLON])
+ if err != nil {
+ return nil, err
+ }
+ ttype, err := parseType(parser)
+ if err != nil {
+ return nil, err
+ }
+ var defaultValue ast.Value
+ if skp, err := skip(parser, lexer.TokenKind[lexer.EQUALS]); err != nil {
+ return nil, err
+ } else if skp {
+ dv, err := parseValueLiteral(parser, true)
+ if err != nil {
+ return nil, err
+ }
+ defaultValue = dv
+ }
+ return ast.NewVariableDefinition(&ast.VariableDefinition{
+ Variable: variable,
+ Type: ttype,
+ DefaultValue: defaultValue,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * Variable : $ Name
+ */
+func parseVariable(parser *Parser) (*ast.Variable, error) {
+ start := parser.Token.Start
+ _, err := expect(parser, lexer.TokenKind[lexer.DOLLAR])
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewVariable(&ast.Variable{
+ Name: name,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * SelectionSet : { Selection+ }
+ */
+func parseSelectionSet(parser *Parser) (*ast.SelectionSet, error) {
+ start := parser.Token.Start
+ iSelections, err := many(parser, lexer.TokenKind[lexer.BRACE_L], parseSelection, lexer.TokenKind[lexer.BRACE_R])
+ if err != nil {
+ return nil, err
+ }
+ selections := []ast.Selection{}
+ for _, iSelection := range iSelections {
+ if iSelection != nil {
+ // type assert interface{} into Selection interface
+ selections = append(selections, iSelection.(ast.Selection))
+ }
+ }
+
+ return ast.NewSelectionSet(&ast.SelectionSet{
+ Selections: selections,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * Selection :
+ * - Field
+ * - FragmentSpread
+ * - InlineFragment
+ */
+func parseSelection(parser *Parser) (interface{}, error) {
+ if peek(parser, lexer.TokenKind[lexer.SPREAD]) {
+ r, err := parseFragment(parser)
+ return r, err
+ }
+ return parseField(parser)
+}
+
+/**
+ * Field : Alias? Name Arguments? Directives? SelectionSet?
+ *
+ * Alias : Name :
+ */
+func parseField(parser *Parser) (*ast.Field, error) {
+ start := parser.Token.Start
+ nameOrAlias, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ var (
+ name *ast.Name
+ alias *ast.Name
+ )
+ if skp, err := skip(parser, lexer.TokenKind[lexer.COLON]); err != nil {
+ return nil, err
+ } else if skp {
+ alias = nameOrAlias
+ n, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ name = n
+ } else {
+ name = nameOrAlias
+ }
+ arguments, err := parseArguments(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ var selectionSet *ast.SelectionSet
+ if peek(parser, lexer.TokenKind[lexer.BRACE_L]) {
+ sSet, err := parseSelectionSet(parser)
+ if err != nil {
+ return nil, err
+ }
+ selectionSet = sSet
+ }
+ return ast.NewField(&ast.Field{
+ Alias: alias,
+ Name: name,
+ Arguments: arguments,
+ Directives: directives,
+ SelectionSet: selectionSet,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * Arguments : ( Argument+ )
+ */
+func parseArguments(parser *Parser) ([]*ast.Argument, error) {
+ arguments := []*ast.Argument{}
+ if peek(parser, lexer.TokenKind[lexer.PAREN_L]) {
+ iArguments, err := many(parser, lexer.TokenKind[lexer.PAREN_L], parseArgument, lexer.TokenKind[lexer.PAREN_R])
+ if err != nil {
+ return arguments, err
+ }
+ for _, iArgument := range iArguments {
+ if iArgument != nil {
+ arguments = append(arguments, iArgument.(*ast.Argument))
+ }
+ }
+ return arguments, nil
+ }
+ return arguments, nil
+}
+
+/**
+ * Argument : Name : Value
+ */
+func parseArgument(parser *Parser) (interface{}, error) {
+ start := parser.Token.Start
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expect(parser, lexer.TokenKind[lexer.COLON])
+ if err != nil {
+ return nil, err
+ }
+ value, err := parseValueLiteral(parser, false)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewArgument(&ast.Argument{
+ Name: name,
+ Value: value,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/* Implements the parsing rules in the Fragments section. */
+
+/**
+ * Corresponds to both FragmentSpread and InlineFragment in the spec.
+ *
+ * FragmentSpread : ... FragmentName Directives?
+ *
+ * InlineFragment : ... TypeCondition? Directives? SelectionSet
+ */
+func parseFragment(parser *Parser) (interface{}, error) {
+ start := parser.Token.Start
+ _, err := expect(parser, lexer.TokenKind[lexer.SPREAD])
+ if err != nil {
+ return nil, err
+ }
+ if peek(parser, lexer.TokenKind[lexer.NAME]) && parser.Token.Value != "on" {
+ name, err := parseFragmentName(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewFragmentSpread(&ast.FragmentSpread{
+ Name: name,
+ Directives: directives,
+ Loc: loc(parser, start),
+ }), nil
+ }
+ var typeCondition *ast.Named
+ if parser.Token.Value == "on" {
+ if err := advance(parser); err != nil {
+ return nil, err
+ }
+ name, err := parseNamed(parser)
+ if err != nil {
+ return nil, err
+ }
+ typeCondition = name
+
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ selectionSet, err := parseSelectionSet(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewInlineFragment(&ast.InlineFragment{
+ TypeCondition: typeCondition,
+ Directives: directives,
+ SelectionSet: selectionSet,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * FragmentDefinition :
+ * - fragment FragmentName on TypeCondition Directives? SelectionSet
+ *
+ * TypeCondition : NamedType
+ */
+func parseFragmentDefinition(parser *Parser) (*ast.FragmentDefinition, error) {
+ start := parser.Token.Start
+ _, err := expectKeyWord(parser, "fragment")
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseFragmentName(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expectKeyWord(parser, "on")
+ if err != nil {
+ return nil, err
+ }
+ typeCondition, err := parseNamed(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ selectionSet, err := parseSelectionSet(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewFragmentDefinition(&ast.FragmentDefinition{
+ Name: name,
+ TypeCondition: typeCondition,
+ Directives: directives,
+ SelectionSet: selectionSet,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * FragmentName : Name but not `on`
+ */
+func parseFragmentName(parser *Parser) (*ast.Name, error) {
+ if parser.Token.Value == "on" {
+ return nil, unexpected(parser, lexer.Token{})
+ }
+ return parseName(parser)
+}
+
+/* Implements the parsing rules in the Values section. */
+
+/**
+ * Value[Const] :
+ * - [~Const] Variable
+ * - IntValue
+ * - FloatValue
+ * - StringValue
+ * - BooleanValue
+ * - EnumValue
+ * - ListValue[?Const]
+ * - ObjectValue[?Const]
+ *
+ * BooleanValue : one of `true` `false`
+ *
+ * EnumValue : Name but not `true`, `false` or `null`
+ */
+func parseValueLiteral(parser *Parser, isConst bool) (ast.Value, error) {
+ token := parser.Token
+ switch token.Kind {
+ case lexer.TokenKind[lexer.BRACKET_L]:
+ return parseList(parser, isConst)
+ case lexer.TokenKind[lexer.BRACE_L]:
+ return parseObject(parser, isConst)
+ case lexer.TokenKind[lexer.INT]:
+ if err := advance(parser); err != nil {
+ return nil, err
+ }
+ return ast.NewIntValue(&ast.IntValue{
+ Value: token.Value,
+ Loc: loc(parser, token.Start),
+ }), nil
+ case lexer.TokenKind[lexer.FLOAT]:
+ if err := advance(parser); err != nil {
+ return nil, err
+ }
+ return ast.NewFloatValue(&ast.FloatValue{
+ Value: token.Value,
+ Loc: loc(parser, token.Start),
+ }), nil
+ case lexer.TokenKind[lexer.BLOCK_STRING]:
+ fallthrough
+ case lexer.TokenKind[lexer.STRING]:
+ return parseStringLiteral(parser)
+ case lexer.TokenKind[lexer.NAME]:
+ if token.Value == "true" || token.Value == "false" {
+ if err := advance(parser); err != nil {
+ return nil, err
+ }
+ value := true
+ if token.Value == "false" {
+ value = false
+ }
+ return ast.NewBooleanValue(&ast.BooleanValue{
+ Value: value,
+ Loc: loc(parser, token.Start),
+ }), nil
+ } else if token.Value != "null" {
+ if err := advance(parser); err != nil {
+ return nil, err
+ }
+ return ast.NewEnumValue(&ast.EnumValue{
+ Value: token.Value,
+ Loc: loc(parser, token.Start),
+ }), nil
+ }
+ case lexer.TokenKind[lexer.DOLLAR]:
+ if !isConst {
+ return parseVariable(parser)
+ }
+ }
+ if err := unexpected(parser, lexer.Token{}); err != nil {
+ return nil, err
+ }
+ return nil, nil
+}
+
+func parseConstValue(parser *Parser) (interface{}, error) {
+ value, err := parseValueLiteral(parser, true)
+ if err != nil {
+ return value, err
+ }
+ return value, nil
+}
+
+func parseValueValue(parser *Parser) (interface{}, error) {
+ return parseValueLiteral(parser, false)
+}
+
+/**
+ * ListValue[Const] :
+ * - [ ]
+ * - [ Value[?Const]+ ]
+ */
+func parseList(parser *Parser, isConst bool) (*ast.ListValue, error) {
+ start := parser.Token.Start
+ var item parseFn
+ if isConst {
+ item = parseConstValue
+ } else {
+ item = parseValueValue
+ }
+ iValues, err := any(parser, lexer.TokenKind[lexer.BRACKET_L], item, lexer.TokenKind[lexer.BRACKET_R])
+ if err != nil {
+ return nil, err
+ }
+ values := []ast.Value{}
+ for _, iValue := range iValues {
+ values = append(values, iValue.(ast.Value))
+ }
+ return ast.NewListValue(&ast.ListValue{
+ Values: values,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * ObjectValue[Const] :
+ * - { }
+ * - { ObjectField[?Const]+ }
+ */
+func parseObject(parser *Parser, isConst bool) (*ast.ObjectValue, error) {
+ start := parser.Token.Start
+ _, err := expect(parser, lexer.TokenKind[lexer.BRACE_L])
+ if err != nil {
+ return nil, err
+ }
+ fields := []*ast.ObjectField{}
+ for {
+ if skp, err := skip(parser, lexer.TokenKind[lexer.BRACE_R]); err != nil {
+ return nil, err
+ } else if skp {
+ break
+ }
+ field, err := parseObjectField(parser, isConst)
+ if err != nil {
+ return nil, err
+ }
+ fields = append(fields, field)
+ }
+ return ast.NewObjectValue(&ast.ObjectValue{
+ Fields: fields,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * ObjectField[Const] : Name : Value[?Const]
+ */
+func parseObjectField(parser *Parser, isConst bool) (*ast.ObjectField, error) {
+ start := parser.Token.Start
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expect(parser, lexer.TokenKind[lexer.COLON])
+ if err != nil {
+ return nil, err
+ }
+ value, err := parseValueLiteral(parser, isConst)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewObjectField(&ast.ObjectField{
+ Name: name,
+ Value: value,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/* Implements the parsing rules in the Directives section. */
+
+/**
+ * Directives : Directive+
+ */
+func parseDirectives(parser *Parser) ([]*ast.Directive, error) {
+ directives := []*ast.Directive{}
+ for {
+ if !peek(parser, lexer.TokenKind[lexer.AT]) {
+ break
+ }
+ directive, err := parseDirective(parser)
+ if err != nil {
+ return directives, err
+ }
+ directives = append(directives, directive)
+ }
+ return directives, nil
+}
+
+/**
+ * Directive : @ Name Arguments?
+ */
+func parseDirective(parser *Parser) (*ast.Directive, error) {
+ start := parser.Token.Start
+ _, err := expect(parser, lexer.TokenKind[lexer.AT])
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ args, err := parseArguments(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewDirective(&ast.Directive{
+ Name: name,
+ Arguments: args,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/* Implements the parsing rules in the Types section. */
+
+/**
+ * Type :
+ * - NamedType
+ * - ListType
+ * - NonNullType
+ */
+func parseType(parser *Parser) (ast.Type, error) {
+ start := parser.Token.Start
+ var ttype ast.Type
+ if skp, err := skip(parser, lexer.TokenKind[lexer.BRACKET_L]); err != nil {
+ return nil, err
+ } else if skp {
+ t, err := parseType(parser)
+ if err != nil {
+ return t, err
+ }
+ ttype = t
+ _, err = expect(parser, lexer.TokenKind[lexer.BRACKET_R])
+ if err != nil {
+ return ttype, err
+ }
+ ttype = ast.NewList(&ast.List{
+ Type: ttype,
+ Loc: loc(parser, start),
+ })
+ } else {
+ name, err := parseNamed(parser)
+ if err != nil {
+ return ttype, err
+ }
+ ttype = name
+ }
+ if skp, err := skip(parser, lexer.TokenKind[lexer.BANG]); err != nil {
+ return nil, err
+ } else if skp {
+ ttype = ast.NewNonNull(&ast.NonNull{
+ Type: ttype,
+ Loc: loc(parser, start),
+ })
+ return ttype, nil
+ }
+ return ttype, nil
+}
+
+/**
+ * NamedType : Name
+ */
+func parseNamed(parser *Parser) (*ast.Named, error) {
+ start := parser.Token.Start
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewNamed(&ast.Named{
+ Name: name,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/* Implements the parsing rules in the Type Definition section. */
+
+/**
+ * TypeSystemDefinition :
+ * - SchemaDefinition
+ * - TypeDefinition
+ * - TypeExtension
+ * - DirectiveDefinition
+ *
+ * TypeDefinition :
+ * - ScalarTypeDefinition
+ * - ObjectTypeDefinition
+ * - InterfaceTypeDefinition
+ * - UnionTypeDefinition
+ * - EnumTypeDefinition
+ * - InputObjectTypeDefinition
+ */
+func parseTypeSystemDefinition(parser *Parser) (ast.Node, error) {
+ var err error
+
+ // Many definitions begin with a description and require a lookahead.
+ keywordToken := parser.Token
+ if peekDescription(parser) {
+ keywordToken, err = lookahead(parser)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if keywordToken.Kind == lexer.NAME {
+ switch keywordToken.Value {
+ case "schema":
+ return parseSchemaDefinition(parser)
+ case "scalar":
+ return parseScalarTypeDefinition(parser)
+ case "type":
+ return parseObjectTypeDefinition(parser)
+ case "interface":
+ return parseInterfaceTypeDefinition(parser)
+ case "union":
+ return parseUnionTypeDefinition(parser)
+ case "enum":
+ return parseEnumTypeDefinition(parser)
+ case "input":
+ return parseInputObjectTypeDefinition(parser)
+ case "extend":
+ return parseTypeExtensionDefinition(parser)
+ case "directive":
+ return parseDirectiveDefinition(parser)
+ }
+ }
+
+ return nil, unexpected(parser, keywordToken)
+}
+
+/**
+ * SchemaDefinition : schema Directives? { OperationTypeDefinition+ }
+ *
+ * OperationTypeDefinition : OperationType : NamedType
+ */
+func parseSchemaDefinition(parser *Parser) (*ast.SchemaDefinition, error) {
+ start := parser.Token.Start
+ _, err := expectKeyWord(parser, "schema")
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ operationTypesI, err := many(
+ parser,
+ lexer.TokenKind[lexer.BRACE_L],
+ parseOperationTypeDefinition,
+ lexer.TokenKind[lexer.BRACE_R],
+ )
+ if err != nil {
+ return nil, err
+ }
+ operationTypes := []*ast.OperationTypeDefinition{}
+ for _, op := range operationTypesI {
+ if op, ok := op.(*ast.OperationTypeDefinition); ok {
+ operationTypes = append(operationTypes, op)
+ }
+ }
+ return ast.NewSchemaDefinition(&ast.SchemaDefinition{
+ OperationTypes: operationTypes,
+ Directives: directives,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+func parseOperationTypeDefinition(parser *Parser) (interface{}, error) {
+ start := parser.Token.Start
+ operation, err := parseOperationType(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expect(parser, lexer.TokenKind[lexer.COLON])
+ if err != nil {
+ return nil, err
+ }
+ ttype, err := parseNamed(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewOperationTypeDefinition(&ast.OperationTypeDefinition{
+ Operation: operation,
+ Type: ttype,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * ScalarTypeDefinition : Description? scalar Name Directives?
+ */
+func parseScalarTypeDefinition(parser *Parser) (*ast.ScalarDefinition, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expectKeyWord(parser, "scalar")
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ def := ast.NewScalarDefinition(&ast.ScalarDefinition{
+ Name: name,
+ Description: description,
+ Directives: directives,
+ Loc: loc(parser, start),
+ })
+ return def, nil
+}
+
+/**
+ * ObjectTypeDefinition :
+ * Description?
+ * type Name ImplementsInterfaces? Directives? { FieldDefinition+ }
+ */
+func parseObjectTypeDefinition(parser *Parser) (*ast.ObjectDefinition, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expectKeyWord(parser, "type")
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ interfaces, err := parseImplementsInterfaces(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ iFields, err := any(parser, lexer.TokenKind[lexer.BRACE_L], parseFieldDefinition, lexer.TokenKind[lexer.BRACE_R])
+ if err != nil {
+ return nil, err
+ }
+ fields := []*ast.FieldDefinition{}
+ for _, iField := range iFields {
+ if iField != nil {
+ fields = append(fields, iField.(*ast.FieldDefinition))
+ }
+ }
+ return ast.NewObjectDefinition(&ast.ObjectDefinition{
+ Name: name,
+ Description: description,
+ Loc: loc(parser, start),
+ Interfaces: interfaces,
+ Directives: directives,
+ Fields: fields,
+ }), nil
+}
+
+/**
+ * ImplementsInterfaces : implements NamedType+
+ */
+func parseImplementsInterfaces(parser *Parser) ([]*ast.Named, error) {
+ types := []*ast.Named{}
+ if parser.Token.Value == "implements" {
+ if err := advance(parser); err != nil {
+ return nil, err
+ }
+ for {
+ ttype, err := parseNamed(parser)
+ if err != nil {
+ return types, err
+ }
+ types = append(types, ttype)
+ if !peek(parser, lexer.TokenKind[lexer.NAME]) {
+ break
+ }
+ }
+ }
+ return types, nil
+}
+
+/**
+ * FieldDefinition : Description? Name ArgumentsDefinition? : Type Directives?
+ */
+func parseFieldDefinition(parser *Parser) (interface{}, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ args, err := parseArgumentDefs(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expect(parser, lexer.TokenKind[lexer.COLON])
+ if err != nil {
+ return nil, err
+ }
+ ttype, err := parseType(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewFieldDefinition(&ast.FieldDefinition{
+ Name: name,
+ Description: description,
+ Arguments: args,
+ Type: ttype,
+ Directives: directives,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * ArgumentsDefinition : ( InputValueDefinition+ )
+ */
+func parseArgumentDefs(parser *Parser) ([]*ast.InputValueDefinition, error) {
+ inputValueDefinitions := []*ast.InputValueDefinition{}
+
+ if !peek(parser, lexer.TokenKind[lexer.PAREN_L]) {
+ return inputValueDefinitions, nil
+ }
+ iInputValueDefinitions, err := many(parser, lexer.TokenKind[lexer.PAREN_L], parseInputValueDef, lexer.TokenKind[lexer.PAREN_R])
+ if err != nil {
+ return inputValueDefinitions, err
+ }
+ for _, iInputValueDefinition := range iInputValueDefinitions {
+ if iInputValueDefinition != nil {
+ inputValueDefinitions = append(inputValueDefinitions, iInputValueDefinition.(*ast.InputValueDefinition))
+ }
+ }
+ return inputValueDefinitions, err
+}
+
+/**
+ * InputValueDefinition : Description? Name : Type DefaultValue? Directives?
+ */
+func parseInputValueDef(parser *Parser) (interface{}, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expect(parser, lexer.TokenKind[lexer.COLON])
+ if err != nil {
+ return nil, err
+ }
+ ttype, err := parseType(parser)
+ if err != nil {
+ return nil, err
+ }
+ var defaultValue ast.Value
+ if skp, err := skip(parser, lexer.TokenKind[lexer.EQUALS]); err != nil {
+ return nil, err
+ } else if skp {
+ val, err := parseConstValue(parser)
+ if err != nil {
+ return nil, err
+ }
+ if val, ok := val.(ast.Value); ok {
+ defaultValue = val
+ }
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewInputValueDefinition(&ast.InputValueDefinition{
+ Name: name,
+ Description: description,
+ Type: ttype,
+ DefaultValue: defaultValue,
+ Directives: directives,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * InterfaceTypeDefinition :
+ * Description?
+ * interface Name Directives? { FieldDefinition+ }
+ */
+func parseInterfaceTypeDefinition(parser *Parser) (*ast.InterfaceDefinition, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expectKeyWord(parser, "interface")
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ iFields, err := any(parser, lexer.TokenKind[lexer.BRACE_L], parseFieldDefinition, lexer.TokenKind[lexer.BRACE_R])
+ if err != nil {
+ return nil, err
+ }
+ fields := []*ast.FieldDefinition{}
+ for _, iField := range iFields {
+ if iField != nil {
+ fields = append(fields, iField.(*ast.FieldDefinition))
+ }
+ }
+ return ast.NewInterfaceDefinition(&ast.InterfaceDefinition{
+ Name: name,
+ Description: description,
+ Directives: directives,
+ Loc: loc(parser, start),
+ Fields: fields,
+ }), nil
+}
+
+/**
+ * UnionTypeDefinition : Description? union Name Directives? = UnionMembers
+ */
+func parseUnionTypeDefinition(parser *Parser) (*ast.UnionDefinition, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expectKeyWord(parser, "union")
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expect(parser, lexer.TokenKind[lexer.EQUALS])
+ if err != nil {
+ return nil, err
+ }
+ types, err := parseUnionMembers(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewUnionDefinition(&ast.UnionDefinition{
+ Name: name,
+ Description: description,
+ Directives: directives,
+ Loc: loc(parser, start),
+ Types: types,
+ }), nil
+}
+
+/**
+ * UnionMembers :
+ * - NamedType
+ * - UnionMembers | NamedType
+ */
+func parseUnionMembers(parser *Parser) ([]*ast.Named, error) {
+ members := []*ast.Named{}
+ for {
+ member, err := parseNamed(parser)
+ if err != nil {
+ return members, err
+ }
+ members = append(members, member)
+ if skp, err := skip(parser, lexer.TokenKind[lexer.PIPE]); err != nil {
+ return nil, err
+ } else if !skp {
+ break
+ }
+ }
+ return members, nil
+}
+
+/**
+ * EnumTypeDefinition : Description? enum Name Directives? { EnumValueDefinition+ }
+ */
+func parseEnumTypeDefinition(parser *Parser) (*ast.EnumDefinition, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expectKeyWord(parser, "enum")
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ iEnumValueDefs, err := any(parser, lexer.TokenKind[lexer.BRACE_L], parseEnumValueDefinition, lexer.TokenKind[lexer.BRACE_R])
+ if err != nil {
+ return nil, err
+ }
+ values := []*ast.EnumValueDefinition{}
+ for _, iEnumValueDef := range iEnumValueDefs {
+ if iEnumValueDef != nil {
+ values = append(values, iEnumValueDef.(*ast.EnumValueDefinition))
+ }
+ }
+ return ast.NewEnumDefinition(&ast.EnumDefinition{
+ Name: name,
+ Description: description,
+ Directives: directives,
+ Loc: loc(parser, start),
+ Values: values,
+ }), nil
+}
+
+/**
+ * EnumValueDefinition : Description? EnumValue Directives?
+ *
+ * EnumValue : Name
+ */
+func parseEnumValueDefinition(parser *Parser) (interface{}, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewEnumValueDefinition(&ast.EnumValueDefinition{
+ Name: name,
+ Description: description,
+ Directives: directives,
+ Loc: loc(parser, start),
+ }), nil
+}
+
+/**
+ * InputObjectTypeDefinition :
+ * - Description? input Name Directives? { InputValueDefinition+ }
+ */
+func parseInputObjectTypeDefinition(parser *Parser) (*ast.InputObjectDefinition, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expectKeyWord(parser, "input")
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ directives, err := parseDirectives(parser)
+ if err != nil {
+ return nil, err
+ }
+ iInputValueDefinitions, err := any(parser, lexer.TokenKind[lexer.BRACE_L], parseInputValueDef, lexer.TokenKind[lexer.BRACE_R])
+ if err != nil {
+ return nil, err
+ }
+ fields := []*ast.InputValueDefinition{}
+ for _, iInputValueDefinition := range iInputValueDefinitions {
+ if iInputValueDefinition != nil {
+ fields = append(fields, iInputValueDefinition.(*ast.InputValueDefinition))
+ }
+ }
+ return ast.NewInputObjectDefinition(&ast.InputObjectDefinition{
+ Name: name,
+ Description: description,
+ Directives: directives,
+ Loc: loc(parser, start),
+ Fields: fields,
+ }), nil
+}
+
+/**
+ * TypeExtensionDefinition : extend ObjectTypeDefinition
+ */
+func parseTypeExtensionDefinition(parser *Parser) (*ast.TypeExtensionDefinition, error) {
+ start := parser.Token.Start
+ _, err := expectKeyWord(parser, "extend")
+ if err != nil {
+ return nil, err
+ }
+
+ definition, err := parseObjectTypeDefinition(parser)
+ if err != nil {
+ return nil, err
+ }
+ return ast.NewTypeExtensionDefinition(&ast.TypeExtensionDefinition{
+ Loc: loc(parser, start),
+ Definition: definition,
+ }), nil
+}
+
+/**
+ * DirectiveDefinition :
+ * - directive @ Name ArgumentsDefinition? on DirectiveLocations
+ */
+func parseDirectiveDefinition(parser *Parser) (*ast.DirectiveDefinition, error) {
+ start := parser.Token.Start
+ description, err := parseDescription(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expectKeyWord(parser, "directive")
+ if err != nil {
+ return nil, err
+ }
+ _, err = expect(parser, lexer.TokenKind[lexer.AT])
+ if err != nil {
+ return nil, err
+ }
+ name, err := parseName(parser)
+ if err != nil {
+ return nil, err
+ }
+ args, err := parseArgumentDefs(parser)
+ if err != nil {
+ return nil, err
+ }
+ _, err = expectKeyWord(parser, "on")
+ if err != nil {
+ return nil, err
+ }
+ locations, err := parseDirectiveLocations(parser)
+ if err != nil {
+ return nil, err
+ }
+
+ return ast.NewDirectiveDefinition(&ast.DirectiveDefinition{
+ Loc: loc(parser, start),
+ Name: name,
+ Description: description,
+ Arguments: args,
+ Locations: locations,
+ }), nil
+}
+
+/**
+ * DirectiveLocations :
+ * - Name
+ * - DirectiveLocations | Name
+ */
+func parseDirectiveLocations(parser *Parser) ([]*ast.Name, error) {
+ locations := []*ast.Name{}
+ for {
+ name, err := parseName(parser)
+ if err != nil {
+ return locations, err
+ }
+ locations = append(locations, name)
+
+ hasPipe, err := skip(parser, lexer.TokenKind[lexer.PIPE])
+ if err != nil {
+ return locations, err
+ }
+ if !hasPipe {
+ break
+ }
+ }
+ return locations, nil
+}
+
+func parseStringLiteral(parser *Parser) (*ast.StringValue, error) {
+ token := parser.Token
+ if err := advance(parser); err != nil {
+ return nil, err
+ }
+ return ast.NewStringValue(&ast.StringValue{
+ Value: token.Value,
+ Loc: loc(parser, token.Start),
+ }), nil
+}
+
+/**
+ * Description : StringValue
+ */
+func parseDescription(parser *Parser) (*ast.StringValue, error) {
+ if peekDescription(parser) {
+ return parseStringLiteral(parser)
+ }
+ return nil, nil
+}
+
+/* Core parsing utility functions */
+
+// Returns a location object, used to identify the place in
+// the source that created a given parsed object.
+func loc(parser *Parser, start int) *ast.Location {
+ if parser.Options.NoLocation {
+ return nil
+ }
+ if parser.Options.NoSource {
+ return ast.NewLocation(&ast.Location{
+ Start: start,
+ End: parser.PrevEnd,
+ })
+ }
+ return ast.NewLocation(&ast.Location{
+ Start: start,
+ End: parser.PrevEnd,
+ Source: parser.Source,
+ })
+}
+
+// Moves the internal parser object to the next lexed token.
+func advance(parser *Parser) error {
+ prevEnd := parser.Token.End
+ parser.PrevEnd = prevEnd
+ token, err := parser.LexToken(prevEnd)
+ if err != nil {
+ return err
+ }
+ parser.Token = token
+ return nil
+}
+
+// lookahead retrieves the next token
+func lookahead(parser *Parser) (lexer.Token, error) {
+ prevEnd := parser.Token.End
+ return parser.LexToken(prevEnd)
+}
+
+// Determines if the next token is of a given kind
+func peek(parser *Parser, Kind int) bool {
+ return parser.Token.Kind == Kind
+}
+
+// peekDescription determines if the next token is a string value
+func peekDescription(parser *Parser) bool {
+ return peek(parser, lexer.STRING) || peek(parser, lexer.BLOCK_STRING)
+}
+
+// If the next token is of the given kind, return true after advancing
+// the parser. Otherwise, do not change the parser state and return false.
+func skip(parser *Parser, Kind int) (bool, error) {
+ if parser.Token.Kind == Kind {
+ err := advance(parser)
+ return true, err
+ }
+ return false, nil
+}
+
+// If the next token is of the given kind, return that token after advancing
+// the parser. Otherwise, do not change the parser state and return error.
+func expect(parser *Parser, kind int) (lexer.Token, error) {
+ token := parser.Token
+ if token.Kind == kind {
+ err := advance(parser)
+ return token, err
+ }
+ descp := fmt.Sprintf("Expected %s, found %s", lexer.GetTokenKindDesc(kind), lexer.GetTokenDesc(token))
+ return token, gqlerrors.NewSyntaxError(parser.Source, token.Start, descp)
+}
+
+// If the next token is a keyword with the given value, return that token after
+// advancing the parser. Otherwise, do not change the parser state and return false.
+func expectKeyWord(parser *Parser, value string) (lexer.Token, error) {
+ token := parser.Token
+ if token.Kind == lexer.TokenKind[lexer.NAME] && token.Value == value {
+ err := advance(parser)
+ return token, err
+ }
+ descp := fmt.Sprintf("Expected \"%s\", found %s", value, lexer.GetTokenDesc(token))
+ return token, gqlerrors.NewSyntaxError(parser.Source, token.Start, descp)
+}
+
+// Helper function for creating an error when an unexpected lexed token
+// is encountered.
+func unexpected(parser *Parser, atToken lexer.Token) error {
+ var token lexer.Token
+ if (atToken == lexer.Token{}) {
+ token = parser.Token
+ } else {
+ token = parser.Token
+ }
+ description := fmt.Sprintf("Unexpected %v", lexer.GetTokenDesc(token))
+ return gqlerrors.NewSyntaxError(parser.Source, token.Start, description)
+}
+
+// Returns a possibly empty list of parse nodes, determined by
+// the parseFn. This list begins with a lex token of openKind
+// and ends with a lex token of closeKind. Advances the parser
+// to the next lex token after the closing token.
+func any(parser *Parser, openKind int, parseFn parseFn, closeKind int) ([]interface{}, error) {
+ var nodes []interface{}
+ _, err := expect(parser, openKind)
+ if err != nil {
+ return nodes, nil
+ }
+ for {
+ if skp, err := skip(parser, closeKind); err != nil {
+ return nil, err
+ } else if skp {
+ break
+ }
+ n, err := parseFn(parser)
+ if err != nil {
+ return nodes, err
+ }
+ nodes = append(nodes, n)
+ }
+ return nodes, nil
+}
+
+// Returns a non-empty list of parse nodes, determined by
+// the parseFn. This list begins with a lex token of openKind
+// and ends with a lex token of closeKind. Advances the parser
+// to the next lex token after the closing token.
+func many(parser *Parser, openKind int, parseFn parseFn, closeKind int) ([]interface{}, error) {
+ _, err := expect(parser, openKind)
+ if err != nil {
+ return nil, err
+ }
+ var nodes []interface{}
+ node, err := parseFn(parser)
+ if err != nil {
+ return nodes, err
+ }
+ nodes = append(nodes, node)
+ for {
+ if skp, err := skip(parser, closeKind); err != nil {
+ return nil, err
+ } else if skp {
+ break
+ }
+ node, err := parseFn(parser)
+ if err != nil {
+ return nodes, err
+ }
+ nodes = append(nodes, node)
+ }
+ return nodes, nil
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/printer/printer.go b/vendor/github.com/graphql-go/graphql/language/printer/printer.go
new file mode 100644
index 00000000..3add3852
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/printer/printer.go
@@ -0,0 +1,821 @@
+package printer
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/graphql-go/graphql/language/ast"
+ "github.com/graphql-go/graphql/language/visitor"
+ "reflect"
+)
+
+func getMapValue(m map[string]interface{}, key string) interface{} {
+ tokens := strings.Split(key, ".")
+ valMap := m
+ for _, token := range tokens {
+ v, ok := valMap[token]
+ if !ok {
+ return nil
+ }
+ switch v := v.(type) {
+ case []interface{}:
+ return v
+ case map[string]interface{}:
+ valMap = v
+ continue
+ default:
+ return v
+ }
+ }
+ return valMap
+}
+func getMapSliceValue(m map[string]interface{}, key string) []interface{} {
+ tokens := strings.Split(key, ".")
+ valMap := m
+ for _, token := range tokens {
+ v, ok := valMap[token]
+ if !ok {
+ return []interface{}{}
+ }
+ switch v := v.(type) {
+ case []interface{}:
+ return v
+ default:
+ return []interface{}{}
+ }
+ }
+ return []interface{}{}
+}
+func getMapValueString(m map[string]interface{}, key string) string {
+ tokens := strings.Split(key, ".")
+ valMap := m
+ for _, token := range tokens {
+ v, ok := valMap[token]
+ if !ok {
+ return ""
+ }
+ if v == nil {
+ return ""
+ }
+ switch v := v.(type) {
+ case map[string]interface{}:
+ valMap = v
+ continue
+ case string:
+ return v
+ default:
+ return fmt.Sprintf("%v", v)
+ }
+ }
+ return ""
+}
+
+func toSliceString(slice interface{}) []string {
+ if slice == nil {
+ return []string{}
+ }
+ res := []string{}
+ switch reflect.TypeOf(slice).Kind() {
+ case reflect.Slice:
+ s := reflect.ValueOf(slice)
+ for i := 0; i < s.Len(); i++ {
+ elem := s.Index(i)
+ elemInterface := elem.Interface()
+ if elem, ok := elemInterface.(string); ok {
+ res = append(res, elem)
+ }
+ }
+ return res
+ default:
+ return res
+ }
+}
+
+func join(str []string, sep string) string {
+ ss := []string{}
+ // filter out empty strings
+ for _, s := range str {
+ if s == "" {
+ continue
+ }
+ ss = append(ss, s)
+ }
+ return strings.Join(ss, sep)
+}
+
+func wrap(start, maybeString, end string) string {
+ if maybeString == "" {
+ return maybeString
+ }
+ return start + maybeString + end
+}
+
+// Given array, print each item on its own line, wrapped in an indented "{ }" block.
+func block(maybeArray interface{}) string {
+ s := toSliceString(maybeArray)
+ if len(s) == 0 {
+ return "{}"
+ }
+ return indent("{\n"+join(s, "\n")) + "\n}"
+}
+
+func indent(maybeString interface{}) string {
+ if maybeString == nil {
+ return ""
+ }
+ switch str := maybeString.(type) {
+ case string:
+ return strings.Replace(str, "\n", "\n ", -1)
+ }
+ return ""
+}
+
+var printDocASTReducer = map[string]visitor.VisitFunc{
+ "Name": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.Name:
+ return visitor.ActionUpdate, node.Value
+ case map[string]interface{}:
+ return visitor.ActionUpdate, getMapValue(node, "Value")
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "Variable": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.Variable:
+ return visitor.ActionUpdate, fmt.Sprintf("$%v", node.Name)
+ case map[string]interface{}:
+ return visitor.ActionUpdate, "$" + getMapValueString(node, "Name")
+ }
+ return visitor.ActionNoChange, nil
+ },
+
+ // Document
+ "Document": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.Document:
+ definitions := toSliceString(node.Definitions)
+ return visitor.ActionUpdate, join(definitions, "\n\n") + "\n"
+ case map[string]interface{}:
+ definitions := toSliceString(getMapValue(node, "Definitions"))
+ return visitor.ActionUpdate, join(definitions, "\n\n") + "\n"
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "OperationDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.OperationDefinition:
+ op := string(node.Operation)
+ name := fmt.Sprintf("%v", node.Name)
+
+ varDefs := wrap("(", join(toSliceString(node.VariableDefinitions), ", "), ")")
+ directives := join(toSliceString(node.Directives), " ")
+ selectionSet := fmt.Sprintf("%v", node.SelectionSet)
+ // Anonymous queries with no directives or variable definitions can use
+ // the query short form.
+ str := ""
+ if name == "" && directives == "" && varDefs == "" && op == ast.OperationTypeQuery {
+ str = selectionSet
+ } else {
+ str = join([]string{
+ op,
+ join([]string{name, varDefs}, ""),
+ directives,
+ selectionSet,
+ }, " ")
+ }
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+
+ op := getMapValueString(node, "Operation")
+ name := getMapValueString(node, "Name")
+
+ varDefs := wrap("(", join(toSliceString(getMapValue(node, "VariableDefinitions")), ", "), ")")
+ directives := join(toSliceString(getMapValue(node, "Directives")), " ")
+ selectionSet := getMapValueString(node, "SelectionSet")
+ str := ""
+ if name == "" && directives == "" && varDefs == "" && op == ast.OperationTypeQuery {
+ str = selectionSet
+ } else {
+ str = join([]string{
+ op,
+ join([]string{name, varDefs}, ""),
+ directives,
+ selectionSet,
+ }, " ")
+ }
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "VariableDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.VariableDefinition:
+ variable := fmt.Sprintf("%v", node.Variable)
+ ttype := fmt.Sprintf("%v", node.Type)
+ defaultValue := fmt.Sprintf("%v", node.DefaultValue)
+
+ return visitor.ActionUpdate, variable + ": " + ttype + wrap(" = ", defaultValue, "")
+ case map[string]interface{}:
+
+ variable := getMapValueString(node, "Variable")
+ ttype := getMapValueString(node, "Type")
+ defaultValue := getMapValueString(node, "DefaultValue")
+
+ return visitor.ActionUpdate, variable + ": " + ttype + wrap(" = ", defaultValue, "")
+
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "SelectionSet": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.SelectionSet:
+ str := block(node.Selections)
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ selections := getMapValue(node, "Selections")
+ str := block(selections)
+ return visitor.ActionUpdate, str
+
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "Field": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.Argument:
+ name := fmt.Sprintf("%v", node.Name)
+ value := fmt.Sprintf("%v", node.Value)
+ return visitor.ActionUpdate, name + ": " + value
+ case map[string]interface{}:
+
+ alias := getMapValueString(node, "Alias")
+ name := getMapValueString(node, "Name")
+ args := toSliceString(getMapValue(node, "Arguments"))
+ directives := toSliceString(getMapValue(node, "Directives"))
+ selectionSet := getMapValueString(node, "SelectionSet")
+
+ str := join(
+ []string{
+ wrap("", alias, ": ") + name + wrap("(", join(args, ", "), ")"),
+ join(directives, " "),
+ selectionSet,
+ },
+ " ",
+ )
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "Argument": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.FragmentSpread:
+ name := fmt.Sprintf("%v", node.Name)
+ directives := toSliceString(node.Directives)
+ return visitor.ActionUpdate, "..." + name + wrap(" ", join(directives, " "), "")
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ value := getMapValueString(node, "Value")
+ return visitor.ActionUpdate, name + ": " + value
+ }
+ return visitor.ActionNoChange, nil
+ },
+
+ // Fragments
+ "FragmentSpread": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.InlineFragment:
+ typeCondition := fmt.Sprintf("%v", node.TypeCondition)
+ directives := toSliceString(node.Directives)
+ selectionSet := fmt.Sprintf("%v", node.SelectionSet)
+ return visitor.ActionUpdate, "... on " + typeCondition + " " + wrap("", join(directives, " "), " ") + selectionSet
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ directives := toSliceString(getMapValue(node, "Directives"))
+ return visitor.ActionUpdate, "..." + name + wrap(" ", join(directives, " "), "")
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "InlineFragment": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case map[string]interface{}:
+ typeCondition := getMapValueString(node, "TypeCondition")
+ directives := toSliceString(getMapValue(node, "Directives"))
+ selectionSet := getMapValueString(node, "SelectionSet")
+ return visitor.ActionUpdate,
+ join([]string{
+ "...",
+ wrap("on ", typeCondition, ""),
+ join(directives, " "),
+ selectionSet,
+ }, " ")
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "FragmentDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.FragmentDefinition:
+ name := fmt.Sprintf("%v", node.Name)
+ typeCondition := fmt.Sprintf("%v", node.TypeCondition)
+ directives := toSliceString(node.Directives)
+ selectionSet := fmt.Sprintf("%v", node.SelectionSet)
+ return visitor.ActionUpdate, "fragment " + name + " on " + typeCondition + " " + wrap("", join(directives, " "), " ") + selectionSet
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ typeCondition := getMapValueString(node, "TypeCondition")
+ directives := toSliceString(getMapValue(node, "Directives"))
+ selectionSet := getMapValueString(node, "SelectionSet")
+ return visitor.ActionUpdate, "fragment " + name + " on " + typeCondition + " " + wrap("", join(directives, " "), " ") + selectionSet
+ }
+ return visitor.ActionNoChange, nil
+ },
+
+ // Value
+ "IntValue": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.IntValue:
+ return visitor.ActionUpdate, fmt.Sprintf("%v", node.Value)
+ case map[string]interface{}:
+ return visitor.ActionUpdate, getMapValueString(node, "Value")
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "FloatValue": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.FloatValue:
+ return visitor.ActionUpdate, fmt.Sprintf("%v", node.Value)
+ case map[string]interface{}:
+ return visitor.ActionUpdate, getMapValueString(node, "Value")
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "StringValue": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.StringValue:
+ return visitor.ActionUpdate, `"` + fmt.Sprintf("%v", node.Value) + `"`
+ case map[string]interface{}:
+ return visitor.ActionUpdate, `"` + getMapValueString(node, "Value") + `"`
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "BooleanValue": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.BooleanValue:
+ return visitor.ActionUpdate, fmt.Sprintf("%v", node.Value)
+ case map[string]interface{}:
+ return visitor.ActionUpdate, getMapValueString(node, "Value")
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "EnumValue": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.EnumValue:
+ return visitor.ActionUpdate, fmt.Sprintf("%v", node.Value)
+ case map[string]interface{}:
+ return visitor.ActionUpdate, getMapValueString(node, "Value")
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "ListValue": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.ListValue:
+ return visitor.ActionUpdate, "[" + join(toSliceString(node.Values), ", ") + "]"
+ case map[string]interface{}:
+ return visitor.ActionUpdate, "[" + join(toSliceString(getMapValue(node, "Values")), ", ") + "]"
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "ObjectValue": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.ObjectValue:
+ return visitor.ActionUpdate, "{" + join(toSliceString(node.Fields), ", ") + "}"
+ case map[string]interface{}:
+ return visitor.ActionUpdate, "{" + join(toSliceString(getMapValue(node, "Fields")), ", ") + "}"
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "ObjectField": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.ObjectField:
+ name := fmt.Sprintf("%v", node.Name)
+ value := fmt.Sprintf("%v", node.Value)
+ return visitor.ActionUpdate, name + ": " + value
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ value := getMapValueString(node, "Value")
+ return visitor.ActionUpdate, name + ": " + value
+ }
+ return visitor.ActionNoChange, nil
+ },
+
+ // Directive
+ "Directive": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.Directive:
+ name := fmt.Sprintf("%v", node.Name)
+ args := toSliceString(node.Arguments)
+ return visitor.ActionUpdate, "@" + name + wrap("(", join(args, ", "), ")")
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ args := toSliceString(getMapValue(node, "Arguments"))
+ return visitor.ActionUpdate, "@" + name + wrap("(", join(args, ", "), ")")
+ }
+ return visitor.ActionNoChange, nil
+ },
+
+ // Type
+ "Named": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.Named:
+ return visitor.ActionUpdate, fmt.Sprintf("%v", node.Name)
+ case map[string]interface{}:
+ return visitor.ActionUpdate, getMapValueString(node, "Name")
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "List": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.List:
+ return visitor.ActionUpdate, "[" + fmt.Sprintf("%v", node.Type) + "]"
+ case map[string]interface{}:
+ return visitor.ActionUpdate, "[" + getMapValueString(node, "Type") + "]"
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "NonNull": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.NonNull:
+ return visitor.ActionUpdate, fmt.Sprintf("%v", node.Type) + "!"
+ case map[string]interface{}:
+ return visitor.ActionUpdate, getMapValueString(node, "Type") + "!"
+ }
+ return visitor.ActionNoChange, nil
+ },
+
+ // Type System Definitions
+ "SchemaDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.SchemaDefinition:
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := join([]string{
+ "schema",
+ join(directives, " "),
+ block(node.OperationTypes),
+ }, " ")
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ operationTypes := toSliceString(getMapValue(node, "OperationTypes"))
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := join([]string{
+ "schema",
+ join(directives, " "),
+ block(operationTypes),
+ }, " ")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "OperationTypeDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.OperationTypeDefinition:
+ str := fmt.Sprintf("%v: %v", node.Operation, node.Type)
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ operation := getMapValueString(node, "Operation")
+ ttype := getMapValueString(node, "Type")
+ str := fmt.Sprintf("%v: %v", operation, ttype)
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "ScalarDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.ScalarDefinition:
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := join([]string{
+ "scalar",
+ fmt.Sprintf("%v", node.Name),
+ join(directives, " "),
+ }, " ")
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := join([]string{
+ "scalar",
+ name,
+ join(directives, " "),
+ }, " ")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "ObjectDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.ObjectDefinition:
+ name := fmt.Sprintf("%v", node.Name)
+ interfaces := toSliceString(node.Interfaces)
+ fields := node.Fields
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := join([]string{
+ "type",
+ name,
+ wrap("implements ", join(interfaces, ", "), ""),
+ join(directives, " "),
+ block(fields),
+ }, " ")
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ interfaces := toSliceString(getMapValue(node, "Interfaces"))
+ fields := getMapValue(node, "Fields")
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := join([]string{
+ "type",
+ name,
+ wrap("implements ", join(interfaces, ", "), ""),
+ join(directives, " "),
+ block(fields),
+ }, " ")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "FieldDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.FieldDefinition:
+ name := fmt.Sprintf("%v", node.Name)
+ ttype := fmt.Sprintf("%v", node.Type)
+ args := toSliceString(node.Arguments)
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := name + wrap("(", join(args, ", "), ")") + ": " + ttype + wrap(" ", join(directives, " "), "")
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ ttype := getMapValueString(node, "Type")
+ args := toSliceString(getMapValue(node, "Arguments"))
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := name + wrap("(", join(args, ", "), ")") + ": " + ttype + wrap(" ", join(directives, " "), "")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "InputValueDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.InputValueDefinition:
+ name := fmt.Sprintf("%v", node.Name)
+ ttype := fmt.Sprintf("%v", node.Type)
+ defaultValue := fmt.Sprintf("%v", node.DefaultValue)
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := join([]string{
+ name + ": " + ttype,
+ wrap("= ", defaultValue, ""),
+ join(directives, " "),
+ }, " ")
+
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ ttype := getMapValueString(node, "Type")
+ defaultValue := getMapValueString(node, "DefaultValue")
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := join([]string{
+ name + ": " + ttype,
+ wrap("= ", defaultValue, ""),
+ join(directives, " "),
+ }, " ")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "InterfaceDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.InterfaceDefinition:
+ name := fmt.Sprintf("%v", node.Name)
+ fields := node.Fields
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := join([]string{
+ "interface",
+ name,
+ join(directives, " "),
+ block(fields),
+ }, " ")
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ fields := getMapValue(node, "Fields")
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := join([]string{
+ "interface",
+ name,
+ join(directives, " "),
+ block(fields),
+ }, " ")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "UnionDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.UnionDefinition:
+ name := fmt.Sprintf("%v", node.Name)
+ types := toSliceString(node.Types)
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := join([]string{
+ "union",
+ name,
+ join(directives, " "),
+ "= " + join(types, " | "),
+ }, " ")
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ types := toSliceString(getMapValue(node, "Types"))
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := join([]string{
+ "union",
+ name,
+ join(directives, " "),
+ "= " + join(types, " | "),
+ }, " ")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "EnumDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.EnumDefinition:
+ name := fmt.Sprintf("%v", node.Name)
+ values := node.Values
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := join([]string{
+ "enum",
+ name,
+ join(directives, " "),
+ block(values),
+ }, " ")
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ values := getMapValue(node, "Values")
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := join([]string{
+ "enum",
+ name,
+ join(directives, " "),
+ block(values),
+ }, " ")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "EnumValueDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.EnumValueDefinition:
+ name := fmt.Sprintf("%v", node.Name)
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := join([]string{
+ name,
+ join(directives, " "),
+ }, " ")
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := join([]string{
+ name,
+ join(directives, " "),
+ }, " ")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "InputObjectDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.InputObjectDefinition:
+ name := fmt.Sprintf("%v", node.Name)
+ fields := node.Fields
+ directives := []string{}
+ for _, directive := range node.Directives {
+ directives = append(directives, fmt.Sprintf("%v", directive.Name))
+ }
+ str := join([]string{
+ "input",
+ name,
+ join(directives, " "),
+ block(fields),
+ }, " ")
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ fields := getMapValue(node, "Fields")
+ directives := []string{}
+ for _, directive := range getMapSliceValue(node, "Directives") {
+ directives = append(directives, fmt.Sprintf("%v", directive))
+ }
+ str := join([]string{
+ "input",
+ name,
+ join(directives, " "),
+ block(fields),
+ }, " ")
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "TypeExtensionDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.TypeExtensionDefinition:
+ definition := fmt.Sprintf("%v", node.Definition)
+ str := "extend " + definition
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ definition := getMapValueString(node, "Definition")
+ str := "extend " + definition
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+ "DirectiveDefinition": func(p visitor.VisitFuncParams) (string, interface{}) {
+ switch node := p.Node.(type) {
+ case *ast.DirectiveDefinition:
+ args := wrap("(", join(toSliceString(node.Arguments), ", "), ")")
+ str := fmt.Sprintf("directive @%v%v on %v", node.Name, args, join(toSliceString(node.Locations), " | "))
+ return visitor.ActionUpdate, str
+ case map[string]interface{}:
+ name := getMapValueString(node, "Name")
+ locations := toSliceString(getMapValue(node, "Locations"))
+ args := toSliceString(getMapValue(node, "Arguments"))
+ argsStr := wrap("(", join(args, ", "), ")")
+ str := fmt.Sprintf("directive @%v%v on %v", name, argsStr, join(locations, " | "))
+ return visitor.ActionUpdate, str
+ }
+ return visitor.ActionNoChange, nil
+ },
+}
+
+func Print(astNode ast.Node) (printed interface{}) {
+ defer func() interface{} {
+ if r := recover(); r != nil {
+ return fmt.Sprintf("%v", astNode)
+ }
+ return printed
+ }()
+ printed = visitor.Visit(astNode, &visitor.VisitorOptions{
+ LeaveKindMap: printDocASTReducer,
+ }, nil)
+ return printed
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/source/source.go b/vendor/github.com/graphql-go/graphql/language/source/source.go
new file mode 100644
index 00000000..f14af003
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/source/source.go
@@ -0,0 +1,20 @@
+package source
+
+const (
+ name = "GraphQL"
+)
+
+type Source struct {
+ Body []byte
+ Name string
+}
+
+func NewSource(s *Source) *Source {
+ if s == nil {
+ s = &Source{Name: name}
+ }
+ if s.Name == "" {
+ s.Name = name
+ }
+ return s
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/typeInfo/type_info.go b/vendor/github.com/graphql-go/graphql/language/typeInfo/type_info.go
new file mode 100644
index 00000000..e012ee02
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/typeInfo/type_info.go
@@ -0,0 +1,11 @@
+package typeInfo
+
+import (
+ "github.com/graphql-go/graphql/language/ast"
+)
+
+// TypeInfoI defines the interface for TypeInfo Implementation
+type TypeInfoI interface {
+ Enter(node ast.Node)
+ Leave(node ast.Node)
+}
diff --git a/vendor/github.com/graphql-go/graphql/language/visitor/visitor.go b/vendor/github.com/graphql-go/graphql/language/visitor/visitor.go
new file mode 100644
index 00000000..9a1c2ac2
--- /dev/null
+++ b/vendor/github.com/graphql-go/graphql/language/visitor/visitor.go
@@ -0,0 +1,873 @@
+package visitor
+
+import (
+ "encoding/json"
+ "fmt"
+ "github.com/graphql-go/graphql/language/ast"
+ "github.com/graphql-go/graphql/language/typeInfo"
+ "reflect"
+)
+
+const (
+ ActionNoChange = ""
+ ActionBreak = "BREAK"
+ ActionSkip = "SKIP"
+ ActionUpdate = "UPDATE"
+)
+
+type KeyMap map[string][]string
+
+// note that the keys are in Capital letters, equivalent to the ast.Node field Names
+var QueryDocumentKeys = KeyMap{
+ "Name": []string{},
+ "Document": []string{"Definitions"},
+ "OperationDefinition": []string{
+ "Name",
+ "VariableDefinitions",
+ "Directives",
+ "SelectionSet",
+ },
+ "VariableDefinition": []string{
+ "Variable",
+ "Type",
+ "DefaultValue",
+ },
+ "Variable": []string{"Name"},
+ "SelectionSet": []string{"Selections"},
+ "Field": []string{
+ "Alias",
+ "Name",
+ "Arguments",
+ "Directives",
+ "SelectionSet",
+ },
+ "Argument": []string{
+ "Name",
+ "Value",
+ },
+
+ "FragmentSpread": []string{
+ "Name",
+ "Directives",
+ },
+ "InlineFragment": []string{
+ "TypeCondition",
+ "Directives",
+ "SelectionSet",
+ },
+ "FragmentDefinition": []string{
+ "Name",
+ "TypeCondition",
+ "Directives",
+ "SelectionSet",
+ },
+
+ "IntValue": []string{},
+ "FloatValue": []string{},
+ "StringValue": []string{},
+ "BooleanValue": []string{},
+ "EnumValue": []string{},
+ "ListValue": []string{"Values"},
+ "ObjectValue": []string{"Fields"},
+ "ObjectField": []string{
+ "Name",
+ "Value",
+ },
+
+ "Directive": []string{
+ "Name",
+ "Arguments",
+ },
+
+ "Named": []string{"Name"},
+ "List": []string{"Type"},
+ "NonNull": []string{"Type"},
+
+ "SchemaDefinition": []string{
+ "Directives",
+ "OperationTypes",
+ },
+ "OperationTypeDefinition": []string{"Type"},
+
+ "ScalarDefinition": []string{
+ "Name",
+ "Directives",
+ },
+ "ObjectDefinition": []string{
+ "Name",
+ "Interfaces",
+ "Directives",
+ "Fields",
+ },
+ "FieldDefinition": []string{
+ "Name",
+ "Arguments",
+ "Type",
+ "Directives",
+ },
+ "InputValueDefinition": []string{
+ "Name",
+ "Type",
+ "DefaultValue",
+ "Directives",
+ },
+ "InterfaceDefinition": []string{
+ "Name",
+ "Directives",
+ "Fields",
+ },
+ "UnionDefinition": []string{
+ "Name",
+ "Directives",
+ "Types",
+ },
+ "EnumDefinition": []string{
+ "Name",
+ "Directives",
+ "Values",
+ },
+ "EnumValueDefinition": []string{
+ "Name",
+ "Directives",
+ },
+ "InputObjectDefinition": []string{
+ "Name",
+ "Directives",
+ "Fields",
+ },
+
+ "TypeExtensionDefinition": []string{"Definition"},
+
+ "DirectiveDefinition": []string{"Name", "Arguments", "Locations"},
+}
+
+type stack struct {
+ Index int
+ Keys []interface{}
+ Edits []*edit
+ inSlice bool
+ Prev *stack
+}
+type edit struct {
+ Key interface{}
+ Value interface{}
+}
+
+type VisitFuncParams struct {
+ Node interface{}
+ Key interface{}
+ Parent ast.Node
+ Path []interface{}
+ Ancestors []ast.Node
+}
+
+type VisitFunc func(p VisitFuncParams) (string, interface{})
+
+type NamedVisitFuncs struct {
+ Kind VisitFunc // 1) Named visitors triggered when entering a node a specific kind.
+ Leave VisitFunc // 2) Named visitors that trigger upon entering and leaving a node of
+ Enter VisitFunc // 2) Named visitors that trigger upon entering and leaving a node of
+}
+
+type VisitorOptions struct {
+ KindFuncMap map[string]NamedVisitFuncs
+ Enter VisitFunc // 3) Generic visitors that trigger upon entering and leaving any node.
+ Leave VisitFunc // 3) Generic visitors that trigger upon entering and leaving any node.
+
+ EnterKindMap map[string]VisitFunc // 4) Parallel visitors for entering and leaving nodes of a specific kind
+ LeaveKindMap map[string]VisitFunc // 4) Parallel visitors for entering and leaving nodes of a specific kind
+}
+
+func Visit(root ast.Node, visitorOpts *VisitorOptions, keyMap KeyMap) interface{} {
+ visitorKeys := keyMap
+ if visitorKeys == nil {
+ visitorKeys = QueryDocumentKeys
+ }
+
+ var result interface{}
+ var newRoot = root
+ var sstack *stack
+ var parent interface{}
+ var parentSlice []interface{}
+ inSlice := false
+ prevInSlice := false
+ keys := []interface{}{newRoot}
+ index := -1
+ edits := []*edit{}
+ path := []interface{}{}
+ ancestors := []interface{}{}
+ ancestorsSlice := [][]interface{}{}
+Loop:
+ for {
+ index = index + 1
+
+ isLeaving := (len(keys) == index)
+ var key interface{} // string for structs or int for slices
+ var node interface{} // ast.Node or can be anything
+ var nodeSlice []interface{}
+ isEdited := (isLeaving && len(edits) != 0)
+
+ if isLeaving {
+ if !inSlice {
+ if len(ancestors) == 0 {
+ key = nil
+ } else {
+ key, path = pop(path)
+ }
+ } else {
+ if len(ancestorsSlice) == 0 {
+ key = nil
+ } else {
+ key, path = pop(path)
+ }
+ }
+
+ node = parent
+ parent, ancestors = pop(ancestors)
+ nodeSlice = parentSlice
+ parentSlice, ancestorsSlice = popNodeSlice(ancestorsSlice)
+
+ if isEdited {
+ prevInSlice = inSlice
+ editOffset := 0
+ for _, edit := range edits {
+ arrayEditKey := 0
+ if inSlice {
+ keyInt := edit.Key.(int)
+ edit.Key = keyInt - editOffset
+ arrayEditKey = edit.Key.(int)
+ }
+ if inSlice && isNilNode(edit.Value) {
+ nodeSlice = spliceNode(nodeSlice, arrayEditKey)
+ editOffset = editOffset + 1
+ } else {
+ if inSlice {
+ nodeSlice[arrayEditKey] = edit.Value
+ } else {
+ key, _ := edit.Key.(string)
+
+ var updatedNode interface{}
+ if !isSlice(edit.Value) {
+ if isStructNode(edit.Value) {
+ updatedNode = updateNodeField(node, key, edit.Value)
+ } else {
+ var todoNode map[string]interface{}
+ b, err := json.Marshal(node)
+ if err != nil {
+ panic(fmt.Sprintf("Invalid root AST Node: %v", root))
+ }
+ err = json.Unmarshal(b, &todoNode)
+ if err != nil {
+ panic(fmt.Sprintf("Invalid root AST Node (2): %v", root))
+ }
+ todoNode[key] = edit.Value
+ updatedNode = todoNode
+ }
+ } else {
+ isSliceOfNodes := true
+
+ // check if edit.value slice is ast.nodes
+ switch reflect.TypeOf(edit.Value).Kind() {
+ case reflect.Slice:
+ s := reflect.ValueOf(edit.Value)
+ for i := 0; i < s.Len(); i++ {
+ elem := s.Index(i)
+ if !isStructNode(elem.Interface()) {
+ isSliceOfNodes = false
+ }
+ }
+ }
+
+ // is a slice of real nodes
+ if isSliceOfNodes {
+ // the node we are writing to is an ast.Node
+ updatedNode = updateNodeField(node, key, edit.Value)
+ } else {
+ var todoNode map[string]interface{}
+ b, err := json.Marshal(node)
+ if err != nil {
+ panic(fmt.Sprintf("Invalid root AST Node: %v", root))
+ }
+ err = json.Unmarshal(b, &todoNode)
+ if err != nil {
+ panic(fmt.Sprintf("Invalid root AST Node (2): %v", root))
+ }
+ todoNode[key] = edit.Value
+ updatedNode = todoNode
+ }
+
+ }
+ node = updatedNode
+ }
+ }
+ }
+ }
+ index = sstack.Index
+ keys = sstack.Keys
+ edits = sstack.Edits
+ inSlice = sstack.inSlice
+ sstack = sstack.Prev
+ } else {
+ // get key
+ if !inSlice {
+ if !isNilNode(parent) {
+ key = getFieldValue(keys, index)
+ } else {
+ // initial conditions
+ key = nil
+ }
+ } else {
+ key = index
+ }
+ // get node
+ if !inSlice {
+ if !isNilNode(parent) {
+ fieldValue := getFieldValue(parent, key)
+ if isNode(fieldValue) {
+ node = fieldValue.(ast.Node)
+ }
+ if isSlice(fieldValue) {
+ nodeSlice = toSliceInterfaces(fieldValue)
+ }
+ } else {
+ // initial conditions
+ node = newRoot
+ }
+ } else {
+ if len(parentSlice) != 0 {
+ fieldValue := getFieldValue(parentSlice, key)
+ if isNode(fieldValue) {
+ node = fieldValue.(ast.Node)
+ }
+ if isSlice(fieldValue) {
+ nodeSlice = toSliceInterfaces(fieldValue)
+ }
+ } else {
+ // initial conditions
+ nodeSlice = []interface{}{}
+ }
+ }
+
+ if isNilNode(node) && len(nodeSlice) == 0 {
+ continue
+ }
+
+ if !inSlice {
+ if !isNilNode(parent) {
+ path = append(path, key)
+ }
+ } else {
+ if len(parentSlice) != 0 {
+ path = append(path, key)
+ }
+ }
+ }
+
+ // get result from visitFn for a node if set
+ var result interface{}
+ resultIsUndefined := true
+ if !isNilNode(node) {
+ if !isNode(node) { // is node-ish.
+ panic(fmt.Sprintf("Invalid AST Node (4): %v", node))
+ }
+
+ // Try to pass in current node as ast.Node
+ // Note that since user can potentially return a non-ast.Node from visit functions.
+ // In that case, we try to unmarshal map[string]interface{} into ast.Node
+ var nodeIn interface{}
+ if _, ok := node.(map[string]interface{}); ok {
+ b, err := json.Marshal(node)
+ if err != nil {
+ panic(fmt.Sprintf("Invalid root AST Node: %v", root))
+ }
+ err = json.Unmarshal(b, &nodeIn)
+ if err != nil {
+ panic(fmt.Sprintf("Invalid root AST Node (2a): %v", root))
+ }
+ } else {
+ nodeIn = node
+ }
+ parentConcrete, _ := parent.(ast.Node)
+ // ancestorsConcrete slice may contain nil values
+ ancestorsConcrete := []ast.Node{}
+ for _, ancestor := range ancestors {
+ if ancestorConcrete, ok := ancestor.(ast.Node); ok {
+ ancestorsConcrete = append(ancestorsConcrete, ancestorConcrete)
+ } else {
+ ancestorsConcrete = append(ancestorsConcrete, nil)
+ }
+ }
+
+ kind := ""
+ if node, ok := node.(map[string]interface{}); ok {
+ kind, _ = node["Kind"].(string)
+ }
+ if node, ok := node.(ast.Node); ok {
+ kind = node.GetKind()
+ }
+
+ visitFn := GetVisitFn(visitorOpts, kind, isLeaving)
+ if visitFn != nil {
+ p := VisitFuncParams{
+ Node: nodeIn,
+ Key: key,
+ Parent: parentConcrete,
+ Path: path,
+ Ancestors: ancestorsConcrete,
+ }
+ action := ActionUpdate
+ action, result = visitFn(p)
+ if action == ActionBreak {
+ break Loop
+ }
+ if action == ActionSkip {
+ if !isLeaving {
+ _, path = pop(path)
+ continue
+ }
+ }
+ if action != ActionNoChange {
+ resultIsUndefined = false
+ edits = append(edits, &edit{
+ Key: key,
+ Value: result,
+ })
+ if !isLeaving {
+ if isNode(result) {
+ node = result
+ } else {
+ _, path = pop(path)
+ continue
+ }
+ }
+ } else {
+ resultIsUndefined = true
+ }
+ }
+
+ }
+
+ // collect back edits on the way out
+ if resultIsUndefined && isEdited {
+ if !prevInSlice {
+ edits = append(edits, &edit{
+ Key: key,
+ Value: node,
+ })
+ } else {
+ edits = append(edits, &edit{
+ Key: key,
+ Value: nodeSlice,
+ })
+ }
+ }
+ if !isLeaving {
+
+ // add to stack
+ prevStack := sstack
+ sstack = &stack{
+ inSlice: inSlice,
+ Index: index,
+ Keys: keys,
+ Edits: edits,
+ Prev: prevStack,
+ }
+
+ // replace keys
+ inSlice = false
+ if len(nodeSlice) > 0 {
+ inSlice = true
+ }
+ keys = []interface{}{}
+
+ if inSlice {
+ // get keys
+ for _, m := range nodeSlice {
+ keys = append(keys, m)
+ }
+ } else {
+ if !isNilNode(node) {
+ if node, ok := node.(ast.Node); ok {
+ kind := node.GetKind()
+ if n, ok := visitorKeys[kind]; ok {
+ for _, m := range n {
+ keys = append(keys, m)
+ }
+ }
+ }
+
+ }
+
+ }
+ index = -1
+ edits = []*edit{}
+
+ ancestors = append(ancestors, parent)
+ parent = node
+ ancestorsSlice = append(ancestorsSlice, parentSlice)
+ parentSlice = nodeSlice
+
+ }
+
+ // loop guard
+ if sstack == nil {
+ break Loop
+ }
+ }
+ if len(edits) != 0 {
+ result = edits[len(edits)-1].Value
+ }
+ return result
+}
+
+func pop(a []interface{}) (x interface{}, aa []interface{}) {
+ if len(a) == 0 {
+ return x, aa
+ }
+ x, aa = a[len(a)-1], a[:len(a)-1]
+ return x, aa
+}
+func popNodeSlice(a [][]interface{}) (x []interface{}, aa [][]interface{}) {
+ if len(a) == 0 {
+ return x, aa
+ }
+ x, aa = a[len(a)-1], a[:len(a)-1]
+ return x, aa
+}
+func spliceNode(a interface{}, i int) (result []interface{}) {
+ if i < 0 {
+ return result
+ }
+ typeOf := reflect.TypeOf(a)
+ if typeOf == nil {
+ return result
+ }
+ switch typeOf.Kind() {
+ case reflect.Slice:
+ s := reflect.ValueOf(a)
+ for i := 0; i < s.Len(); i++ {
+ elem := s.Index(i)
+ elemInterface := elem.Interface()
+ result = append(result, elemInterface)
+ }
+ if i >= s.Len() {
+ return result
+ }
+ return append(result[:i], result[i+1:]...)
+ default:
+ return result
+ }
+}
+
+func getFieldValue(obj interface{}, key interface{}) interface{} {
+ val := reflect.ValueOf(obj)
+ if val.Type().Kind() == reflect.Ptr {
+ val = val.Elem()
+ }
+ if val.Type().Kind() == reflect.Struct {
+ key, ok := key.(string)
+ if !ok {
+ return nil
+ }
+ valField := val.FieldByName(key)
+ if valField.IsValid() {
+ return valField.Interface()
+ }
+ return nil
+ }
+ if val.Type().Kind() == reflect.Slice {
+ key, ok := key.(int)
+ if !ok {
+ return nil
+ }
+ if key >= val.Len() {
+ return nil
+ }
+ valField := val.Index(key)
+ if valField.IsValid() {
+ return valField.Interface()
+ }
+ return nil
+ }
+ if val.Type().Kind() == reflect.Map {
+ keyVal := reflect.ValueOf(key)
+ valField := val.MapIndex(keyVal)
+ if valField.IsValid() {
+ return valField.Interface()
+ }
+ return nil
+ }
+ return nil
+}
+
+func updateNodeField(value interface{}, fieldName string, fieldValue interface{}) (retVal interface{}) {
+ retVal = value
+ val := reflect.ValueOf(value)
+
+ isPtr := false
+ if val.IsValid() && val.Type().Kind() == reflect.Ptr {
+ val = val.Elem()
+ isPtr = true
+ }
+ if !val.IsValid() {
+ return retVal
+ }
+ if val.Type().Kind() == reflect.Struct {
+ for i := 0; i < val.NumField(); i++ {
+ valueField := val.Field(i)
+ typeField := val.Type().Field(i)
+
+ // try matching the field name
+ if typeField.Name == fieldName {
+ fieldValueVal := reflect.ValueOf(fieldValue)
+ if valueField.CanSet() {
+
+ if fieldValueVal.IsValid() {
+ if valueField.Type().Kind() == fieldValueVal.Type().Kind() {
+ if fieldValueVal.Type().Kind() == reflect.Slice {
+ newSliceValue := reflect.MakeSlice(reflect.TypeOf(valueField.Interface()), fieldValueVal.Len(), fieldValueVal.Len())
+ for i := 0; i < newSliceValue.Len(); i++ {
+ dst := newSliceValue.Index(i)
+ src := fieldValueVal.Index(i)
+ srcValue := reflect.ValueOf(src.Interface())
+ if dst.CanSet() {
+ dst.Set(srcValue)
+ }
+ }
+ valueField.Set(newSliceValue)
+
+ } else {
+ valueField.Set(fieldValueVal)
+ }
+ }
+ } else {
+ valueField.Set(reflect.New(valueField.Type()).Elem())
+ }
+ if isPtr == true {
+ retVal = val.Addr().Interface()
+ return retVal
+ }
+ retVal = val.Interface()
+ return retVal
+
+ }
+ }
+ }
+ }
+ return retVal
+}
+func toSliceInterfaces(slice interface{}) (result []interface{}) {
+ switch reflect.TypeOf(slice).Kind() {
+ case reflect.Slice:
+ s := reflect.ValueOf(slice)
+ for i := 0; i < s.Len(); i++ {
+ elem := s.Index(i)
+ elemInterface := elem.Interface()
+ if elem, ok := elemInterface.(ast.Node); ok {
+ result = append(result, elem)
+ }
+ }
+ return result
+ default:
+ return result
+ }
+}
+
+func isSlice(value interface{}) bool {
+ val := reflect.ValueOf(value)
+ if val.IsValid() && val.Type().Kind() == reflect.Slice {
+ return true
+ }
+ return false
+}
+func isNode(node interface{}) bool {
+ val := reflect.ValueOf(node)
+ if val.IsValid() && val.Type().Kind() == reflect.Ptr {
+ val = val.Elem()
+ }
+ if !val.IsValid() {
+ return false
+ }
+ if val.Type().Kind() == reflect.Map {
+ keyVal := reflect.ValueOf("Kind")
+ valField := val.MapIndex(keyVal)
+ return valField.IsValid()
+ }
+ if val.Type().Kind() == reflect.Struct {
+ valField := val.FieldByName("Kind")
+ return valField.IsValid()
+ }
+ return false
+}
+func isStructNode(node interface{}) bool {
+ val := reflect.ValueOf(node)
+ if val.IsValid() && val.Type().Kind() == reflect.Ptr {
+ val = val.Elem()
+ }
+ if !val.IsValid() {
+ return false
+ }
+ if val.Type().Kind() == reflect.Struct {
+ valField := val.FieldByName("Kind")
+ return valField.IsValid()
+ }
+ return false
+}
+
+func isNilNode(node interface{}) bool {
+ val := reflect.ValueOf(node)
+ if !val.IsValid() {
+ return true
+ }
+ if val.Type().Kind() == reflect.Ptr {
+ return val.IsNil()
+ }
+ if val.Type().Kind() == reflect.Slice {
+ return val.Len() == 0
+ }
+ if val.Type().Kind() == reflect.Map {
+ return val.Len() == 0
+ }
+ if val.Type().Kind() == reflect.Bool {
+ return val.Interface().(bool)
+ }
+ return val.Interface() == nil
+}
+
+// VisitInParallel Creates a new visitor instance which delegates to many visitors to run in
+// parallel. Each visitor will be visited for each node before moving on.
+//
+// If a prior visitor edits a node, no following visitors will see that node.
+func VisitInParallel(visitorOptsSlice ...*VisitorOptions) *VisitorOptions {
+ skipping := map[int]interface{}{}
+
+ return &VisitorOptions{
+ Enter: func(p VisitFuncParams) (string, interface{}) {
+ for i, visitorOpts := range visitorOptsSlice {
+ if _, ok := skipping[i]; !ok {
+ switch node := p.Node.(type) {
+ case ast.Node:
+ kind := node.GetKind()
+ fn := GetVisitFn(visitorOpts, kind, false)
+ if fn != nil {
+ action, result := fn(p)
+ if action == ActionSkip {
+ skipping[i] = node
+ } else if action == ActionBreak {
+ skipping[i] = ActionBreak
+ } else if action == ActionUpdate {
+ return ActionUpdate, result
+ }
+ }
+ }
+ }
+ }
+ return ActionNoChange, nil
+ },
+ Leave: func(p VisitFuncParams) (string, interface{}) {
+ for i, visitorOpts := range visitorOptsSlice {
+ skippedNode, ok := skipping[i]
+ if !ok {
+ switch node := p.Node.(type) {
+ case ast.Node:
+ kind := node.GetKind()
+ fn := GetVisitFn(visitorOpts, kind, true)
+ if fn != nil {
+ action, result := fn(p)
+ if action == ActionBreak {
+ skipping[i] = ActionBreak
+ } else if action == ActionUpdate {
+ return ActionUpdate, result
+ }
+ }
+ }
+ } else if skippedNode == p.Node {
+ delete(skipping, i)
+ }
+ }
+ return ActionNoChange, nil
+ },
+ }
+}
+
+// VisitWithTypeInfo Creates a new visitor instance which maintains a provided TypeInfo instance
+// along with visiting visitor.
+func VisitWithTypeInfo(ttypeInfo typeInfo.TypeInfoI, visitorOpts *VisitorOptions) *VisitorOptions {
+ return &VisitorOptions{
+ Enter: func(p VisitFuncParams) (string, interface{}) {
+ if node, ok := p.Node.(ast.Node); ok {
+ ttypeInfo.Enter(node)
+ fn := GetVisitFn(visitorOpts, node.GetKind(), false)
+ if fn != nil {
+ action, result := fn(p)
+ if action == ActionUpdate {
+ ttypeInfo.Leave(node)
+ if isNode(result) {
+ if result, ok := result.(ast.Node); ok {
+ ttypeInfo.Enter(result)
+ }
+ }
+ }
+ return action, result
+ }
+ }
+ return ActionNoChange, nil
+ },
+ Leave: func(p VisitFuncParams) (string, interface{}) {
+ action := ActionNoChange
+ var result interface{}
+ if node, ok := p.Node.(ast.Node); ok {
+ fn := GetVisitFn(visitorOpts, node.GetKind(), true)
+ if fn != nil {
+ action, result = fn(p)
+ }
+ ttypeInfo.Leave(node)
+ }
+ return action, result
+ },
+ }
+}
+
+// GetVisitFn Given a visitor instance, if it is leaving or not, and a node kind, return
+// the function the visitor runtime should call.
+func GetVisitFn(visitorOpts *VisitorOptions, kind string, isLeaving bool) VisitFunc {
+ if visitorOpts == nil {
+ return nil
+ }
+ kindVisitor, ok := visitorOpts.KindFuncMap[kind]
+ if ok {
+ if !isLeaving && kindVisitor.Kind != nil {
+ // { Kind() {} }
+ return kindVisitor.Kind
+ }
+ if isLeaving {
+ // { Kind: { leave() {} } }
+ return kindVisitor.Leave
+ }
+ // { Kind: { enter() {} } }
+ return kindVisitor.Enter
+
+ }
+ if isLeaving {
+ // { enter() {} }
+ specificVisitor := visitorOpts.Leave
+ if specificVisitor != nil {
+ return specificVisitor
+ }
+ if specificKindVisitor, ok := visitorOpts.LeaveKindMap[kind]; ok {
+ // { leave: { Kind() {} } }
+ return specificKindVisitor
+ }
+
+ }
+ // { leave() {} }
+ specificVisitor := visitorOpts.Enter
+ if specificVisitor != nil {
+ return specificVisitor
+ }
+ if specificKindVisitor, ok := visitorOpts.EnterKindMap[kind]; ok {
+ // { enter: { Kind() {} } }
+ return specificKindVisitor
+ }
+ return nil
+}