From c27dc4d661a727817d950a96cf22847981350d26 Mon Sep 17 00:00:00 2001 From: Ernest Micklei Date: Thu, 7 Sep 2017 06:18:13 +0200 Subject: [PATCH] fix Issue #8, aggregate option syntax case --- .gitignore | 3 ++- option.go | 21 +++++++++++++++------ option_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 3502f8e..596a093 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ cmd/proto2xsd/sample.proto cmd/proto2xsd/proto2xsd -cmd/protofmt/protofmt \ No newline at end of file +cmd/protofmt/protofmt +debug.test diff --git a/option.go b/option.go index 578aecb..cf065c4 100644 --- a/option.go +++ b/option.go @@ -169,8 +169,22 @@ func (o *Option) parseAggregate(p *Parser) error { o.AggregatedConstants = []*NamedLiteral{} for { tok, lit := p.scanIgnoreWhitespace() + if tRIGHTSQUARE == tok { + p.unscan() + // caller has checked for open square ; will consume rightsquare, rightcurly and semicolon + return nil + } if tRIGHTCURLY == tok { - break + continue + } + if tSEMICOLON == tok { + return nil + } + if tCOMMA == tok { + if len(o.AggregatedConstants) == 0 { + return p.unexpected(lit, "non-empty option aggregate key", o) + } + continue } if tIDENT != tok { return p.unexpected(lit, "option aggregate key", o) @@ -186,9 +200,4 @@ func (o *Option) parseAggregate(p *Parser) error { } o.AggregatedConstants = append(o.AggregatedConstants, &NamedLiteral{Name: key, Literal: l}) } - tok, lit := p.scanIgnoreWhitespace() - if tSEMICOLON != tok { - return p.unexpected(lit, "option aggregate end ;", o) - } - return nil } diff --git a/option_test.go b/option_test.go index 51968d6..a383600 100644 --- a/option_test.go +++ b/option_test.go @@ -126,3 +126,42 @@ option Help = "me"; // inline` t.Fatalf("got [%v] want [%v]", got, want) } } + +func TestIssue8(t *testing.T) { + proto := ` +// usage: +message Bar { + // alternative aggregate syntax (uses TextFormat): + int32 b = 2 [(foo_options) = { + opt1: 123, + opt2: "baz" + }]; +} + ` + p := newParserOn(proto) + pr, err := p.Parse() + if err != nil { + t.Fatal(err) + } + o := pr.Elements[0].(*Message) + f := o.Elements[0].(*NormalField) + if got, want := len(f.Options), 1; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } + ac := f.Options[0].AggregatedConstants + if got, want := len(ac), 2; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } + if got, want := ac[0].Name, "opt1"; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } + if got, want := ac[1].Name, "opt2"; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } + if got, want := ac[0].Source, "123"; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } + if got, want := ac[1].Source, "baz"; got != want { + t.Fatalf("got [%v] want [%v]", got, want) + } +}