refactor again. I want to make this clean
as clean as possible because, I use this tool alot. everywhere. I want it to always work. I need do not want it to break
This commit is contained in:
parent
0d2dc9fb25
commit
cfd9ec5ccd
28
Makefile
28
Makefile
|
@ -1,15 +1,27 @@
|
||||||
VERSION = $(shell git describe --tags)
|
VERSION = $(shell git describe --tags)
|
||||||
BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
|
BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
|
||||||
|
|
||||||
simple: build
|
simple: test
|
||||||
make -C example clean simpleMutexGlobal goimports vet
|
# make -C example clean simpleMutexGlobal goimports vet
|
||||||
make -C example clean simpleMutexProtoc goimports vet
|
# make -C example clean simpleMutexProtoc goimports vet
|
||||||
# make -C example deleteproto
|
# make -C example deleteproto
|
||||||
|
|
||||||
full: install clean auto goimports vet build test install
|
full: install clean auto goimports vet build test install
|
||||||
@echo everything worked and the example ran
|
@echo everything worked and the example ran
|
||||||
|
|
||||||
test: goimports build test
|
|
||||||
|
# if this passes, it should be OK to 'go install'
|
||||||
|
test:
|
||||||
|
reset
|
||||||
|
make goimports vet build
|
||||||
|
make -C example testGlobal
|
||||||
|
make -C example testProtoc
|
||||||
|
|
||||||
|
dryrun: build
|
||||||
|
make -C example dryrun
|
||||||
|
|
||||||
|
dryrun-clean: clean auto build
|
||||||
|
make -C example dryrun
|
||||||
|
|
||||||
vet:
|
vet:
|
||||||
@GO111MODULE=off go vet
|
@GO111MODULE=off go vet
|
||||||
|
@ -31,7 +43,7 @@ build: goimports
|
||||||
bak:
|
bak:
|
||||||
mv -f autogenpb autogenpb.last
|
mv -f autogenpb autogenpb.last
|
||||||
|
|
||||||
install:
|
install: test
|
||||||
GO111MODULE=off go install \
|
GO111MODULE=off go install \
|
||||||
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
||||||
|
|
||||||
|
@ -40,12 +52,6 @@ auto:
|
||||||
autogenpb --proto file.proto --package main
|
autogenpb --proto file.proto --package main
|
||||||
# rm -f auto.sort.pb.go auto.newsort.pb.go # auto.marshal.pb.go
|
# rm -f auto.sort.pb.go auto.newsort.pb.go # auto.marshal.pb.go
|
||||||
|
|
||||||
test:
|
|
||||||
make -C example rawproto
|
|
||||||
# The Go Protocol Buffers library embeds a sync.Mutex within the MessageState struct to prevent unintended shallow copies of message structs
|
|
||||||
# It only fails in Marshal() functions though. That is dumb.
|
|
||||||
make -C example modproto # THIS DOES NOT WORK. It could work however. This autogenerated code could be used to debug it.
|
|
||||||
|
|
||||||
junk:
|
junk:
|
||||||
cd example; rm -f go.* *.pb.go
|
cd example; rm -f go.* *.pb.go
|
||||||
cd example; ../autogenpb --proto file.proto --package yellow
|
cd example; ../autogenpb --proto file.proto --package yellow
|
||||||
|
|
|
@ -4,6 +4,20 @@ BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
|
||||||
all: clean simpleMutexProtoc goimports build
|
all: clean simpleMutexProtoc goimports build
|
||||||
./example
|
./example
|
||||||
|
|
||||||
|
# if this passes, then autogenpb should be working
|
||||||
|
# and it is OK to 'go install' the binary
|
||||||
|
test: testGlobal testProtoc
|
||||||
|
|
||||||
|
testGlobal:
|
||||||
|
make clean
|
||||||
|
../autogenpb --proto fruit.proto --package main --mutex=false # first build with a global mutex
|
||||||
|
make build
|
||||||
|
|
||||||
|
testProtoc:
|
||||||
|
make clean
|
||||||
|
../autogenpb --proto fruit.proto --package main # inserts mutex into protoc .pb.go file
|
||||||
|
make build
|
||||||
|
|
||||||
modproto: clean withMutex goimports vet build
|
modproto: clean withMutex goimports vet build
|
||||||
./example
|
./example
|
||||||
|
|
||||||
|
@ -47,6 +61,10 @@ withoutMutex: clean
|
||||||
../autogenpb --proto file.proto --package main --mutex=false
|
../autogenpb --proto file.proto --package main --mutex=false
|
||||||
../autogenpb --proto patchset.proto --package main --mutex=false
|
../autogenpb --proto patchset.proto --package main --mutex=false
|
||||||
|
|
||||||
|
dryrun:
|
||||||
|
../autogenpb --proto fruit.proto --package main --dry-run
|
||||||
|
# ../autogenpb --proto file.proto --package main
|
||||||
|
|
||||||
goimports:
|
goimports:
|
||||||
goimports -w *.go
|
goimports -w *.go
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ message MsgName {
|
||||||
repeated string sort = 7; // keys to sort on
|
repeated string sort = 7; // keys to sort on
|
||||||
repeated string unique = 8; // if the fields should have AppendUnique() functions
|
repeated string unique = 8; // if the fields should have AppendUnique() functions
|
||||||
repeated MsgVar vars = 9; // store all the vars in the message
|
repeated MsgVar vars = 9; // store all the vars in the message
|
||||||
|
bool needIter = 10; // true if the sort iterator has not been generated yet
|
||||||
}
|
}
|
||||||
|
|
||||||
message File {
|
message File {
|
||||||
|
|
|
@ -22,8 +22,23 @@ message Apple { // `autogenpb:marshal`
|
||||||
}
|
}
|
||||||
|
|
||||||
message Pear {
|
message Pear {
|
||||||
string name = 1; //
|
string name = 1; // `autogenpb:sort`
|
||||||
string favorite = 2; // `autogenpb:sort`
|
string favorite = 2; // `autogenpb:sort` `autogenpb:unique`
|
||||||
|
}
|
||||||
|
|
||||||
|
message Banana {
|
||||||
|
repeated string name = 1; // `autogenpb:sort`
|
||||||
|
string favorite = 2; // `autogenpb:sort` `autogenpb:unique`
|
||||||
|
string country = 3; // `autogenpb:sort`
|
||||||
|
}
|
||||||
|
|
||||||
|
message Basket {
|
||||||
|
repeated string name = 1; // `autogenpb:sort` `autogenpb:unique`
|
||||||
|
string favorite = 2; // `autogenpb:sort` `autogenpb:unique`
|
||||||
|
int64 price = 3; // `autogenpb:sort`
|
||||||
|
repeated Banana banna = 4;
|
||||||
|
repeated Pear pears = 5;
|
||||||
|
repeated Apple stacks = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Fruit" must exist. you can put anything in it
|
// "Fruit" must exist. you can put anything in it
|
||||||
|
@ -33,6 +48,9 @@ message Fruit { // `autogenpb:marshal`
|
||||||
repeated Pear pears = 3;
|
repeated Pear pears = 3;
|
||||||
string UPC = 4; // `autogenpb:sort` `autogenpb:unique`
|
string UPC = 4; // `autogenpb:sort` `autogenpb:unique`
|
||||||
string city = 5; // `autogenpb:sort`
|
string city = 5; // `autogenpb:sort`
|
||||||
|
repeated Pear notpears = 6;
|
||||||
|
repeated Pear fakepears = 7;
|
||||||
|
repeated Basket gifts = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Fruits" MUST EXIST and start exactly this way
|
// "Fruits" MUST EXIST and start exactly this way
|
||||||
|
@ -43,4 +61,5 @@ message Fruits { // `autogenpb:marshal` `autogenpb:mutex`
|
||||||
repeated Fruit Fruits = 3; // THIS MUST BE "Fruit" and then "Fruit" + "s"
|
repeated Fruit Fruits = 3; // THIS MUST BE "Fruit" and then "Fruit" + "s"
|
||||||
// you can add additional things here but the three lines above must conform to the standard above
|
// you can add additional things here but the three lines above must conform to the standard above
|
||||||
int64 cost = 4;
|
int64 cost = 4;
|
||||||
|
map<string, string> junk = 5;
|
||||||
}
|
}
|
||||||
|
|
20
file.proto
20
file.proto
|
@ -43,9 +43,27 @@ message MsgName {
|
||||||
repeated string sort = 7; // keys to sort on
|
repeated string sort = 7; // keys to sort on
|
||||||
repeated string unique = 8; // if the fields should have AppendUnique() functions
|
repeated string unique = 8; // if the fields should have AppendUnique() functions
|
||||||
repeated MsgVar vars = 9; // store all the vars in the message
|
repeated MsgVar vars = 9; // store all the vars in the message
|
||||||
|
bool needIter = 10; // true if the sort iterator has not been generated yet
|
||||||
|
bool needAll = 11; // true if the sort iterator has not been generated yet
|
||||||
|
}
|
||||||
|
|
||||||
|
message Sort {
|
||||||
|
string msgName = 1; // `autogenpb:unique` File
|
||||||
|
string varType = 2; // `autogenpb:unique` MsgName
|
||||||
|
string varName = 3; // `autogenpb:unique` msgNames, sortNames
|
||||||
|
string lockname = 4; //
|
||||||
|
bool needAll = 5; //
|
||||||
|
}
|
||||||
|
|
||||||
|
message Find {
|
||||||
|
string parent = 1; // `autogenpb:unique` File
|
||||||
|
string varType = 2; // `autogenpb:unique` MsgName
|
||||||
|
string varName = 3; // `autogenpb:unique` msgNames, sortNames
|
||||||
|
bool needAll = 4; //
|
||||||
}
|
}
|
||||||
|
|
||||||
message File {
|
message File {
|
||||||
|
// `autogenpb:var:w io.Writer`
|
||||||
string Package = 1; // whatever the package name is at the top of the .go file
|
string Package = 1; // whatever the package name is at the top of the .go file
|
||||||
string filename = 2; // yellow.proto
|
string filename = 2; // yellow.proto
|
||||||
string pbfilename = 3; // yellow.pb.go
|
string pbfilename = 3; // yellow.pb.go
|
||||||
|
@ -58,6 +76,8 @@ message File {
|
||||||
// every struct in this proto file, this file has: "Apple", "Apples", ... "File", etc...
|
// every struct in this proto file, this file has: "Apple", "Apples", ... "File", etc...
|
||||||
repeated MsgName msgNames = 9;
|
repeated MsgName msgNames = 9;
|
||||||
repeated MsgName sortNames = 10; // variables that are repeated can have the standard functions generated (Sort(), etc)
|
repeated MsgName sortNames = 10; // variables that are repeated can have the standard functions generated (Sort(), etc)
|
||||||
|
map<string, string> iterMap = 11;
|
||||||
|
repeated Sort toSort = 12; // variables that are repeated can have the standard functions generated (Sort(), etc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// I know, I know, the whole point of using protobuf
|
// I know, I know, the whole point of using protobuf
|
||||||
|
|
254
generate.go
254
generate.go
|
@ -15,19 +15,212 @@ import (
|
||||||
func (pb *Files) makeNewSortfile(pf *File) error {
|
func (pb *Files) makeNewSortfile(pf *File) error {
|
||||||
wSort, _ := os.OpenFile(pf.Filebase+".sort.pb.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
wSort, _ := os.OpenFile(pf.Filebase+".sort.pb.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||||
defer wSort.Close()
|
defer wSort.Close()
|
||||||
wFind, _ := os.OpenFile(pf.Filebase+".find.pb.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
|
||||||
defer wFind.Close()
|
|
||||||
|
|
||||||
header(wSort, pf)
|
header(wSort, pf)
|
||||||
|
pf.syncLock(wSort)
|
||||||
|
|
||||||
// pf.Base.iterTop(wSort)
|
log.Printf("START ITERATORS\n")
|
||||||
// pf.Base.iterNext(wSort)
|
// add iterators for all the structs to be used
|
||||||
// pf.selectAllFunc(wSort)
|
for i, msg := range pf.allMsg() {
|
||||||
// pf.iterSelect(wSort)
|
PARENT := msg.Name
|
||||||
|
LOCK := msg.Lockname
|
||||||
|
|
||||||
// pf.sortByFunc(wSort, pf.Bases, pf.Base)
|
funcdef := newIter(wSort, msg)
|
||||||
|
log.Printf("ITER: %-2d %20s %20s %20s %20s %s\n", i, PARENT, "", "", LOCK, funcdef)
|
||||||
|
}
|
||||||
|
log.Printf("END ITERATORS\n")
|
||||||
|
log.Printf("\n")
|
||||||
|
|
||||||
|
log.Printf("START COMPARE\n")
|
||||||
|
for i, msg := range pf.allMsg() {
|
||||||
|
PARENT := msg.Name
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if !v.HasSort {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
VARNAME := v.VarName
|
||||||
|
funcdef := newSortType(wSort, PARENT, VARNAME)
|
||||||
|
log.Printf("TYPE: %-2d %20s %20s %20s %10s %s\n", i, PARENT, "", "", "", funcdef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Printf("END COMPARE\n")
|
||||||
|
log.Printf("\n")
|
||||||
|
|
||||||
|
// add selectAll() functions for all the sort combinations that will be used
|
||||||
|
for i, s := range pf.ToSort {
|
||||||
|
// log.Printf("SORT: %-2d %20s %20s %20s %20s\n", i, s.MsgName, s.VarType, s.VarName, s.Lockname)
|
||||||
|
FRUIT := s.MsgName
|
||||||
|
APPLE := s.VarType
|
||||||
|
APPLES := s.VarName
|
||||||
|
LOCK := s.Lockname
|
||||||
|
funcdef := newIterAll(wSort, FRUIT, APPLE, APPLES, LOCK)
|
||||||
|
log.Printf("JUNK: %-2d %20s %20s %20s %20s %s\n", i, FRUIT, APPLE, "", LOCK, funcdef)
|
||||||
|
}
|
||||||
|
log.Printf("\n")
|
||||||
|
|
||||||
|
// make the sort iterators selectAll()
|
||||||
|
for i, s := range pf.ToSort {
|
||||||
|
PARENT := s.MsgName
|
||||||
|
CHILD := s.VarType
|
||||||
|
VARNAME := s.VarName
|
||||||
|
LOCK := s.Lockname
|
||||||
|
|
||||||
|
funcdef := addSelectAll(wSort, PARENT, CHILD, VARNAME, LOCK)
|
||||||
|
log.Printf("SORT: %-2d %20s %20s %20s %20s %s\n", i, PARENT, CHILD, VARNAME, LOCK, funcdef)
|
||||||
|
}
|
||||||
|
log.Printf("\n")
|
||||||
|
|
||||||
|
// make Len()
|
||||||
|
for _, msg := range pf.allMsg() {
|
||||||
|
PARENT := msg.Name
|
||||||
|
LOCK := msg.Lockname
|
||||||
|
|
||||||
|
for i, v := range msg.Vars {
|
||||||
|
if v.IsRepeated {
|
||||||
|
CHILD := v.VarType
|
||||||
|
VARNAME := v.VarName
|
||||||
|
// funcdef := "func (x *" + PARENT + ") Len" + VARNAME + "() int " + CHILD + " name:" + VARNAME
|
||||||
|
|
||||||
|
if PARENT == VARNAME {
|
||||||
|
// special case
|
||||||
|
funcdef := addLenFunc(wSort, PARENT, VARNAME, LOCK) // + " " + v.VarType + " name:" + v.VarName
|
||||||
|
funcdef += " # is special struct=varname"
|
||||||
|
log.Printf("LEN: %-2d %20s %20s %20s %20s %s\n", i, PARENT, CHILD, VARNAME, LOCK, funcdef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("\n")
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %20s\n", "", "PARENT STRUCT", "VAR STRUCT TYPE", "VAR NAME", "LOCK")
|
||||||
|
// for i, s := range slices.Backward(pf.ToSort) {
|
||||||
|
for i, s := range pf.ToSort {
|
||||||
|
var funcname string
|
||||||
|
PARENT := s.MsgName
|
||||||
|
CHILD := s.VarType
|
||||||
|
VARNAME := s.VarName
|
||||||
|
LOCK := s.Lockname
|
||||||
|
|
||||||
|
log.Printf("SORT: %-2d %20s %20s %20s %20s %s\n", i, PARENT, CHILD, VARNAME, LOCK, "")
|
||||||
|
|
||||||
|
var FUNCTYPE string
|
||||||
|
if PARENT == VARNAME {
|
||||||
|
FUNCTYPE = PARENT
|
||||||
|
} else {
|
||||||
|
FUNCTYPE = VARNAME
|
||||||
|
}
|
||||||
|
|
||||||
|
if PARENT == VARNAME {
|
||||||
|
funcname := addAllFunc(wSort, PARENT, CHILD, VARNAME)
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "done", "", funcname)
|
||||||
|
}
|
||||||
|
if s.VarType+"s" == s.VarName {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") All() *[]iter" + s.VarType
|
||||||
|
} else {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") all" + s.VarName + "() *[]iter" + s.VarType
|
||||||
|
}
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
msg := pf.findMsg(s.VarType)
|
||||||
|
if msg == nil {
|
||||||
|
return fmt.Errorf("failed to find struct %s", s.VarType)
|
||||||
|
}
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if v.HasSort {
|
||||||
|
funcname := "func (x *" + FUNCTYPE + ") SortBy" + v.VarName + "(" + v.VarType + ") *[]iter" + s.VarType
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
// funcdef := "func (x *"+FRUIT+") SortBy"+COLOR+"() *"+APPLE+"Iterator"
|
||||||
|
|
||||||
|
if v.VarType == "string" {
|
||||||
|
funcdef := newSortBy(wSort, FUNCTYPE, CHILD, VARNAME, v.VarName)
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcdef)
|
||||||
|
} else {
|
||||||
|
funcname := "func (x *" + FUNCTYPE + ") SortBy" + v.VarName + "(" + v.VarType + ") *[]iter" + s.VarType + " # can not do this yet"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ucount int
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if v.HasUnique {
|
||||||
|
ucount += 1
|
||||||
|
funcname := "func (x *" + FUNCTYPE + ") AppendUnique" + v.VarName + "(" + v.VarType + ")"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if v.HasUnique {
|
||||||
|
funcname := "func (x *" + FUNCTYPE + ") DeleteBy" + v.VarName + "(" + v.VarType + ") bool"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if v.HasUnique {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") FindBy" + v.VarName + "(a " + v.VarType + ") *" + s.VarType + "(using" + v.VarName + ")"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
} else {
|
||||||
|
if v.VarType == "string" {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") FindBy" + v.VarName + "(a string) []*" + s.VarType + " ???"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ucount == 1 {
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if !v.HasUnique {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") Insert(a *" + v.VarType + ") (*" + CHILD + ", isNew bool)"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ucount > 1 {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") Insert(a *" + CHILD + ") (*" + CHILD + ", isNew bool)"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// everything struct used in here needs a sort iterator (but just one)
|
||||||
|
for FRUIT, APPLE := range pf.IterMap {
|
||||||
|
msg := pf.findMsg(FRUIT)
|
||||||
|
if msg == nil {
|
||||||
|
return fmt.Errorf("failed to find struct %s", FRUIT)
|
||||||
|
}
|
||||||
|
log.Printf("Add newIter() message %s\n", FRUIT)
|
||||||
|
newIter(wSort, msg)
|
||||||
|
|
||||||
|
child := pf.findMsg(APPLE)
|
||||||
|
if child == nil {
|
||||||
|
return fmt.Errorf("failed to find struct %s", APPLE)
|
||||||
|
}
|
||||||
|
log.Printf("Add newIter() message %s\n", APPLE)
|
||||||
|
newIter(wSort, child)
|
||||||
|
|
||||||
|
// now add the allKEY() functions
|
||||||
|
msg.newIterAll(wSort, FRUIT, APPLE)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
log.Info("START")
|
||||||
|
log.Printf("Add all() FRUIT=%s APPLE=%s\n", FRUIT, APPLE)
|
||||||
|
addAllFunc(w, FRUIT, APPLE, LOCK)
|
||||||
|
log.Printf("Add len() FRUIT=%s APPLES=%s\n", FRUIT, APPLES)
|
||||||
|
addLenFunc(w, FRUIT, APPLES, LOCK)
|
||||||
|
log.Printf("Add selectAll() FRUIT=%s APPLE=%s APPLES=%s\n", FRUIT, APPLE, APPLES)
|
||||||
|
addSelectAll(w, FRUIT, APPLE, APPLES, LOCK)
|
||||||
|
// newIter(w, FRUIT, APPLE, APPLES, LOCK)
|
||||||
|
log.Info("END")
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
return nil
|
||||||
pf.newGenerateSort(wSort, pf.Bases)
|
pf.newGenerateSort(wSort, pf.Bases)
|
||||||
pf.newGenerateSort(wSort, pf.Base)
|
pf.newGenerateSort(wSort, pf.Base)
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pf.appendUnique(wFind) // Append() enforce no unique keys
|
pf.appendUnique(wFind) // Append() enforce no unique keys
|
||||||
|
@ -39,8 +232,10 @@ func (pb *Files) makeNewSortfile(pf *File) error {
|
||||||
pf.findFunc(wFind)
|
pf.findFunc(wFind)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
wFind, _ := os.OpenFile(pf.Filebase+".find.pb.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||||
|
defer wFind.Close()
|
||||||
header(wFind, pf)
|
header(wFind, pf)
|
||||||
pf.syncLock(wFind)
|
|
||||||
pf.specialBases(wFind)
|
pf.specialBases(wFind)
|
||||||
|
|
||||||
// attempt to add sort functions for pf.Base
|
// attempt to add sort functions for pf.Base
|
||||||
|
@ -50,33 +245,46 @@ func (pb *Files) makeNewSortfile(pf *File) error {
|
||||||
if err := pf.processMessage(pf.Base, wSort, wFind); err != nil {
|
if err := pf.processMessage(pf.Base, wSort, wFind); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func addIterNew(w io.Write, msg *MsgName {
|
||||||
|
var FRUIT string = parent.Name
|
||||||
|
var LOCK string = parent.Lockname
|
||||||
|
newIter(w, FRUIT, APPLE, APPLES, LOCK)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func (pf *File) newGenerateSort(w io.Writer, parent *MsgName) error {
|
func (pf *File) newGenerateSort(w io.Writer, parent *MsgName) error {
|
||||||
var FRUIT string = parent.Name
|
var FRUIT string = parent.Name
|
||||||
var LOCK string = parent.Lockname
|
var LOCK string = parent.Lockname
|
||||||
|
|
||||||
var allLen bool
|
|
||||||
|
|
||||||
for _, v := range parent.Vars {
|
for _, v := range parent.Vars {
|
||||||
if !v.IsRepeated {
|
if !v.IsRepeated {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var APPLES string = v.VarName
|
var APPLES string = v.VarName
|
||||||
var APPLE string = v.VarType
|
var APPLE string = v.VarType
|
||||||
if !allLen {
|
|
||||||
// only can run these once for now
|
|
||||||
addAllFunc(w, FRUIT, APPLE, LOCK)
|
|
||||||
addLenFunc(w, FRUIT, APPLES, LOCK)
|
|
||||||
allLen = true
|
|
||||||
}
|
|
||||||
addSelectAll(w, FRUIT, APPLE, APPLES, LOCK)
|
|
||||||
newIter(w, FRUIT, APPLE, APPLES, LOCK)
|
|
||||||
msg := pf.findMsg(APPLE)
|
msg := pf.findMsg(APPLE)
|
||||||
if msg == nil {
|
if msg == nil {
|
||||||
return fmt.Errorf("failed to find struct %s", APPLE)
|
return fmt.Errorf("failed to find struct %s", APPLE)
|
||||||
}
|
}
|
||||||
|
if msg.NeedIter {
|
||||||
|
parent.NeedIter = false
|
||||||
|
// only can run these once for now
|
||||||
|
log.Info("START")
|
||||||
|
log.Printf("Add all() FRUIT=%s APPLE=%s\n", FRUIT, APPLE)
|
||||||
|
// addAllFunc(w, FRUIT, APPLE, LOCK)
|
||||||
|
log.Printf("Add len() FRUIT=%s APPLES=%s\n", FRUIT, APPLES)
|
||||||
|
addLenFunc(w, FRUIT, APPLES, LOCK)
|
||||||
|
log.Printf("Add selectAll() FRUIT=%s APPLE=%s APPLES=%s\n", FRUIT, APPLE, APPLES)
|
||||||
|
addSelectAll(w, FRUIT, APPLE, APPLES, LOCK)
|
||||||
|
// newIter(w, FRUIT, APPLE, APPLES, LOCK)
|
||||||
|
log.Info("END")
|
||||||
|
}
|
||||||
|
|
||||||
for _, v := range msg.Vars {
|
for _, v := range msg.Vars {
|
||||||
if !v.HasSort {
|
if !v.HasSort {
|
||||||
continue
|
continue
|
||||||
|
@ -104,6 +312,16 @@ func (pf *File) findMsg(s string) *MsgName {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pf *File) allMsg() []*MsgName {
|
||||||
|
var all []*MsgName
|
||||||
|
all = append(all, pf.Bases)
|
||||||
|
all = append(all, pf.Base)
|
||||||
|
for _, msg := range pf.MsgNames {
|
||||||
|
all = append(all, msg)
|
||||||
|
}
|
||||||
|
return all
|
||||||
|
}
|
||||||
|
|
||||||
func (pf *File) specialBases(wFind io.Writer) {
|
func (pf *File) specialBases(wFind io.Writer) {
|
||||||
var FRUIT string = cases.Title(language.English, cases.NoLower).String(pf.Bases.Name)
|
var FRUIT string = cases.Title(language.English, cases.NoLower).String(pf.Bases.Name)
|
||||||
var APPLES string = cases.Title(language.English, cases.NoLower).String(pf.Bases.Name)
|
var APPLES string = cases.Title(language.English, cases.NoLower).String(pf.Bases.Name)
|
||||||
|
|
|
@ -5,16 +5,11 @@ import (
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// only make one of these for each message in the protobuf file
|
func newIterAll(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) string {
|
||||||
func newIter(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) {
|
funcdef := "func (x *" + FRUIT + ") all" + APPLES + "() []*" + APPLE + " {"
|
||||||
fmt.Fprintln(w, "// DEFINE THE ITERATOR. is unique to the "+APPLE+" protobuf message")
|
|
||||||
fmt.Fprintln(w, "// itializes a new iterator.")
|
|
||||||
fmt.Fprintln(w, "func New"+APPLE+"Iterator(things []*"+APPLE+") *"+APPLE+"Iterator {")
|
|
||||||
fmt.Fprintln(w, " return &"+APPLE+"Iterator{things: things}")
|
|
||||||
fmt.Fprintln(w, "}")
|
|
||||||
fmt.Fprintln(w, "")
|
|
||||||
fmt.Fprintln(w, "// safely returns a slice of pointers to the FRUIT protobufs")
|
fmt.Fprintln(w, "// safely returns a slice of pointers to the FRUIT protobufs")
|
||||||
fmt.Fprintln(w, "func (x *"+FRUIT+") all"+APPLES+"() []*"+APPLE+" {")
|
fmt.Fprintln(w, funcdef)
|
||||||
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
||||||
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
@ -28,6 +23,26 @@ func newIter(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) {
|
||||||
fmt.Fprintln(w, " return tmp")
|
fmt.Fprintln(w, " return tmp")
|
||||||
fmt.Fprintln(w, "}")
|
fmt.Fprintln(w, "}")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
|
||||||
|
return funcdef
|
||||||
|
}
|
||||||
|
|
||||||
|
// only make one of these for each message in the protobuf file
|
||||||
|
func newIter(w io.Writer, msg *MsgName) string {
|
||||||
|
if !msg.NeedIter {
|
||||||
|
return "iter already done for " + msg.Name
|
||||||
|
}
|
||||||
|
msg.NeedIter = false
|
||||||
|
APPLE := msg.Name
|
||||||
|
|
||||||
|
funcdef := "func New" + APPLE + "Iterator(things []*" + APPLE + ") *" + APPLE + "Iterator"
|
||||||
|
|
||||||
|
fmt.Fprintln(w, "// DEFINE THE", APPLE, "ITERATOR.")
|
||||||
|
fmt.Fprintln(w, "// itializes a new iterator.")
|
||||||
|
fmt.Fprintln(w, funcdef, "{")
|
||||||
|
fmt.Fprintln(w, " return &"+APPLE+"Iterator{things: things}")
|
||||||
|
fmt.Fprintln(w, "}")
|
||||||
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, "type "+APPLE+"Iterator struct {")
|
fmt.Fprintln(w, "type "+APPLE+"Iterator struct {")
|
||||||
fmt.Fprintln(w, " sync.RWMutex // this isn't getting used properly yet?")
|
fmt.Fprintln(w, " sync.RWMutex // this isn't getting used properly yet?")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
@ -53,9 +68,28 @@ func newIter(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) {
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, "// END DEFINE THE ITERATOR")
|
fmt.Fprintln(w, "// END DEFINE THE ITERATOR")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
|
||||||
|
return funcdef
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSortBy(w io.Writer, FRUIT, APPLE, APPLES, COLOR string) {
|
// maybe there are better ways in GO now adays // that's fine though. this is easy to read
|
||||||
|
// TODO; figure out what types this actually works on
|
||||||
|
// TODO; add timestamppb compare
|
||||||
|
func newSortType(w io.Writer, STRUCT, VARNAME string) string {
|
||||||
|
fmt.Fprintln(w, "// sort struct by", VARNAME)
|
||||||
|
fmt.Fprintln(w, "type "+STRUCT+VARNAME+" []*"+STRUCT+"")
|
||||||
|
fmt.Fprintln(w, "")
|
||||||
|
fmt.Fprintln(w, "func (a "+STRUCT+VARNAME+") Len() int { return len(a) }")
|
||||||
|
fmt.Fprintln(w, "func (a "+STRUCT+VARNAME+") Less(i, j int) bool { return a[i]."+VARNAME+" < a[j]."+VARNAME+" }")
|
||||||
|
fmt.Fprintln(w, "func (a "+STRUCT+VARNAME+") Swap(i, j int) { a[i], a[j] = a[j], a[i] }")
|
||||||
|
fmt.Fprintln(w, "")
|
||||||
|
|
||||||
|
return "type " + STRUCT + VARNAME + " []*" + STRUCT + " // { return a[i]." + VARNAME + " < a[j]." + VARNAME + " }"
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSortBy(w io.Writer, FRUIT, APPLE, APPLES, COLOR string) string {
|
||||||
|
funcdef := "func (x *" + FRUIT + ") SortBy" + COLOR + "() *" + APPLE + "Iterator // field: " + COLOR
|
||||||
|
|
||||||
fmt.Fprintln(w, "// START sort by ", COLOR, "(this is all you need once the Iterator is defined)")
|
fmt.Fprintln(w, "// START sort by ", COLOR, "(this is all you need once the Iterator is defined)")
|
||||||
fmt.Fprintln(w, "type "+APPLE+COLOR+" []*"+APPLE+"")
|
fmt.Fprintln(w, "type "+APPLE+COLOR+" []*"+APPLE+"")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
@ -72,32 +106,42 @@ func newSortBy(w io.Writer, FRUIT, APPLE, APPLES, COLOR string) {
|
||||||
fmt.Fprintln(w, " return iterator")
|
fmt.Fprintln(w, " return iterator")
|
||||||
fmt.Fprintln(w, "}")
|
fmt.Fprintln(w, "}")
|
||||||
fmt.Fprintln(w, "// END sort by", COLOR)
|
fmt.Fprintln(w, "// END sort by", COLOR)
|
||||||
|
|
||||||
|
return funcdef
|
||||||
}
|
}
|
||||||
|
|
||||||
func addAllFunc(w io.Writer, FRUIT, APPLE, LOCK string) {
|
func addAllFunc(w io.Writer, FRUIT, APPLE, APPLES string) string {
|
||||||
fmt.Fprintln(w, "func (x *"+FRUIT+") All() *"+APPLE+"Iterator {")
|
funcdef := "func (x *" + FRUIT + ") All() *" + APPLE + "Iterator {"
|
||||||
fmt.Fprintln(w, " "+APPLE+"Pointers := x.selectAll"+APPLE+"()")
|
|
||||||
|
fmt.Fprintln(w, funcdef)
|
||||||
|
fmt.Fprintln(w, " "+APPLE+"Pointers := x.selectAll"+APPLES+"()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, " iterator := New"+APPLE+"Iterator("+APPLE+"Pointers)")
|
fmt.Fprintln(w, " iterator := New"+APPLE+"Iterator("+APPLE+"Pointers)")
|
||||||
fmt.Fprintln(w, " return iterator")
|
fmt.Fprintln(w, " return iterator")
|
||||||
fmt.Fprintln(w, "}")
|
fmt.Fprintln(w, "}")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
|
||||||
|
return funcdef
|
||||||
}
|
}
|
||||||
|
|
||||||
func addLenFunc(w io.Writer, FRUIT, APPLES, LOCK string) {
|
func addLenFunc(w io.Writer, FRUIT, APPLES, LOCK string) string {
|
||||||
|
funcdef := "func (x *" + FRUIT + ") Len() int {"
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, "func (x *"+FRUIT+") Len() int {")
|
fmt.Fprintln(w, funcdef)
|
||||||
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
||||||
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, " return len(x."+APPLES+")")
|
fmt.Fprintln(w, " return len(x."+APPLES+")")
|
||||||
fmt.Fprintln(w, "}")
|
fmt.Fprintln(w, "}")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
|
||||||
|
return funcdef
|
||||||
}
|
}
|
||||||
|
|
||||||
func addSelectAll(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) {
|
func addSelectAll(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) string {
|
||||||
|
funcdef := "func (x *" + FRUIT + ") selectAll" + APPLES + "() []*" + APPLE
|
||||||
fmt.Fprintln(w, "// safely returns a slice of pointers to the "+APPLE+" protobufs")
|
fmt.Fprintln(w, "// safely returns a slice of pointers to the "+APPLE+" protobufs")
|
||||||
fmt.Fprintln(w, "func (x *"+FRUIT+") selectAll"+APPLE+"() []*"+APPLE+" {")
|
fmt.Fprintln(w, funcdef, "{")
|
||||||
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
fmt.Fprintln(w, " "+LOCK+".RLock()")
|
||||||
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
fmt.Fprintln(w, " defer "+LOCK+".RUnlock()")
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
|
@ -110,4 +154,6 @@ func addSelectAll(w io.Writer, FRUIT, APPLE, APPLES, LOCK string) {
|
||||||
fmt.Fprintln(w, "")
|
fmt.Fprintln(w, "")
|
||||||
fmt.Fprintln(w, " return tmp")
|
fmt.Fprintln(w, " return tmp")
|
||||||
fmt.Fprintln(w, "}")
|
fmt.Fprintln(w, "}")
|
||||||
|
|
||||||
|
return funcdef
|
||||||
}
|
}
|
||||||
|
|
88
human.go
88
human.go
|
@ -1,11 +1,18 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// This was just going to be a function to print the results to stdout
|
||||||
|
|
||||||
|
// instead, it's the core logic of the whole app
|
||||||
|
// --dry-run on the command line will just print what would be generated
|
||||||
|
|
||||||
// print the protobuf in human form
|
// print the protobuf in human form
|
||||||
func (pf *File) printMsgTable() {
|
func (pf *File) printMsgTable() error {
|
||||||
pf.Bases.printMsg()
|
pf.Bases.printMsg()
|
||||||
pf.Base.printMsg()
|
pf.Base.printMsg()
|
||||||
|
|
||||||
|
@ -13,6 +20,85 @@ func (pf *File) printMsgTable() {
|
||||||
for _, msg := range pf.MsgNames {
|
for _, msg := range pf.MsgNames {
|
||||||
msg.printMsg()
|
msg.printMsg()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("\n")
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %20s\n", "", "PARENT STRUCT", "VAR STRUCT TYPE", "VAR NAME", "LOCK")
|
||||||
|
// for i, s := range slices.Backward(pf.ToSort) {
|
||||||
|
for i, s := range pf.ToSort {
|
||||||
|
var funcname string
|
||||||
|
STRUCT := s.MsgName
|
||||||
|
CHILD := s.VarType
|
||||||
|
VARNAME := s.VarName
|
||||||
|
LOCK := s.Lockname
|
||||||
|
|
||||||
|
log.Printf("SORT: %-2d %20s %20s %20s %20s %s\n", i, STRUCT, CHILD, VARNAME, LOCK, "")
|
||||||
|
|
||||||
|
var FUNCTYPE string
|
||||||
|
if STRUCT == VARNAME {
|
||||||
|
FUNCTYPE = STRUCT
|
||||||
|
} else {
|
||||||
|
FUNCTYPE = VARNAME
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.VarType+"s" == s.VarName {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") All() *[]iter" + s.VarType
|
||||||
|
} else {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") all" + s.VarName + "() *[]iter" + s.VarType
|
||||||
|
}
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
msg := pf.findMsg(s.VarType)
|
||||||
|
if msg == nil {
|
||||||
|
return fmt.Errorf("failed to find struct %s", s.VarType)
|
||||||
|
}
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if v.HasSort {
|
||||||
|
funcname := "func (x *" + FUNCTYPE + ") SortBy" + v.VarName + "(" + v.VarType + ") *[]iter" + s.VarType
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ucount int
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if v.HasUnique {
|
||||||
|
ucount += 1
|
||||||
|
funcname := "func (x *" + FUNCTYPE + ") AppendUnique" + v.VarName + "(" + v.VarType + ")"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if v.HasUnique {
|
||||||
|
funcname := "func (x *" + FUNCTYPE + ") DeleteBy" + v.VarName + "(" + v.VarType + ") bool"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if v.HasUnique {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") FindBy" + v.VarName + "(a " + v.VarType + ") *" + s.VarType + "(using" + v.VarName + ")"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
} else {
|
||||||
|
if v.VarType == "string" {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") FindBy" + v.VarName + "(a string) []*" + s.VarType + " ???"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ucount == 1 {
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if !v.HasUnique {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") Insert(a *" + v.VarType + ") (*" + CHILD + ", isNew bool)"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ucount > 1 {
|
||||||
|
funcname = "func (x *" + FUNCTYPE + ") Insert(a *" + CHILD + ") (*" + CHILD + ", isNew bool)"
|
||||||
|
log.Printf(" %-2s %20s %20s %20s %s %s\n", "", "", "", "", "", funcname)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *MsgName) printMsg() {
|
func (msg *MsgName) printMsg() {
|
||||||
|
|
23
main.go
23
main.go
|
@ -2,9 +2,10 @@
|
||||||
// +build go1.20
|
// +build go1.20
|
||||||
|
|
||||||
// protobuf the way I am using them, require GO 1.20. I think. I could be wrong.
|
// protobuf the way I am using them, require GO 1.20. I think. I could be wrong.
|
||||||
|
// The Go Protocol Buffers library embeds a sync.Mutex within the MessageState struct to prevent unintended shallow copies of message structs
|
||||||
|
// this optionally (but it is the default) inserts a mutex into the struct generated by protoc
|
||||||
|
|
||||||
// go:generate go-mod-clean
|
// go:generate autogenpb --proto file.proto
|
||||||
// go:generate autogenpb auto.proto
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -25,6 +26,8 @@ import (
|
||||||
var VERSION string
|
var VERSION string
|
||||||
var BUILDTIME string
|
var BUILDTIME string
|
||||||
|
|
||||||
|
var fsort *os.File // the sort.pb.go output file
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
pp := arg.MustParse(&argv)
|
pp := arg.MustParse(&argv)
|
||||||
|
|
||||||
|
@ -51,6 +54,7 @@ func main() {
|
||||||
pf := new(File)
|
pf := new(File)
|
||||||
pb.Files = append(pb.Files, pf)
|
pb.Files = append(pb.Files, pf)
|
||||||
pf.Filename = argv.Proto
|
pf.Filename = argv.Proto
|
||||||
|
pf.IterMap = make(map[string]string)
|
||||||
|
|
||||||
pf.Filebase = strings.TrimSuffix(argv.Proto, ".proto")
|
pf.Filebase = strings.TrimSuffix(argv.Proto, ".proto")
|
||||||
|
|
||||||
|
@ -69,6 +73,21 @@ func main() {
|
||||||
badExit(fmt.Errorf("Base was nil. 'message %s {` did not exist", pf.Filebase))
|
badExit(fmt.Errorf("Base was nil. 'message %s {` did not exist", pf.Filebase))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// prep the output file
|
||||||
|
if !argv.DryRun {
|
||||||
|
var err error
|
||||||
|
fsort, err = os.OpenFile(pf.Filebase+".newsort.pb.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||||
|
if err != nil {
|
||||||
|
badExit(err)
|
||||||
|
}
|
||||||
|
defer fsort.Close()
|
||||||
|
|
||||||
|
header(fsort, pf)
|
||||||
|
pf.syncLock(fsort)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// show the protobuf of the protobuf. It's like Inception
|
// show the protobuf of the protobuf. It's like Inception
|
||||||
pf.printMsgTable()
|
pf.printMsgTable()
|
||||||
|
|
||||||
|
|
|
@ -56,15 +56,15 @@ func (pb *Files) hasPluralMessage(f *File) error {
|
||||||
return fmt.Errorf("proto file error %s", f.Filename)
|
return fmt.Errorf("proto file error %s", f.Filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pb *Files) protoParse(f *File) error {
|
func (pb *Files) protoParse(pf *File) error {
|
||||||
// does the file conform to the standard? (also reads in UUID & Version)
|
// does the file conform to the standard? (also reads in UUID & Version)
|
||||||
if err := pb.hasPluralMessage(f); err != nil {
|
if err := pb.hasPluralMessage(pf); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Info(f.Filename, "is valid so far")
|
log.Info(pf.Filename, "is valid so far")
|
||||||
|
|
||||||
// read in the .proto file
|
// read in the .proto file
|
||||||
data, err := os.ReadFile(f.Filename)
|
data, err := os.ReadFile(pf.Filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ func (pb *Files) protoParse(f *File) error {
|
||||||
// parse the proto file for message struct names
|
// parse the proto file for message struct names
|
||||||
for _, line := range strings.Split(string(data), "\n") {
|
for _, line := range strings.Split(string(data), "\n") {
|
||||||
if strings.HasPrefix(line, "message ") {
|
if strings.HasPrefix(line, "message ") {
|
||||||
curmsg = f.parseForMessage(line)
|
curmsg = pf.parseForMessage(line)
|
||||||
}
|
}
|
||||||
// this logic isn't right. find end of message with more bravado
|
// this logic isn't right. find end of message with more bravado
|
||||||
if strings.HasPrefix(line, "}") {
|
if strings.HasPrefix(line, "}") {
|
||||||
|
@ -93,6 +93,10 @@ func (pb *Files) protoParse(f *File) error {
|
||||||
// log.Info("Junk in .proto file? line did not contain a message var:", line)
|
// log.Info("Junk in .proto file? line did not contain a message var:", line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if msgvar.IsRepeated {
|
||||||
|
log.Info("ADDING ITER MAP", curmsg.Name, msgvar.VarType)
|
||||||
|
pf.IterMap[curmsg.Name] = msgvar.VarType
|
||||||
|
}
|
||||||
|
|
||||||
if strings.Contains(line, "autogenpb:sort") {
|
if strings.Contains(line, "autogenpb:sort") {
|
||||||
newS := cases.Title(language.English, cases.NoLower).String(parts[1])
|
newS := cases.Title(language.English, cases.NoLower).String(parts[1])
|
||||||
|
@ -110,9 +114,40 @@ func (pb *Files) protoParse(f *File) error {
|
||||||
}
|
}
|
||||||
curmsg.Vars = append(curmsg.Vars, msgvar)
|
curmsg.Vars = append(curmsg.Vars, msgvar)
|
||||||
}
|
}
|
||||||
|
pf.makeSortTable()
|
||||||
|
|
||||||
|
// for i, s := range slices.Backward(pf.ToSort) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pf *File) makeSortTable() {
|
||||||
|
pf.sortWhat(pf.Bases)
|
||||||
|
pf.sortWhat(pf.Base)
|
||||||
|
|
||||||
|
// everything else
|
||||||
|
for _, msg := range pf.MsgNames {
|
||||||
|
pf.sortWhat(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pf *File) sortWhat(msg *MsgName) {
|
||||||
|
for _, v := range msg.Vars {
|
||||||
|
if !v.IsRepeated {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if check := pf.findMsg(v.VarType); check == nil {
|
||||||
|
// the VarType must be a struct
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s := new(Sort)
|
||||||
|
s.MsgName = msg.Name
|
||||||
|
s.VarType = v.VarType
|
||||||
|
s.VarName = v.VarName
|
||||||
|
s.Lockname = msg.Lockname
|
||||||
|
pf.ToSort = append(pf.ToSort, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func parseMsgVar(line string) *MsgVar {
|
func parseMsgVar(line string) *MsgVar {
|
||||||
if strings.Contains(line, "//") {
|
if strings.Contains(line, "//") {
|
||||||
parts := strings.Split(line, "//")
|
parts := strings.Split(line, "//")
|
||||||
|
@ -169,6 +204,7 @@ func (pf *File) parseForMessage(line string) *MsgName {
|
||||||
log.Info("found messge:", msgName)
|
log.Info("found messge:", msgName)
|
||||||
msg.Name = msgName
|
msg.Name = msgName
|
||||||
msg.Lockname = pf.Filebase + "Mu" // this should be lowercase. do not export the Mutex
|
msg.Lockname = pf.Filebase + "Mu" // this should be lowercase. do not export the Mutex
|
||||||
|
msg.NeedIter = true
|
||||||
|
|
||||||
if strings.Contains(line, "`autogenpb:mutex`") {
|
if strings.Contains(line, "`autogenpb:mutex`") {
|
||||||
msg.DoMutex = true
|
msg.DoMutex = true
|
||||||
|
|
Loading…
Reference in New Issue