diff --git a/cmd/proto3fmt/example0.proto b/cmd/proto3fmt/example0.proto index 92ada2d..4349edc 100644 --- a/cmd/proto3fmt/example0.proto +++ b/cmd/proto3fmt/example0.proto @@ -40,4 +40,11 @@ message Message } map terrain = 4; + + enum EnumAllowingAlias { + option allow_alias = true; + UNKNOWN = 0; + STARTED = 1; + RUNNING = 2 [(custom_option) = "hello world"]; +} } \ No newline at end of file diff --git a/cmd/proto3fmt/example1.proto b/cmd/proto3fmt/example1.proto deleted file mode 100644 index e7e6db5..0000000 --- a/cmd/proto3fmt/example1.proto +++ /dev/null @@ -1,56 +0,0 @@ -syntax = "proto3"; - -import "google/protobuf/any.proto"; -import "testdata/test.proto"; - -package proto3_proto; - -message Message { - enum Humour { - UNKNOWN = 0; - PUNS = 1; - SLAPSTICK = 2; - BILL_BAILEY = 3; - } - - string name = 1; - Humour hilarity = 2; - uint32 height_in_cm = 3; - bytes data = 4; - int64 result_count = 7; - bool true_scotsman = 8; - float score = 9; - - repeated uint64 key = 5; - repeated int32 short_key = 19; - Nested nested = 6; - repeated Humour r_funny = 16; - - map terrain = 10; - testdata.SubDefaults proto2_field = 11; - map proto2_value = 13; - - google.protobuf.Any anything = 14; - repeated google.protobuf.Any many_things = 15; - - Message submessage = 17; - repeated Message children = 18; -} - -message Nested { - string bunny = 1; - bool cute = 2; -} - -message MessageWithMap { - map byte_mapping = 1; -} - - -message IntMap { - map rtt = 1; -} - -message IntMaps { - repeated IntMap maps = 1; -} \ No newline at end of file diff --git a/cmd/proto3fmt/formatter.go b/cmd/proto3fmt/formatter.go index f4fb409..f14e164 100644 --- a/cmd/proto3fmt/formatter.go +++ b/cmd/proto3fmt/formatter.go @@ -42,10 +42,13 @@ func (f *formatter) VisitEnum(e *proto3.Enum) { func (f *formatter) VisitEnumField(e *proto3.EnumField) { f.begin("field") io.WriteString(f.w, paddedTo(e.Name, 10)) + fmt.Fprintf(f.w, " = %d", e.Integer) if e.ValueOption != nil { + io.WriteString(f.w, " ") e.ValueOption.Accept(f) + } else { + io.WriteString(f.w, ";\n") } - fmt.Fprintf(f.w, " = %d;\n", e.Integer) } func (f *formatter) VisitField(f1 *proto3.Field) { @@ -76,7 +79,29 @@ func (f *formatter) VisitMessage(m *proto3.Message) { } func (f *formatter) VisitOption(o *proto3.Option) { - panic(errors.New("Not implemented")) + if o.PartOfFieldOrEnum { + io.WriteString(f.w, "[(") + } else { + f.begin("option") + io.WriteString(f.w, "option ") + } + if len(o.Name) > 0 { + io.WriteString(f.w, o.Name) + } + if o.PartOfFieldOrEnum { + io.WriteString(f.w, ")") + } + io.WriteString(f.w, " = ") + if len(o.String) > 0 { + fmt.Fprintf(f.w, "%q", o.String) + } else { + fmt.Fprintf(f.w, "%s", o.Identifier) + } + if o.PartOfFieldOrEnum { + io.WriteString(f.w, "];\n") + } else { + io.WriteString(f.w, ";\n") + } } func (f *formatter) VisitPackage(p *proto3.Package) { diff --git a/enum.go b/enum.go index d3e55c0..9fd1b86 100644 --- a/enum.go +++ b/enum.go @@ -48,6 +48,7 @@ func (f *EnumField) parse(p *Parser) error { tok, lit = p.scanIgnoreWhitespace() if tok == tLEFTSQUARE { o := new(Option) + o.PartOfFieldOrEnum = true err := o.parse(p) if err != nil { return err diff --git a/enum_test.go b/enum_test.go index d1281fb..f2aa301 100644 --- a/enum_test.go +++ b/enum_test.go @@ -3,8 +3,7 @@ package proto3 import "testing" func TestEnum(t *testing.T) { - proto := ` -// EnumAllowingAlias is part of TestEnumWithBody + proto := ` enum EnumAllowingAlias { option allow_alias = true; UNKNOWN = 0; @@ -16,14 +15,25 @@ enum EnumAllowingAlias { if err != nil { t.Fatal(err) } - if got, want := len(collect(pr).Enums()), 1; got != want { + enums := collect(pr).Enums() + if got, want := len(enums), 1; got != want { t.Errorf("got [%v] want [%v]", got, want) } - if got, want := len(collect(pr).Enums()[0].Elements), 4; got != want { + if got, want := len(enums[0].Elements), 4; got != want { t.Errorf("got [%v] want [%v]", got, want) } - e := collect(pr).Enums()[0].Elements[1].(*EnumField) - if got, want := e.Integer, 0; got != want { + ef1 := enums[0].Elements[1].(*EnumField) + if got, want := ef1.Integer, 0; got != want { + t.Errorf("got [%v] want [%v]", got, want) + } + ef3 := enums[0].Elements[3].(*EnumField) + if got, want := ef3.Integer, 2; got != want { + t.Errorf("got [%v] want [%v]", got, want) + } + if got, want := ef3.ValueOption.Name, "custom_option"; got != want { + t.Errorf("got [%v] want [%v]", got, want) + } + if got, want := ef3.ValueOption.String, "hello world"; got != want { t.Errorf("got [%v] want [%v]", got, want) } } diff --git a/import.go b/import.go index d271955..0e0e900 100644 --- a/import.go +++ b/import.go @@ -1,10 +1,7 @@ package proto3 -import "fmt" - // Import holds a filename to another .proto definition. type Import struct { - Line int Filename string Kind string // weak, public, } @@ -16,7 +13,6 @@ func (i *Import) Accept(v Visitor) { func (i *Import) parse(p *Parser) error { tok, lit := p.scanIgnoreWhitespace() - i.Line = p.s.line switch tok { case tWEAK: i.Kind = lit @@ -27,7 +23,7 @@ func (i *Import) parse(p *Parser) error { case tQUOTE: i.Filename = p.s.scanUntil('"') default: - return fmt.Errorf("found %q, expected weak|public|quoted identifier", lit) + return p.unexpected(lit, "weak|public|quoted identifier") } return nil } diff --git a/option.go b/option.go index c913ba8..f482448 100644 --- a/option.go +++ b/option.go @@ -5,10 +5,10 @@ import "fmt" // Option is a protoc compiler option type Option struct { Name string - Identifier string - String string - Boolean bool + String string // will be quoted + Identifier string // will not be quoted PartOfFieldOrEnum bool + IsCustom bool // TODO needed? } // Accept dispatches the call to the visitor. diff --git a/parser.go b/parser.go index 5f9091c..29e2dbd 100644 --- a/parser.go +++ b/parser.go @@ -60,10 +60,7 @@ func (p *Parser) unscan() { p.buf.n = 1 } // newComment returns a comment with line indication. func (p *Parser) newComment(lit string) *Comment { - return &Comment{ - Line: p.s.line - 1, // line number that started the comment - Message: lit, - } + return &Comment{Message: lit} } // Line returns the line number on which the last token was read. diff --git a/proto.go b/proto.go index 3da5ae2..b987d87 100644 --- a/proto.go +++ b/proto.go @@ -9,7 +9,6 @@ type Proto struct { // Comment holds a message and line number. type Comment struct { - Line int Message string } diff --git a/service.go b/service.go index 46dfa1e..8d7be83 100644 --- a/service.go +++ b/service.go @@ -4,7 +4,6 @@ import "fmt" // Service defines a set of RPC calls. type Service struct { - Line int Name string RPCalls []*RPcall } diff --git a/syntax_test.go b/syntax_test.go index c03075b..a0d2789 100644 --- a/syntax_test.go +++ b/syntax_test.go @@ -39,8 +39,5 @@ func TestCommentAroundSyntax(t *testing.T) { if got, want := comments[i-1].Message, " comment"+strconv.Itoa(i); got != want { t.Errorf("got [%v] want [%v]", got, want) } - if got, want := comments[i-1].Line, i+1; got != want { - t.Errorf("got [%v] want [%v]", got, want) - } } }