func parseSchemaDefinition(parser *Parser) (ast.Node, 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 := reverse(
		parser,
		lexer.TokenKind[lexer.BRACE_L], parseOperationTypeDefinition, lexer.TokenKind[lexer.BRACE_R],
		true,
	)
	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
}
SchemaDefinition : schema Directives? { OperationTypeDefinition+ }

OperationTypeDefinition : OperationType : NamedType
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 parseDefinitionFn func(parser *Parser) (ast.Node, error)
var tokenDefinitionFn map[string]parseDefinitionFn
func init() {
	tokenDefinitionFn = make(map[string]parseDefinitionFn)
	{
		tokenDefinitionFn[lexer.GetTokenKindDesc(lexer.BRACE_L)] = parseOperationDefinition
		tokenDefinitionFn[lexer.GetTokenKindDesc(lexer.STRING)] = parseTypeSystemDefinition
		tokenDefinitionFn[lexer.GetTokenKindDesc(lexer.BLOCK_STRING)] = parseTypeSystemDefinition
		tokenDefinitionFn[lexer.GetTokenKindDesc(lexer.NAME)] = parseTypeSystemDefinition
		tokenDefinitionFn[lexer.FRAGMENT] = parseFragmentDefinition
		tokenDefinitionFn[lexer.QUERY] = parseOperationDefinition
		tokenDefinitionFn[lexer.MUTATION] = parseOperationDefinition
		tokenDefinitionFn[lexer.SUBSCRIPTION] = parseOperationDefinition
		tokenDefinitionFn[lexer.SCHEMA] = parseSchemaDefinition
		tokenDefinitionFn[lexer.SCALAR] = parseScalarTypeDefinition
		tokenDefinitionFn[lexer.TYPE] = parseObjectTypeDefinition
		tokenDefinitionFn[lexer.INTERFACE] = parseInterfaceTypeDefinition
		tokenDefinitionFn[lexer.UNION] = parseUnionTypeDefinition
		tokenDefinitionFn[lexer.ENUM] = parseEnumTypeDefinition
		tokenDefinitionFn[lexer.INPUT] = parseInputObjectTypeDefinition
		tokenDefinitionFn[lexer.EXTEND] = parseTypeExtensionDefinition
		tokenDefinitionFn[lexer.DIRECTIVE] = parseDirectiveDefinition
	}
}
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
}
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
}
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
}
func parseDocument(parser *Parser) (*ast.Document, error) {
	var (
		nodes []ast.Node
		node  ast.Node
		item  parseDefinitionFn
		err   error
	)
	start := parser.Token.Start
	for {
		if skp, err := skip(parser, lexer.TokenKind[lexer.EOF]); err != nil {
			return nil, err
		} else if skp {
			break
		}
		switch parser.Token.Kind {
		case lexer.TokenKind[lexer.BRACE_L]:
			item = tokenDefinitionFn[lexer.GetTokenKindDesc(lexer.TokenKind[lexer.BRACE_L])]
		case lexer.TokenKind[lexer.NAME]:
			item = tokenDefinitionFn[lexer.GetTokenKindDesc(lexer.TokenKind[lexer.NAME])]
		case lexer.TokenKind[lexer.STRING]:
			item = tokenDefinitionFn[lexer.GetTokenKindDesc(lexer.TokenKind[lexer.STRING])]
		case lexer.TokenKind[lexer.BLOCK_STRING]:
			item = tokenDefinitionFn[lexer.GetTokenKindDesc(lexer.TokenKind[lexer.BLOCK_STRING])]
		default:
			return nil, unexpected(parser, lexer.Token{})
		}
		if node, err = item(parser); err != nil {
			return nil, err
		}
		nodes = append(nodes, node)
	}
	return ast.NewDocument(&ast.Document{
		Loc:         loc(parser, start),
		Definitions: nodes,
	}), nil
}
func parseOperationDefinition(parser *Parser) (ast.Node, error) {
	var (
		operation           string
		variableDefinitions []*ast.VariableDefinition
		name                *ast.Name
		directives          []*ast.Directive
		selectionSet        *ast.SelectionSet
		err                 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
	}
	if operation, err = parseOperationType(parser); err != nil {
		return nil, err
	}
	if peek(parser, lexer.TokenKind[lexer.NAME]) {
		if name, err = parseName(parser); err != nil {
			return nil, err
		}
	}
	if variableDefinitions, err = parseVariableDefinitions(parser); err != nil {
		return nil, err
	}
	if directives, err = parseDirectives(parser); err != nil {
		return nil, err
	}
	if selectionSet, err = parseSelectionSet(parser); 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
}
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)
	}
}
func parseVariableDefinitions(parser *Parser) ([]*ast.VariableDefinition, error) {
	variableDefinitions := []*ast.VariableDefinition{}
	if !peek(parser, lexer.TokenKind[lexer.PAREN_L]) {
		return variableDefinitions, nil
	}
	if vdefs, err := reverse(parser,
		lexer.TokenKind[lexer.PAREN_L], parseVariableDefinition, lexer.TokenKind[lexer.PAREN_R],
		true,
	); err != nil {
		return variableDefinitions, err
	} else {
		for _, vdef := range vdefs {
			variableDefinitions = append(variableDefinitions, vdef.(*ast.VariableDefinition))
		}
	}
	return variableDefinitions, nil
}
func parseVariableDefinition(parser *Parser) (interface{}, error) {
	var (
		variable *ast.Variable
		ttype    ast.Type
		err      error
	)
	start := parser.Token.Start
	if variable, err = parseVariable(parser); err != nil {
		return nil, err
	}
	if _, err = expect(parser, lexer.TokenKind[lexer.COLON]); err != nil {
		return nil, err
	}
	if ttype, err = parseType(parser); 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 {
		if defaultValue, err = parseValueLiteral(parser, true); err != nil {
			return nil, err
		}
	}
	return ast.NewVariableDefinition(&ast.VariableDefinition{
		Variable:     variable,
		Type:         ttype,
		DefaultValue: defaultValue,
		Loc:          loc(parser, start),
	}), nil
}
func parseVariable(parser *Parser) (*ast.Variable, error) {
	var (
		err  error
		name *ast.Name
	)
	start := parser.Token.Start
	if _, err = expect(parser, lexer.TokenKind[lexer.DOLLAR]); err != nil {
		return nil, err
	}
	if name, err = parseName(parser); err != nil {
		return nil, err
	}
	return ast.NewVariable(&ast.Variable{
		Name: name,
		Loc:  loc(parser, start),
	}), nil
}
func parseSelectionSet(parser *Parser) (*ast.SelectionSet, error) {
	start := parser.Token.Start
	selections := []ast.Selection{}
	if iSelections, err := reverse(parser,
		lexer.TokenKind[lexer.BRACE_L], parseSelection, lexer.TokenKind[lexer.BRACE_R],
		true,
	); err != nil {
		return nil, err
	} else {
		for _, iSelection := range iSelections {
			selections = append(selections, iSelection.(ast.Selection))
		}
	}
	return ast.NewSelectionSet(&ast.SelectionSet{
		Selections: selections,
		Loc:        loc(parser, start),
	}), nil
}
func parseSelection(parser *Parser) (interface{}, error) {
	if peek(parser, lexer.TokenKind[lexer.SPREAD]) {
		return parseFragment(parser)
	}
	return parseField(parser)
}
func parseField(parser *Parser) (*ast.Field, error) {
	var (
		name       *ast.Name
		alias      *ast.Name
		arguments  []*ast.Argument
		directives []*ast.Directive
		err        error
	)
	start := parser.Token.Start
	if name, err = parseName(parser); err != nil {
		return nil, err
	}
	if skp, err := skip(parser, lexer.TokenKind[lexer.COLON]); err != nil {
		return nil, err
	} else if skp {
		alias = name
		if name, err = parseName(parser); err != nil {
			return nil, err
		}
	}
	if arguments, err = parseArguments(parser); err != nil {
		return nil, err
	}
	if directives, err = parseDirectives(parser); err != nil {
		return nil, err
	}
	var selectionSet *ast.SelectionSet
	if peek(parser, lexer.TokenKind[lexer.BRACE_L]) {
		if selectionSet, err = parseSelectionSet(parser); err != nil {
			return nil, err
		}
	}
	return ast.NewField(&ast.Field{
		Alias:        alias,
		Name:         name,
		Arguments:    arguments,
		Directives:   directives,
		SelectionSet: selectionSet,
		Loc:          loc(parser, start),
	}), nil
}
func parseArguments(parser *Parser) ([]*ast.Argument, error) {
	arguments := []*ast.Argument{}
	if peek(parser, lexer.TokenKind[lexer.PAREN_L]) {
		if iArguments, err := reverse(parser,
			lexer.TokenKind[lexer.PAREN_L], parseArgument, lexer.TokenKind[lexer.PAREN_R],
			true,
		); err != nil {
			return arguments, err
		} else {
			for _, iArgument := range iArguments {
				arguments = append(arguments, iArgument.(*ast.Argument))
			}
		}
	}
	return arguments, nil
}
func parseArgument(parser *Parser) (interface{}, error) {
	var (
		err   error
		name  *ast.Name
		value ast.Value
	)
	start := parser.Token.Start
	if name, err = parseName(parser); err != nil {
		return nil, err
	}
	if _, err = expect(parser, lexer.TokenKind[lexer.COLON]); err != nil {
		return nil, err
	}
	if value, err = parseValueLiteral(parser, false); err != nil {
		return nil, err
	}
	return ast.NewArgument(&ast.Argument{
		Name:  name,
		Value: value,
		Loc:   loc(parser, start),
	}), nil
}
func parseFragment(parser *Parser) (interface{}, error) {
	var (
		err error
	)
	start := parser.Token.Start
	if _, err = expect(parser, lexer.TokenKind[lexer.SPREAD]); 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
}
func parseFragmentDefinition(parser *Parser) (ast.Node, error) {
	start := parser.Token.Start
	_, err := expectKeyWord(parser, lexer.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
}
func parseFragmentName(parser *Parser) (*ast.Name, error) {
	if parser.Token.Value == "on" {
		return nil, unexpected(parser, lexer.Token{})
	}
	return parseName(parser)
}
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)
		}
	}
	return nil, unexpected(parser, lexer.Token{})
}
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)
}
func parseList(parser *Parser, isConst bool) (*ast.ListValue, error) {
	start := parser.Token.Start
	var item parseFn = parseValueValue
	if isConst {
		item = parseConstValue
	}
	values := []ast.Value{}
	if iValues, err := reverse(parser,
		lexer.TokenKind[lexer.BRACKET_L], item, lexer.TokenKind[lexer.BRACKET_R],
		false,
	); err != nil {
		return nil, err
	} else {
		for _, iValue := range iValues {
			values = append(values, iValue.(ast.Value))
		}
	}
	return ast.NewListValue(&ast.ListValue{
		Values: values,
		Loc:    loc(parser, start),
	}), nil
}
func parseObject(parser *Parser, isConst bool) (*ast.ObjectValue, error) {
	start := parser.Token.Start
	if _, err := expect(parser, lexer.TokenKind[lexer.BRACE_L]); 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
		}
		if field, err := parseObjectField(parser, isConst); err != nil {
			return nil, err
		} else {
			fields = append(fields, field)
		}
	}
	return ast.NewObjectValue(&ast.ObjectValue{
		Fields: fields,
		Loc:    loc(parser, start),
	}), nil
}
func parseObjectField(parser *Parser, isConst bool) (*ast.ObjectField, error) {
	var (
		name  *ast.Name
		value ast.Value
		err   error
	)
	start := parser.Token.Start
	if name, err = parseName(parser); err != nil {
		return nil, err
	}
	if _, err = expect(parser, lexer.TokenKind[lexer.COLON]); err != nil {
		return nil, err
	}
	if value, err = parseValueLiteral(parser, isConst); err != nil {
		return nil, err
	}
	return ast.NewObjectField(&ast.ObjectField{
		Name:  name,
		Value: value,
		Loc:   loc(parser, start),
	}), nil
}
func parseDirectives(parser *Parser) ([]*ast.Directive, error) {
	directives := []*ast.Directive{}
	for peek(parser, lexer.TokenKind[lexer.AT]) {
		if directive, err := parseDirective(parser); err != nil {
			return directives, err
		} else {
			directives = append(directives, directive)
		}
	}
	return directives, nil
}
func parseDirective(parser *Parser) (*ast.Directive, error) {
	var (
		err  error
		name *ast.Name
		args []*ast.Argument
	)
	start := parser.Token.Start
	if _, err = expect(parser, lexer.TokenKind[lexer.AT]); err != nil {
		return nil, err
	}
	if name, err = parseName(parser); err != nil {
		return nil, err
	}
	if args, err = parseArguments(parser); err != nil {
		return nil, err
	}
	return ast.NewDirective(&ast.Directive{
		Name:      name,
		Arguments: args,
		Loc:       loc(parser, start),
	}), nil
}
func parseType(parser *Parser) (ttype ast.Type, err error) {
	token := parser.Token
	switch token.Kind {
	case lexer.TokenKind[lexer.BRACKET_L]:
		if err = advance(parser); err != nil {
			return nil, err
		}
		if ttype, err = parseType(parser); err != nil {
			return nil, err
		}
		fallthrough
	case lexer.TokenKind[lexer.BRACKET_R]:
		if err = advance(parser); err != nil {
			return nil, err
		}
		ttype = ast.NewList(&ast.List{
			Type: ttype,
			Loc:  loc(parser, token.Start),
		})
	case lexer.TokenKind[lexer.NAME]:
		if ttype, err = parseNamed(parser); err != nil {
			return nil, err
		}
	}
	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, token.Start),
		})
	}
	return ttype, nil
}
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
}
func parseTypeSystemDefinition(parser *Parser) (ast.Node, error) {
	var (
		item parseDefinitionFn
		err  error
	)
	keywordToken := parser.Token
	if peekDescription(parser) {
		if keywordToken, err = lookahead(parser); err != nil {
			return nil, err
		}
	}
	if keywordToken.Kind != lexer.NAME {
		return nil, unexpected(parser, keywordToken)
	}
	var ok bool
	if item, ok = tokenDefinitionFn[keywordToken.Value]; !ok {
		return nil, unexpected(parser, keywordToken)
	}
	return item(parser)
}