diff --git a/file.proto b/file.proto index a13a94e..c1d97f8 100644 --- a/file.proto +++ b/file.proto @@ -77,6 +77,7 @@ message FormatMsg { repeated string lines = 7; // the variables string footer = 8; // the '}' line Type type = 9; // yep. type. yep. that's what this is for + bool padAfter = 10; } message Find { diff --git a/protoReformat.go b/protoReformat.go index 01f0023..2e9b498 100644 --- a/protoReformat.go +++ b/protoReformat.go @@ -18,6 +18,7 @@ import ( var allTheLines *LinesScanner var allTheNewLines []string +var lastMessage *FormatMsg /* type EnumMessage struct { @@ -78,26 +79,42 @@ func protoReformat(filename string) error { func doParse(lines []string) *FormatMsg { var comments string - var inMessage bool var basemsg *FormatMsg basemsg = new(FormatMsg) - inMessage = false + lastMessage = basemsg + + // TODO: read in start of the file + allTheLines = newLinesScanner(lines) + for allTheLines.Scan() { + line := allTheLines.NextRaw() + if strings.HasPrefix(line, "oneof ") { + break + } + if strings.HasPrefix(line, "enum ") { + break + } + if strings.HasPrefix(line, "message ") { + break + } + basemsg.Notes = append(basemsg.Notes, line) + } + // rewind a line + allTheLines.UnScan() // write out the messages - allTheLines = newLinesScanner(lines) for allTheLines.Scan() { line := allTheLines.NextRaw() if strings.HasPrefix(line, "oneof ") { - inMessage = true - comments = "" if strings.Contains(line, "}") { newmsg := basemsg.newMessage(line, comments, FormatMsg_ONEOF) newmsg.Footer = "} // blah" + comments = "" continue } newmsg := basemsg.newMessage(line, comments, FormatMsg_ONEOF) + comments = "" newmsg.load() continue } @@ -105,7 +122,6 @@ func doParse(lines []string) *FormatMsg { if strings.HasPrefix(line, "enum ") { newmsg := basemsg.newMessage(line, comments, FormatMsg_ENUM) comments = "" - inMessage = true if strings.Contains(line, "}") { newmsg.Footer = "} // blah" continue @@ -118,7 +134,6 @@ func doParse(lines []string) *FormatMsg { log.Info("got to message", line) newmsg := basemsg.newMessage(line, comments, FormatMsg_MESSAGE) comments = "" - inMessage = true if strings.Contains(line, "}") { newmsg.Footer = "} // blah" continue @@ -127,11 +142,12 @@ func doParse(lines []string) *FormatMsg { continue } - if inMessage { - comments += fmt.Sprintln(line) - } else { - basemsg.Notes = append(basemsg.Notes, line) + if comments == "" { + if strings.TrimSpace(line) == "" { + lastMessage.PadAfter = true + } } + comments += fmt.Sprintln(line) } return basemsg @@ -153,6 +169,7 @@ func saveFile(filename string, data string) error { func newDepth(fmtmsg *FormatMsg, header string) *FormatMsg { newmsg := new(FormatMsg) + lastMessage = newmsg newmsg.MaxVarname = fmtmsg.MaxVarname newmsg.MaxVartype = fmtmsg.MaxVartype newmsg.Header = strings.TrimSpace(header) @@ -308,7 +325,12 @@ func formatEnum(curmsg *FormatMsg) []string { newmsg = append(newmsg, curmsg.formatLine(line, "enum")) } - newmsg = append(newmsg, curmsg.formatLineBase(curmsg.Footer, "enum header")) + // newmsg = append(newmsg, curmsg.formatLineBase(curmsg.Footer, "enum footer")) + newmsg = append(newmsg, curmsg.formatFooter(curmsg.Footer, "enum footer")) + if curmsg.PadAfter { + newmsg = append(newmsg, curmsg.formatLineBase("", "PadAfter")) + } + return newmsg } @@ -323,7 +345,12 @@ func formatOneof(curmsg *FormatMsg) []string { newmsg = append(newmsg, curmsg.formatMsgLine(line, "oneof")) } - newmsg = append(newmsg, curmsg.formatLineBase(curmsg.Footer, "oneof header")) + // newmsg = append(newmsg, curmsg.formatLineBase(curmsg.Footer, "oneof footer")) + newmsg = append(newmsg, curmsg.formatFooter(curmsg.Footer, "oneof footer")) + if curmsg.PadAfter { + newmsg = append(newmsg, curmsg.formatLineBase("", "PadAfter")) + } + return newmsg } @@ -388,6 +415,38 @@ func (parent *FormatMsg) format() []string { } } +func (msg *FormatMsg) formatFooter(line string, dbg string) string { + if line == "" { + return "// footer was empty" + } + return msg.formatLineBase(line, "footer") +} + +func (msg *FormatMsg) formatHeader(line string, dbg string) string { + if line == "" { + if msg.Depth != 0 { + return "// ERROR: header was blank" + } + } + + parts := strings.Fields(line) + if len(parts) <= 3 { + return msg.formatLineBase(msg.Header, "header") + } + + // hack to actually indent comments on the message line itself. you're welcome + start := parts[0] + " " + parts[1] + " " + parts[2] + end := strings.Join(parts[3:], " ") + offset := int(msg.MaxVarname) + int(msg.MaxVartype) + 16 - len(start) + pad := fmt.Sprintf("%d", offset) + if argv.Debug { + hmm := "%s%s %" + pad + "s %s // depth=%d" + return fmt.Sprintf(hmm, msg.padBase(), start, " ", end, msg.Depth) + } + hmm := "%s%s %" + pad + "s %s" + return fmt.Sprintf(hmm, msg.padBase(), start, " ", end) +} + func (msg *FormatMsg) formatLineBase(line string, dbg string) string { line = strings.TrimSpace(line) if argv.Debug { @@ -450,47 +509,32 @@ func (msg *FormatMsg) formatMsgLine(line string, dbg string) string { return msg.formatVarLine(line, "var "+dbg) } +// chop extra spaces and blank lines func trimLines(lines []string) []string { - return strings.Split(strings.TrimSuffix(strings.Join(lines, "\n"), "\n"), "\n") + return strings.Split(strings.TrimSpace(strings.Join(lines, "\n")), "\n") } func formatMessage(curmsg *FormatMsg) []string { var newmsg []string // add the notes & comments before the header - // newmsg = append(newmsg, strings.TrimSpace(strings.Join(curmsg.Notes, "\n"))) - for _, line := range trimLines(curmsg.Notes) { - newmsg = append(newmsg, curmsg.formatLineBase(line, "notes")) - } - - if curmsg.Header != "" { - var line string - line = curmsg.formatLineBase(curmsg.Header, "header") - - parts := strings.Fields(line) - if len(parts) > 3 { - // hack to actually indent comments on the message line itself. you're welcome - start := parts[0] + " " + parts[1] + " " + parts[2] - end := strings.Join(parts[3:], " ") - offset := int(curmsg.MaxVarname) + int(curmsg.MaxVartype) + 16 - len(start) - pad := fmt.Sprintf("%d", offset) - if argv.Debug { - hmm := "%s %" + pad + "s %s // depth=%d" - line = fmt.Sprintf(hmm, start, " ", end, curmsg.Depth) - } else { - hmm := "%s %" + pad + "s %s" - line = fmt.Sprintf(hmm, start, " ", end) - } - newmsg = append(newmsg, line) // +"// header") + notes := trimLines(curmsg.Notes) + if len(notes) == 0 { + // do nothing { + } else if len(notes) == 1 { + if notes[0] == "" { + // todo: track space in original file } else { - newmsg = append(newmsg, line) // +"// header") + newmsg = append(newmsg, curmsg.formatLineBase(notes[0], "notes1")) } } else { - if curmsg.Depth != 0 { - newmsg = append(newmsg, "// ERROR: header was blank") + for _, line := range notes { + newmsg = append(newmsg, curmsg.formatLineBase(line, "notes2")) } } + newmsg = append(newmsg, curmsg.formatHeader(curmsg.Header, "header")) + for _, msg := range curmsg.Msgs { switch msg.Type { case FormatMsg_ENUM: @@ -546,13 +590,20 @@ func formatMessage(curmsg *FormatMsg) []string { } } - if curmsg.Footer == "" { - newmsg = append(newmsg, "// footer was empty") - } else { - // newline := fmt.Sprintf("%s%s", curmsg.padding(1), curmsg.Footer) // +" //footer") - // newmsg = append(newmsg, newline) - newmsg = append(newmsg, curmsg.formatLineBase(curmsg.Footer, "msg depth")) + newmsg = append(newmsg, curmsg.formatFooter(curmsg.Footer, "footer")) + if curmsg.PadAfter { + newmsg = append(newmsg, curmsg.formatLineBase("", "PadAfter")) } + + /* + if curmsg.Footer == "" { + newmsg = append(newmsg, "// footer was empty") + } else { + // newline := fmt.Sprintf("%s%s", curmsg.padding(1), curmsg.Footer) // +" //footer") + // newmsg = append(newmsg, newline) + newmsg = append(newmsg, curmsg.formatLineBase(curmsg.Footer, "msg depth")) + } + */ return newmsg } @@ -579,6 +630,17 @@ func (it *LinesScanner) Scan() bool { return true } +func (it *LinesScanner) UnScan() bool { + if it.index < 1 { + it.index = 0 + return false + } + it.Lock() + it.index-- + it.Unlock() + return true +} + // does no cleaning of the data func (it *LinesScanner) NextRaw() string { if it.index-1 == len(it.things) {