Skip to content

Commit f18a27e

Browse files
authored
Inline comments before body token { breaks parser (#119)
* issue #118 , enum group message oneof * process comment-before-body in service
1 parent af9dcad commit f18a27e

11 files changed

+114
-3
lines changed

comment.go

+13
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,16 @@ func mergeOrReturnComment(elements []Visitee, lit string, pos scanner.Position)
144144

145145
// parent is part of elementContainer
146146
func (c *Comment) parent(Visitee) {}
147+
148+
// consumeCommentFor is for reading and taking all comment lines before the body of an element (starting at {)
149+
func consumeCommentFor(p *Parser, e elementContainer) {
150+
pos, tok, lit := p.next()
151+
if tok == tCOMMENT {
152+
if com := mergeOrReturnComment(e.elements(), lit, pos); com != nil { // not merged?
153+
e.addElement(com)
154+
}
155+
consumeCommentFor(p, e) // bit of recursion is fine
156+
} else {
157+
p.nextPut(pos, tok, lit)
158+
}
159+
}

enum.go

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func (e *Enum) parse(p *Parser) error {
7272
}
7373
}
7474
e.Name = lit
75+
consumeCommentFor(p, e)
7576
_, tok, lit = p.next()
7677
if tok != tLEFTCURLY {
7778
return p.unexpected(lit, "enum opening {", e)

enum_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,26 @@ func TestEnumWithHex(t *testing.T) {
142142
t.Errorf("got [%v] want [%v]", got, want)
143143
}
144144
}
145+
146+
func TestEnumInlineCommentBeforeBody(t *testing.T) {
147+
src := `enum BarEnum // BarEnum
148+
// with another line
149+
{
150+
BAR_TYPE_INVALID= 0;
151+
BAR_TYPE_BAD = 1;
152+
}
153+
`
154+
p := newParserOn(src)
155+
e := new(Enum)
156+
p.next()
157+
if err := e.parse(p); err != nil {
158+
t.Fatal(err)
159+
}
160+
nestedComment := e.Elements[0].(*Comment)
161+
if nestedComment == nil {
162+
t.Fatal("expected comment present")
163+
}
164+
if got, want := len(nestedComment.Lines), 2; got != want {
165+
t.Errorf("got %d want %d lines", got, want)
166+
}
167+
}

group.go

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ func (g *Group) parse(p *Parser) error {
8888
return p.unexpected(lit, "group sequence number", g)
8989
}
9090
g.Sequence = i
91+
consumeCommentFor(p, g)
9192
_, tok, lit = p.next()
9293
if tok != tLEFTCURLY {
9394
return p.unexpected(lit, "group opening {", g)

group_test.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ import "testing"
2828
func TestGroup(t *testing.T) {
2929
oto := `message M {
3030
// group
31-
optional group OptionalGroup = 16 {
31+
optional group OptionalGroup = 16 // group comment 1
32+
// group comment 2
33+
{
3234
// field
3335
optional int32 a = 17;
3436
}
@@ -45,7 +47,7 @@ func TestGroup(t *testing.T) {
4547
t.Fatalf("got [%v] want [%v]", got, want)
4648
}
4749
g := m.Elements[0].(*Group)
48-
if got, want := len(g.Elements), 1; got != want {
50+
if got, want := len(g.Elements), 2; got != want {
4951
t.Fatalf("got [%v] want [%v]", got, want)
5052
}
5153
if got, want := g.Position.Line, 3; got != want {
@@ -54,7 +56,7 @@ func TestGroup(t *testing.T) {
5456
if got, want := g.Comment != nil, true; got != want {
5557
t.Errorf("got [%v] want [%v]", got, want)
5658
}
57-
f := g.Elements[0].(*NormalField)
59+
f := g.Elements[1].(*NormalField)
5860
if got, want := f.Name, "a"; got != want {
5961
t.Errorf("got [%v] want [%v]", got, want)
6062
}

message.go

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func (m *Message) parse(p *Parser) error {
5353
}
5454
}
5555
m.Name = lit
56+
consumeCommentFor(p, m)
5657
_, tok, lit = p.next()
5758
if tok != tLEFTCURLY {
5859
return p.unexpected(lit, m.groupName()+" opening {", m)

message_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,25 @@ func TestSingleQuotedReservedNames(t *testing.T) {
152152
t.Fatalf("got [%v] want [%v]", got, want)
153153
}
154154
}
155+
156+
func TestMessageInlineCommentBeforeBody(t *testing.T) {
157+
src := `message BarMessage // BarMessage
158+
// with another line
159+
{
160+
name string = 1;
161+
}
162+
`
163+
p := newParserOn(src)
164+
msg := new(Message)
165+
p.next()
166+
if err := msg.parse(p); err != nil {
167+
t.Fatal(err)
168+
}
169+
nestedComment := msg.Elements[0].(*Comment)
170+
if nestedComment == nil {
171+
t.Fatal("expected comment present")
172+
}
173+
if got, want := len(nestedComment.Lines), 2; got != want {
174+
t.Errorf("got %d want %d lines", got, want)
175+
}
176+
}

oneof.go

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ func (o *Oneof) parse(p *Parser) error {
6464
}
6565
}
6666
o.Name = lit
67+
consumeCommentFor(p, o)
6768
pos, tok, lit = p.next()
6869
if tok != tLEFTCURLY {
6970
return p.unexpected(lit, "oneof opening {", o)

oneof_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,25 @@ func TestOneOfWithOption(t *testing.T) {
142142
t.Errorf("got [%v] want [%v]", got, want)
143143
}
144144
}
145+
146+
func TestOneofInlineCommentBeforeBody(t *testing.T) {
147+
src := `oneof BarOption // BarOption
148+
// with another line
149+
{
150+
name string = 1;
151+
}
152+
`
153+
p := newParserOn(src)
154+
oneof := new(Oneof)
155+
p.next()
156+
if err := oneof.parse(p); err != nil {
157+
t.Fatal(err)
158+
}
159+
nestedComment := oneof.Elements[0].(*Comment)
160+
if nestedComment == nil {
161+
t.Fatal("expected comment present")
162+
}
163+
if got, want := len(nestedComment.Lines), 2; got != want {
164+
t.Errorf("got %d want %d lines", got, want)
165+
}
166+
}

service.go

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ func (s *Service) parse(p *Parser) error {
7373
}
7474
}
7575
s.Name = lit
76+
consumeCommentFor(p, s)
7677
pos, tok, lit = p.next()
7778
if tok != tLEFTCURLY {
7879
return p.unexpected(lit, "service opening {", s)

service_test.go

+24
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,27 @@ func TestRPCWithTypeThatHasLeadingDot(t *testing.T) {
183183
t.Fatal(err)
184184
}
185185
}
186+
187+
func TestServiceInlineCommentBeforeBody(t *testing.T) {
188+
src := `service BarService // BarService
189+
// with another line
190+
{
191+
rpc Foo (Void) returns (Magic) // FooRPC {
192+
// yet another line
193+
}
194+
}
195+
`
196+
p := newParserOn(src)
197+
svc := new(Service)
198+
p.next()
199+
if err := svc.parse(p); err != nil {
200+
t.Fatal(err)
201+
}
202+
nestedComment := svc.Elements[0].(*Comment)
203+
if nestedComment == nil {
204+
t.Fatal("expected comment present")
205+
}
206+
if got, want := len(nestedComment.Lines), 2; got != want {
207+
t.Errorf("got %d want %d lines", got, want)
208+
}
209+
}

0 commit comments

Comments
 (0)