protofmt.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package main
  2. import (
  3. "bufio"
  4. "flag"
  5. "fmt"
  6. "io"
  7. "log"
  8. "os"
  9. "regexp"
  10. "strings"
  11. "text/tabwriter"
  12. )
  13. func main() {
  14. flag.Parse()
  15. file := flag.Arg(0)
  16. in, err := os.Open(file)
  17. if err != nil {
  18. log.Fatal(err)
  19. }
  20. out, err := os.Create(file + ".tmp")
  21. if err != nil {
  22. log.Fatal(err)
  23. }
  24. if err := formatProto(in, out); err != nil {
  25. log.Fatal(err)
  26. }
  27. if err := os.Rename(file+".tmp", file); err != nil {
  28. log.Fatal(err)
  29. }
  30. }
  31. func formatProto(in io.Reader, out io.Writer) error {
  32. sc := bufio.NewScanner(in)
  33. lineExp := regexp.MustCompile(`([^=]+)\s+([^=\s]+?)\s*=(.+)`)
  34. var tw *tabwriter.Writer
  35. for sc.Scan() {
  36. line := sc.Text()
  37. if strings.HasPrefix(line, "//") {
  38. if _, err := fmt.Fprintln(out, line); err != nil {
  39. return err
  40. }
  41. continue
  42. }
  43. ms := lineExp.FindStringSubmatch(line)
  44. for i := range ms {
  45. ms[i] = strings.TrimSpace(ms[i])
  46. }
  47. if len(ms) == 4 && ms[1] != "option" {
  48. typ := strings.Join(strings.Fields(ms[1]), " ")
  49. name := ms[2]
  50. id := ms[3]
  51. if tw == nil {
  52. tw = tabwriter.NewWriter(out, 4, 4, 1, ' ', 0)
  53. }
  54. if typ == "" {
  55. // We're in an enum
  56. fmt.Fprintf(tw, "\t%s\t= %s\n", name, id)
  57. } else {
  58. // Message
  59. fmt.Fprintf(tw, "\t%s\t%s\t= %s\n", typ, name, id)
  60. }
  61. } else {
  62. if tw != nil {
  63. if err := tw.Flush(); err != nil {
  64. return err
  65. }
  66. tw = nil
  67. }
  68. if _, err := fmt.Fprintln(out, line); err != nil {
  69. return err
  70. }
  71. }
  72. }
  73. return nil
  74. }