...

Source file src/github.com/vektah/gqlparser/v2/parser/parser.go

Documentation: github.com/vektah/gqlparser/v2/parser

     1  package parser
     2  
     3  import (
     4  	"strconv"
     5  
     6  	"github.com/vektah/gqlparser/v2/ast"
     7  	"github.com/vektah/gqlparser/v2/gqlerror"
     8  	"github.com/vektah/gqlparser/v2/lexer"
     9  )
    10  
    11  type parser struct {
    12  	lexer lexer.Lexer
    13  	err   error
    14  
    15  	peeked    bool
    16  	peekToken lexer.Token
    17  	peekError error
    18  
    19  	prev lexer.Token
    20  
    21  	comment          *ast.CommentGroup
    22  	commentConsuming bool
    23  }
    24  
    25  func (p *parser) consumeComment() (*ast.Comment, bool) {
    26  	if p.err != nil {
    27  		return nil, false
    28  	}
    29  	tok := p.peek()
    30  	if tok.Kind != lexer.Comment {
    31  		return nil, false
    32  	}
    33  	p.next()
    34  	return &ast.Comment{
    35  		Value:    tok.Value,
    36  		Position: &tok.Pos,
    37  	}, true
    38  }
    39  
    40  func (p *parser) consumeCommentGroup() {
    41  	if p.err != nil {
    42  		return
    43  	}
    44  	if p.commentConsuming {
    45  		return
    46  	}
    47  	p.commentConsuming = true
    48  
    49  	var comments []*ast.Comment
    50  	for {
    51  		comment, ok := p.consumeComment()
    52  		if !ok {
    53  			break
    54  		}
    55  		comments = append(comments, comment)
    56  	}
    57  
    58  	p.comment = &ast.CommentGroup{List: comments}
    59  	p.commentConsuming = false
    60  }
    61  
    62  func (p *parser) peekPos() *ast.Position {
    63  	if p.err != nil {
    64  		return nil
    65  	}
    66  
    67  	peek := p.peek()
    68  	return &peek.Pos
    69  }
    70  
    71  func (p *parser) peek() lexer.Token {
    72  	if p.err != nil {
    73  		return p.prev
    74  	}
    75  
    76  	if !p.peeked {
    77  		p.peekToken, p.peekError = p.lexer.ReadToken()
    78  		p.peeked = true
    79  		if p.peekToken.Kind == lexer.Comment {
    80  			p.consumeCommentGroup()
    81  		}
    82  	}
    83  
    84  	return p.peekToken
    85  }
    86  
    87  func (p *parser) error(tok lexer.Token, format string, args ...interface{}) {
    88  	if p.err != nil {
    89  		return
    90  	}
    91  	p.err = gqlerror.ErrorLocf(tok.Pos.Src.Name, tok.Pos.Line, tok.Pos.Column, format, args...)
    92  }
    93  
    94  func (p *parser) next() lexer.Token {
    95  	if p.err != nil {
    96  		return p.prev
    97  	}
    98  	if p.peeked {
    99  		p.peeked = false
   100  		p.comment = nil
   101  		p.prev, p.err = p.peekToken, p.peekError
   102  	} else {
   103  		p.prev, p.err = p.lexer.ReadToken()
   104  		if p.prev.Kind == lexer.Comment {
   105  			p.consumeCommentGroup()
   106  		}
   107  	}
   108  	return p.prev
   109  }
   110  
   111  func (p *parser) expectKeyword(value string) (lexer.Token, *ast.CommentGroup) {
   112  	tok := p.peek()
   113  	comment := p.comment
   114  	if tok.Kind == lexer.Name && tok.Value == value {
   115  		return p.next(), comment
   116  	}
   117  
   118  	p.error(tok, "Expected %s, found %s", strconv.Quote(value), tok.String())
   119  	return tok, comment
   120  }
   121  
   122  func (p *parser) expect(kind lexer.Type) (lexer.Token, *ast.CommentGroup) {
   123  	tok := p.peek()
   124  	comment := p.comment
   125  	if tok.Kind == kind {
   126  		return p.next(), comment
   127  	}
   128  
   129  	p.error(tok, "Expected %s, found %s", kind, tok.Kind.String())
   130  	return tok, comment
   131  }
   132  
   133  func (p *parser) skip(kind lexer.Type) bool {
   134  	if p.err != nil {
   135  		return false
   136  	}
   137  
   138  	tok := p.peek()
   139  
   140  	if tok.Kind != kind {
   141  		return false
   142  	}
   143  	p.next()
   144  	return true
   145  }
   146  
   147  func (p *parser) unexpectedError() {
   148  	p.unexpectedToken(p.peek())
   149  }
   150  
   151  func (p *parser) unexpectedToken(tok lexer.Token) {
   152  	p.error(tok, "Unexpected %s", tok.String())
   153  }
   154  
   155  func (p *parser) many(start lexer.Type, end lexer.Type, cb func()) {
   156  	hasDef := p.skip(start)
   157  	if !hasDef {
   158  		return
   159  	}
   160  
   161  	for p.peek().Kind != end && p.err == nil {
   162  		cb()
   163  	}
   164  	p.next()
   165  }
   166  
   167  func (p *parser) some(start lexer.Type, end lexer.Type, cb func()) *ast.CommentGroup {
   168  	hasDef := p.skip(start)
   169  	if !hasDef {
   170  		return nil
   171  	}
   172  
   173  	called := false
   174  	for p.peek().Kind != end && p.err == nil {
   175  		called = true
   176  		cb()
   177  	}
   178  
   179  	if !called {
   180  		p.error(p.peek(), "expected at least one definition, found %s", p.peek().Kind.String())
   181  		return nil
   182  	}
   183  
   184  	comment := p.comment
   185  	p.next()
   186  	return comment
   187  }
   188  

View as plain text