From 01d521f0e391d6e1f5eda373e68fd3550bf9c6d2 Mon Sep 17 00:00:00 2001 From: Ernest Micklei Date: Thu, 2 Feb 2017 16:58:49 +0100 Subject: [PATCH] see last commit msg --- cmd/protofmt/unformatted.proto | 2 +- field.go | 8 +++++--- formatter_utils.go | 14 +++----------- message.go | 4 +++- oneof.go | 4 +++- option.go | 10 +++++++--- parser.go | 6 ------ parser_test.go | 11 ----------- proto.go | 2 +- scanner.go | 26 ++------------------------ service.go | 4 +++- token.go | 8 ++++++++ 12 files changed, 36 insertions(+), 63 deletions(-) diff --git a/cmd/protofmt/unformatted.proto b/cmd/protofmt/unformatted.proto index 089ceb9..16c2ce6 100644 --- a/cmd/protofmt/unformatted.proto +++ b/cmd/protofmt/unformatted.proto @@ -67,5 +67,5 @@ enum enum { enum = 0; } message message { - message message = 1; + sometype message = 1; } \ No newline at end of file diff --git a/field.go b/field.go index d58de5d..760174d 100644 --- a/field.go +++ b/field.go @@ -31,14 +31,14 @@ func (f *NormalField) columns() (cols []aligned) { } else { cols = append(cols, alignedSpace) } - cols = append(cols, leftAligned(f.Name), rightAligned(f.Type), alignedEquals, rightAligned(strconv.Itoa(f.Sequence))) + cols = append(cols, rightAligned(f.Type), alignedSpace, leftAligned(f.Name), alignedEquals, rightAligned(strconv.Itoa(f.Sequence))) if len(f.Options) > 0 { cols = append(cols, leftAligned(" [")) for i, each := range f.Options { if i > 0 { cols = append(cols, alignedComma) } - cols = append(cols, each.keyValuePair()...) + cols = append(cols, each.keyValuePair(true)...) } cols = append(cols, leftAligned("]")) } @@ -73,7 +73,9 @@ done: func parseFieldAfterType(f *Field, p *Parser) error { tok, lit := p.scanIgnoreWhitespace() if tok != tIDENT { - return p.unexpected(lit, "field identifier", f) + if !isKeyword(tok) { + return p.unexpected(lit, "field identifier", f) + } } f.Name = lit tok, lit = p.scanIgnoreWhitespace() diff --git a/formatter_utils.go b/formatter_utils.go index 290d4b3..9dc4325 100644 --- a/formatter_utils.go +++ b/formatter_utils.go @@ -8,7 +8,7 @@ import ( func (f *Formatter) begin(stmt string) { if f.lastStmt != stmt && len(f.lastStmt) > 0 { // not the first line // add separator because stmt is changed, unless it nested thingy - if !strings.Contains("comment enum service", f.lastStmt) { + if !strings.Contains("comment ", f.lastStmt) { io.WriteString(f.w, "\n") } } @@ -70,14 +70,6 @@ func (f *Formatter) printListOfColumns(list []columnsPrintable) { f.nl() } -// paddedTo return the word padding with spaces to match the length. -func paddedTo(word string, length int) string { - if len(word) >= length { - return word - } - return word + strings.Repeat(" ", length-len(word)) -} - func (f *Formatter) nl() *Formatter { io.WriteString(f.w, "\n") return f @@ -95,10 +87,10 @@ func (f *Formatter) printAsGroups(list []Visitee) { printable, isColumnsPrintable := each.(columnsPrintable) if isColumnsPrintable { if lastGroupName != groupName { + lastGroupName = groupName // print current group if len(group) > 0 { f.printListOfColumns(group) - lastGroupName = groupName // begin new group group = []columnsPrintable{} } @@ -106,10 +98,10 @@ func (f *Formatter) printAsGroups(list []Visitee) { group = append(group, printable) } else { // not printable in group + lastGroupName = groupName // print current group if len(group) > 0 { f.printListOfColumns(group) - lastGroupName = groupName // begin new group group = []columnsPrintable{} } diff --git a/message.go b/message.go index 80c6fce..00e94ae 100644 --- a/message.go +++ b/message.go @@ -14,7 +14,9 @@ func (m *Message) Accept(v Visitor) { func (m *Message) parse(p *Parser) error { tok, lit := p.scanIgnoreWhitespace() if tok != tIDENT { - return p.unexpected(lit, "message identifier", m) + if !isKeyword(tok) { + return p.unexpected(lit, "message identifier", m) + } } m.Name = lit tok, lit = p.scanIgnoreWhitespace() diff --git a/oneof.go b/oneof.go index f41cb30..dd12b38 100644 --- a/oneof.go +++ b/oneof.go @@ -60,7 +60,9 @@ func (o *OneOfField) Accept(v Visitor) { func (o *OneOfField) parse(p *Parser) error { tok, lit := p.scanIgnoreWhitespace() if tok != tIDENT { - return p.unexpected(lit, "oneof field identifier", o) + if !isKeyword(tok) { + return p.unexpected(lit, "oneof field identifier", o) + } } o.Name = lit tok, lit = p.scanIgnoreWhitespace() diff --git a/option.go b/option.go index f4abbba..6337094 100644 --- a/option.go +++ b/option.go @@ -22,7 +22,7 @@ func (o *Option) columns() (cols []aligned) { } else { cols = append(cols, leftAligned(" [")) } - cols = append(cols, o.keyValuePair()...) + cols = append(cols, o.keyValuePair(o.IsEmbedded)...) if o.IsEmbedded { cols = append(cols, leftAligned("]")) } @@ -30,8 +30,12 @@ func (o *Option) columns() (cols []aligned) { } // keyValuePair returns key = value or "value" -func (o *Option) keyValuePair() (cols []aligned) { - return append(cols, leftAligned(o.Name), alignedShortEquals, rightAligned(o.Constant.String())) +func (o *Option) keyValuePair(embedded bool) (cols []aligned) { + equals := alignedEquals + if embedded { + equals = alignedShortEquals + } + return append(cols, leftAligned(o.Name), equals, rightAligned(o.Constant.String())) } // parse reads an Option body diff --git a/parser.go b/parser.go index fd31485..3eb09a5 100644 --- a/parser.go +++ b/parser.go @@ -55,12 +55,6 @@ func (p *Parser) scanIgnoreWhitespace() (tok token, lit string) { return } -// scanIdent scans all whitespaces and scans the next non-whitespace identifier (not a keyword). -func (p *Parser) scanIdent() (tok token, lit string) { - p.s.skipWhitespace() - return p.s.scanIdent() -} - // unscan pushes the previously read token back onto the buffer. func (p *Parser) unscan() { p.buf.n = 1 } diff --git a/parser_test.go b/parser_test.go index dea458a..e5b1b51 100644 --- a/parser_test.go +++ b/parser_test.go @@ -26,14 +26,3 @@ func newParserOn(def string) *Parser { p.debug = true return p } - -func TestScanIdent(t *testing.T) { - p := NewParser(strings.NewReader(" message ")) - tok, lit := p.scanIdent() - if got, want := tok, tIDENT; got != want { - t.Errorf("got [%v] want [%v]", got, want) - } - if got, want := lit, "message"; got != want { - t.Errorf("got [%v] want [%v]", got, want) - } -} diff --git a/proto.go b/proto.go index 555a191..5226ed1 100644 --- a/proto.go +++ b/proto.go @@ -76,7 +76,7 @@ func (proto *Proto) parse(p *Parser) error { case tEOF: goto done default: - return p.unexpected(lit, "comment|option|import|syntax|enum|service|package|message", p) + return p.unexpected(lit, ".proto element {comment|option|import|syntax|enum|service|package|message}", p) } } done: diff --git a/scanner.go b/scanner.go index f55fda8..b85d49c 100644 --- a/scanner.go +++ b/scanner.go @@ -33,7 +33,7 @@ func (s *scanner) scan() (tok token, lit string) { return s.scanWhitespace() } else if isLetter(ch) { s.unread(ch) - return s.scanKeyword() + return s.scanIdent() } // Otherwise read the individual character. @@ -123,27 +123,6 @@ func (s *scanner) scanIdent() (tok token, lit string) { var buf bytes.Buffer buf.WriteRune(s.read()) - // Read every subsequent ident character into the buffer. - // Non-ident characters and EOF will cause the loop to exit. - for { - if ch := s.read(); ch == eof { - break - } else if !isLetter(ch) && !isDigit(ch) && ch != '_' && ch != '.' { // underscore and dot can be part of identifier - s.unread(ch) - break - } else { - _, _ = buf.WriteRune(ch) - } - } - return tIDENT, buf.String() -} - -// scanKeyword consumes the current rune and all contiguous ident runes. -func (s *scanner) scanKeyword() (tok token, lit string) { - // Create a buffer and read the current character into it. - var buf bytes.Buffer - buf.WriteRune(s.read()) - // Read every subsequent ident character into the buffer. // Non-ident characters and EOF will cause the loop to exit. for { @@ -195,8 +174,7 @@ func (s *scanner) scanKeyword() (tok token, lit string) { return tOPTIONAL, buf.String() } - // Otherwise return as a regular identifier. - return tIDENT, ident + return tIDENT, buf.String() } // read reads the next rune from the bufferred reader. diff --git a/service.go b/service.go index e7b4578..abb1a1b 100644 --- a/service.go +++ b/service.go @@ -15,7 +15,9 @@ func (s *Service) Accept(v Visitor) { func (s *Service) parse(p *Parser) error { tok, lit := p.scanIgnoreWhitespace() if tok != tIDENT { - return p.unexpected(lit, "service identifier", s) + if !isKeyword(tok) { + return p.unexpected(lit, "service identifier", s) + } } s.Name = lit tok, lit = p.scanIgnoreWhitespace() diff --git a/token.go b/token.go index b285ca6..f9aa73b 100644 --- a/token.go +++ b/token.go @@ -30,6 +30,7 @@ const ( tDOT // . // Keywords + KeywordsStart tSYNTAX tSERVICE tRPC @@ -50,6 +51,8 @@ const ( // proto2 tOPTIONAL + tGROUP + KeywordsEnd ) const typeTokens = "double float int32 int64 uint32 uint64 sint32 sint64 fixed32 sfixed32 sfixed64 bool string bytes" @@ -58,3 +61,8 @@ const typeTokens = "double float int32 int64 uint32 uint64 sint32 sint64 fixed32 const ( iSTREAM = "stream" ) + +// isKeyword returns if tok is in the keywords range +func isKeyword(tok token) bool { + return KeywordsStart < tok && tok < KeywordsEnd +}