rules.go

   1package graphql
   2
   3import (
   4	"fmt"
   5	"math"
   6	"sort"
   7	"strings"
   8
   9	"github.com/graphql-go/graphql/gqlerrors"
  10	"github.com/graphql-go/graphql/language/ast"
  11	"github.com/graphql-go/graphql/language/kinds"
  12	"github.com/graphql-go/graphql/language/printer"
  13	"github.com/graphql-go/graphql/language/visitor"
  14)
  15
  16// SpecifiedRules set includes all validation rules defined by the GraphQL spec.
  17var SpecifiedRules = []ValidationRuleFn{
  18	ArgumentsOfCorrectTypeRule,
  19	DefaultValuesOfCorrectTypeRule,
  20	FieldsOnCorrectTypeRule,
  21	FragmentsOnCompositeTypesRule,
  22	KnownArgumentNamesRule,
  23	KnownDirectivesRule,
  24	KnownFragmentNamesRule,
  25	KnownTypeNamesRule,
  26	LoneAnonymousOperationRule,
  27	NoFragmentCyclesRule,
  28	NoUndefinedVariablesRule,
  29	NoUnusedFragmentsRule,
  30	NoUnusedVariablesRule,
  31	OverlappingFieldsCanBeMergedRule,
  32	PossibleFragmentSpreadsRule,
  33	ProvidedNonNullArgumentsRule,
  34	ScalarLeafsRule,
  35	UniqueArgumentNamesRule,
  36	UniqueFragmentNamesRule,
  37	UniqueInputFieldNamesRule,
  38	UniqueOperationNamesRule,
  39	UniqueVariableNamesRule,
  40	VariablesAreInputTypesRule,
  41	VariablesInAllowedPositionRule,
  42}
  43
  44type ValidationRuleInstance struct {
  45	VisitorOpts *visitor.VisitorOptions
  46}
  47type ValidationRuleFn func(context *ValidationContext) *ValidationRuleInstance
  48
  49func newValidationError(message string, nodes []ast.Node) *gqlerrors.Error {
  50	return gqlerrors.NewError(
  51		message,
  52		nodes,
  53		"",
  54		nil,
  55		[]int{},
  56		nil, // TODO: this is interim, until we port "better-error-messages-for-inputs"
  57	)
  58}
  59
  60func reportError(context *ValidationContext, message string, nodes []ast.Node) (string, interface{}) {
  61	context.ReportError(newValidationError(message, nodes))
  62	return visitor.ActionNoChange, nil
  63}
  64
  65// ArgumentsOfCorrectTypeRule Argument values of correct type
  66//
  67// A GraphQL document is only valid if all field argument literal values are
  68// of the type expected by their position.
  69func ArgumentsOfCorrectTypeRule(context *ValidationContext) *ValidationRuleInstance {
  70	visitorOpts := &visitor.VisitorOptions{
  71		KindFuncMap: map[string]visitor.NamedVisitFuncs{
  72			kinds.Argument: {
  73				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
  74					if argAST, ok := p.Node.(*ast.Argument); ok {
  75						value := argAST.Value
  76						argDef := context.Argument()
  77						if argDef != nil {
  78							isValid, messages := isValidLiteralValue(argDef.Type, value)
  79							if !isValid {
  80								argNameValue := ""
  81								if argAST.Name != nil {
  82									argNameValue = argAST.Name.Value
  83								}
  84
  85								messagesStr := ""
  86								if len(messages) > 0 {
  87									messagesStr = "\n" + strings.Join(messages, "\n")
  88								}
  89								reportError(
  90									context,
  91									fmt.Sprintf(`Argument "%v" has invalid value %v.%v`,
  92										argNameValue, printer.Print(value), messagesStr),
  93									[]ast.Node{value},
  94								)
  95							}
  96
  97						}
  98					}
  99					return visitor.ActionSkip, nil
 100				},
 101			},
 102		},
 103	}
 104	return &ValidationRuleInstance{
 105		VisitorOpts: visitorOpts,
 106	}
 107}
 108
 109// DefaultValuesOfCorrectTypeRule Variable default values of correct type
 110//
 111// A GraphQL document is only valid if all variable default values are of the
 112// type expected by their definition.
 113func DefaultValuesOfCorrectTypeRule(context *ValidationContext) *ValidationRuleInstance {
 114	visitorOpts := &visitor.VisitorOptions{
 115		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 116			kinds.VariableDefinition: {
 117				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 118					if varDefAST, ok := p.Node.(*ast.VariableDefinition); ok {
 119						name := ""
 120						if varDefAST.Variable != nil && varDefAST.Variable.Name != nil {
 121							name = varDefAST.Variable.Name.Value
 122						}
 123						defaultValue := varDefAST.DefaultValue
 124						ttype := context.InputType()
 125
 126						if ttype, ok := ttype.(*NonNull); ok && defaultValue != nil {
 127							reportError(
 128								context,
 129								fmt.Sprintf(`Variable "$%v" of type "%v" is required and will not use the default value. Perhaps you meant to use type "%v".`,
 130									name, ttype, ttype.OfType),
 131								[]ast.Node{defaultValue},
 132							)
 133						}
 134						isValid, messages := isValidLiteralValue(ttype, defaultValue)
 135						if ttype != nil && defaultValue != nil && !isValid {
 136							messagesStr := ""
 137							if len(messages) > 0 {
 138								messagesStr = "\n" + strings.Join(messages, "\n")
 139							}
 140							reportError(
 141								context,
 142								fmt.Sprintf(`Variable "$%v" has invalid default value: %v.%v`,
 143									name, printer.Print(defaultValue), messagesStr),
 144								[]ast.Node{defaultValue},
 145							)
 146						}
 147					}
 148					return visitor.ActionSkip, nil
 149				},
 150			},
 151			kinds.SelectionSet: {
 152				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 153					return visitor.ActionSkip, nil
 154				},
 155			},
 156			kinds.FragmentDefinition: {
 157				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 158					return visitor.ActionSkip, nil
 159				},
 160			},
 161		},
 162	}
 163	return &ValidationRuleInstance{
 164		VisitorOpts: visitorOpts,
 165	}
 166}
 167func quoteStrings(slice []string) []string {
 168	quoted := []string{}
 169	for _, s := range slice {
 170		quoted = append(quoted, fmt.Sprintf(`"%v"`, s))
 171	}
 172	return quoted
 173}
 174
 175// quotedOrList Given [ A, B, C ] return '"A", "B", or "C"'.
 176// Notice oxford comma
 177func quotedOrList(slice []string) string {
 178	maxLength := 5
 179	if len(slice) == 0 {
 180		return ""
 181	}
 182	quoted := quoteStrings(slice)
 183	if maxLength > len(quoted) {
 184		maxLength = len(quoted)
 185	}
 186	if maxLength > 2 {
 187		return fmt.Sprintf("%v, or %v", strings.Join(quoted[0:maxLength-1], ", "), quoted[maxLength-1])
 188	}
 189	if maxLength > 1 {
 190		return fmt.Sprintf("%v or %v", strings.Join(quoted[0:maxLength-1], ", "), quoted[maxLength-1])
 191	}
 192	return quoted[0]
 193}
 194func UndefinedFieldMessage(fieldName string, ttypeName string, suggestedTypeNames []string, suggestedFieldNames []string) string {
 195	message := fmt.Sprintf(`Cannot query field "%v" on type "%v".`, fieldName, ttypeName)
 196	if len(suggestedTypeNames) > 0 {
 197		message = fmt.Sprintf(`%v Did you mean to use an inline fragment on %v?`, message, quotedOrList(suggestedTypeNames))
 198	} else if len(suggestedFieldNames) > 0 {
 199		message = fmt.Sprintf(`%v Did you mean %v?`, message, quotedOrList(suggestedFieldNames))
 200	}
 201	return message
 202}
 203
 204// FieldsOnCorrectTypeRule Fields on correct type
 205//
 206// A GraphQL document is only valid if all fields selected are defined by the
 207// parent type, or are an allowed meta field such as __typenamme
 208func FieldsOnCorrectTypeRule(context *ValidationContext) *ValidationRuleInstance {
 209	visitorOpts := &visitor.VisitorOptions{
 210		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 211			kinds.Field: {
 212				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 213					var action = visitor.ActionNoChange
 214					var result interface{}
 215					if node, ok := p.Node.(*ast.Field); ok {
 216						ttype := context.ParentType()
 217						if ttype == nil {
 218							return action, result
 219						}
 220						if t, ok := ttype.(*Object); ok && t == nil {
 221							return action, result
 222						}
 223						if t, ok := ttype.(*Interface); ok && t == nil {
 224							return action, result
 225						}
 226						if t, ok := ttype.(*Union); ok && t == nil {
 227							return action, result
 228						}
 229						fieldDef := context.FieldDef()
 230						if fieldDef == nil {
 231							// This field doesn't exist, lets look for suggestions.
 232							nodeName := ""
 233							if node.Name != nil {
 234								nodeName = node.Name.Value
 235							}
 236							// First determine if there are any suggested types to condition on.
 237							suggestedTypeNames := getSuggestedTypeNames(context.Schema(), ttype, nodeName)
 238
 239							// If there are no suggested types, then perhaps this was a typo?
 240							suggestedFieldNames := []string{}
 241							if len(suggestedTypeNames) == 0 {
 242								suggestedFieldNames = getSuggestedFieldNames(context.Schema(), ttype, nodeName)
 243							}
 244							reportError(
 245								context,
 246								UndefinedFieldMessage(nodeName, ttype.Name(), suggestedTypeNames, suggestedFieldNames),
 247								[]ast.Node{node},
 248							)
 249						}
 250					}
 251					return action, result
 252				},
 253			},
 254		},
 255	}
 256	return &ValidationRuleInstance{
 257		VisitorOpts: visitorOpts,
 258	}
 259}
 260
 261// getSuggestedTypeNames Go through all of the implementations of type, as well as the interfaces
 262// that they implement. If any of those types include the provided field,
 263// suggest them, sorted by how often the type is referenced,  starting
 264// with Interfaces.
 265func getSuggestedTypeNames(schema *Schema, ttype Output, fieldName string) []string {
 266
 267	possibleTypes := schema.PossibleTypes(ttype)
 268
 269	suggestedObjectTypes := []string{}
 270	suggestedInterfaces := []*suggestedInterface{}
 271	// stores a map of interface name => index in suggestedInterfaces
 272	suggestedInterfaceMap := map[string]int{}
 273	// stores a maps of object name => true to remove duplicates from results
 274	suggestedObjectMap := map[string]bool{}
 275
 276	for _, possibleType := range possibleTypes {
 277		if field, ok := possibleType.Fields()[fieldName]; !ok || field == nil {
 278			continue
 279		}
 280		// This object type defines this field.
 281		suggestedObjectTypes = append(suggestedObjectTypes, possibleType.Name())
 282		suggestedObjectMap[possibleType.Name()] = true
 283
 284		for _, possibleInterface := range possibleType.Interfaces() {
 285			if field, ok := possibleInterface.Fields()[fieldName]; !ok || field == nil {
 286				continue
 287			}
 288
 289			// This interface type defines this field.
 290
 291			// - find the index of the suggestedInterface and retrieving the interface
 292			// - increase count
 293			index, ok := suggestedInterfaceMap[possibleInterface.Name()]
 294			if !ok {
 295				suggestedInterfaces = append(suggestedInterfaces, &suggestedInterface{
 296					name:  possibleInterface.Name(),
 297					count: 0,
 298				})
 299				index = len(suggestedInterfaces) - 1
 300				suggestedInterfaceMap[possibleInterface.Name()] = index
 301			}
 302			if index < len(suggestedInterfaces) {
 303				s := suggestedInterfaces[index]
 304				if s.name == possibleInterface.Name() {
 305					s.count = s.count + 1
 306				}
 307			}
 308		}
 309	}
 310
 311	// sort results (by count usage for interfaces, alphabetical order for objects)
 312	sort.Sort(suggestedInterfaceSortedSlice(suggestedInterfaces))
 313	sort.Sort(sort.StringSlice(suggestedObjectTypes))
 314
 315	// return concatenated slices of both interface and object type names
 316	// and removing duplicates
 317	// ordered by: interface (sorted) and object (sorted)
 318	results := []string{}
 319	for _, s := range suggestedInterfaces {
 320		if _, ok := suggestedObjectMap[s.name]; !ok {
 321			results = append(results, s.name)
 322
 323		}
 324	}
 325	results = append(results, suggestedObjectTypes...)
 326	return results
 327}
 328
 329// getSuggestedFieldNames For the field name provided, determine if there are any similar field names
 330// that may be the result of a typo.
 331func getSuggestedFieldNames(schema *Schema, ttype Output, fieldName string) []string {
 332
 333	fields := FieldDefinitionMap{}
 334	switch ttype := ttype.(type) {
 335	case *Object:
 336		fields = ttype.Fields()
 337	case *Interface:
 338		fields = ttype.Fields()
 339	default:
 340		return []string{}
 341	}
 342
 343	possibleFieldNames := []string{}
 344	for possibleFieldName := range fields {
 345		possibleFieldNames = append(possibleFieldNames, possibleFieldName)
 346	}
 347	return suggestionList(fieldName, possibleFieldNames)
 348}
 349
 350// suggestedInterface an internal struct to sort interface by usage count
 351type suggestedInterface struct {
 352	name  string
 353	count int
 354}
 355type suggestedInterfaceSortedSlice []*suggestedInterface
 356
 357func (s suggestedInterfaceSortedSlice) Len() int {
 358	return len(s)
 359}
 360func (s suggestedInterfaceSortedSlice) Swap(i, j int) {
 361	s[i], s[j] = s[j], s[i]
 362}
 363func (s suggestedInterfaceSortedSlice) Less(i, j int) bool {
 364	if s[i].count == s[j].count {
 365		return s[i].name < s[j].name
 366	}
 367	return s[i].count > s[j].count
 368}
 369
 370// FragmentsOnCompositeTypesRule Fragments on composite type
 371//
 372// Fragments use a type condition to determine if they apply, since fragments
 373// can only be spread into a composite type (object, interface, or union), the
 374// type condition must also be a composite type.
 375func FragmentsOnCompositeTypesRule(context *ValidationContext) *ValidationRuleInstance {
 376	visitorOpts := &visitor.VisitorOptions{
 377		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 378			kinds.InlineFragment: {
 379				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 380					if node, ok := p.Node.(*ast.InlineFragment); ok {
 381						ttype := context.Type()
 382						if node.TypeCondition != nil && ttype != nil && !IsCompositeType(ttype) {
 383							reportError(
 384								context,
 385								fmt.Sprintf(`Fragment cannot condition on non composite type "%v".`, ttype),
 386								[]ast.Node{node.TypeCondition},
 387							)
 388						}
 389					}
 390					return visitor.ActionNoChange, nil
 391				},
 392			},
 393			kinds.FragmentDefinition: {
 394				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 395					if node, ok := p.Node.(*ast.FragmentDefinition); ok {
 396						ttype := context.Type()
 397						if ttype != nil && !IsCompositeType(ttype) {
 398							nodeName := ""
 399							if node.Name != nil {
 400								nodeName = node.Name.Value
 401							}
 402							reportError(
 403								context,
 404								fmt.Sprintf(`Fragment "%v" cannot condition on non composite type "%v".`, nodeName, printer.Print(node.TypeCondition)),
 405								[]ast.Node{node.TypeCondition},
 406							)
 407						}
 408					}
 409					return visitor.ActionNoChange, nil
 410				},
 411			},
 412		},
 413	}
 414	return &ValidationRuleInstance{
 415		VisitorOpts: visitorOpts,
 416	}
 417}
 418
 419func unknownArgMessage(argName string, fieldName string, parentTypeName string, suggestedArgs []string) string {
 420	message := fmt.Sprintf(`Unknown argument "%v" on field "%v" of type "%v".`, argName, fieldName, parentTypeName)
 421
 422	if len(suggestedArgs) > 0 {
 423		message = fmt.Sprintf(`%v Did you mean %v?`, message, quotedOrList(suggestedArgs))
 424	}
 425
 426	return message
 427}
 428
 429func unknownDirectiveArgMessage(argName string, directiveName string, suggestedArgs []string) string {
 430	message := fmt.Sprintf(`Unknown argument "%v" on directive "@%v".`, argName, directiveName)
 431
 432	if len(suggestedArgs) > 0 {
 433		message = fmt.Sprintf(`%v Did you mean %v?`, message, quotedOrList(suggestedArgs))
 434	}
 435
 436	return message
 437}
 438
 439// KnownArgumentNamesRule Known argument names
 440//
 441// A GraphQL field is only valid if all supplied arguments are defined by
 442// that field.
 443func KnownArgumentNamesRule(context *ValidationContext) *ValidationRuleInstance {
 444	visitorOpts := &visitor.VisitorOptions{
 445		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 446			kinds.Argument: {
 447				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 448					var action = visitor.ActionNoChange
 449					var result interface{}
 450					if node, ok := p.Node.(*ast.Argument); ok {
 451						var argumentOf ast.Node
 452						if len(p.Ancestors) > 0 {
 453							argumentOf = p.Ancestors[len(p.Ancestors)-1]
 454						}
 455						if argumentOf == nil {
 456							return action, result
 457						}
 458						var fieldArgDef *Argument
 459						if argumentOf.GetKind() == kinds.Field {
 460							fieldDef := context.FieldDef()
 461							if fieldDef == nil {
 462								return action, result
 463							}
 464							nodeName := ""
 465							if node.Name != nil {
 466								nodeName = node.Name.Value
 467							}
 468							argNames := []string{}
 469							for _, arg := range fieldDef.Args {
 470								argNames = append(argNames, arg.Name())
 471								if arg.Name() == nodeName {
 472									fieldArgDef = arg
 473								}
 474							}
 475							if fieldArgDef == nil {
 476								parentType := context.ParentType()
 477								parentTypeName := ""
 478								if parentType != nil {
 479									parentTypeName = parentType.Name()
 480								}
 481								reportError(
 482									context,
 483									unknownArgMessage(nodeName, fieldDef.Name, parentTypeName, suggestionList(nodeName, argNames)),
 484									[]ast.Node{node},
 485								)
 486							}
 487						} else if argumentOf.GetKind() == kinds.Directive {
 488							directive := context.Directive()
 489							if directive == nil {
 490								return action, result
 491							}
 492							nodeName := ""
 493							if node.Name != nil {
 494								nodeName = node.Name.Value
 495							}
 496							argNames := []string{}
 497							var directiveArgDef *Argument
 498							for _, arg := range directive.Args {
 499								argNames = append(argNames, arg.Name())
 500								if arg.Name() == nodeName {
 501									directiveArgDef = arg
 502								}
 503							}
 504							if directiveArgDef == nil {
 505								reportError(
 506									context,
 507									unknownDirectiveArgMessage(nodeName, directive.Name, suggestionList(nodeName, argNames)),
 508									[]ast.Node{node},
 509								)
 510							}
 511						}
 512
 513					}
 514					return action, result
 515				},
 516			},
 517		},
 518	}
 519	return &ValidationRuleInstance{
 520		VisitorOpts: visitorOpts,
 521	}
 522}
 523
 524func MisplaceDirectiveMessage(directiveName string, location string) string {
 525	return fmt.Sprintf(`Directive "%v" may not be used on %v.`, directiveName, location)
 526}
 527
 528// KnownDirectivesRule Known directives
 529//
 530// A GraphQL document is only valid if all `@directives` are known by the
 531// schema and legally positioned.
 532func KnownDirectivesRule(context *ValidationContext) *ValidationRuleInstance {
 533	visitorOpts := &visitor.VisitorOptions{
 534		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 535			kinds.Directive: {
 536				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 537					var action = visitor.ActionNoChange
 538					var result interface{}
 539					if node, ok := p.Node.(*ast.Directive); ok {
 540
 541						nodeName := ""
 542						if node.Name != nil {
 543							nodeName = node.Name.Value
 544						}
 545
 546						var directiveDef *Directive
 547						for _, def := range context.Schema().Directives() {
 548							if def.Name == nodeName {
 549								directiveDef = def
 550							}
 551						}
 552						if directiveDef == nil {
 553							return reportError(
 554								context,
 555								fmt.Sprintf(`Unknown directive "%v".`, nodeName),
 556								[]ast.Node{node},
 557							)
 558						}
 559
 560						candidateLocation := getDirectiveLocationForASTPath(p.Ancestors)
 561
 562						directiveHasLocation := false
 563						for _, loc := range directiveDef.Locations {
 564							if loc == candidateLocation {
 565								directiveHasLocation = true
 566								break
 567							}
 568						}
 569
 570						if candidateLocation == "" {
 571							reportError(
 572								context,
 573								MisplaceDirectiveMessage(nodeName, node.GetKind()),
 574								[]ast.Node{node},
 575							)
 576						} else if !directiveHasLocation {
 577							reportError(
 578								context,
 579								MisplaceDirectiveMessage(nodeName, candidateLocation),
 580								[]ast.Node{node},
 581							)
 582						}
 583
 584					}
 585					return action, result
 586				},
 587			},
 588		},
 589	}
 590	return &ValidationRuleInstance{
 591		VisitorOpts: visitorOpts,
 592	}
 593}
 594
 595func getDirectiveLocationForASTPath(ancestors []ast.Node) string {
 596	var appliedTo ast.Node
 597	if len(ancestors) > 0 {
 598		appliedTo = ancestors[len(ancestors)-1]
 599	}
 600	if appliedTo == nil {
 601		return ""
 602	}
 603	kind := appliedTo.GetKind()
 604	if kind == kinds.OperationDefinition {
 605		appliedTo, _ := appliedTo.(*ast.OperationDefinition)
 606		if appliedTo.Operation == ast.OperationTypeQuery {
 607			return DirectiveLocationQuery
 608		}
 609		if appliedTo.Operation == ast.OperationTypeMutation {
 610			return DirectiveLocationMutation
 611		}
 612		if appliedTo.Operation == ast.OperationTypeSubscription {
 613			return DirectiveLocationSubscription
 614		}
 615	}
 616	if kind == kinds.Field {
 617		return DirectiveLocationField
 618	}
 619	if kind == kinds.FragmentSpread {
 620		return DirectiveLocationFragmentSpread
 621	}
 622	if kind == kinds.InlineFragment {
 623		return DirectiveLocationInlineFragment
 624	}
 625	if kind == kinds.FragmentDefinition {
 626		return DirectiveLocationFragmentDefinition
 627	}
 628	if kind == kinds.SchemaDefinition {
 629		return DirectiveLocationSchema
 630	}
 631	if kind == kinds.ScalarDefinition {
 632		return DirectiveLocationScalar
 633	}
 634	if kind == kinds.ObjectDefinition {
 635		return DirectiveLocationObject
 636	}
 637	if kind == kinds.FieldDefinition {
 638		return DirectiveLocationFieldDefinition
 639	}
 640	if kind == kinds.InterfaceDefinition {
 641		return DirectiveLocationInterface
 642	}
 643	if kind == kinds.UnionDefinition {
 644		return DirectiveLocationUnion
 645	}
 646	if kind == kinds.EnumDefinition {
 647		return DirectiveLocationEnum
 648	}
 649	if kind == kinds.EnumValueDefinition {
 650		return DirectiveLocationEnumValue
 651	}
 652	if kind == kinds.InputObjectDefinition {
 653		return DirectiveLocationInputObject
 654	}
 655	if kind == kinds.InputValueDefinition {
 656		var parentNode ast.Node
 657		if len(ancestors) >= 3 {
 658			parentNode = ancestors[len(ancestors)-3]
 659		}
 660		if parentNode.GetKind() == kinds.InputObjectDefinition {
 661			return DirectiveLocationInputFieldDefinition
 662		} else {
 663			return DirectiveLocationArgumentDefinition
 664		}
 665	}
 666	return ""
 667}
 668
 669// KnownFragmentNamesRule Known fragment names
 670//
 671// A GraphQL document is only valid if all `...Fragment` fragment spreads refer
 672// to fragments defined in the same document.
 673func KnownFragmentNamesRule(context *ValidationContext) *ValidationRuleInstance {
 674	visitorOpts := &visitor.VisitorOptions{
 675		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 676			kinds.FragmentSpread: {
 677				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 678					var action = visitor.ActionNoChange
 679					var result interface{}
 680					if node, ok := p.Node.(*ast.FragmentSpread); ok {
 681
 682						fragmentName := ""
 683						if node.Name != nil {
 684							fragmentName = node.Name.Value
 685						}
 686
 687						fragment := context.Fragment(fragmentName)
 688						if fragment == nil {
 689							reportError(
 690								context,
 691								fmt.Sprintf(`Unknown fragment "%v".`, fragmentName),
 692								[]ast.Node{node.Name},
 693							)
 694						}
 695					}
 696					return action, result
 697				},
 698			},
 699		},
 700	}
 701	return &ValidationRuleInstance{
 702		VisitorOpts: visitorOpts,
 703	}
 704}
 705
 706func unknownTypeMessage(typeName string, suggestedTypes []string) string {
 707	message := fmt.Sprintf(`Unknown type "%v".`, typeName)
 708	if len(suggestedTypes) > 0 {
 709		message = fmt.Sprintf(`%v Did you mean %v?`, message, quotedOrList(suggestedTypes))
 710	}
 711
 712	return message
 713}
 714
 715// KnownTypeNamesRule Known type names
 716//
 717// A GraphQL document is only valid if referenced types (specifically
 718// variable definitions and fragment conditions) are defined by the type schema.
 719func KnownTypeNamesRule(context *ValidationContext) *ValidationRuleInstance {
 720	visitorOpts := &visitor.VisitorOptions{
 721		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 722			kinds.ObjectDefinition: {
 723				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 724					return visitor.ActionSkip, nil
 725				},
 726			},
 727			kinds.InterfaceDefinition: {
 728				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 729					return visitor.ActionSkip, nil
 730				},
 731			},
 732			kinds.UnionDefinition: {
 733				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 734					return visitor.ActionSkip, nil
 735				},
 736			},
 737			kinds.InputObjectDefinition: {
 738				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 739					return visitor.ActionSkip, nil
 740				},
 741			},
 742			kinds.Named: {
 743				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 744					if node, ok := p.Node.(*ast.Named); ok {
 745						typeNameValue := ""
 746						typeName := node.Name
 747						if typeName != nil {
 748							typeNameValue = typeName.Value
 749						}
 750						ttype := context.Schema().Type(typeNameValue)
 751						if ttype == nil {
 752							suggestedTypes := []string{}
 753							for key := range context.Schema().TypeMap() {
 754								suggestedTypes = append(suggestedTypes, key)
 755							}
 756							reportError(
 757								context,
 758								unknownTypeMessage(typeNameValue, suggestionList(typeNameValue, suggestedTypes)),
 759								[]ast.Node{node},
 760							)
 761						}
 762					}
 763					return visitor.ActionNoChange, nil
 764				},
 765			},
 766		},
 767	}
 768	return &ValidationRuleInstance{
 769		VisitorOpts: visitorOpts,
 770	}
 771}
 772
 773// LoneAnonymousOperationRule Lone anonymous operation
 774//
 775// A GraphQL document is only valid if when it contains an anonymous operation
 776// (the query short-hand) that it contains only that one operation definition.
 777func LoneAnonymousOperationRule(context *ValidationContext) *ValidationRuleInstance {
 778	var operationCount = 0
 779	visitorOpts := &visitor.VisitorOptions{
 780		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 781			kinds.Document: {
 782				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 783					if node, ok := p.Node.(*ast.Document); ok {
 784						operationCount = 0
 785						for _, definition := range node.Definitions {
 786							if definition.GetKind() == kinds.OperationDefinition {
 787								operationCount = operationCount + 1
 788							}
 789						}
 790					}
 791					return visitor.ActionNoChange, nil
 792				},
 793			},
 794			kinds.OperationDefinition: {
 795				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 796					if node, ok := p.Node.(*ast.OperationDefinition); ok {
 797						if node.Name == nil && operationCount > 1 {
 798							reportError(
 799								context,
 800								`This anonymous operation must be the only defined operation.`,
 801								[]ast.Node{node},
 802							)
 803						}
 804					}
 805					return visitor.ActionNoChange, nil
 806				},
 807			},
 808		},
 809	}
 810	return &ValidationRuleInstance{
 811		VisitorOpts: visitorOpts,
 812	}
 813}
 814
 815func CycleErrorMessage(fragName string, spreadNames []string) string {
 816	via := ""
 817	if len(spreadNames) > 0 {
 818		via = " via " + strings.Join(spreadNames, ", ")
 819	}
 820	return fmt.Sprintf(`Cannot spread fragment "%v" within itself%v.`, fragName, via)
 821}
 822
 823// NoFragmentCyclesRule No fragment cycles
 824func NoFragmentCyclesRule(context *ValidationContext) *ValidationRuleInstance {
 825
 826	// Tracks already visited fragments to maintain O(N) and to ensure that cycles
 827	// are not redundantly reported.
 828	visitedFrags := map[string]bool{}
 829
 830	// Array of AST nodes used to produce meaningful errors
 831	spreadPath := []*ast.FragmentSpread{}
 832
 833	// Position in the spread path
 834	spreadPathIndexByName := map[string]int{}
 835
 836	// This does a straight-forward DFS to find cycles.
 837	// It does not terminate when a cycle was found but continues to explore
 838	// the graph to find all possible cycles.
 839	var detectCycleRecursive func(fragment *ast.FragmentDefinition)
 840	detectCycleRecursive = func(fragment *ast.FragmentDefinition) {
 841
 842		fragmentName := ""
 843		if fragment.Name != nil {
 844			fragmentName = fragment.Name.Value
 845		}
 846		visitedFrags[fragmentName] = true
 847
 848		spreadNodes := context.FragmentSpreads(fragment.SelectionSet)
 849		if len(spreadNodes) == 0 {
 850			return
 851		}
 852
 853		spreadPathIndexByName[fragmentName] = len(spreadPath)
 854
 855		for _, spreadNode := range spreadNodes {
 856
 857			spreadName := ""
 858			if spreadNode.Name != nil {
 859				spreadName = spreadNode.Name.Value
 860			}
 861			cycleIndex, ok := spreadPathIndexByName[spreadName]
 862			if !ok {
 863				spreadPath = append(spreadPath, spreadNode)
 864				if visited, ok := visitedFrags[spreadName]; !ok || !visited {
 865					spreadFragment := context.Fragment(spreadName)
 866					if spreadFragment != nil {
 867						detectCycleRecursive(spreadFragment)
 868					}
 869				}
 870				spreadPath = spreadPath[:len(spreadPath)-1]
 871			} else {
 872				cyclePath := spreadPath[cycleIndex:]
 873
 874				spreadNames := []string{}
 875				for _, s := range cyclePath {
 876					name := ""
 877					if s.Name != nil {
 878						name = s.Name.Value
 879					}
 880					spreadNames = append(spreadNames, name)
 881				}
 882
 883				nodes := []ast.Node{}
 884				for _, c := range cyclePath {
 885					nodes = append(nodes, c)
 886				}
 887				nodes = append(nodes, spreadNode)
 888
 889				reportError(
 890					context,
 891					CycleErrorMessage(spreadName, spreadNames),
 892					nodes,
 893				)
 894			}
 895
 896		}
 897		delete(spreadPathIndexByName, fragmentName)
 898
 899	}
 900
 901	visitorOpts := &visitor.VisitorOptions{
 902		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 903			kinds.OperationDefinition: {
 904				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 905					return visitor.ActionSkip, nil
 906				},
 907			},
 908			kinds.FragmentDefinition: {
 909				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 910					if node, ok := p.Node.(*ast.FragmentDefinition); ok && node != nil {
 911						nodeName := ""
 912						if node.Name != nil {
 913							nodeName = node.Name.Value
 914						}
 915						if _, ok := visitedFrags[nodeName]; !ok {
 916							detectCycleRecursive(node)
 917						}
 918					}
 919					return visitor.ActionSkip, nil
 920				},
 921			},
 922		},
 923	}
 924	return &ValidationRuleInstance{
 925		VisitorOpts: visitorOpts,
 926	}
 927}
 928
 929func UndefinedVarMessage(varName string, opName string) string {
 930	if opName != "" {
 931		return fmt.Sprintf(`Variable "$%v" is not defined by operation "%v".`, varName, opName)
 932	}
 933	return fmt.Sprintf(`Variable "$%v" is not defined.`, varName)
 934}
 935
 936// NoUndefinedVariablesRule No undefined variables
 937//
 938// A GraphQL operation is only valid if all variables encountered, both directly
 939// and via fragment spreads, are defined by that operation.
 940func NoUndefinedVariablesRule(context *ValidationContext) *ValidationRuleInstance {
 941	var variableNameDefined = map[string]bool{}
 942
 943	visitorOpts := &visitor.VisitorOptions{
 944		KindFuncMap: map[string]visitor.NamedVisitFuncs{
 945			kinds.OperationDefinition: {
 946				Enter: func(p visitor.VisitFuncParams) (string, interface{}) {
 947					variableNameDefined = map[string]bool{}
 948					return visitor.ActionNoChange, nil
 949				},
 950				Leave: func(p visitor.VisitFuncParams) (string, interface{}) {
 951					if operation, ok := p.Node.(*ast.OperationDefinition); ok && operation != nil {
 952						usages := context.RecursiveVariableUsages(operation)
 953
 954						for _, usage := range usages {
 955							if usage == nil {
 956								continue
 957							}
 958							if usage.Node == nil {
 959								continue
 960							}
 961							varName := ""
 962							if usage.Node.Name != nil {
 963								varName = usage.Node.Name.Value
 964							}
 965							opName := ""
 966							if operation.Name != nil {
 967								opName = operation.Name.Value
 968							}
 969							if res, ok := variableNameDefined[varName]; !ok || !res {
 970								reportError(
 971									context,
 972									UndefinedVarMessage(varName, opName),
 973									[]ast.Node{usage.Node, operation},
 974								)
 975							}
 976						}
 977					}
 978					return visitor.ActionNoChange, nil
 979				},
 980			},
 981			kinds.VariableDefinition: {
 982				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
 983					if node, ok := p.Node.(*ast.VariableDefinition); ok && node != nil {
 984						variableName := ""
 985						if node.Variable != nil && node.Variable.Name != nil {
 986							variableName = node.Variable.Name.Value
 987						}
 988						variableNameDefined[variableName] = true
 989					}
 990					return visitor.ActionNoChange, nil
 991				},
 992			},
 993		},
 994	}
 995	return &ValidationRuleInstance{
 996		VisitorOpts: visitorOpts,
 997	}
 998}
 999
