1 Star 0 Fork 0

Cruvie Kang / kk_go_kit

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
generate_proto_file.go 3.42 KB
一键复制 编辑 原始数据 按行查看 历史
cruvie 提交于 2024-03-02 22:23 . update
package kk_protobuf
import (
"fmt"
"gitee.com/cruvie/kk_go_kit/kk_string"
"log/slog"
"os"
"reflect"
"time"
)
// GenerateProtoFile generates a protobuf file from a struct
// eg: GenerateProtoFile(User{}, "models_user", true, true)
func GenerateProtoFile(yourStruct any, packageName string, importTime bool, importAny bool) {
structType := reflect.TypeOf(yourStruct)
protoContent := fmt.Sprintf(`syntax = "proto3";
package %s;
%s
option go_package = "./;%s";
//生成go文件命令
// protoc -I=. --go_out=./ *.proto
//生成dart文件命令
// protoc -I=. --dart_out=../../lib/%s *.proto %s
message PB%s {
`, packageName, getImportStatement(importTime, importAny), packageName, packageName, getCmdStatement(importTime, importAny), structType.Name())
msgIndex := 1
for i := 0; i < structType.NumField(); i++ {
field := structType.Field(i)
fieldType := field.Type
// 如果字段是嵌套结构体
if fieldType.Kind() == reflect.Struct && fieldType != reflect.TypeOf(time.Time{}) {
nestedFields := getNestedFields(fieldType)
// 添加嵌套结构体的字段
for _, nestedField := range nestedFields {
protoContent += fmt.Sprintf(" %s %s = %d;\n", getPBFieldType(nestedField.Type), nestedField.Name, msgIndex)
msgIndex++
}
} else {
protoContent += fmt.Sprintf(" %s %s = %d;\n", getPBFieldType(fieldType), field.Name, msgIndex)
msgIndex++
}
}
protoContent += "}\n"
protoContent += fmt.Sprintf(`
message PBList%s{
repeated PB%s List%s = 1;
}`, structType.Name(), structType.Name(), structType.Name())
err := os.Mkdir("newpb", 0755)
if err != nil && !os.IsExist(err) {
return
}
fileName := fmt.Sprintf("newpb/pb_%s.proto", kk_string.CamelToSnakeCase(structType.Name()))
err = os.WriteFile(fileName, []byte(protoContent), 0644)
if err != nil {
slog.Info("Error writing protobuf file", "err:", err)
return
}
slog.Info("Successfully generated protobuf file", "fileName", fileName)
}
// 支持无限嵌套
func getNestedFields(structType reflect.Type) []reflect.StructField {
var fields []reflect.StructField
for i := 0; i < structType.NumField(); i++ {
field := structType.Field(i)
nestedType := field.Type
if nestedType.Kind() == reflect.Struct && nestedType != reflect.TypeOf(time.Time{}) {
nestedFields := getNestedFields(nestedType)
fields = append(fields, nestedFields...)
} else {
fields = append(fields, field)
}
}
return fields
}
func getImportStatement(importTime bool, importAny bool) string {
importStatement := ""
if importTime {
importStatement += `import "google/protobuf/timestamp.proto";
` //这里确保换行
}
if importAny {
importStatement += `import "google/protobuf/any.proto";
`
}
return importStatement
}
func getCmdStatement(importTime bool, importAny bool) string {
cmdStatement := ""
if importTime {
cmdStatement += ` google/protobuf/timestamp.proto`
}
if importAny {
cmdStatement += ` google/protobuf/any.proto`
}
return cmdStatement
}
func getPBFieldType(fieldType reflect.Type) string {
switch fieldType.Kind() {
case reflect.Uint64:
return "uint64"
case reflect.String:
return "string"
case reflect.Int:
return "int32"
case reflect.Int32:
return "int32"
case reflect.Int64:
return "int64"
case reflect.Float32:
return "float"
case reflect.Float64:
return "double"
case reflect.Struct:
if fieldType == reflect.TypeOf(time.Time{}) {
return "google.protobuf.Timestamp"
}
default:
return "unknown"
}
return "unknown"
}
1
https://gitee.com/cruvie/kk_go_kit.git
git@gitee.com:cruvie/kk_go_kit.git
cruvie
kk_go_kit
kk_go_kit
6c1fc534a942

搜索帮助

53164aa7 5694891 3bd8fe86 5694891