package main import ( "fmt" "os" "path" "path/filepath" "strings" "git.apinb.com/bsm-sdk/engine/utils" "github.com/jhump/protoreflect/desc" "github.com/jhump/protoreflect/desc/protoparse" ) var ( protoPath string = "./proto" jsPath string = "./axios/service" ) func main() { fmt.Println("Conv poroto file to js file.") srvPaths := getSubDirs(protoPath) fmt.Println("Root:", protoPath, srvPaths, "JS Out:", jsPath) parseProtos(protoPath, srvPaths[1]) } func getSubDirs(root string) []string { var paths []string files, _ := os.ReadDir(root) for _, file := range files { if file.IsDir() { paths = append(paths, file.Name()) } } return paths } func parseProtos(root, dir string) { //var msg []pbparser.MessageElement var mess []*desc.MessageDescriptor fPath := path.Join(root, dir) tsPath := path.Join(jsPath, dir) files, _ := os.ReadDir(fPath) for _, file := range files { if file.IsDir() { continue } else { pfPath := filepath.Join(fPath, file.Name()) Parser := protoparse.Parser{ IncludeSourceCodeInfo: true, } descs, err := Parser.ParseFiles(pfPath) if err != nil { panic(err) } mess = append(mess, descs[0].GetMessageTypes()...) } } writeMessageTypes(tsPath, mess) } func writeSrvs(fileName string) { } func writeMessageTypes(tsPath string, msg []*desc.MessageDescriptor) { tpl := ` {{Commit}} export interface {{Name}} { {{Data}} }` keyMap := make(map[string]int) var bodys []string for _, msgItem := range msg { var data []string var msgBody = tpl for _, fd := range msgItem.GetFields() { data = append(data, dispFields(fd)) } keyFname := strings.ToLower(msgItem.GetName()) if _, ok := keyMap[keyFname]; !ok { var commit string = "" if msgItem.GetSourceInfo().GetLeadingComments() != "" { commit = msgItem.GetSourceInfo().GetLeadingComments() } msgBody = strings.ReplaceAll(msgBody, "{{Commit}}", commit) msgBody = strings.ReplaceAll(msgBody, "{{Name}}", msgItem.GetName()) msgBody = strings.ReplaceAll(msgBody, "{{Data}}", strings.Join(data, "\r\n")) bodys = append(bodys, msgBody) keyMap[keyFname] = 1 } } typesPath := filepath.Join(tsPath, "types.ts") utils.StringToFile(typesPath, strings.Join(bodys, "\r\n")) } func dispFields(fd *desc.FieldDescriptor) string { tpl := " {{Name}}?: {{Type}}; {{Commit}}" name := strings.Trim(fd.GetName(), "") name = strings.ReplaceAll(name, "\t", "") tpl = strings.ReplaceAll(tpl, "{{Name}}", name) var commit string = "" if fd.GetSourceInfo().GetLeadingComments() != "" { commit = commit + fd.GetSourceInfo().GetLeadingComments() + " " } if fd.GetSourceInfo().GetTrailingComments() != "" { commit = commit + fd.GetSourceInfo().GetTrailingComments() + " " } if commit == "" { tpl = strings.ReplaceAll(tpl, "{{Commit}}", "") } else { tpl = strings.ReplaceAll(tpl, "{{Commit}}", " // "+commit) } var fdType string = "" switch fd.GetType().String() { case "TYPE_STRING": fdType = "string" case "TYPE_INT64", "TYPE_INT32", "TYPE_FLOAT32", "TYPE_FLOAT64": fdType = "number" case "bool": fdType = "TYPE_BOOL" default: if fd.GetLabel().String() == "LABEL_REPEATED" { fdType = fd.GetMessageType().GetName() + "[]" } else { fdType = fd.GetType().String() } } tpl = strings.ReplaceAll(tpl, "{{Type}}", fdType) tpl = strings.ReplaceAll(tpl, "\r\n", "") return tpl }