代码拉取完成,页面将自动刷新
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"
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。