summaryrefslogtreecommitdiff
path: root/protoReformat.go
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-07-21 12:59:16 -0500
committerJeff Carr <[email protected]>2025-07-21 12:59:16 -0500
commit931e7ac1a614f1fca33cd5bbf026cc061e196dcb (patch)
tree28b4d19898cfed1e0f60387f36e80694b8e18c92 /protoReformat.go
parent760e7d560fda48c8535e11ce7c4b30b072790cb4 (diff)
used gemini to make function docsv0.0.75
Diffstat (limited to 'protoReformat.go')
-rw-r--r--protoReformat.go118
1 files changed, 98 insertions, 20 deletions
diff --git a/protoReformat.go b/protoReformat.go
index 681cbc2..8b49879 100644
--- a/protoReformat.go
+++ b/protoReformat.go
@@ -37,6 +37,10 @@ type Message interface {
}
*/
+// protoReformatComments reads a .proto file, processes its comments using
+// commentPreprocessor and commentPreprocessorFull, and writes the modified
+// content back to the file. This function serves as a dedicated comment
+// processing tool.
func protoReformatComments(filename string) error {
// read in the .proto file
data, err := os.ReadFile(filename)
@@ -58,6 +62,9 @@ func protoReformatComments(filename string) error {
return nil
}
+// protoReformat reads a .proto file, parses it into a structured format,
+// aligns its contents for readability, and writes the formatted output back to
+// the original file. It acts as the main entry point for the formatting process.
func protoReformat(filename string) error {
// read in the .proto file
data, err := os.ReadFile(filename)
@@ -77,6 +84,18 @@ func protoReformat(filename string) error {
return saveFile(filename, newfile)
}
+// doParse is the core parsing engine for the protoReformat tool. It processes
+// the raw lines of a .proto file and constructs a hierarchical tree of
+// FormatMsg structs.
+//
+// This tree mirrors the .proto file's logical structure, representing `message`,
+// `enum`, and `oneof` blocks as distinct nodes. The function recursively
+// handles nested definitions and carefully preserves associated comments and
+// surrounding whitespace, which are essential for the final formatting.
+//
+// The returned *FormatMsg is the root of this tree, containing the complete,
+// structured representation of the file, which is then used by the format
+// functions to generate a clean, aligned output.
func doParse(lines []string) *FormatMsg {
var comments string
@@ -156,6 +175,9 @@ func doParse(lines []string) *FormatMsg {
return basemsg
}
+// saveFile writes the provided data to a specified file, creating it if it
+// doesn't exist or truncating it if it does. It ensures the data is trimmed of
+// surrounding whitespace before writing.
func saveFile(filename string, data string) error {
pf, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
@@ -170,6 +192,9 @@ func saveFile(filename string, data string) error {
return nil
}
+// newDepth creates a new FormatMsg, representing a nested message structure.
+// It inherits formatting parameters from its parent and increments the nesting
+// depth, which is used to calculate indentation.
func newDepth(fmtmsg *FormatMsg, header string) *FormatMsg {
newmsg := new(FormatMsg)
lastMessage = newmsg
@@ -181,6 +206,9 @@ func newDepth(fmtmsg *FormatMsg, header string) *FormatMsg {
return newmsg
}
+// newMessage creates a new FormatMsg of a specified type (e.g., message, enum)
+// and appends it to the parent's list of messages. It associates the new
+// message with its preceding comments.
func (msgPB *FormatMsg) newMessage(header string, comments string, msgType FormatMsg_Type) *FormatMsg {
newmsg := newDepth(msgPB, header)
newmsg.Type = msgType
@@ -192,6 +220,9 @@ func (msgPB *FormatMsg) newMessage(header string, comments string, msgType Forma
return newmsg
}
+// load recursively parses the content within a message, enum, or oneof block.
+// It consumes lines from the global line scanner until it reaches the closing
+// brace '}' of the current block, creating nested messages as needed.
func (msg *FormatMsg) load() {
// fmtmsg := msg.msgPB
for allTheLines.Scan() {
@@ -234,7 +265,10 @@ func (msg *FormatMsg) load() {
return
}
-// returns vartype, varname, id, end
+// tokenMsgVar parses a line containing a field definition within a .proto message.
+// It extracts and returns the variable type, name, ID, and any trailing comments
+// or options. For example, from "string name = 1; // User's name", it returns
+// "string", "name", "1", and "// User's name".
func tokenMsgVar(line string) (string, string, string, string) {
parts := strings.Split(line, ";")
front := parts[0]
@@ -253,6 +287,8 @@ func tokenMsgVar(line string) (string, string, string, string) {
return vartype, varname, id, end
}
+// slicesPop removes and returns the last element from a slice of strings,
+// along with the modified slice. It is a utility function for tokenizing lines.
func slicesPop(parts []string) ([]string, string) {
if len(parts) == 0 {
return nil, ""
@@ -265,7 +301,9 @@ func slicesPop(parts []string) ([]string, string) {
return parts[0 : x-1], end
}
-// 'for x := range' syntax using the smartly done golang 1.24 'iter'
+// makeLineIter creates a Go 1.24+ style iterator (iter.Seq) from a byte slice
+// of file content. This allows for convenient line-by-line iteration using
+// `for ... range`.
func makeLineIter(data []byte) iter.Seq[string] {
items := strings.Split(string(data), "\n")
// log.Println("Made All() Iter.Seq[] with length", len(items))
@@ -278,7 +316,9 @@ func makeLineIter(data []byte) iter.Seq[string] {
}
}
-// find the max length of varname and vartype
+// setMaxSizes calculates the maximum length of field types and names within a
+// message. These values are used later to determine the padding required for
+// consistent alignment of fields.
func setMaxSizes(curmsg *FormatMsg) {
for _, line := range curmsg.Lines {
parts := strings.Split(line, ";")
@@ -297,7 +337,8 @@ func setMaxSizes(curmsg *FormatMsg) {
}
}
-// use this for header and footer lines
+// padBase generates the indentation string for message headers and footers
+// based on their nesting depth.
func (msg *FormatMsg) padBase() string {
var pad string
for i := 1; i < int(msg.Depth); i += 1 {
@@ -306,7 +347,8 @@ func (msg *FormatMsg) padBase() string {
return pad
}
-// use this for lines inside the message
+// pad generates the indentation string for lines inside a message block,
+// such as field definitions, based on the message's nesting depth.
func (msg *FormatMsg) pad() string {
var pad string
for i := 0; i < int(msg.Depth); i += 1 {
@@ -315,6 +357,8 @@ func (msg *FormatMsg) pad() string {
return pad
}
+// padding generates an indentation string with a custom offset, allowing for
+// flexible alignment calculations.
func (msg *FormatMsg) padding(offset int) string {
var pad string
for i := offset; i < int(msg.Depth); i += 1 {
@@ -323,6 +367,8 @@ func (msg *FormatMsg) padding(offset int) string {
return pad
}
+// formatEnum formats an enum block, including its header, values, and footer,
+// ensuring proper indentation.
func formatEnum(curmsg *FormatMsg) []string {
var newmsg []string
newmsg = append(newmsg, curmsg.formatLineBase(curmsg.Header, "enum header"))
@@ -340,6 +386,8 @@ func formatEnum(curmsg *FormatMsg) []string {
return newmsg
}
+// formatOneof formats a oneof block, aligning its fields and comments
+// according to the calculated padding.
func formatOneof(curmsg *FormatMsg) []string {
// curmsg.formatStandardSizes()
@@ -360,7 +408,9 @@ func formatOneof(curmsg *FormatMsg) []string {
return newmsg
}
-// set all children to have the same max sizes
+// formatStandardSizes traverses the message tree and standardizes the padding
+// for field types and names across all sibling messages. This ensures that
+// fields in adjacent messages are vertically aligned, improving readability.
func (parent *FormatMsg) formatStandardSizes() {
var bigType int64
var bigName int64
@@ -406,6 +456,8 @@ func (parent *FormatMsg) formatStandardSizes() {
}
}
+// format is the main formatting dispatcher. It calls the appropriate formatting
+// function (formatEnum, formatOneof, or formatMessage) based on the message type.
func (parent *FormatMsg) format() []string {
parent.formatStandardSizes()
@@ -421,6 +473,8 @@ func (parent *FormatMsg) format() []string {
}
}
+// formatFooter formats the closing brace '}' of a message block, applying the
+// correct base indentation.
func (msg *FormatMsg) formatFooter(line string, dbg string) string {
if line == "" {
if argv.Debug {
@@ -431,6 +485,8 @@ func (msg *FormatMsg) formatFooter(line string, dbg string) string {
return msg.formatLineBase(line, "footer")
}
+// formatPadAfter adds a blank line after a message block if the original
+// file contained one, preserving vertical spacing.
func (msg *FormatMsg) formatPadAfter() string {
if argv.Debug {
return msg.formatLineBase("", "pad after")
@@ -438,6 +494,8 @@ func (msg *FormatMsg) formatPadAfter() string {
return ""
}
+// formatHeader formats the opening line of a message block (e.g., "message Foo {"),
+// aligning any trailing comments.
func (msg *FormatMsg) formatHeader(line string, dbg string) string {
if line == "" {
if msg.Depth != 0 {
@@ -463,6 +521,8 @@ func (msg *FormatMsg) formatHeader(line string, dbg string) string {
return fmt.Sprintf(hmm, msg.padBase(), start, " ", end)
}
+// formatLineBase formats a line using the base indentation level, suitable for
+// headers, footers, and comments outside of message bodies.
func (msg *FormatMsg) formatLineBase(line string, dbg string) string {
line = strings.TrimSpace(line)
if argv.Debug {
@@ -471,6 +531,8 @@ func (msg *FormatMsg) formatLineBase(line string, dbg string) string {
return fmt.Sprintf("%s%s", msg.padBase(), line)
}
+// formatLine formats a line using the standard block indentation, suitable for
+// field definitions and other content inside a message body.
func (msg *FormatMsg) formatLine(line string, dbg string) string {
line = strings.TrimSpace(line)
if argv.Debug {
@@ -479,6 +541,8 @@ func (msg *FormatMsg) formatLine(line string, dbg string) string {
return fmt.Sprintf("%s%s", msg.pad(), line)
}
+// formatComment formats a comment line, aligning it with the surrounding code
+// based on the calculated maximum field widths.
func (msg *FormatMsg) formatComment(line string, dbg string) string {
line = strings.TrimSpace(line)
pad := fmt.Sprintf("%d", msg.MaxVartype+msg.MaxVarname+13) // 21 is correct?
@@ -490,6 +554,8 @@ func (msg *FormatMsg) formatComment(line string, dbg string) string {
return fmt.Sprintf("%s%s", msg.pad(), comment)
}
+// formatVarLine formats a field definition line, padding the type and name to
+// ensure vertical alignment with other fields in the same scope.
func (msg *FormatMsg) formatVarLine(line string, dbg string) string {
line = strings.TrimSpace(line)
mt := fmt.Sprintf("%d", msg.MaxVartype)
@@ -510,6 +576,9 @@ func (msg *FormatMsg) formatVarLine(line string, dbg string) string {
return fmt.Sprintf("%s%s", msg.pad(), newline)
}
+// formatMsgLine is a dispatcher for formatting a single line within a message.
+// It determines whether the line is a comment or a field definition and calls
+// the appropriate formatting function.
func (msg *FormatMsg) formatMsgLine(line string, dbg string) string {
line = strings.TrimSpace(line)
if line == "" {
@@ -525,11 +594,15 @@ func (msg *FormatMsg) formatMsgLine(line string, dbg string) string {
return msg.formatVarLine(line, "var "+dbg)
}
-// chop extra spaces and blank lines
+// trimLines removes leading/trailing whitespace and blank lines from a slice
+// of strings by joining and splitting them.
func trimLines(lines []string) []string {
return strings.Split(strings.TrimSpace(strings.Join(lines, "\n")), "\n")
}
+// formatMessage is the main function for formatting a `message` block. It
+// orchestrates the formatting of comments, nested messages, and field
+// definitions to produce a clean, aligned output.
func formatMessage(curmsg *FormatMsg) []string {
var newmsg []string
@@ -620,11 +693,14 @@ func formatMessage(curmsg *FormatMsg) []string {
}
// DEFINE THE Lines ITERATOR.
-// itializes a new iterator.
+
+// newLinesScanner initializes a new LinesScanner iterator with a slice of strings.
func newLinesScanner(things []string) *LinesScanner {
return &LinesScanner{things: things}
}
+// LinesScanner provides an iterator over a slice of strings, allowing for
+// sequential access and the ability to un-scan (step back).
type LinesScanner struct {
sync.Mutex
@@ -632,6 +708,8 @@ type LinesScanner struct {
index int
}
+// Scan advances the iterator to the next line. It returns false if there are
+// no more lines.
func (it *LinesScanner) Scan() bool {
if it.index >= len(it.things) {
return false
@@ -642,6 +720,8 @@ func (it *LinesScanner) Scan() bool {
return true
}
+// UnScan moves the iterator back one line. It returns false if the iterator
+// is already at the beginning.
func (it *LinesScanner) UnScan() bool {
if it.index < 1 {
it.index = 0
@@ -653,7 +733,7 @@ func (it *LinesScanner) UnScan() bool {
return true
}
-// does no cleaning of the data
+// NextRaw returns the current line from the scanner without any modification.
func (it *LinesScanner) NextRaw() string {
if it.index-1 == len(it.things) {
fmt.Println("Next() error in LinesScanner", it.index)
@@ -661,7 +741,8 @@ func (it *LinesScanner) NextRaw() string {
return it.things[it.index-1]
}
-// trims whitespace
+// Next returns the current line from the scanner with leading and trailing
+// whitespace removed.
func (it *LinesScanner) Next() string {
if it.index-1 == len(it.things) {
fmt.Println("Next() error in LinesScanner", it.index)
@@ -674,8 +755,9 @@ func (it *LinesScanner) Next() string {
// END DEFINE THE ITERATOR
-// turns: "/* test */ reserved /* linkPreviews */ 4;"
-// into: reserved 1; // test // linkPreviews
+// commentPreprocessor converts single-line C-style block comments (/* ... */)
+// into Go-style line comments (// ...) appended to the end of the line.
+// For example, "/* test */ reserved 4;" becomes "reserved 4; // test".
func commentPreprocessor(line string) string {
// Match all /* comment */ blocks
re := regexp.MustCompile(`/\*([^*]+)\*/`)
@@ -701,14 +783,8 @@ func commentPreprocessor(line string) string {
return line
}
-// /* this
-// - thing
-// */
-//
-// becomes
-//
-// this
-// thing
+// commentPreprocessorFull transforms multi-line C-style block comments
+// (/* ... */) into a series of single-line Go-style comments (// ...).
func commentPreprocessorFull(full string) string {
// Match all /* comment */ blocks
// re := regexp.MustCompile(`/\*([^*]+)\*/`)
@@ -741,6 +817,8 @@ func commentPreprocessorFull(full string) string {
})
}
+// trimCommentPrefix is a helper function for commentPreprocessorFull that
+// removes leading comment markers like '/*', '*', and '*/' from a line.
func trimCommentPrefix(line string) string {
trimmed := strings.TrimSpace(line)