summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-01-09 15:03:05 -0600
committerJeff Carr <[email protected]>2025-01-09 15:03:05 -0600
commitff1721c250420fb4f1ce24f13d2e20721e40a07b (patch)
tree3a61ac908c628077368ad27158746b726f0a5659
parente725c0cc8011ab6d2c418f83d9b86c7897fabef4 (diff)
compiles again
-rw-r--r--Makefile4
-rw-r--r--auto.proto61
-rw-r--r--example/file.proto (renamed from example/auto.proto)0
-rw-r--r--example/fruit.New.go1
-rw-r--r--file.proto70
-rw-r--r--main.go8
-rw-r--r--marshal.go2
-rw-r--r--protoParse.go131
8 files changed, 159 insertions, 118 deletions
diff --git a/Makefile b/Makefile
index 9290772..97ef344 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ install:
auto:
rm -f auto.pb.go
- ./autogenpb --proto auto.proto --package main
+ ./autogenpb --proto file.proto --package main
rm -f auto.sort.pb.go auto.newsort.pb.go # auto.marshal.pb.go
test:
@@ -33,7 +33,7 @@ test:
junk:
cd example; rm -f go.* *.pb.go
- cd example; ../autogenpb --proto auto.proto --package yellow
+ cd example; ../autogenpb --proto file.proto --package yellow
cd example; GO111MODULE=off go vet
goimports:
diff --git a/auto.proto b/auto.proto
index a19afa6..87e6836 100644
--- a/auto.proto
+++ b/auto.proto
@@ -1,5 +1,9 @@
syntax = "proto3";
+// Look at "example/fruit.proto" not this file
+
+// this file is actually used by autogenpb
+
// here are some docs, but probably it's just easier to run
// autogenpb on this file and see what gets autogenerated
// in this directory. All autogenerated files are named *.pb.go
@@ -15,26 +19,6 @@ syntax = "proto3";
package main;
-message Apple { // `autogenpb:marshal`
- string name = 1; // `autogenpb:unique` // generates SortByxxx() and AppendUnique() functions
- string genus = 2; // `autogenpb:unique` // generates same thing here but SortByGenus()
-}
-
-message Apples { // `autogenpb:marshal` `autogenpb:mutex`
- string uuid = 1; // `autogenpb:default:b2a2de35-07b6-443b-8188-709e27bee8a7`
- string version = 2; // `autogenpb:default:2`
- repeated Apple Apples = 3; // `autogenpb:sort`
- repeated Pears More = 4; // `autogenpb:sort`
- repeated string Color = 5; // `autogenpb:sort` `autogenpb:unique`
-}
-
-message Pears {
- string name = 1; //
- string favorite = 2; // `autogenpb:sort`
-}
-
-// above is an example
-
//
// below are the actual structs autogen uses
// autogen parses the .proto file and then store the information
@@ -42,34 +26,13 @@ message Pears {
// protobuf files to write out *.sort.pb.go and *.marshal.pb.go files
//
message MsgName {
- // If you have:
- //
- // "Shelf" for msgname
- // "Books" for name
- //
- // Then in the proto file, that would mean it would look like:
- //
- // message Shelf {
- // and then
- // repeated string Books = 42;
- //
- // autogenpb will then generate sort functions for each 'name'
- // things like:
- //
- // for _, b := range all.Book {
- //
- // and sort functions like:
- //
- // func (a ShelfBook) Less(i, j int) bool { return a[i].Book < a[j].Book }
- //
-
string name = 1; // the name of the message aka struct. for this example: "Shelf"
- string lockname = 2; // ShelfMU
- bool doMarshal = 3; // if "Shelf" should have Marshal & Unmarshal functions
+ string lockname = 2; // name of the lockfile. ends in Mu
+ bool doMarshal = 3; // if msg struct should have Marshal & Unmarshal functions
bool doMutex = 4; // true if a mutex is needed for the message struct
bool doProtocMutex = 5; // an experiment to insert a mutex into the protoc generated msg struct (bad idea?)
bool mutexFound = 6; // true if the mutex was added to the protoc pb.go file
- repeated string sort = 7; // "Book", "Picture", etc
+ repeated string sort = 7; // keys to sort on
repeated string unique = 8; // if the fields should have AppendUnique() functions
}
@@ -79,10 +42,12 @@ message File { // `autogenpb:nomarshal`
string pbfilename = 3; // yellow.pb.go
string filebase = 4; // yellow
string uuid = 5; // the uuid to use in a func NewMsgName()
- int64 version = 6; // the version to use in a func NewMsgName()
+ string version = 6; // the version to use in a func NewMsgName()
+ MsgName bases = 7; // the message in "plural" form
+ MsgName base = 8; // the primary repeated message for the master struct
// every struct in this proto file, this file has: "Apple", "Apples", ... "File", etc...
- repeated MsgName msgNames = 7; // `autogenpb:unique` // in this file
+ repeated MsgName msgNames = 9; // `autogenpb:unique` // in this file
}
// I know, I know, the whole point of using protobuf
@@ -92,8 +57,8 @@ message File { // `autogenpb:nomarshal`
// also, this could be used to modify /usr/bin/file /usr/share/magic to identify the files
// maybe this is already been done and is pointless, but it seems like a good idea
message Files { // `autogenpb:marshal`
- string uuid = 1; // if you use this scheme, autogen will be able to identify your
- int64 version = 2; // protobuf files from the command line.
+ string uuid = 1; // `autogenpb:uuid:6c9ae4dd-648d-4b51-9738-bd59fb8fafd5`
+ string version = 2; // `autogenpb:version:v0.0.38`
repeated File Files = 3; // an array of each .proto file in the working directory
}
diff --git a/example/auto.proto b/example/file.proto
index d65ccd0..d65ccd0 100644
--- a/example/auto.proto
+++ b/example/file.proto
diff --git a/example/fruit.New.go b/example/fruit.New.go
index c00f981..6d32ded 100644
--- a/example/fruit.New.go
+++ b/example/fruit.New.go
@@ -3,5 +3,6 @@ package main
func NewFruits() *Fruits {
x := new(Fruits)
x.Uuid = "test"
+ x.Version = "v0.0.2"
return x
}
diff --git a/file.proto b/file.proto
new file mode 100644
index 0000000..87e6836
--- /dev/null
+++ b/file.proto
@@ -0,0 +1,70 @@
+syntax = "proto3";
+
+// Look at "example/fruit.proto" not this file
+
+// this file is actually used by autogenpb
+
+// here are some docs, but probably it's just easier to run
+// autogenpb on this file and see what gets autogenerated
+// in this directory. All autogenerated files are named *.pb.go
+
+// the 'uuid' standard at the end is an experiment
+// establish a way to identify arbitrary .pb files
+
+// You can generate Marshal & Unmarshal for any struct (message) you want
+// You can generate SortBy and Append functions ONLY FOR 'repeated <message>'
+// Also, those structs must be defined in the same file
+// Additionally, you must use `autogenpb:mutex` on the parent struct.
+// The autogenerated code requires a RW mutex and autogenpb will insert it into the struct
+
+package main;
+
+//
+// below are the actual structs autogen uses
+// autogen parses the .proto file and then store the information
+// it needs in these protobuf files, then it processes the
+// protobuf files to write out *.sort.pb.go and *.marshal.pb.go files
+//
+message MsgName {
+ string name = 1; // the name of the message aka struct. for this example: "Shelf"
+ string lockname = 2; // name of the lockfile. ends in Mu
+ bool doMarshal = 3; // if msg struct should have Marshal & Unmarshal functions
+ bool doMutex = 4; // true if a mutex is needed for the message struct
+ bool doProtocMutex = 5; // an experiment to insert a mutex into the protoc generated msg struct (bad idea?)
+ bool mutexFound = 6; // true if the mutex was added to the protoc pb.go file
+ repeated string sort = 7; // keys to sort on
+ repeated string unique = 8; // if the fields should have AppendUnique() functions
+}
+
+message File { // `autogenpb:nomarshal`
+ string Package = 1; // whatever the package name is at the top of the .go file
+ string filename = 2; // yellow.proto
+ string pbfilename = 3; // yellow.pb.go
+ string filebase = 4; // yellow
+ string uuid = 5; // the uuid to use in a func NewMsgName()
+ string version = 6; // the version to use in a func NewMsgName()
+ MsgName bases = 7; // the message in "plural" form
+ MsgName base = 8; // the primary repeated message for the master struct
+
+ // every struct in this proto file, this file has: "Apple", "Apples", ... "File", etc...
+ repeated MsgName msgNames = 9; // `autogenpb:unique` // in this file
+}
+
+// I know, I know, the whole point of using protobuf
+// is so you don't need a uuid or versions because it's
+// inherently forward compatable. nonetheless, a simple stubbed out
+// trivial and empty protobuf message can marshal and identify all the files
+// also, this could be used to modify /usr/bin/file /usr/share/magic to identify the files
+// maybe this is already been done and is pointless, but it seems like a good idea
+message Files { // `autogenpb:marshal`
+ string uuid = 1; // `autogenpb:uuid:6c9ae4dd-648d-4b51-9738-bd59fb8fafd5`
+ string version = 2; // `autogenpb:version:v0.0.38`
+ repeated File Files = 3; // an array of each .proto file in the working directory
+}
+
+// this generic message is used by autogen to identify and
+// then dump the uuid and version from any arbitrary .pb file
+message Identify { // `autogenpb:marshal`
+ string uuid = 1; //
+ int64 version = 2; //
+}
diff --git a/main.go b/main.go
index 6e85d5b..f9f62da 100644
--- a/main.go
+++ b/main.go
@@ -108,16 +108,10 @@ func main() {
protobase := strings.TrimSuffix(argv.Proto, ".proto")
f.Filebase = protobase
- // parse the .proto file
- if err := pb.protoParse(f); err != nil {
- log.Info("autogenpb parse error:", err)
- os.Exit(-1)
- }
-
// parse sort & marshal options from the .proto file
// this goes through the .proto files and looks
// for `autogenpb: ` lines
- if err := pb.protoParseNew(f); err != nil {
+ if err := pb.protoParse(f); err != nil {
log.Info("autogenpb parse error:", err)
os.Exit(-1)
}
diff --git a/marshal.go b/marshal.go
index 43d8c14..9709d5a 100644
--- a/marshal.go
+++ b/marshal.go
@@ -52,7 +52,7 @@ func marshalThing(w io.Writer, thing string) {
fmt.Fprintln(w, "")
fmt.Fprintln(w, "// apparently this isn't stable, but it's awesomely better")
fmt.Fprintln(w, "// https://protobuf.dev/reference/go/faq/#unstable-text")
- fmt.Fprintln(w, "// it's so great for config files, I'm using it by default to try to fix the problems with it")
+ fmt.Fprintln(w, "// it's brilliant for config files!")
fmt.Fprintln(w, "func (v *"+thing+") FormatTEXT() string {")
fmt.Fprintln(w, " return prototext.Format(v)")
fmt.Fprintln(w, "}")
diff --git a/protoParse.go b/protoParse.go
index 31e2f6d..bd7db81 100644
--- a/protoParse.go
+++ b/protoParse.go
@@ -3,6 +3,8 @@ package main
// auto run protoc with the correct args
import (
+ "bufio"
+ "fmt"
"os"
"strings"
@@ -13,15 +15,59 @@ import (
// this parses the .proto file and handles anything with `autogenpb: `
-// finds autogenpb:marshal and autogenpb:unique in the .proto file
-//
-// adds fields to []marshal and []unique
-func (pb *Files) protoParseNew(f *File) error {
- // log.Info("starting findAutogenpb() on", names["protofile"])
+// does the fruit.proto file have "message Fruits"
+func (pb *Files) hasPluralMessage(f *File) error {
+ file, err := os.Open(f.Filename)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ line := scanner.Text()
+
+ base := cases.Title(language.English, cases.NoLower).String(f.Filebase)
+ prefix := "message " + base + "s" // to conform, it must have an added 's'
+ if !strings.HasPrefix(line, prefix) {
+ // log.Info("nope", prefix, "line", line)
+ // nope, not this line
+ continue
+ }
+ // found the matching message
+ // f.Bases = f.parseForMessage(line)
+
+ line = scanner.Text()
+ fields := strings.Fields(line)
+ if fields[0] == "string" && fields[1] != "uuid" {
+ return fmt.Errorf("proto file does not have a UUID")
+ }
+ // ok, uuid is here
+ f.Uuid = line
+ log.Info("found UUID:", line)
+
+ line = scanner.Text()
+ fields = strings.Fields(line)
+ if fields[0] == "string" && fields[1] != "version" {
+ return fmt.Errorf("proto file does not have a version")
+ }
+ // found "version", the .proto file conforms
+ f.Version = line
+ log.Info("found Version:", line)
+ return nil
+ }
+ return fmt.Errorf("proto file error %s", f.Filename)
+}
+
+func (pb *Files) protoParse(f *File) error {
+ // does the file conform to the standard? (also reads in UUID & Version)
+ if err := pb.hasPluralMessage(f); err != nil {
+ return err
+ }
+ log.Info(f.Filename, "is valid so far")
+
// read in the .proto file
data, err := os.ReadFile(f.Filename)
if err != nil {
- // log.Info("open config file :", err)
return err
}
@@ -29,45 +75,38 @@ func (pb *Files) protoParseNew(f *File) error {
// parse the proto file for message struct names
for _, line := range strings.Split(string(data), "\n") {
+ base := cases.Title(language.English, cases.NoLower).String(f.Filebase)
if strings.HasPrefix(line, "message ") {
curmsg = f.parseForMessage(line)
+ prefix := "message " + base // only look for this for now
+ if strings.HasPrefix(line, prefix) {
+ // f.Base = curmsg
+ } else {
+ f.MsgNames = append(f.MsgNames, curmsg)
+ }
}
if strings.HasPrefix(line, "}") {
curmsg = nil
}
+ if curmsg == nil {
+ // can't contiue on nil below here
+ continue
+ }
// log.Info("line:", line)
parts := strings.Fields(line)
if strings.Contains(line, "autogenpb:sort") {
- if parts[0] == "repeated" {
- newS := parts[1]
- if curmsg == nil {
- log.Info("Error: Found Sort for:", newS, "however, this struct can't be used")
- } else {
- log.Info("Addded Sort:", newS, "in struct", curmsg.Name)
- curmsg.Sort = append(curmsg.Sort, newS)
- }
- } else {
- log.Info("Error:", line)
- log.Info("Error: can not sort on non repeated fields")
- }
+ newS := parts[1]
+ log.Info("Addded Sort:", newS, "in struct", curmsg.Name)
+ curmsg.Sort = append(curmsg.Sort, newS)
}
if strings.Contains(line, "autogenpb:unique") {
- if parts[0] == "repeated" {
- newU := parts[1]
- newU = cases.Title(language.English, cases.NoLower).String(newU)
- if curmsg == nil {
- log.Info("Error: Found Unique for:", newU, "however, this struct can't be used")
- } else {
- log.Info("Added Unique:", newU, "in struct", curmsg.Name)
- curmsg.Unique = append(curmsg.Unique, newU)
- }
- } else {
- log.Info("Error:", line)
- log.Info("Error: can not append on non repeated fields")
- }
+ newU := parts[1]
+ newU = cases.Title(language.English, cases.NoLower).String(newU)
+ log.Info("Added Unique:", newU, "in struct", curmsg.Name)
+ curmsg.Unique = append(curmsg.Unique, newU)
}
}
return nil
@@ -80,8 +119,8 @@ func (f *File) parseForMessage(line string) *MsgName {
return nil
}
msgName := fields[1]
+ log.Info("found messge:", msgName)
msg := new(MsgName)
- f.MsgNames = append(f.MsgNames, msg)
msg.Name = msgName
msg.Lockname = msgName + "Mu"
@@ -95,31 +134,3 @@ func (f *File) parseForMessage(line string) *MsgName {
}
return msg
}
-
-// this doesn't do anything anymore (?)
-func (pb *Files) protoParse(f *File) error {
- // log.Info("starting findAutogenpb() on", filename)
- // read in the .proto file
- data, err := os.ReadFile(f.Filename)
- if err != nil {
- // log.Info("open config file :", err)
- return err
- }
-
- lines := strings.Split(string(data), "\n")
- for _, line := range lines {
- if strings.Contains(line, "autogenpb:ignoreproto") {
- // ignore this protofile completely (don't make foo.pb.go)
- os.Exit(0)
- }
- if strings.Contains(line, "autogenpb:no-marshal") {
- // don't marshal anything (don't make foo.marshal.pb.go)
- argv.NoMarshal = true
- }
- if strings.Contains(line, "autogenpb:no-sort") {
- // don't sort anything (don't make foo.sort.pb.go)
- argv.NoSort = true
- }
- }
- return nil
-}