diff options
Diffstat (limited to 'vendor/github.com/graphql-go/graphql/language/parser/parser.go')
-rw-r--r-- | vendor/github.com/graphql-go/graphql/language/parser/parser.go | 1636 |
1 files changed, 0 insertions, 1636 deletions
diff --git a/vendor/github.com/graphql-go/graphql/language/parser/parser.go b/vendor/github.com/graphql-go/graphql/language/parser/parser.go deleted file mode 100644 index 32beef37..00000000 --- a/vendor/github.com/graphql-go/graphql/language/parser/parser.go +++ /dev/null @@ -1,1636 +0,0 @@ -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 -} |