2025-01-10 19:37:32 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2025-01-12 01:32:52 -06:00
|
|
|
"fmt"
|
2025-01-12 09:28:58 -06:00
|
|
|
"os/exec"
|
2025-01-12 01:32:52 -06:00
|
|
|
|
2025-01-12 09:28:58 -06:00
|
|
|
"github.com/go-cmd/cmd"
|
|
|
|
"github.com/google/uuid"
|
2025-01-10 19:37:32 -06:00
|
|
|
"go.wit.com/log"
|
2025-01-12 09:28:58 -06:00
|
|
|
"golang.org/x/text/cases"
|
|
|
|
"golang.org/x/text/language"
|
2025-01-10 19:37:32 -06:00
|
|
|
)
|
|
|
|
|
2025-01-12 01:32:52 -06:00
|
|
|
// This was just going to be a function to print the results to stdout
|
|
|
|
|
2025-01-10 19:37:32 -06:00
|
|
|
// print the protobuf in human form
|
2025-01-12 01:32:52 -06:00
|
|
|
func (pf *File) printMsgTable() error {
|
2025-01-10 19:37:32 -06:00
|
|
|
pf.Bases.printMsg()
|
|
|
|
pf.Base.printMsg()
|
|
|
|
|
|
|
|
// everything else
|
|
|
|
for _, msg := range pf.MsgNames {
|
|
|
|
msg.printMsg()
|
|
|
|
}
|
2025-01-12 01:32:52 -06:00
|
|
|
|
|
|
|
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
|
2025-01-10 19:37:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (msg *MsgName) printMsg() {
|
|
|
|
var s string
|
|
|
|
if msg.DoMutex {
|
|
|
|
s += "(mutex) "
|
|
|
|
}
|
|
|
|
if msg.DoMarshal {
|
|
|
|
s += "(marshal) "
|
|
|
|
}
|
|
|
|
log.Printf("%s %s\n", msg.Name, s)
|
|
|
|
|
|
|
|
for _, v := range msg.Vars {
|
|
|
|
var end string
|
|
|
|
if v.IsRepeated {
|
|
|
|
end += "(repeated) "
|
|
|
|
}
|
|
|
|
if v.HasSort {
|
|
|
|
end += "(sort) "
|
|
|
|
}
|
|
|
|
if v.HasUnique {
|
|
|
|
end += "(unique) "
|
|
|
|
}
|
|
|
|
log.Printf("\t%s %s %s\n", v.VarName, v.VarType, end)
|
|
|
|
}
|
|
|
|
}
|
2025-01-12 09:28:58 -06:00
|
|
|
|
|
|
|
func checkCmd(cmd string) {
|
|
|
|
path, err := exec.LookPath(cmd)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("\n%s is not in the PATH\n", cmd)
|
|
|
|
userInstructions()
|
|
|
|
log.Sleep(2)
|
|
|
|
} else {
|
|
|
|
fmt.Printf("%s is available at %s\n", cmd, path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (pf *File) noPluralMessage() {
|
|
|
|
base := cases.Title(language.English, cases.NoLower).String(pf.Filebase)
|
|
|
|
|
|
|
|
log.Info("")
|
|
|
|
log.Info("###########################################################################")
|
|
|
|
log.Info("Your proto file", pf.Filename, "does not contain the correct 'message' definitions")
|
|
|
|
log.Info("")
|
|
|
|
log.Info("For autogenpb to work on your file", pf.Filename, ", you must have both names exactly:")
|
|
|
|
log.Info("")
|
|
|
|
log.Printf("message %s {\n", base)
|
|
|
|
log.Info("}")
|
|
|
|
log.Printf("message %s {\n", base+"s")
|
|
|
|
log.Info("}")
|
|
|
|
log.Info("")
|
|
|
|
log.Info("###########################################################################")
|
|
|
|
badExit(fmt.Errorf("proto file error %s", pf.Filename))
|
|
|
|
}
|
|
|
|
|
|
|
|
// message Fruits { // `autogenpb:marshal` `autogenpb:mutex`
|
|
|
|
// string uuid = 1; // `autogenpb:uuid:be926ad9-f07f-484c-adf2-d96eeabf3079`
|
|
|
|
// string version = 2; // `autogenpb:version:v0.0.1`
|
|
|
|
// repeated Fruit Fruits = 3; // THIS MUST BE "Fruit" and then "Fruit" + "s"
|
|
|
|
// }
|
|
|
|
|
|
|
|
func (pf *File) noUuid() {
|
|
|
|
base := cases.Title(language.English, cases.NoLower).String(pf.Filebase)
|
|
|
|
id := uuid.New()
|
|
|
|
|
|
|
|
log.Info("")
|
|
|
|
log.Info("###########################################################################")
|
|
|
|
log.Info("Your proto file", pf.Filename, "is incorrect for 'message' ", base+"s")
|
|
|
|
log.Info("")
|
|
|
|
log.Info("For autogenpb to work on your file", pf.Filename, ",", base+"s must be exactly:")
|
|
|
|
log.Info("")
|
|
|
|
log.Info("message", base+"s", "{ // `autogenpb:marshal` `autogenpb:mutex`")
|
|
|
|
log.Info(" string uuid = 1; // `autogenpb:uuid:" + id.String() + "`")
|
|
|
|
log.Info(" string version = 2; // `autogenpb:version:v0.0.1`")
|
|
|
|
log.Info(" repeated", base, base+"s", " = 3; // THIS MUST BE ", base, " and then ", base+"s")
|
|
|
|
log.Info("}")
|
|
|
|
log.Info("")
|
|
|
|
log.Info("If you don't have a UUID, you can use the randomly generated one here")
|
|
|
|
log.Info("")
|
|
|
|
log.Info("###########################################################################")
|
|
|
|
badExit(fmt.Errorf("proto file error %s", pf.Filename))
|
|
|
|
}
|
|
|
|
|
|
|
|
func userNotes(result cmd.Status) error {
|
|
|
|
log.Info("protoc failed", result.Cmd, "with", result.Exit)
|
|
|
|
for _, line := range result.Stdout {
|
|
|
|
log.Info("STDOUT:", line)
|
|
|
|
}
|
|
|
|
for _, line := range result.Stderr {
|
|
|
|
log.Info("STDERR:", line)
|
|
|
|
}
|
|
|
|
userInstructions()
|
|
|
|
return fmt.Errorf("protoc failed with %d %v", result.Exit, result.Error)
|
|
|
|
}
|
|
|
|
|
|
|
|
func userInstructions() {
|
|
|
|
log.Info("This is likely because you don't have protoc and protoc-gen-go installed")
|
|
|
|
log.Info("")
|
|
|
|
log.Info("On debian, you can:")
|
|
|
|
log.Info(" apt install protobuf-compiler # for protoc")
|
|
|
|
log.Info(" apt install protoc-gen-go # for protoc-gen-go")
|
|
|
|
log.Info("")
|
|
|
|
}
|