javascript/cli/main.go

237 lines
5.4 KiB
Go

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)
for _, v := range srvPaths {
parseProtos(protoPath, v)
}
}
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)
}
if len(descs) > 0 {
mess = append(mess, descs[0].GetMessageTypes()...)
}
if len(descs[0].GetServices()) > 0 {
for _, srvItem := range descs[0].GetServices() {
writeSrvs(dir, tsPath, srvItem.GetName(), srvItem.GetSourceInfo().GetLeadingComments(), srvItem.GetMethods())
}
}
}
}
writeMessageTypes(tsPath, mess)
}
func writeSrvs(PkgName, tsPath, srvName, commit string, methods []*desc.MethodDescriptor) {
var bodys []string
var types []string
var funcs []string
headerTpl := `
import request from "../../request";
import { AxiosPromise } from "axios";
import { {{Types}} } from "./types";
`
methodsTpl := `
{{Commit}}
export function {{MethodName}}(data: {{In}}): AxiosPromise<{{Reply}}> {
return request({
url: "/{{PkgName}}.{{SrvName}}.{{MethodName}}",
method: "post",
data: data,
});
}
`
for _, v := range methods {
tmp := methodsTpl
tmp = strings.ReplaceAll(tmp, "{{PkgName}}", PkgName)
tmp = strings.ReplaceAll(tmp, "{{SrvName}}", srvName)
tmp = strings.ReplaceAll(tmp, "{{MethodName}}", v.GetName())
var commit string = ""
if v.GetSourceInfo().GetLeadingComments() != "" {
commit = commit + v.GetSourceInfo().GetLeadingComments() + " "
}
if v.GetSourceInfo().GetTrailingComments() != "" {
commit = commit + v.GetSourceInfo().GetTrailingComments() + " "
}
commit = strings.ReplaceAll(commit, "\r\n", "")
if commit == "" {
tmp = strings.ReplaceAll(tmp, "{{Commit}}", "")
} else {
tmp = strings.ReplaceAll(tmp, "{{Commit}}", " // "+commit)
}
in := v.GetInputType().GetName()
reply := v.GetOutputType().GetName()
tmp = strings.ReplaceAll(tmp, "{{In}}", in)
tmp = strings.ReplaceAll(tmp, "{{Reply}}", reply)
if !utils.In(in, types) {
types = append(types, in)
}
if !utils.In(reply, types) {
types = append(types, reply)
}
funcs = append(funcs, tmp)
}
header := strings.ReplaceAll(headerTpl, "{{Types}}", strings.Join(types, ","))
bodys = append(bodys, header)
bodys = append(bodys, funcs...)
tsFileName := strings.ToLower(srvName) + ".ts"
destPath := filepath.Join(tsPath, tsFileName)
utils.StringToFile(destPath, strings.Join(bodys, "\r\n"))
}
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
}