Skip to content

Commit

Permalink
allow options to have keywords in names (#72)
Browse files Browse the repository at this point in the history
* allow options to have keywords in names
  • Loading branch information
emicklei authored Mar 16, 2018
1 parent c43723a commit ae5d402
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 7 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,6 @@ test: testdeps lint
.PHONY: clean
clean:
go clean -i ./...

integration:
PB=y go test -cover
10 changes: 6 additions & 4 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (o *Option) parse(p *Parser) error {
}
pos, tok, _ = p.next()
if tok != tRIGHTPAREN {
return p.unexpected(lit, "full identifier closing )", o)
return p.unexpected(lit, "option full identifier closing )", o)
}
o.Name = fmt.Sprintf("(%s)", lit)
} else {
Expand All @@ -69,15 +69,17 @@ func (o *Option) parse(p *Parser) error {
pos, tok, lit = p.next()
if tDOT == tok {
// extend identifier
pos, tok, lit = p.nextIdentifier()
pos, tok, lit = p.nextIdent(true) // keyword allowed as start
if tok != tIDENT {
return p.unexpected(lit, "option postfix identifier", o)
if !isKeyword(tok) {
return p.unexpected(lit, "option postfix identifier", o)
}
}
o.Name = fmt.Sprintf("%s.%s", o.Name, lit)
pos, tok, lit = p.next()
}
if tEQUALS != tok {
return p.unexpected(lit, "option constant =", o)
return p.unexpected(lit, "option value assignment =", o)
}
r := p.peekNonWhitespace()
if '{' == r {
Expand Down
18 changes: 18 additions & 0 deletions option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ func TestOptionCases(t *testing.T) {
"optimize_for",
"",
"SPEED",
}, {
"option (my.enum.service.is.like).rpc = 1;",
"(my.enum.service.is.like).rpc",
"",
"1",
}} {
p := newParserOn(each.proto)
pr, err := p.Parse()
Expand Down Expand Up @@ -244,6 +249,19 @@ func TestFieldCustomOptions(t *testing.T) {
}
}

func TestFieldCustomOptionExtendedIdent(t *testing.T) {
proto := `Type field = 1 [(validate.rules).enum.defined_only = true];`
p := newParserOn(proto)
f := newNormalField()
err := f.parse(p)
if err != nil {
t.Fatal(err)
}
if got, want := f.Options[0].Name, "(validate.rules).enum.defined_only"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}

// issue #50
func TestNestedAggregateConstants(t *testing.T) {
src := `syntax = "proto3";
Expand Down
10 changes: 9 additions & 1 deletion parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,17 @@ func (p *Parser) nextInteger() (i int, err error) {

// nextIdentifier consumes tokens which may have one or more dot separators (namespaced idents).
func (p *Parser) nextIdentifier() (pos scanner.Position, tok token, lit string) {
return p.nextIdent(false)
}

func (p *Parser) nextIdent(keywordStartAllowed bool) (pos scanner.Position, tok token, lit string) {
pos, tok, lit = p.next()
if tIDENT != tok {
return
// can be keyword
if !(isKeyword(tok) && keywordStartAllowed) {
return
}
// proceed with keyword as first literal
}
startPos := pos
fullLit := lit
Expand Down
20 changes: 18 additions & 2 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,29 @@ func TestNextIdentifier(t *testing.T) {
}

func TestNextIdentifierWithKeyword(t *testing.T) {
ident := " aap.rpc.mies "
ident := " aap.rpc.mies.enum ="
p := newParserOn(ident)
_, tok, lit := p.nextIdentifier()
if got, want := tok, tIDENT; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
if got, want := lit, strings.TrimSpace(ident); got != want {
if got, want := lit, "aap.rpc.mies.enum"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
_, tok, _ = p.next()
if got, want := tok, tEQUALS; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}

func TestNextIdentifierNoIdent(t *testing.T) {
ident := "("
p := newParserOn(ident)
_, tok, lit := p.nextIdentifier()
if got, want := tok, tLEFTPAREN; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
if got, want := lit, "("; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}
1 change: 1 addition & 0 deletions protobuf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestPublicProtoDefinitions(t *testing.T) {
"https://raw.githubusercontent.com/gogo/protobuf/master/test/thetest.proto",
"https://raw.githubusercontent.com/gogo/protobuf/master/test/theproto3/theproto3.proto",
"https://raw.githubusercontent.com/googleapis/googleapis/master/google/privacy/dlp/v2beta2/dlp.proto",
// "https://raw.githubusercontent.com/envoyproxy/data-plane-api/master/envoy/api/v2/auth/cert.proto",
} {
def := fetchAndParse(t, each)
checkParent(def, t)
Expand Down

0 comments on commit ae5d402

Please sign in to comment.