package main import ( "fmt" "os/exec" "github.com/go-cmd/cmd" "github.com/google/uuid" "go.wit.com/log" "golang.org/x/text/cases" "golang.org/x/text/language" ) // This was just going to be a function to print the results to stdout // print the protobuf in human form func (pf *File) printMsgTable() error { pf.Bases.printMsg() pf.Base.printMsg() // everything else for _, msg := range pf.MsgNames { 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() { 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) } } func checkCmd(cmd string) { // path, err := exec.LookPath(cmd) _, 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("") }