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

Commit

Permalink
proper parsing extensions, refactored parsing reserved
Browse files Browse the repository at this point in the history
Change-Id: Ia7ff015d8fb87ccebd02152a45533c5352509f04
  • Loading branch information
emicklei committed Feb 15, 2017
1 parent f046ec0 commit e5da597
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 88 deletions.
9 changes: 4 additions & 5 deletions enum_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand Down Expand Up @@ -59,5 +59,4 @@ enum EnumAllowingAlias {
if got, want := ef3.ValueOption.Constant.Source, "hello world"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
logformatted(t, pr.Elements[0])
}
32 changes: 11 additions & 21 deletions extensions.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand All @@ -26,7 +26,7 @@ package proto
// Extensions declare that a range of field numbers in a message are available for third-party extensions.
// proto2 only
type Extensions struct {
Ranges string
Ranges []Range
Comment *Comment
}

Expand All @@ -40,22 +40,12 @@ func (e *Extensions) Accept(v Visitor) {
v.VisitExtensions(e)
}

// parse expects ident { messageBody
// parse expects ranges
func (e *Extensions) parse(p *Parser) error {
// TODO proper range parsing
e.Ranges = p.s.scanUntil(';')
p.s.unread(';') // for reading inline comment
return nil
}

// columns returns printable source tokens
func (e *Extensions) columns() (cols []aligned) {
cols = append(cols,
notAligned("extensions "),
leftAligned(e.Ranges),
alignedSemicolon)
if e.Comment != nil {
cols = append(cols, notAligned(" //"), notAligned(e.Comment.Message))
list, err := parseRanges(p, e)
if err != nil {
return err
}
return
e.Ranges = list
return nil
}
13 changes: 8 additions & 5 deletions extensions_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand Down Expand Up @@ -40,7 +40,10 @@ func TestExtensions(t *testing.T) {
t.Fatal("extensions expected")
}
f := m.Elements[0].(*Extensions)
if got, want := f.Ranges, " 4, 20 to max"; got != want {
if got, want := len(f.Ranges), 2; got != want {
t.Fatalf("got [%d] want [%d]", got, want)
}
if got, want := f.Ranges[1].String(), "20 to max"; got != want {
t.Errorf("got [%s] want [%s]", got, want)
}
if f.Comment == nil {
Expand Down
24 changes: 17 additions & 7 deletions formatter.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand Down Expand Up @@ -155,14 +155,14 @@ func (f *Formatter) VisitReserved(r *Reserved) {
if len(r.Ranges) > 0 {
for i, each := range r.Ranges {
if i > 0 {
io.WriteString(f.w, ",")
io.WriteString(f.w, ", ")
}
fmt.Fprintf(f.w, "%s", each.String())
}
} else {
for i, each := range r.FieldNames {
if i > 0 {
io.WriteString(f.w, ",")
io.WriteString(f.w, ", ")
}
fmt.Fprintf(f.w, "%q", each)
}
Expand Down Expand Up @@ -197,4 +197,14 @@ func (f *Formatter) VisitGroup(g *Group) {
}

// VisitExtensions formats a proto2 Extensions.
func (f *Formatter) VisitExtensions(e *Extensions) {}
func (f *Formatter) VisitExtensions(e *Extensions) {
f.begin("extensions")
io.WriteString(f.w, "extensions ")
for i, each := range e.Ranges {
if i > 0 {
io.WriteString(f.w, ", ")
}
fmt.Fprintf(f.w, "%s", each.String())
}
f.endWithComment(e.Comment)
}
90 changes: 90 additions & 0 deletions range.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) 2017 Ernest Micklei
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package proto

import (
"fmt"
"strconv"
)

// Range is to specify number intervals (with special end value "max")
type Range struct {
From, To int
Max bool
}

// String return a single number if from = to. Returns <from> to <to> otherwise unless Max then return <from> to max.
func (r Range) String() string {
if r.Max {
return fmt.Sprintf("%d to max", r.From)
}
if r.From == r.To {
return strconv.Itoa(r.From)
}
return fmt.Sprintf("%d to %d", r.From, r.To)
}

// parseRanges is used to parse ranges for extensions and reserved
func parseRanges(p *Parser, n Visitee) (list []Range, err error) {
seenTo := false
for {
lit, isString := p.s.scanLiteral()
if isString {
return list, p.unexpected(lit, "integer, <to> <max>", n)
}
switch lit {
case ",":
case "to":
seenTo = true
case ";":
p.s.unread(';') // allow for inline comment parsing
goto done
case "max":
if !seenTo {
return list, p.unexpected(lit, "to", n)
}
from := list[len(list)-1]
list = append(list[0:len(list)-1], Range{From: from.From, Max: true})
default:
// must be number
i, err := strconv.Atoi(lit)
if err != nil {
return list, p.unexpected(lit, "range integer", n)
}
if seenTo {
// replace last two ranges with one
if len(list) < 1 {
p.unexpected(lit, "integer", n)
}
from := list[len(list)-1]
list = append(list[0:len(list)-1], Range{From: from.From, To: i})
seenTo = false
} else {
list = append(list, Range{From: i, To: i})
}
}
}
done:
return
}
68 changes: 68 additions & 0 deletions range_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) 2017 Ernest Micklei
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package proto

import "testing"

func TestParseRanges(t *testing.T) {
r := new(Reserved)
p := newParserOn(`reserved 2, 15, 9 to 11;`)
_, _ = p.scanIgnoreWhitespace()
ranges, err := parseRanges(p, r)
if err != nil {
t.Fatal(err)
}
if got, want := ranges[2].String(), "9 to 11"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}

func TestParseRangesMax(t *testing.T) {
r := new(Extensions)
p := newParserOn(`extensions 3 to max;`)
_, _ = p.scanIgnoreWhitespace()
ranges, err := parseRanges(p, r)
if err != nil {
t.Fatal(err)
}
if got, want := ranges[0].String(), "3 to max"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}

func TestParseRangesMultiToMax(t *testing.T) {
r := new(Extensions)
p := newParserOn(`extensions 1,2 to 5,6 to 9,10 to max;`)
_, _ = p.scanIgnoreWhitespace()
ranges, err := parseRanges(p, r)
if err != nil {
t.Fatal(err)
}
if got, want := len(ranges), 4; got != want {
t.Fatalf("got [%v] want [%v]", got, want)
}
if got, want := ranges[3].String(), "10 to max"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}
Loading

0 comments on commit e5da597

Please sign in to comment.