package proto
import (
)
type StructProperties struct {
Prop []*Properties
OneofTypes map[string]*OneofProperties
}
type Properties struct {
Name string
OrigName string
JSONName string
Enum string
Weak string
Wire string
WireType int
Tag int
Required bool
Optional bool
Repeated bool
Packed bool
Proto3 bool
Oneof bool
Default string
HasDefault bool
MapKeyProp *Properties
MapValProp *Properties
}
type OneofProperties struct {
Type reflect.Type
Field int
Prop *Properties
}
func ( *Properties) () string {
:= .Wire
+= "," + strconv.Itoa(.Tag)
if .Required {
+= ",req"
}
if .Optional {
+= ",opt"
}
if .Repeated {
+= ",rep"
}
if .Packed {
+= ",packed"
}
+= ",name=" + .OrigName
if .JSONName != "" {
+= ",json=" + .JSONName
}
if len(.Enum) > 0 {
+= ",enum=" + .Enum
}
if len(.Weak) > 0 {
+= ",weak=" + .Weak
}
if .Proto3 {
+= ",proto3"
}
if .Oneof {
+= ",oneof"
}
if .HasDefault {
+= ",def=" + .Default
}
return
}
func ( *Properties) ( string) {
for len() > 0 {
:= strings.IndexByte(, ',')
if < 0 {
= len()
}
switch := [:]; {
case strings.HasPrefix(, "name="):
.OrigName = [len("name="):]
case strings.HasPrefix(, "json="):
.JSONName = [len("json="):]
case strings.HasPrefix(, "enum="):
.Enum = [len("enum="):]
case strings.HasPrefix(, "weak="):
.Weak = [len("weak="):]
case strings.Trim(, "0123456789") == "":
, := strconv.ParseUint(, 10, 32)
.Tag = int()
case == "opt":
.Optional = true
case == "req":
.Required = true
case == "rep":
.Repeated = true
case == "varint" || == "zigzag32" || == "zigzag64":
.Wire =
.WireType = WireVarint
case == "fixed32":
.Wire =
.WireType = WireFixed32
case == "fixed64":
.Wire =
.WireType = WireFixed64
case == "bytes":
.Wire =
.WireType = WireBytes
case == "group":
.Wire =
.WireType = WireStartGroup
case == "packed":
.Packed = true
case == "proto3":
.Proto3 = true
case == "oneof":
.Oneof = true
case strings.HasPrefix(, "def="):
.HasDefault = true
.Default, = [len("def="):], len()
}
= strings.TrimPrefix([:], ",")
}
}
func ( *Properties) ( reflect.Type, , string, *reflect.StructField) {
.Name =
.OrigName =
if == "" {
return
}
.Parse()
if != nil && .Kind() == reflect.Map {
.MapKeyProp = new(Properties)
.MapKeyProp.(nil, "Key", .Tag.Get("protobuf_key"), nil)
.MapValProp = new(Properties)
.MapValProp.(nil, "Value", .Tag.Get("protobuf_val"), nil)
}
}
var propertiesCache sync.Map
func ( reflect.Type) *StructProperties {
if , := propertiesCache.Load(); {
return .(*StructProperties)
}
, := propertiesCache.LoadOrStore(, newProperties())
return .(*StructProperties)
}
func ( reflect.Type) *StructProperties {
if .Kind() != reflect.Struct {
panic(fmt.Sprintf("%v is not a generated message in the open-struct API", ))
}
var bool
:= new(StructProperties)
for := 0; < .NumField(); ++ {
:= new(Properties)
:= .Field()
:= .Tag.Get("protobuf")
.Init(.Type, .Name, , &)
:= .Tag.Get("protobuf_oneof")
if != "" {
= true
.OrigName =
}
if == "" && == "" && !strings.HasPrefix(.Name, "XXX_") {
.Name = "XXX_" + .Name
.OrigName = "XXX_" + .OrigName
} else if .Weak != "" {
.Name = .OrigName
}
.Prop = append(.Prop, )
}
if {
var []interface{}
if , := reflect.PtrTo().MethodByName("XXX_OneofFuncs"); {
= .Func.Call([]reflect.Value{reflect.Zero(.Type.In(0))})[3].Interface().([]interface{})
}
if , := reflect.PtrTo().MethodByName("XXX_OneofWrappers"); {
= .Func.Call([]reflect.Value{reflect.Zero(.Type.In(0))})[0].Interface().([]interface{})
}
if , := reflect.Zero(reflect.PtrTo()).Interface().(protoreflect.ProtoMessage); {
if , := .ProtoReflect().(interface{ () *protoimpl.MessageInfo }); {
= .().OneofWrappers
}
}
.OneofTypes = make(map[string]*OneofProperties)
for , := range {
:= &OneofProperties{
Type: reflect.ValueOf().Type(),
Prop: new(Properties),
}
:= .Type.Elem().Field(0)
.Prop.Name = .Name
.Prop.Parse(.Tag.Get("protobuf"))
var bool
for := 0; < .NumField() && !; ++ {
if .Type.AssignableTo(.Field().Type) {
.Field =
= true
}
}
if ! {
panic(fmt.Sprintf("%v is not a generated message in the open-struct API", ))
}
.OneofTypes[.Prop.OrigName] =
}
}
return
}
func ( *StructProperties) () int { return len(.Prop) }
func ( *StructProperties) (, int) bool { return false }
func ( *StructProperties) (, int) { return }