207 lines
6.1 KiB
Go
207 lines
6.1 KiB
Go
package protofmt
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"strconv"
|
|
|
|
"github.com/emicklei/proto"
|
|
)
|
|
|
|
func columns(v proto.Visitee) []aligned {
|
|
return asColumnsPrintable(v).columns()
|
|
}
|
|
|
|
// columnsPrintable is for elements that can be printed in aligned columns.
|
|
type columnsPrintable interface {
|
|
columns() (cols []aligned)
|
|
}
|
|
|
|
type columnsPrinter struct {
|
|
cols []aligned
|
|
visitee proto.Visitee
|
|
}
|
|
|
|
func asColumnsPrintable(v proto.Visitee) *columnsPrinter {
|
|
p := new(columnsPrinter)
|
|
p.visitee = v
|
|
return p
|
|
}
|
|
|
|
// columns is part of columnsPrintable
|
|
func (p *columnsPrinter) columns() []aligned {
|
|
p.visitee.Accept(p)
|
|
return p.cols
|
|
}
|
|
|
|
func (p *columnsPrinter) VisitMessage(m *proto.Message) {}
|
|
func (p *columnsPrinter) VisitService(v *proto.Service) {}
|
|
func (p *columnsPrinter) VisitSyntax(s *proto.Syntax) {}
|
|
func (p *columnsPrinter) VisitPackage(pkg *proto.Package) {
|
|
p.cols = append(p.cols, notAligned("package "), notAligned(pkg.Name), alignedSemicolon)
|
|
if pkg.InlineComment != nil {
|
|
p.cols = append(p.cols, notAligned(" //"), notAligned(pkg.InlineComment.Message()))
|
|
}
|
|
}
|
|
func (p *columnsPrinter) VisitOption(o *proto.Option) {
|
|
if !o.IsEmbedded {
|
|
p.cols = append(p.cols, leftAligned("option "))
|
|
} else {
|
|
p.cols = append(p.cols, leftAligned(" ["))
|
|
}
|
|
p.cols = append(p.cols, keyValuePair(o, o.IsEmbedded)...)
|
|
if o.IsEmbedded {
|
|
p.cols = append(p.cols, leftAligned("]"))
|
|
}
|
|
if !o.IsEmbedded {
|
|
p.cols = append(p.cols, alignedSemicolon)
|
|
if o.InlineComment != nil {
|
|
p.cols = append(p.cols, notAligned(" //"), notAligned(o.InlineComment.Message()))
|
|
}
|
|
}
|
|
}
|
|
func (p *columnsPrinter) VisitImport(i *proto.Import) {
|
|
p.cols = append(p.cols, leftAligned("import"), alignedSpace)
|
|
if len(i.Kind) > 0 {
|
|
p.cols = append(p.cols, leftAligned(i.Kind), alignedSpace)
|
|
}
|
|
p.cols = append(p.cols, notAligned(fmt.Sprintf("%q", i.Filename)), alignedSemicolon)
|
|
if i.InlineComment != nil {
|
|
p.cols = append(p.cols, notAligned(" //"), notAligned(i.InlineComment.Message()))
|
|
}
|
|
}
|
|
|
|
// VisitNormalField
|
|
// [|repeated][|optional][space][name][equals][sequence][|option]
|
|
func (p *columnsPrinter) VisitNormalField(f *proto.NormalField) {
|
|
if f.Repeated {
|
|
p.cols = append(p.cols, leftAligned("repeated "))
|
|
} else if f.Optional {
|
|
p.cols = append(p.cols, leftAligned("optional "))
|
|
} else if f.Required {
|
|
p.cols = append(p.cols, leftAligned("required "))
|
|
} else {
|
|
p.cols = append(p.cols, alignedEmpty)
|
|
}
|
|
p.cols = append(p.cols, leftAligned(f.Type), alignedSpace, leftAligned(f.Name), alignedEquals, rightAligned(strconv.Itoa(f.Sequence)))
|
|
if len(f.Options) > 0 {
|
|
p.cols = append(p.cols, leftAligned(" ["))
|
|
for i, each := range f.Options {
|
|
if i > 0 {
|
|
p.cols = append(p.cols, alignedComma)
|
|
}
|
|
p.cols = append(p.cols, keyValuePair(each, true)...)
|
|
}
|
|
p.cols = append(p.cols, leftAligned("]"))
|
|
}
|
|
p.cols = append(p.cols, alignedSemicolon)
|
|
if f.InlineComment != nil {
|
|
p.cols = append(p.cols, alignedInlinePrefix(f.InlineComment), notAligned(f.InlineComment.Message()))
|
|
}
|
|
}
|
|
|
|
func (p *columnsPrinter) VisitEnumField(f *proto.EnumField) {
|
|
p.cols = append(p.cols, leftAligned(f.Name), alignedEquals, rightAligned(strconv.Itoa(f.Integer)))
|
|
if f.ValueOption != nil {
|
|
p.cols = append(p.cols, columns(f.ValueOption)...)
|
|
}
|
|
p.cols = append(p.cols, alignedSemicolon)
|
|
if f.InlineComment != nil {
|
|
p.cols = append(p.cols, alignedInlinePrefix(f.InlineComment), notAligned(f.InlineComment.Message()))
|
|
}
|
|
}
|
|
func (p *columnsPrinter) VisitEnum(e *proto.Enum) {}
|
|
func (p *columnsPrinter) VisitComment(e *proto.Comment) {}
|
|
func (p *columnsPrinter) VisitOneof(o *proto.Oneof) {}
|
|
func (p *columnsPrinter) VisitOneofField(o *proto.OneOfField) {
|
|
p.cols = append(p.cols,
|
|
leftAligned(o.Type),
|
|
alignedSpace,
|
|
leftAligned(o.Name),
|
|
alignedEquals,
|
|
rightAligned(strconv.Itoa(o.Sequence)))
|
|
if len(o.Options) > 0 {
|
|
p.cols = append(p.cols, leftAligned(" ["))
|
|
for i, each := range o.Options {
|
|
if i > 0 {
|
|
p.cols = append(p.cols, alignedComma)
|
|
}
|
|
p.cols = append(p.cols, keyValuePair(each, true)...)
|
|
}
|
|
p.cols = append(p.cols, leftAligned("]"))
|
|
}
|
|
p.cols = append(p.cols, alignedSemicolon)
|
|
if o.InlineComment != nil {
|
|
p.cols = append(p.cols, notAligned(" //"), notAligned(o.InlineComment.Message()))
|
|
}
|
|
}
|
|
func (p *columnsPrinter) VisitReserved(rs *proto.Reserved) {}
|
|
func (p *columnsPrinter) VisitRPC(r *proto.RPC) {
|
|
p.cols = append(p.cols,
|
|
leftAligned("rpc "),
|
|
leftAligned(r.Name),
|
|
leftAligned(" ("))
|
|
if r.StreamsRequest {
|
|
p.cols = append(p.cols, leftAligned("stream "))
|
|
} else {
|
|
p.cols = append(p.cols, alignedEmpty)
|
|
}
|
|
p.cols = append(p.cols,
|
|
leftAligned(r.RequestType),
|
|
leftAligned(") "),
|
|
leftAligned("returns"),
|
|
leftAligned(" ("))
|
|
if r.StreamsReturns {
|
|
p.cols = append(p.cols, leftAligned("stream "))
|
|
} else {
|
|
p.cols = append(p.cols, alignedEmpty)
|
|
}
|
|
p.cols = append(p.cols,
|
|
leftAligned(r.ReturnsType),
|
|
leftAligned(")"))
|
|
if len(r.Elements) > 0 {
|
|
buf := new(bytes.Buffer)
|
|
io.WriteString(buf, " {\n")
|
|
f := NewFormatter(buf, " ") // TODO get separator, now 2 spaces
|
|
f.level(1)
|
|
for _, each := range r.Elements {
|
|
each.Accept(f)
|
|
io.WriteString(buf, "\n")
|
|
}
|
|
f.indent(-1)
|
|
io.WriteString(buf, "}")
|
|
p.cols = append(p.cols, notAligned(buf.String()))
|
|
} else {
|
|
p.cols = append(p.cols, alignedSemicolon)
|
|
}
|
|
if r.InlineComment != nil {
|
|
p.cols = append(p.cols, notAligned(" //"), notAligned(r.InlineComment.Message()))
|
|
}
|
|
}
|
|
func (p *columnsPrinter) VisitMapField(f *proto.MapField) {
|
|
p.cols = append(p.cols,
|
|
alignedEmpty, // no repeated no optional
|
|
leftAligned(fmt.Sprintf("map <%s,%s>", f.KeyType, f.Type)),
|
|
alignedSpace,
|
|
leftAligned(f.Name),
|
|
alignedEquals,
|
|
rightAligned(strconv.Itoa(f.Sequence)))
|
|
if len(f.Options) > 0 {
|
|
p.cols = append(p.cols, leftAligned(" ["))
|
|
for i, each := range f.Options {
|
|
if i > 0 {
|
|
p.cols = append(p.cols, alignedComma)
|
|
}
|
|
p.cols = append(p.cols, keyValuePair(each, true)...)
|
|
}
|
|
p.cols = append(p.cols, leftAligned("]"))
|
|
}
|
|
p.cols = append(p.cols, alignedSemicolon)
|
|
if f.InlineComment != nil {
|
|
p.cols = append(p.cols, alignedInlinePrefix(f.InlineComment), notAligned(f.InlineComment.Message()))
|
|
}
|
|
}
|
|
func (p *columnsPrinter) VisitGroup(g *proto.Group) {}
|
|
func (p *columnsPrinter) VisitExtensions(e *proto.Extensions) {}
|