github.com/jhump/protoreflect@v1.16.0/desc/protoparse/ast/print.go (about) 1 package ast 2 3 import "io" 4 5 // Print prints the given AST node to the given output. This operation 6 // basically walks the AST and, for each TerminalNode, prints the node's 7 // leading comments, leading whitespace, the node's raw text, and then 8 // any trailing comments. If the given node is a *FileNode, it will then 9 // also print the file's FinalComments and FinalWhitespace. 10 func Print(w io.Writer, node Node) error { 11 sw, ok := w.(stringWriter) 12 if !ok { 13 sw = &strWriter{w} 14 } 15 var err error 16 Walk(node, func(n Node) (bool, VisitFunc) { 17 if err != nil { 18 return false, nil 19 } 20 token, ok := n.(TerminalNode) 21 if !ok { 22 return true, nil 23 } 24 25 err = printComments(sw, token.LeadingComments()) 26 if err != nil { 27 return false, nil 28 } 29 30 _, err = sw.WriteString(token.LeadingWhitespace()) 31 if err != nil { 32 return false, nil 33 } 34 35 _, err = sw.WriteString(token.RawText()) 36 if err != nil { 37 return false, nil 38 } 39 40 err = printComments(sw, token.TrailingComments()) 41 return false, nil 42 }) 43 if err != nil { 44 return err 45 } 46 47 if file, ok := node.(*FileNode); ok { 48 err = printComments(sw, file.FinalComments) 49 if err != nil { 50 return err 51 } 52 _, err = sw.WriteString(file.FinalWhitespace) 53 return err 54 } 55 56 return nil 57 } 58 59 func printComments(sw stringWriter, comments []Comment) error { 60 for _, comment := range comments { 61 if _, err := sw.WriteString(comment.LeadingWhitespace); err != nil { 62 return err 63 } 64 if _, err := sw.WriteString(comment.Text); err != nil { 65 return err 66 } 67 } 68 return nil 69 } 70 71 // many io.Writer impls also provide a string-based method 72 type stringWriter interface { 73 WriteString(s string) (n int, err error) 74 } 75 76 // adapter, in case the given writer does NOT provide a string-based method 77 type strWriter struct { 78 io.Writer 79 } 80 81 func (s *strWriter) WriteString(str string) (int, error) { 82 if str == "" { 83 return 0, nil 84 } 85 return s.Write([]byte(str)) 86 }