1000// NoUnusedFragmentsRule No unused fragments
1001//
1002// A GraphQL document is only valid if all fragment definitions are spread
1003// within operations, or spread within other fragments spread within operations.
1004func NoUnusedFragmentsRule(context *ValidationContext) *ValidationRuleInstance {
1005
1006	var fragmentDefs = []*ast.FragmentDefinition{}
1007	var operationDefs = []*ast.OperationDefinition{}
1008
1009	visitorOpts := &visitor.VisitorOptions{
1010		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1011			kinds.OperationDefinition: {
1012				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1013					if node, ok := p.Node.(*ast.OperationDefinition); ok && node != nil {
1014						operationDefs = append(operationDefs, node)
1015					}
1016					return visitor.ActionSkip, nil
1017				},
1018			},
1019			kinds.FragmentDefinition: {
1020				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1021					if node, ok := p.Node.(*ast.FragmentDefinition); ok && node != nil {
1022						fragmentDefs = append(fragmentDefs, node)
1023					}
1024					return visitor.ActionSkip, nil
1025				},
1026			},
1027			kinds.Document: {
1028				Leave: func(p visitor.VisitFuncParams) (string, interface{}) {
1029					fragmentNameUsed := map[string]bool{}
1030					for _, operation := range operationDefs {
1031						fragments := context.RecursivelyReferencedFragments(operation)
1032						for _, fragment := range fragments {
1033							fragName := ""
1034							if fragment.Name != nil {
1035								fragName = fragment.Name.Value
1036							}
1037							fragmentNameUsed[fragName] = true
1038						}
1039					}
1040
1041					for _, def := range fragmentDefs {
1042						defName := ""
1043						if def.Name != nil {
1044							defName = def.Name.Value
1045						}
1046
1047						isFragNameUsed, ok := fragmentNameUsed[defName]
1048						if !ok || isFragNameUsed != true {
1049							reportError(
1050								context,
1051								fmt.Sprintf(`Fragment "%v" is never used.`, defName),
1052								[]ast.Node{def},
1053							)
1054						}
1055					}
1056					return visitor.ActionNoChange, nil
1057				},
1058			},
1059		},
1060	}
1061	return &ValidationRuleInstance{
1062		VisitorOpts: visitorOpts,
1063	}
1064}
1065
1066func UnusedVariableMessage(varName string, opName string) string {
1067	if opName != "" {
1068		return fmt.Sprintf(`Variable "$%v" is never used in operation "%v".`, varName, opName)
1069	}
1070	return fmt.Sprintf(`Variable "$%v" is never used.`, varName)
1071}
1072
1073// NoUnusedVariablesRule No unused variables
1074//
1075// A GraphQL operation is only valid if all variables defined by an operation
1076// are used, either directly or within a spread fragment.
1077func NoUnusedVariablesRule(context *ValidationContext) *ValidationRuleInstance {
1078
1079	var variableDefs = []*ast.VariableDefinition{}
1080
1081	visitorOpts := &visitor.VisitorOptions{
1082		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1083			kinds.OperationDefinition: {
1084				Enter: func(p visitor.VisitFuncParams) (string, interface{}) {
1085					variableDefs = []*ast.VariableDefinition{}
1086					return visitor.ActionNoChange, nil
1087				},
1088				Leave: func(p visitor.VisitFuncParams) (string, interface{}) {
1089					if operation, ok := p.Node.(*ast.OperationDefinition); ok && operation != nil {
1090						variableNameUsed := map[string]bool{}
1091						usages := context.RecursiveVariableUsages(operation)
1092
1093						for _, usage := range usages {
1094							varName := ""
1095							if usage != nil && usage.Node != nil && usage.Node.Name != nil {
1096								varName = usage.Node.Name.Value
1097							}
1098							if varName != "" {
1099								variableNameUsed[varName] = true
1100							}
1101						}
1102						for _, variableDef := range variableDefs {
1103							variableName := ""
1104							if variableDef != nil && variableDef.Variable != nil && variableDef.Variable.Name != nil {
1105								variableName = variableDef.Variable.Name.Value
1106							}
1107							opName := ""
1108							if operation.Name != nil {
1109								opName = operation.Name.Value
1110							}
1111							if res, ok := variableNameUsed[variableName]; !ok || !res {
1112								reportError(
1113									context,
1114									UnusedVariableMessage(variableName, opName),
1115									[]ast.Node{variableDef},
1116								)
1117							}
1118						}
1119
1120					}
1121
1122					return visitor.ActionNoChange, nil
1123				},
1124			},
1125			kinds.VariableDefinition: {
1126				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1127					if def, ok := p.Node.(*ast.VariableDefinition); ok && def != nil {
1128						variableDefs = append(variableDefs, def)
1129					}
1130					return visitor.ActionNoChange, nil
1131				},
1132			},
1133		},
1134	}
1135	return &ValidationRuleInstance{
1136		VisitorOpts: visitorOpts,
1137	}
1138}
1139
1140func getFragmentType(context *ValidationContext, name string) Type {
1141	frag := context.Fragment(name)
1142	if frag == nil {
1143		return nil
1144	}
1145	ttype, _ := typeFromAST(*context.Schema(), frag.TypeCondition)
1146	return ttype
1147}
1148
1149func doTypesOverlap(schema *Schema, t1 Type, t2 Type) bool {
1150	if t1 == t2 {
1151		return true
1152	}
1153	if _, ok := t1.(*Object); ok {
1154		if _, ok := t2.(*Object); ok {
1155			return false
1156		}
1157		if t2, ok := t2.(Abstract); ok {
1158			for _, ttype := range schema.PossibleTypes(t2) {
1159				if ttype == t1 {
1160					return true
1161				}
1162			}
1163			return false
1164		}
1165	}
1166	if t1, ok := t1.(Abstract); ok {
1167		if _, ok := t2.(*Object); ok {
1168			for _, ttype := range schema.PossibleTypes(t1) {
1169				if ttype == t2 {
1170					return true
1171				}
1172			}
1173			return false
1174		}
1175		t1TypeNames := map[string]bool{}
1176		for _, ttype := range schema.PossibleTypes(t1) {
1177			t1TypeNames[ttype.Name()] = true
1178		}
1179		if t2, ok := t2.(Abstract); ok {
1180			for _, ttype := range schema.PossibleTypes(t2) {
1181				if hasT1TypeName, _ := t1TypeNames[ttype.Name()]; hasT1TypeName {
1182					return true
1183				}
1184			}
1185			return false
1186		}
1187	}
1188	return false
1189}
1190
1191// PossibleFragmentSpreadsRule Possible fragment spread
1192//
1193// A fragment spread is only valid if the type condition could ever possibly
1194// be true: if there is a non-empty intersection of the possible parent types,
1195// and possible types which pass the type condition.
1196func PossibleFragmentSpreadsRule(context *ValidationContext) *ValidationRuleInstance {
1197
1198	visitorOpts := &visitor.VisitorOptions{
1199		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1200			kinds.InlineFragment: {
1201				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1202					if node, ok := p.Node.(*ast.InlineFragment); ok && node != nil {
1203						fragType := context.Type()
1204						parentType, _ := context.ParentType().(Type)
1205
1206						if fragType != nil && parentType != nil && !doTypesOverlap(context.Schema(), fragType, parentType) {
1207							reportError(
1208								context,
1209								fmt.Sprintf(`Fragment cannot be spread here as objects of `+
1210									`type "%v" can never be of type "%v".`, parentType, fragType),
1211								[]ast.Node{node},
1212							)
1213						}
1214					}
1215					return visitor.ActionNoChange, nil
1216				},
1217			},
1218			kinds.FragmentSpread: {
1219				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1220					if node, ok := p.Node.(*ast.FragmentSpread); ok && node != nil {
1221						fragName := ""
1222						if node.Name != nil {
1223							fragName = node.Name.Value
1224						}
1225						fragType := getFragmentType(context, fragName)
1226						parentType, _ := context.ParentType().(Type)
1227						if fragType != nil && parentType != nil && !doTypesOverlap(context.Schema(), fragType, parentType) {
1228							reportError(
1229								context,
1230								fmt.Sprintf(`Fragment "%v" cannot be spread here as objects of `+
1231									`type "%v" can never be of type "%v".`, fragName, parentType, fragType),
1232								[]ast.Node{node},
1233							)
1234						}
1235					}
1236					return visitor.ActionNoChange, nil
1237				},
1238			},
1239		},
1240	}
1241	return &ValidationRuleInstance{
1242		VisitorOpts: visitorOpts,
1243	}
1244}
1245
1246// ProvidedNonNullArgumentsRule Provided required arguments
1247//
1248// A field or directive is only valid if all required (non-null) field arguments
1249// have been provided.
1250func ProvidedNonNullArgumentsRule(context *ValidationContext) *ValidationRuleInstance {
1251
1252	visitorOpts := &visitor.VisitorOptions{
1253		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1254			kinds.Field: {
1255				Leave: func(p visitor.VisitFuncParams) (string, interface{}) {
1256					// Validate on leave to allow for deeper errors to appear first.
1257					if fieldAST, ok := p.Node.(*ast.Field); ok && fieldAST != nil {
1258						fieldDef := context.FieldDef()
1259						if fieldDef == nil {
1260							return visitor.ActionSkip, nil
1261						}
1262
1263						argASTs := fieldAST.Arguments
1264
1265						argASTMap := map[string]*ast.Argument{}
1266						for _, arg := range argASTs {
1267							name := ""
1268							if arg.Name != nil {
1269								name = arg.Name.Value
1270							}
1271							argASTMap[name] = arg
1272						}
1273						for _, argDef := range fieldDef.Args {
1274							argAST, _ := argASTMap[argDef.Name()]
1275							if argAST == nil {
1276								if argDefType, ok := argDef.Type.(*NonNull); ok {
1277									fieldName := ""
1278									if fieldAST.Name != nil {
1279										fieldName = fieldAST.Name.Value
1280									}
1281									reportError(
1282										context,
1283										fmt.Sprintf(`Field "%v" argument "%v" of type "%v" `+
1284											`is required but not provided.`, fieldName, argDef.Name(), argDefType),
1285										[]ast.Node{fieldAST},
1286									)
1287								}
1288							}
1289						}
1290					}
1291					return visitor.ActionNoChange, nil
1292				},
1293			},
1294			kinds.Directive: {
1295				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1296					// Validate on leave to allow for deeper errors to appear first.
1297
1298					if directiveAST, ok := p.Node.(*ast.Directive); ok && directiveAST != nil {
1299						directiveDef := context.Directive()
1300						if directiveDef == nil {
1301							return visitor.ActionSkip, nil
1302						}
1303						argASTs := directiveAST.Arguments
1304
1305						argASTMap := map[string]*ast.Argument{}
1306						for _, arg := range argASTs {
1307							name := ""
1308							if arg.Name != nil {
1309								name = arg.Name.Value
1310							}
1311							argASTMap[name] = arg
1312						}
1313
1314						for _, argDef := range directiveDef.Args {
1315							argAST, _ := argASTMap[argDef.Name()]
1316							if argAST == nil {
1317								if argDefType, ok := argDef.Type.(*NonNull); ok {
1318									directiveName := ""
1319									if directiveAST.Name != nil {
1320										directiveName = directiveAST.Name.Value
1321									}
1322									reportError(
1323										context,
1324										fmt.Sprintf(`Directive "@%v" argument "%v" of type `+
1325											`"%v" is required but not provided.`, directiveName, argDef.Name(), argDefType),
1326										[]ast.Node{directiveAST},
1327									)
1328								}
1329							}
1330						}
1331					}
1332					return visitor.ActionNoChange, nil
1333				},
1334			},
1335		},
1336	}
1337	return &ValidationRuleInstance{
1338		VisitorOpts: visitorOpts,
1339	}
1340}
1341
1342// ScalarLeafsRule Scalar leafs
1343//
1344// A GraphQL document is valid only if all leaf fields (fields without
1345// sub selections) are of scalar or enum types.
1346func ScalarLeafsRule(context *ValidationContext) *ValidationRuleInstance {
1347
1348	visitorOpts := &visitor.VisitorOptions{
1349		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1350			kinds.Field: {
1351				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1352					if node, ok := p.Node.(*ast.Field); ok && node != nil {
1353						nodeName := ""
1354						if node.Name != nil {
1355							nodeName = node.Name.Value
1356						}
1357						ttype := context.Type()
1358						if ttype != nil {
1359							if IsLeafType(ttype) {
1360								if node.SelectionSet != nil {
1361									reportError(
1362										context,
1363										fmt.Sprintf(`Field "%v" of type "%v" must not have a sub selection.`, nodeName, ttype),
1364										[]ast.Node{node.SelectionSet},
1365									)
1366								}
1367							} else if node.SelectionSet == nil {
1368								reportError(
1369									context,
1370									fmt.Sprintf(`Field "%v" of type "%v" must have a sub selection.`, nodeName, ttype),
1371									[]ast.Node{node},
1372								)
1373							}
1374						}
1375					}
1376					return visitor.ActionNoChange, nil
1377				},
1378			},
1379		},
1380	}
1381	return &ValidationRuleInstance{
1382		VisitorOpts: visitorOpts,
1383	}
1384}
1385
1386// UniqueArgumentNamesRule Unique argument names
1387//
1388// A GraphQL field or directive is only valid if all supplied arguments are
1389// uniquely named.
1390func UniqueArgumentNamesRule(context *ValidationContext) *ValidationRuleInstance {
1391	knownArgNames := map[string]*ast.Name{}
1392
1393	visitorOpts := &visitor.VisitorOptions{
1394		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1395			kinds.Field: {
1396				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1397					knownArgNames = map[string]*ast.Name{}
1398					return visitor.ActionNoChange, nil
1399				},
1400			},
1401			kinds.Directive: {
1402				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1403					knownArgNames = map[string]*ast.Name{}
1404					return visitor.ActionNoChange, nil
1405				},
1406			},
1407			kinds.Argument: {
1408				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1409					if node, ok := p.Node.(*ast.Argument); ok {
1410						argName := ""
1411						if node.Name != nil {
1412							argName = node.Name.Value
1413						}
1414						if nameAST, ok := knownArgNames[argName]; ok {
1415							reportError(
1416								context,
1417								fmt.Sprintf(`There can be only one argument named "%v".`, argName),
1418								[]ast.Node{nameAST, node.Name},
1419							)
1420						} else {
1421							knownArgNames[argName] = node.Name
1422						}
1423					}
1424					return visitor.ActionSkip, nil
1425				},
1426			},
1427		},
1428	}
1429	return &ValidationRuleInstance{
1430		VisitorOpts: visitorOpts,
1431	}
1432}
1433
1434// UniqueFragmentNamesRule Unique fragment names
1435//
1436// A GraphQL document is only valid if all defined fragments have unique names.
1437func UniqueFragmentNamesRule(context *ValidationContext) *ValidationRuleInstance {
1438	knownFragmentNames := map[string]*ast.Name{}
1439
1440	visitorOpts := &visitor.VisitorOptions{
1441		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1442			kinds.OperationDefinition: {
1443				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1444					return visitor.ActionSkip, nil
1445				},
1446			},
1447			kinds.FragmentDefinition: {
1448				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1449					if node, ok := p.Node.(*ast.FragmentDefinition); ok && node != nil {
1450						fragmentName := ""
1451						if node.Name != nil {
1452							fragmentName = node.Name.Value
1453						}
1454						if nameAST, ok := knownFragmentNames[fragmentName]; ok {
1455							reportError(
1456								context,
1457								fmt.Sprintf(`There can only be one fragment named "%v".`, fragmentName),
1458								[]ast.Node{nameAST, node.Name},
1459							)
1460						} else {
1461							knownFragmentNames[fragmentName] = node.Name
1462						}
1463					}
1464					return visitor.ActionSkip, nil
1465				},
1466			},
1467		},
1468	}
1469	return &ValidationRuleInstance{
1470		VisitorOpts: visitorOpts,
1471	}
1472}
1473
1474// UniqueInputFieldNamesRule Unique input field names
1475//
1476// A GraphQL input object value is only valid if all supplied fields are
1477// uniquely named.
1478func UniqueInputFieldNamesRule(context *ValidationContext) *ValidationRuleInstance {
1479	knownNameStack := []map[string]*ast.Name{}
1480	knownNames := map[string]*ast.Name{}
1481
1482	visitorOpts := &visitor.VisitorOptions{
1483		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1484			kinds.ObjectValue: {
1485				Enter: func(p visitor.VisitFuncParams) (string, interface{}) {
1486					knownNameStack = append(knownNameStack, knownNames)
1487					knownNames = map[string]*ast.Name{}
1488					return visitor.ActionNoChange, nil
1489				},
1490				Leave: func(p visitor.VisitFuncParams) (string, interface{}) {
1491					// pop
1492					knownNames, knownNameStack = knownNameStack[len(knownNameStack)-1], knownNameStack[:len(knownNameStack)-1]
1493					return visitor.ActionNoChange, nil
1494				},
1495			},
1496			kinds.ObjectField: {
1497				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1498					if node, ok := p.Node.(*ast.ObjectField); ok {
1499						fieldName := ""
1500						if node.Name != nil {
1501							fieldName = node.Name.Value
1502						}
1503						if knownNameAST, ok := knownNames[fieldName]; ok {
1504							reportError(
1505								context,
1506								fmt.Sprintf(`There can be only one input field named "%v".`, fieldName),
1507								[]ast.Node{knownNameAST, node.Name},
1508							)
1509						} else {
1510							knownNames[fieldName] = node.Name
1511						}
1512
1513					}
1514					return visitor.ActionSkip, nil
1515				},
1516			},
1517		},
1518	}
1519	return &ValidationRuleInstance{
1520		VisitorOpts: visitorOpts,
1521	}
1522}
1523
1524// UniqueOperationNamesRule Unique operation names
1525//
1526// A GraphQL document is only valid if all defined operations have unique names.
1527func UniqueOperationNamesRule(context *ValidationContext) *ValidationRuleInstance {
1528	knownOperationNames := make(map[string]ast.Node)
1529
1530	visitorOpts := &visitor.VisitorOptions{
1531		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1532			kinds.OperationDefinition: {
1533				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1534					if node, ok := p.Node.(*ast.OperationDefinition); ok && node != nil {
1535						operationName := ""
1536						if node.Name != nil {
1537							operationName = node.Name.Value
1538						}
1539						var errNode ast.Node = node
1540						if node.Name != nil {
1541							errNode = node.Name
1542						}
1543						if nameAST, ok := knownOperationNames[operationName]; ok {
1544							reportError(
1545								context,
1546								fmt.Sprintf(`There can only be one operation named "%v".`, operationName),
1547								[]ast.Node{nameAST, errNode},
1548							)
1549						} else {
1550							knownOperationNames[operationName] = errNode
1551						}
1552					}
1553					return visitor.ActionSkip, nil
1554				},
1555			},
1556			kinds.FragmentDefinition: {
1557				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1558					return visitor.ActionSkip, nil
1559				},
1560			},
1561		},
1562	}
1563	return &ValidationRuleInstance{
1564		VisitorOpts: visitorOpts,
1565	}
1566}
1567
1568// UniqueVariableNamesRule Unique variable names
1569//
1570// A GraphQL operation is only valid if all its variables are uniquely named.
1571func UniqueVariableNamesRule(context *ValidationContext) *ValidationRuleInstance {
1572	knownVariableNames := map[string]*ast.Name{}
1573
1574	visitorOpts := &visitor.VisitorOptions{
1575		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1576			kinds.OperationDefinition: {
1577				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1578					if node, ok := p.Node.(*ast.OperationDefinition); ok && node != nil {
1579						knownVariableNames = map[string]*ast.Name{}
1580					}
1581					return visitor.ActionNoChange, nil
1582				},
1583			},
1584			kinds.VariableDefinition: {
1585				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1586					if node, ok := p.Node.(*ast.VariableDefinition); ok && node != nil {
1587						variableName := ""
1588						var variableNameAST *ast.Name
1589						if node.Variable != nil && node.Variable.Name != nil {
1590							variableNameAST = node.Variable.Name
1591							variableName = node.Variable.Name.Value
1592						}
1593						if nameAST, ok := knownVariableNames[variableName]; ok {
1594							reportError(
1595								context,
1596								fmt.Sprintf(`There can only be one variable named "%v".`, variableName),
1597								[]ast.Node{nameAST, variableNameAST},
1598							)
1599						} else {
1600							knownVariableNames[variableName] = variableNameAST
1601						}
1602					}
1603					return visitor.ActionNoChange, nil
1604				},
1605			},
1606		},
1607	}
1608	return &ValidationRuleInstance{
1609		VisitorOpts: visitorOpts,
1610	}
1611}
1612
1613// VariablesAreInputTypesRule Variables are input types
1614//
1615// A GraphQL operation is only valid if all the variables it defines are of
1616// input types (scalar, enum, or input object).
1617func VariablesAreInputTypesRule(context *ValidationContext) *ValidationRuleInstance {
1618
1619	visitorOpts := &visitor.VisitorOptions{
1620		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1621			kinds.VariableDefinition: {
1622				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1623					if node, ok := p.Node.(*ast.VariableDefinition); ok && node != nil {
1624						ttype, _ := typeFromAST(*context.Schema(), node.Type)
1625
1626						// If the variable type is not an input type, return an error.
1627						if ttype != nil && !IsInputType(ttype) {
1628							variableName := ""
1629							if node.Variable != nil && node.Variable.Name != nil {
1630								variableName = node.Variable.Name.Value
1631							}
1632							reportError(
1633								context,
1634								fmt.Sprintf(`Variable "$%v" cannot be non-input type "%v".`,
1635									variableName, printer.Print(node.Type)),
1636								[]ast.Node{node.Type},
1637							)
1638						}
1639					}
1640					return visitor.ActionNoChange, nil
1641				},
1642			},
1643		},
1644	}
1645	return &ValidationRuleInstance{
1646		VisitorOpts: visitorOpts,
1647	}
1648}
1649
1650// If a variable definition has a default value, it's effectively non-null.
1651func effectiveType(varType Type, varDef *ast.VariableDefinition) Type {
1652	if varDef.DefaultValue == nil {
1653		return varType
1654	}
1655	if _, ok := varType.(*NonNull); ok {
1656		return varType
1657	}
1658	return NewNonNull(varType)
1659}
1660
1661// VariablesInAllowedPositionRule Variables passed to field arguments conform to type
1662func VariablesInAllowedPositionRule(context *ValidationContext) *ValidationRuleInstance {
1663
1664	varDefMap := map[string]*ast.VariableDefinition{}
1665
1666	visitorOpts := &visitor.VisitorOptions{
1667		KindFuncMap: map[string]visitor.NamedVisitFuncs{
1668			kinds.OperationDefinition: {
1669				Enter: func(p visitor.VisitFuncParams) (string, interface{}) {
1670					varDefMap = map[string]*ast.VariableDefinition{}
1671					return visitor.ActionNoChange, nil
1672				},
1673				Leave: func(p visitor.VisitFuncParams) (string, interface{}) {
1674					if operation, ok := p.Node.(*ast.OperationDefinition); ok {
1675
1676						usages := context.RecursiveVariableUsages(operation)
1677						for _, usage := range usages {
1678							varName := ""
1679							if usage != nil && usage.Node != nil && usage.Node.Name != nil {
1680								varName = usage.Node.Name.Value
1681							}
1682							varDef, _ := varDefMap[varName]
1683							if varDef != nil && usage.Type != nil {
1684								varType, err := typeFromAST(*context.Schema(), varDef.Type)
1685								if err != nil {
1686									varType = nil
1687								}
1688								if varType != nil && !isTypeSubTypeOf(context.Schema(), effectiveType(varType, varDef), usage.Type) {
1689									reportError(
1690										context,
1691										fmt.Sprintf(`Variable "$%v" of type "%v" used in position `+
1692											`expecting type "%v".`, varName, varType, usage.Type),
1693										[]ast.Node{varDef, usage.Node},
1694									)
1695								}
1696							}
1697						}
1698
1699					}
1700					return visitor.ActionNoChange, nil
1701				},
1702			},
1703			kinds.VariableDefinition: {
1704				Kind: func(p visitor.VisitFuncParams) (string, interface{}) {
1705					if varDefAST, ok := p.Node.(*ast.VariableDefinition); ok {
1706						defName := ""
1707						if varDefAST.Variable != nil && varDefAST.Variable.Name != nil {
1708							defName = varDefAST.Variable.Name.Value
1709						}
1710						if defName != "" {
1711							varDefMap[defName] = varDefAST
1712						}
1713					}
1714					return visitor.ActionNoChange, nil
1715				},
1716			},
1717		},
1718	}
1719	return &ValidationRuleInstance{
1720		VisitorOpts: visitorOpts,
1721	}
1722}
1723
1724// Utility for validators which determines if a value literal AST is valid given
1725// an input type.
1726//
1727// Note that this only validates literal values, variables are assumed to
1728// provide values of the correct type.
1729func isValidLiteralValue(ttype Input, valueAST ast.Value) (bool, []string) {
1730	// A value must be provided if the type is non-null.
1731	if ttype, ok := ttype.(*NonNull); ok {
1732		if e := ttype.Error(); e != nil {
1733			return false, []string{e.Error()}
1734		}
1735		if valueAST == nil {
1736			if ttype.OfType.Name() != "" {
1737				return false, []string{fmt.Sprintf(`Expected "%v!", found null.`, ttype.OfType.Name())}
1738			}
1739			return false, []string{"Expected non-null value, found null."}
1740		}
1741		ofType, _ := ttype.OfType.(Input)
1742		return isValidLiteralValue(ofType, valueAST)
1743	}
1744
1745	if valueAST == nil {
1746		return true, nil
1747	}
1748
1749	// This function only tests literals, and assumes variables will provide
1750	// values of the correct type.
1751	if valueAST.GetKind() == kinds.Variable {
1752		return true, nil
1753	}
1754
1755	// Lists accept a non-list value as a list of one.
1756	if ttype, ok := ttype.(*List); ok {
1757		itemType, _ := ttype.OfType.(Input)
1758		if valueAST, ok := valueAST.(*ast.ListValue); ok {
1759			messagesReduce := []string{}
1760			for _, value := range valueAST.Values {
1761				_, messages := isValidLiteralValue(itemType, value)
1762				for idx, message := range messages {
1763					messagesReduce = append(messagesReduce, fmt.Sprintf(`In element #%v: %v`, idx+1, message))
1764				}
1765			}
1766			return (len(messagesReduce) == 0), messagesReduce
1767		}
1768		return isValidLiteralValue(itemType, valueAST)
1769
1770	}
1771
1772	// Input objects check each defined field and look for undefined fields.
1773	if ttype, ok := ttype.(*InputObject); ok {
1774		valueAST, ok := valueAST.(*ast.ObjectValue)
1775		if !ok {
1776			return false, []string{fmt.Sprintf(`Expected "%v", found not an object.`, ttype.Name())}
1777		}
1778		fields := ttype.Fields()
1779		messagesReduce := []string{}
1780
1781		// Ensure every provided field is defined.
1782		fieldASTs := valueAST.Fields
1783		fieldASTMap := map[string]*ast.ObjectField{}
1784		for _, fieldAST := range fieldASTs {
1785			fieldASTName := ""
1786			if fieldAST.Name != nil {
1787				fieldASTName = fieldAST.Name.Value
1788			}
1789
1790			fieldASTMap[fieldASTName] = fieldAST
1791
1792			field, ok := fields[fieldASTName]
1793			if !ok || field == nil {
1794				messagesReduce = append(messagesReduce, fmt.Sprintf(`In field "%v": Unknown field.`, fieldASTName))
1795			}
1796		}
1797		// Ensure every defined field is valid.
1798		for fieldName, field := range fields {
1799			fieldAST, _ := fieldASTMap[fieldName]
1800			var fieldASTValue ast.Value
1801			if fieldAST != nil {
1802				fieldASTValue = fieldAST.Value
1803			}
1804			if isValid, messages := isValidLiteralValue(field.Type, fieldASTValue); !isValid {
1805				for _, message := range messages {
1806					messagesReduce = append(messagesReduce, fmt.Sprintf("In field \"%v\": %v", fieldName, message))
1807				}
1808			}
1809		}
1810		return (len(messagesReduce) == 0), messagesReduce
1811	}
1812
1813	if ttype, ok := ttype.(*Scalar); ok {
1814		if isNullish(ttype.ParseLiteral(valueAST)) {
1815			return false, []string{fmt.Sprintf(`Expected type "%v", found %v.`, ttype.Name(), printer.Print(valueAST))}
1816		}
1817	}
1818	if ttype, ok := ttype.(*Enum); ok {
1819		if isNullish(ttype.ParseLiteral(valueAST)) {
1820			return false, []string{fmt.Sprintf(`Expected type "%v", found %v.`, ttype.Name(), printer.Print(valueAST))}
1821		}
1822	}
1823
1824	return true, nil
1825}
1826
1827// Internal struct to sort results from suggestionList()
1828type suggestionListResult struct {
1829	Options   []string
1830	Distances []float64
1831}
1832
1833func (s suggestionListResult) Len() int {
1834	return len(s.Options)
1835}
1836func (s suggestionListResult) Swap(i, j int) {
1837	s.Options[i], s.Options[j] = s.Options[j], s.Options[i]
1838}
1839func (s suggestionListResult) Less(i, j int) bool {
1840	return s.Distances[i] < s.Distances[j]
1841}
1842
1843// suggestionList Given an invalid input string and a list of valid options, returns a filtered
1844// list of valid options sorted based on their similarity with the input.
1845func suggestionList(input string, options []string) []string {
1846	dists := []float64{}
1847	filteredOpts := []string{}
1848	inputThreshold := float64(len(input) / 2)
1849
1850	for _, opt := range options {
1851		dist := lexicalDistance(input, opt)
1852		threshold := math.Max(inputThreshold, float64(len(opt)/2))
1853		threshold = math.Max(threshold, 1)
1854		if dist <= threshold {
1855			filteredOpts = append(filteredOpts, opt)
1856			dists = append(dists, dist)
1857		}
1858	}
1859	//sort results
1860	suggested := suggestionListResult{filteredOpts, dists}
1861	sort.Sort(suggested)
1862	return suggested.Options
1863}
1864
1865// lexicalDistance Computes the lexical distance between strings A and B.
1866// The "distance" between two strings is given by counting the minimum number
1867// of edits needed to transform string A into string B. An edit can be an
1868// insertion, deletion, or substitution of a single character, or a swap of two
1869// adjacent characters.
1870// This distance can be useful for detecting typos in input or sorting
1871func lexicalDistance(a, b string) float64 {
1872	d := [][]float64{}
1873	aLen := len(a)
1874	bLen := len(b)
1875	for i := 0; i <= aLen; i++ {
1876		d = append(d, []float64{float64(i)})
1877	}
1878	for k := 1; k <= bLen; k++ {
1879		d[0] = append(d[0], float64(k))
1880	}
1881
1882	for i := 1; i <= aLen; i++ {
1883		for k := 1; k <= bLen; k++ {
1884			cost := 1.0
1885			if a[i-1] == b[k-1] {
1886				cost = 0.0
1887			}
1888			minCostFloat := math.Min(
1889				d[i-1][k]+1.0,
1890				d[i][k-1]+1.0,
1891			)
1892			minCostFloat = math.Min(
1893				minCostFloat,
1894				d[i-1][k-1]+cost,
1895			)
1896			d[i] = append(d[i], minCostFloat)
1897
1898			if i > 1 && k < 1 &&
1899				a[i-1] == b[k-2] &&
1900				a[i-2] == b[k-1] {
1901				d[i][k] = math.Min(d[i][k], d[i-2][k-2]+cost)
1902			}
1903		}
1904	}
1905
1906	return d[aLen][bLen]
1907}