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

Commit

Permalink
work on aligned fields in formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
Ernest Micklei authored and Ernest Micklei committed Feb 1, 2017
1 parent 5869bbd commit 394737f
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 80 deletions.
5 changes: 5 additions & 0 deletions cmd/protofmt/unformatted.proto
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ message Message
}
}


service SearchService { // comment
rpc Search ( SearchRequest ) returns ( SearchResponse );
rpc Find ( Finder ) returns ( stream Result );}

// emptiness
enum Enum {}
service Service {}
Expand Down
2 changes: 1 addition & 1 deletion enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (f *EnumField) Accept(v Visitor) {

// columns returns printable source tokens
func (f EnumField) columns() (cols []aligned) {
cols = append(cols, leftAligned(f.Name), alignedEquals, leftAligned(strconv.Itoa(f.Integer)))
cols = append(cols, leftAligned(f.Name), alignedEquals, rightAligned(strconv.Itoa(f.Integer)))
if f.ValueOption != nil {
cols = append(cols, f.ValueOption.columns()...)
}
Expand Down
86 changes: 24 additions & 62 deletions formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,17 @@ func (f *Formatter) VisitComment(c *Comment) {
func (f *Formatter) VisitEnum(e *Enum) {
f.begin("enum")
fmt.Fprintf(f.w, "enum %s {", e.Name)
f.indentLevel++
f.printAsGroups(e.Elements)
f.indent(-1)
if len(e.Elements) > 0 {
f.nl()
f.indentLevel++
f.printAsGroups(e.Elements)
f.indent(-1)
}
io.WriteString(f.w, "}\n")
}

// VisitEnumField formats a EnumField.
func (f *Formatter) VisitEnumField(e *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")
}
}
func (f *Formatter) VisitEnumField(e *EnumField) {}

// VisitImport formats a Import.
func (f *Formatter) VisitImport(i *Import) {
Expand All @@ -75,37 +68,17 @@ func (f *Formatter) VisitImport(i *Import) {
func (f *Formatter) VisitMessage(m *Message) {
f.begin("message")
fmt.Fprintf(f.w, "message %s {", m.Name)
f.newLineIf(len(m.Elements) > 0)
f.indentLevel++
for _, each := range m.Elements {
each.Accept(f)
if len(m.Elements) > 0 {
f.nl()
f.indentLevel++
f.printAsGroups(m.Elements)
f.indent(-1)
}
f.indent(-1)
io.WriteString(f.w, "}\n")
}

// VisitOption formats a Option.
func (f *Formatter) VisitOption(o *Option) {
if o.IsEmbedded {
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.IsEmbedded {
io.WriteString(f.w, ")")
}
io.WriteString(f.w, " = ")
io.WriteString(f.w, o.Constant.String())
if o.IsEmbedded {
io.WriteString(f.w, "];\n")
} else {
io.WriteString(f.w, ";\n")
}
}
func (f *Formatter) VisitOption(o *Option) {}

// VisitPackage formats a Package.
func (f *Formatter) VisitPackage(p *Package) {
Expand All @@ -117,11 +90,12 @@ func (f *Formatter) VisitPackage(p *Package) {
func (f *Formatter) VisitService(s *Service) {
f.begin("service")
fmt.Fprintf(f.w, "service %s {", s.Name)
f.indentLevel++
for _, each := range s.Elements {
each.Accept(f)
if len(s.Elements) > 0 {
f.nl()
f.indentLevel++
f.printAsGroups(s.Elements)
f.indent(-1)
}
f.indent(-1)
io.WriteString(f.w, "}\n")
}

Expand All @@ -134,11 +108,12 @@ func (f *Formatter) VisitSyntax(s *Syntax) {
func (f *Formatter) VisitOneof(o *Oneof) {
f.begin("oneof")
fmt.Fprintf(f.w, "oneof %s {", o.Name)
f.indentLevel++
for _, each := range o.Elements {
each.Accept(f)
if len(o.Elements) > 0 {
f.nl()
f.indentLevel++
f.printAsGroups(o.Elements)
f.indent(-1)
}
f.indent(-1)
io.WriteString(f.w, "}\n")
}

Expand Down Expand Up @@ -170,20 +145,7 @@ func (f *Formatter) VisitReserved(r *Reserved) {
}

// VisitRPC formats a RPC.
func (f *Formatter) VisitRPC(r *RPC) {
f.begin("rpc")
fmt.Fprintf(f.w, "rpc %s (", r.Name)
if r.StreamsRequest {
io.WriteString(f.w, "stream ")
}
io.WriteString(f.w, r.RequestType)
io.WriteString(f.w, ") returns (")
if r.StreamsReturns {
io.WriteString(f.w, "stream ")
}
io.WriteString(f.w, r.ReturnsType)
io.WriteString(f.w, ");\n")
}
func (f *Formatter) VisitRPC(r *RPC) {}

// VisitMapField formats a MapField.
func (f *Formatter) VisitMapField(m *MapField) {
Expand Down
5 changes: 2 additions & 3 deletions formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ func TestPrintListOfColumns(t *testing.T) {
b := new(bytes.Buffer)
f := NewFormatter(b, " ")
f.printListOfColumns(list)
formatted := `
A = 1 [a =1234];
ABC = 12 [ab=1234];
formatted := `A = 1 [a = 1234];
ABC = 12 [ab = 1234];
`
if got, want := b.String(), formatted; got != want {
t.Errorf("got [%v] want [%v]", got, want)
Expand Down
25 changes: 15 additions & 10 deletions formatter_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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", f.lastStmt) {
if !strings.Contains("comment enum service", f.lastStmt) {
io.WriteString(f.w, "\n")
}
}
Expand All @@ -28,6 +28,9 @@ type columnsPrintable interface {
}

func (f *Formatter) printListOfColumns(list []columnsPrintable) {
if len(list) == 0 {
return
}
// collect all column values
values := [][]aligned{}
widths := map[int]int{}
Expand All @@ -48,8 +51,10 @@ func (f *Formatter) printListOfColumns(list []columnsPrintable) {
}
}
// now print all values
for _, each := range values {
io.WriteString(f.w, "\n")
for i, each := range values {
if i > 0 {
f.nl()
}
f.indent(0)
for c := 0; c < len(widths); c++ {
pw := widths[c]
Expand All @@ -62,29 +67,29 @@ func (f *Formatter) printListOfColumns(list []columnsPrintable) {
}
io.WriteString(f.w, ";")
}
io.WriteString(f.w, "\n")
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) newLineIf(ok bool) {
if ok {
io.WriteString(f.w, "\n")
}
func (f *Formatter) nl() *Formatter {
io.WriteString(f.w, "\n")
return f
}

func (f *Formatter) printAsGroups(list []Visitee) {
if len(list) == 0 {
return
}
group := []columnsPrintable{}
lastGroupName := nameOfVisitee(list[0])
for i := 1; i < len(list); i++ {
lastGroupName := ""
for i := 0; i < len(list); i++ {
groupName := nameOfVisitee(list[i])
printable, isColumnsPrintable := list[i].(columnsPrintable)
if isColumnsPrintable {
Expand Down
4 changes: 2 additions & 2 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ func (o *Option) Accept(v Visitor) {
// columns returns printable source tokens
func (o *Option) columns() (cols []aligned) {
if !o.IsEmbedded {
cols = append(cols, leftAligned("option"))
cols = append(cols, leftAligned("option "))
} else {
cols = append(cols, leftAligned(" ["))
}
cols = append(cols, leftAligned(o.Name), leftAligned("="), rightAligned(o.Constant.String()))
cols = append(cols, leftAligned(o.Name), alignedEquals, rightAligned(o.Constant.String()))
if o.IsEmbedded {
cols = append(cols, leftAligned("]"))
}
Expand Down
25 changes: 25 additions & 0 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,31 @@ func (r *RPC) Accept(v Visitor) {
v.VisitRPC(r)
}

// columns returns printable source tokens
func (r *RPC) columns() (cols []aligned) {
cols = append(cols,
leftAligned("rpc "),
leftAligned(r.Name),
leftAligned(" ("))
stream := ""
if r.StreamsRequest {
stream = "stream "
}
cols = append(cols,
leftAligned(stream+r.RequestType),
leftAligned(") "),
leftAligned("returns"),
leftAligned(" ("))
stream = ""
if r.StreamsReturns {
stream = "stream "
}
cols = append(cols,
leftAligned(stream+r.ReturnsType),
leftAligned(")"))
return cols
}

// parse continues after reading "rpc"
func (r *RPC) parse(p *Parser) error {
tok, lit := p.scanIgnoreWhitespace()
Expand Down
7 changes: 5 additions & 2 deletions service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ func TestService(t *testing.T) {
proto := `service AccountService {
// comment
rpc CreateAccount (CreateAccount) returns (ServiceFault);
// comment
rpc GetAccounts (stream Int64) returns (Account);
}`
pr, err := newParserOn(proto).Parse()
if err != nil {
t.Fatal(err)
}
srv := collect(pr).Services()[0]
if got, want := len(srv.Elements), 4; got != want {
if got, want := len(srv.Elements), 3; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
rpc1 := srv.Elements[1].(*RPC)
if got, want := rpc1.Name, "CreateAccount"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
rpc2 := srv.Elements[2].(*RPC)
if got, want := rpc2.Name, "GetAccounts"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}

0 comments on commit 394737f

Please sign in to comment.