protostostruct.go 2.8 KB
package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
)

var (
	ProtoCode = "syntax = \"proto3\";\noption go_package = \"./pb;pb\";\n\npackage protocode;\n\nenum ProtoCode\n{\n  UNKNOWN = 0x000;\n %s\n}"
	ProtoCodeLine = "\t%sRpc = %02x;\n"

	GoProtoCodeStr = "package common\n\nimport (\n\t\"github.com/golang/protobuf/proto\"\n\t\"pro2d/actions\"\n\t\"pro2d/components/net\"\n\t\"pro2d/protos/pb\"\n)\n\ntype ActionHandler func (msg *net.MsgPkg)  (int32, proto.Message)\n\nvar ActionMap map[pb.ProtoCode]ActionHandler\n\nfunc init()  {\n%s\n}"
	GoProtoCodeLine = "\tActionMap[pb.ProtoCode_%sRpc] = actions.%sRpc\n"
)

func ProtoToCode(readPath, filename string) (string, string) {
	protofile , err := os.Open(readPath+filename)
	code := 0x000
	protoData := ""
	goProtoData := ""
	if err != nil {
		fmt.Errorf("ReadExcel|xlsx.OpenFile is err :%v", err)
		return "", ""
	}
	defer protofile.Close()

	r := bufio.NewReader(protofile)
	for {
		line, isPrefix, err := r.ReadLine()
		if len(line) > 0 && err != nil {
			fmt.Errorf("ReadLine returned both data and error: %s", err)
			return "", ""

		}
		if isPrefix {
			fmt.Errorf("ReadLine returned prefix")
			return "", ""
		}
		if err != nil {
			if err != io.EOF {
				fmt.Errorf("Got unknown error: %s", err)
				return "", ""
			}
			break
		}
		n := bytes.Index(line, []byte("message"))
		if n < 0 {
			continue
		}
		lb := bytes.Split(line, []byte(" "))
		for _, v := range lb {
			n = bytes.Index(v, []byte("Req"))
			if n < 0 {
				continue
			}
			code++
			protoData += fmt.Sprintf(ProtoCodeLine, v[:n],code)
			goProtoData += fmt.Sprintf(GoProtoCodeLine, v[:n], v[:n])
		}
	}

	return protoData ,goProtoData
}

func ReadProtos(readPath, OutPath string ) error {
	files, err := ioutil.ReadDir(readPath)
	if err != nil {
		return fmt.Errorf("ReadExcel|ReadDir is err:%v", err)
	}


	protoData, goProtoData := "", ""
	for _, file := range files {
		if path.Ext(file.Name()) != ".proto"{
			continue
		}
		tprotoData, tgoProtoData := ProtoToCode(readPath, file.Name())
		if tprotoData == "" || tgoProtoData == "" {
		 	continue
		}
		protoData += tprotoData
		goProtoData += tgoProtoData

	}
	fw, err := os.OpenFile( OutPath+"protos/protocode.proto", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return fmt.Errorf("WriteNewFile|OpenFile is err:%v", err)
	}
	defer fw.Close()

	_, err = fw.Write([]byte(fmt.Sprintf(ProtoCode, protoData)))
	if err != nil {
		return fmt.Errorf("WriteNewFile|Write is err:%v", err)
	}

	fw, err = os.OpenFile( OutPath+"common/protocode.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return fmt.Errorf("WriteNewFile|OpenFile is err:%v", err)
	}
	defer fw.Close()

	_, err = fw.Write([]byte(fmt.Sprintf(GoProtoCodeStr, goProtoData)))
	if err != nil {
		return fmt.Errorf("WriteNewFile|Write is err:%v", err)
	}
	return nil
}