diff options
author | Michael Muré <batolettre@gmail.com> | 2018-09-14 12:40:31 +0200 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2018-09-14 12:41:59 +0200 |
commit | b478cd1bcb4756b20f7f4b15fcf81f23e1a60a02 (patch) | |
tree | 8ce232dcab3dd00708f8ba66c334472457e5980d /vendor/github.com/vektah/gqlparser/parser/query.go | |
parent | a3fc9abb921f5ce7084d6ab7473442d0b72b1d78 (diff) | |
download | git-bug-b478cd1bcb4756b20f7f4b15fcf81f23e1a60a02.tar.gz |
graphql: update gqlgen to 0.5.1
fix #6
Diffstat (limited to 'vendor/github.com/vektah/gqlparser/parser/query.go')
-rw-r--r-- | vendor/github.com/vektah/gqlparser/parser/query.go | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/vendor/github.com/vektah/gqlparser/parser/query.go b/vendor/github.com/vektah/gqlparser/parser/query.go new file mode 100644 index 00000000..7fecb57f --- /dev/null +++ b/vendor/github.com/vektah/gqlparser/parser/query.go @@ -0,0 +1,334 @@ +package parser + +import ( + "github.com/vektah/gqlparser/gqlerror" + "github.com/vektah/gqlparser/lexer" + + . "github.com/vektah/gqlparser/ast" +) + +func ParseQuery(source *Source) (*QueryDocument, *gqlerror.Error) { + p := parser{ + lexer: lexer.New(source), + } + return p.parseQueryDocument(), p.err +} + +func (p *parser) parseQueryDocument() *QueryDocument { + var doc QueryDocument + for p.peek().Kind != lexer.EOF { + if p.err != nil { + return &doc + } + doc.Position = p.peekPos() + switch p.peek().Kind { + case lexer.Name: + switch p.peek().Value { + case "query", "mutation", "subscription": + doc.Operations = append(doc.Operations, p.parseOperationDefinition()) + case "fragment": + doc.Fragments = append(doc.Fragments, p.parseFragmentDefinition()) + default: + p.unexpectedError() + } + case lexer.BraceL: + doc.Operations = append(doc.Operations, p.parseOperationDefinition()) + default: + p.unexpectedError() + } + } + + return &doc +} + +func (p *parser) parseOperationDefinition() *OperationDefinition { + if p.peek().Kind == lexer.BraceL { + return &OperationDefinition{ + Position: p.peekPos(), + Operation: Query, + SelectionSet: p.parseSelectionSet(), + } + } + + var od OperationDefinition + od.Position = p.peekPos() + od.Operation = p.parseOperationType() + + if p.peek().Kind == lexer.Name { + od.Name = p.next().Value + } + + od.VariableDefinitions = p.parseVariableDefinitions() + od.Directives = p.parseDirectives(false) + od.SelectionSet = p.parseSelectionSet() + + return &od +} + +func (p *parser) parseOperationType() Operation { + tok := p.next() + switch tok.Value { + case "query": + return Query + case "mutation": + return Mutation + case "subscription": + return Subscription + } + p.unexpectedToken(tok) + return "" +} + +func (p *parser) parseVariableDefinitions() VariableDefinitionList { + var defs []*VariableDefinition + p.many(lexer.ParenL, lexer.ParenR, func() { + defs = append(defs, p.parseVariableDefinition()) + }) + + return defs +} + +func (p *parser) parseVariableDefinition() *VariableDefinition { + var def VariableDefinition + def.Position = p.peekPos() + def.Variable = p.parseVariable() + + p.expect(lexer.Colon) + + def.Type = p.parseTypeReference() + + if p.skip(lexer.Equals) { + def.DefaultValue = p.parseValueLiteral(true) + } + + return &def +} + +func (p *parser) parseVariable() string { + p.expect(lexer.Dollar) + return p.parseName() +} + +func (p *parser) parseSelectionSet() SelectionSet { + var selections []Selection + p.many(lexer.BraceL, lexer.BraceR, func() { + selections = append(selections, p.parseSelection()) + }) + + return SelectionSet(selections) +} + +func (p *parser) parseSelection() Selection { + if p.peek().Kind == lexer.Spread { + return p.parseFragment() + } + return p.parseField() +} + +func (p *parser) parseField() *Field { + var field Field + field.Position = p.peekPos() + field.Alias = p.parseName() + + if p.skip(lexer.Colon) { + field.Name = p.parseName() + } else { + field.Name = field.Alias + } + + field.Arguments = p.parseArguments(false) + field.Directives = p.parseDirectives(false) + if p.peek().Kind == lexer.BraceL { + field.SelectionSet = p.parseSelectionSet() + } + + return &field +} + +func (p *parser) parseArguments(isConst bool) ArgumentList { + var arguments ArgumentList + p.many(lexer.ParenL, lexer.ParenR, func() { + arguments = append(arguments, p.parseArgument(isConst)) + }) + + return arguments +} + +func (p *parser) parseArgument(isConst bool) *Argument { + arg := Argument{} + arg.Position = p.peekPos() + arg.Name = p.parseName() + p.expect(lexer.Colon) + + arg.Value = p.parseValueLiteral(isConst) + return &arg +} + +func (p *parser) parseFragment() Selection { + p.expect(lexer.Spread) + + if peek := p.peek(); peek.Kind == lexer.Name && peek.Value != "on" { + return &FragmentSpread{ + Position: p.peekPos(), + Name: p.parseFragmentName(), + Directives: p.parseDirectives(false), + } + } + + var def InlineFragment + def.Position = p.peekPos() + if p.peek().Value == "on" { + p.next() // "on" + + def.TypeCondition = p.parseName() + } + + def.Directives = p.parseDirectives(false) + def.SelectionSet = p.parseSelectionSet() + return &def +} + +func (p *parser) parseFragmentDefinition() *FragmentDefinition { + var def FragmentDefinition + def.Position = p.peekPos() + p.expectKeyword("fragment") + + def.Name = p.parseFragmentName() + def.VariableDefinition = p.parseVariableDefinitions() + + p.expectKeyword("on") + + def.TypeCondition = p.parseName() + def.Directives = p.parseDirectives(false) + def.SelectionSet = p.parseSelectionSet() + return &def +} + +func (p *parser) parseFragmentName() string { + if p.peek().Value == "on" { + p.unexpectedError() + return "" + } + + return p.parseName() +} + +func (p *parser) parseValueLiteral(isConst bool) *Value { + token := p.peek() + + var kind ValueKind + switch token.Kind { + case lexer.BracketL: + return p.parseList(isConst) + case lexer.BraceL: + return p.parseObject(isConst) + case lexer.Dollar: + if isConst { + p.unexpectedError() + return nil + } + return &Value{Position: &token.Pos, Raw: p.parseVariable(), Kind: Variable} + case lexer.Int: + kind = IntValue + case lexer.Float: + kind = FloatValue + case lexer.String: + kind = StringValue + case lexer.BlockString: + kind = BlockValue + case lexer.Name: + switch token.Value { + case "true", "false": + kind = BooleanValue + case "null": + kind = NullValue + default: + kind = EnumValue + } + default: + p.unexpectedError() + return nil + } + + p.next() + + return &Value{Position: &token.Pos, Raw: token.Value, Kind: kind} +} + +func (p *parser) parseList(isConst bool) *Value { + var values ChildValueList + pos := p.peekPos() + p.many(lexer.BracketL, lexer.BracketR, func() { + values = append(values, &ChildValue{Value: p.parseValueLiteral(isConst)}) + }) + + return &Value{Children: values, Kind: ListValue, Position: pos} +} + +func (p *parser) parseObject(isConst bool) *Value { + var fields ChildValueList + pos := p.peekPos() + p.many(lexer.BraceL, lexer.BraceR, func() { + fields = append(fields, p.parseObjectField(isConst)) + }) + + return &Value{Children: fields, Kind: ObjectValue, Position: pos} +} + +func (p *parser) parseObjectField(isConst bool) *ChildValue { + field := ChildValue{} + field.Position = p.peekPos() + field.Name = p.parseName() + + p.expect(lexer.Colon) + + field.Value = p.parseValueLiteral(isConst) + return &field +} + +func (p *parser) parseDirectives(isConst bool) []*Directive { + var directives []*Directive + + for p.peek().Kind == lexer.At { + if p.err != nil { + break + } + directives = append(directives, p.parseDirective(isConst)) + } + return directives +} + +func (p *parser) parseDirective(isConst bool) *Directive { + p.expect(lexer.At) + + return &Directive{ + Position: p.peekPos(), + Name: p.parseName(), + Arguments: p.parseArguments(isConst), + } +} + +func (p *parser) parseTypeReference() *Type { + var typ Type + + if p.skip(lexer.BracketL) { + typ.Position = p.peekPos() + typ.Elem = p.parseTypeReference() + p.expect(lexer.BracketR) + } else { + typ.Position = p.peekPos() + typ.NamedType = p.parseName() + } + + if p.skip(lexer.Bang) { + typ.Position = p.peekPos() + typ.NonNull = true + } + return &typ +} + +func (p *parser) parseName() string { + token := p.expect(lexer.Name) + + return token.Value +} |