Skip to content
This repository has been archived by the owner on Jan 5, 2019. It is now read-only.

Commit

Permalink
proper parsing reserved ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
Ernest Micklei authored and Ernest Micklei committed Feb 10, 2017
1 parent 769690f commit 66ffa3d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
7 changes: 6 additions & 1 deletion formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,12 @@ func (f *Formatter) VisitReserved(r *Reserved) {
f.begin("reserved")
io.WriteString(f.w, "reserved ")
if len(r.Ranges) > 0 {
io.WriteString(f.w, r.Ranges)
for i, each := range r.Ranges {
if i > 0 {
io.WriteString(f.w, ",")
}
fmt.Fprintf(f.w, "%s", each.String())
}
} else {
for i, each := range r.FieldNames {
if i > 0 {
Expand Down
57 changes: 46 additions & 11 deletions reserved.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ package proto
import (
"fmt"
"strconv"
"strings"
)

// Reserved statements declare a range of field numbers or field names that cannot be used in a message.
type Reserved struct {
Ranges string
Ranges []Range
FieldNames []string
Comment *Comment
}
Expand Down Expand Up @@ -37,16 +36,52 @@ func (r *Reserved) Accept(v Visitor) {
}

func (r *Reserved) parse(p *Parser) error {
// TODO proper parsing ranges
content := strings.TrimSpace(p.s.scanUntil(';'))
if strings.Contains(content, "\"") {
quoted := strings.Split(content, ",")
for _, each := range quoted {
r.FieldNames = append(r.FieldNames, strings.Trim(strings.TrimSpace(each), "\""))
seenRangeTo := false
for {
tok, lit := p.scanIgnoreWhitespace()
if len(lit) == 0 {
return p.unexpected(lit, "reserved string or integer", r)
}
// first char that determined tok
ch := []rune(lit)[0]
if isDigit(ch) {
// use unread here because scanInteger does not look at buf
p.s.unread(ch)
i, err := p.s.scanInteger()
if err != nil {
return p.unexpected(lit, "reserved integer", r)
}
if seenRangeTo {
// replace last two ranges with one
if len(r.Ranges) < 1 {
p.unexpected(lit, "reserved integer", r)
}
from := r.Ranges[len(r.Ranges)-1]
r.Ranges = append(r.Ranges[0:len(r.Ranges)-1], Range{From: from.From, To: i})
seenRangeTo = false
} else {
r.Ranges = append(r.Ranges, Range{From: i, To: i})
}
continue
}
if tIDENT == tok && "to" == lit {
seenRangeTo = true
continue
}
if tQUOTE == tok || tSINGLEQUOTE == tok {
// use unread here because scanLiteral does not look at buf
p.s.unread(ch)
field, isString := p.s.scanLiteral()
if !isString {
return p.unexpected(lit, "reserved string", r)
}
r.FieldNames = append(r.FieldNames, field)
continue
}
if tSEMICOLON == tok {
p.unscan()
break
}
} else {
r.Ranges = content
}
p.s.unread(';') // put it back for reading inline comments TODO
return nil
}
7 changes: 5 additions & 2 deletions reserved_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ func TestReservedRanges(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if got, want := r.Ranges, "2, 15, 9 to 11"; got != want {
if got, want := r.Ranges[0].String(), "2"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
if got, want := r.Ranges[2].String(), "9 to 11"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}
Expand All @@ -27,7 +30,7 @@ func TestReservedFieldNames(t *testing.T) {
t.Fatal(err)
}
if got, want := len(r.FieldNames), 2; got != want {
t.Errorf("got [%v] want [%v]", got, want)
t.Fatalf("got [%v] want [%v]", got, want)
}
if got, want := r.FieldNames[0], "foo"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
Expand Down

0 comments on commit 66ffa3d

Please sign in to comment.