package impl
import (
)
type unwrapper interface {
protoUnwrap() interface{}
}
type Converter interface {
PBValueOf(reflect.Value) protoreflect.Value
GoValueOf(protoreflect.Value) reflect.Value
IsValidPB(protoreflect.Value) bool
IsValidGo(reflect.Value) bool
New() protoreflect.Value
Zero() protoreflect.Value
}
func ( reflect.Type, protoreflect.FieldDescriptor) Converter {
switch {
case .IsList():
return newListConverter(, )
case .IsMap():
return newMapConverter(, )
default:
return newSingularConverter(, )
}
panic(fmt.Sprintf("invalid Go type %v for field %v", , .FullName()))
}
var (
boolType = reflect.TypeOf(bool(false))
int32Type = reflect.TypeOf(int32(0))
int64Type = reflect.TypeOf(int64(0))
uint32Type = reflect.TypeOf(uint32(0))
uint64Type = reflect.TypeOf(uint64(0))
float32Type = reflect.TypeOf(float32(0))
float64Type = reflect.TypeOf(float64(0))
stringType = reflect.TypeOf(string(""))
bytesType = reflect.TypeOf([]byte(nil))
byteType = reflect.TypeOf(byte(0))
)
var (
boolZero = protoreflect.ValueOfBool(false)
int32Zero = protoreflect.ValueOfInt32(0)
int64Zero = protoreflect.ValueOfInt64(0)
uint32Zero = protoreflect.ValueOfUint32(0)
uint64Zero = protoreflect.ValueOfUint64(0)
float32Zero = protoreflect.ValueOfFloat32(0)
float64Zero = protoreflect.ValueOfFloat64(0)
stringZero = protoreflect.ValueOfString("")
bytesZero = protoreflect.ValueOfBytes(nil)
)
func ( reflect.Type, protoreflect.FieldDescriptor) Converter {
:= func( protoreflect.FieldDescriptor, protoreflect.Value) protoreflect.Value {
if .Cardinality() == protoreflect.Repeated {
return
}
return .Default()
}
switch .Kind() {
case protoreflect.BoolKind:
if .Kind() == reflect.Bool {
return &boolConverter{, (, boolZero)}
}
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
if .Kind() == reflect.Int32 {
return &int32Converter{, (, int32Zero)}
}
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
if .Kind() == reflect.Int64 {
return &int64Converter{, (, int64Zero)}
}
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
if .Kind() == reflect.Uint32 {
return &uint32Converter{, (, uint32Zero)}
}
case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
if .Kind() == reflect.Uint64 {
return &uint64Converter{, (, uint64Zero)}
}
case protoreflect.FloatKind:
if .Kind() == reflect.Float32 {
return &float32Converter{, (, float32Zero)}
}
case protoreflect.DoubleKind:
if .Kind() == reflect.Float64 {
return &float64Converter{, (, float64Zero)}
}
case protoreflect.StringKind:
if .Kind() == reflect.String || (.Kind() == reflect.Slice && .Elem() == byteType) {
return &stringConverter{, (, stringZero)}
}
case protoreflect.BytesKind:
if .Kind() == reflect.String || (.Kind() == reflect.Slice && .Elem() == byteType) {
return &bytesConverter{, (, bytesZero)}
}
case protoreflect.EnumKind:
if .Kind() == reflect.Int32 {
return newEnumConverter(, )
}
case protoreflect.MessageKind, protoreflect.GroupKind:
return newMessageConverter()
}
panic(fmt.Sprintf("invalid Go type %v for field %v", , .FullName()))
}
type boolConverter struct {
goType reflect.Type
def protoreflect.Value
}
func ( *boolConverter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfBool(.Bool())
}
func ( *boolConverter) ( protoreflect.Value) reflect.Value {
return reflect.ValueOf(.Bool()).Convert(.goType)
}
func ( *boolConverter) ( protoreflect.Value) bool {
, := .Interface().(bool)
return
}
func ( *boolConverter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *boolConverter) () protoreflect.Value { return .def }
func ( *boolConverter) () protoreflect.Value { return .def }
type int32Converter struct {
goType reflect.Type
def protoreflect.Value
}
func ( *int32Converter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfInt32(int32(.Int()))
}
func ( *int32Converter) ( protoreflect.Value) reflect.Value {
return reflect.ValueOf(int32(.Int())).Convert(.goType)
}
func ( *int32Converter) ( protoreflect.Value) bool {
, := .Interface().(int32)
return
}
func ( *int32Converter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *int32Converter) () protoreflect.Value { return .def }
func ( *int32Converter) () protoreflect.Value { return .def }
type int64Converter struct {
goType reflect.Type
def protoreflect.Value
}
func ( *int64Converter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfInt64(int64(.Int()))
}
func ( *int64Converter) ( protoreflect.Value) reflect.Value {
return reflect.ValueOf(int64(.Int())).Convert(.goType)
}
func ( *int64Converter) ( protoreflect.Value) bool {
, := .Interface().(int64)
return
}
func ( *int64Converter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *int64Converter) () protoreflect.Value { return .def }
func ( *int64Converter) () protoreflect.Value { return .def }
type uint32Converter struct {
goType reflect.Type
def protoreflect.Value
}
func ( *uint32Converter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfUint32(uint32(.Uint()))
}
func ( *uint32Converter) ( protoreflect.Value) reflect.Value {
return reflect.ValueOf(uint32(.Uint())).Convert(.goType)
}
func ( *uint32Converter) ( protoreflect.Value) bool {
, := .Interface().(uint32)
return
}
func ( *uint32Converter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *uint32Converter) () protoreflect.Value { return .def }
func ( *uint32Converter) () protoreflect.Value { return .def }
type uint64Converter struct {
goType reflect.Type
def protoreflect.Value
}
func ( *uint64Converter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfUint64(uint64(.Uint()))
}
func ( *uint64Converter) ( protoreflect.Value) reflect.Value {
return reflect.ValueOf(uint64(.Uint())).Convert(.goType)
}
func ( *uint64Converter) ( protoreflect.Value) bool {
, := .Interface().(uint64)
return
}
func ( *uint64Converter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *uint64Converter) () protoreflect.Value { return .def }
func ( *uint64Converter) () protoreflect.Value { return .def }
type float32Converter struct {
goType reflect.Type
def protoreflect.Value
}
func ( *float32Converter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfFloat32(float32(.Float()))
}
func ( *float32Converter) ( protoreflect.Value) reflect.Value {
return reflect.ValueOf(float32(.Float())).Convert(.goType)
}
func ( *float32Converter) ( protoreflect.Value) bool {
, := .Interface().(float32)
return
}
func ( *float32Converter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *float32Converter) () protoreflect.Value { return .def }
func ( *float32Converter) () protoreflect.Value { return .def }
type float64Converter struct {
goType reflect.Type
def protoreflect.Value
}
func ( *float64Converter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfFloat64(float64(.Float()))
}
func ( *float64Converter) ( protoreflect.Value) reflect.Value {
return reflect.ValueOf(float64(.Float())).Convert(.goType)
}
func ( *float64Converter) ( protoreflect.Value) bool {
, := .Interface().(float64)
return
}
func ( *float64Converter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *float64Converter) () protoreflect.Value { return .def }
func ( *float64Converter) () protoreflect.Value { return .def }
type stringConverter struct {
goType reflect.Type
def protoreflect.Value
}
func ( *stringConverter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfString(.Convert(stringType).String())
}
func ( *stringConverter) ( protoreflect.Value) reflect.Value {
:= .Interface().(string)
if .goType.Kind() == reflect.Slice && == "" {
return reflect.Zero(.goType)
}
return reflect.ValueOf().Convert(.goType)
}
func ( *stringConverter) ( protoreflect.Value) bool {
, := .Interface().(string)
return
}
func ( *stringConverter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *stringConverter) () protoreflect.Value { return .def }
func ( *stringConverter) () protoreflect.Value { return .def }
type bytesConverter struct {
goType reflect.Type
def protoreflect.Value
}
func ( *bytesConverter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
if .goType.Kind() == reflect.String && .Len() == 0 {
return protoreflect.ValueOfBytes(nil)
}
return protoreflect.ValueOfBytes(.Convert(bytesType).Bytes())
}
func ( *bytesConverter) ( protoreflect.Value) reflect.Value {
return reflect.ValueOf(.Bytes()).Convert(.goType)
}
func ( *bytesConverter) ( protoreflect.Value) bool {
, := .Interface().([]byte)
return
}
func ( *bytesConverter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *bytesConverter) () protoreflect.Value { return .def }
func ( *bytesConverter) () protoreflect.Value { return .def }
type enumConverter struct {
goType reflect.Type
def protoreflect.Value
}
func ( reflect.Type, protoreflect.FieldDescriptor) Converter {
var protoreflect.Value
if .Cardinality() == protoreflect.Repeated {
= protoreflect.ValueOfEnum(.Enum().Values().Get(0).Number())
} else {
= .Default()
}
return &enumConverter{, }
}
func ( *enumConverter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfEnum(protoreflect.EnumNumber(.Int()))
}
func ( *enumConverter) ( protoreflect.Value) reflect.Value {
return reflect.ValueOf(.Enum()).Convert(.goType)
}
func ( *enumConverter) ( protoreflect.Value) bool {
, := .Interface().(protoreflect.EnumNumber)
return
}
func ( *enumConverter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *enumConverter) () protoreflect.Value {
return .def
}
func ( *enumConverter) () protoreflect.Value {
return .def
}
type messageConverter struct {
goType reflect.Type
}
func ( reflect.Type) Converter {
return &messageConverter{}
}
func ( *messageConverter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
if .isNonPointer() {
if .CanAddr() {
= .Addr()
} else {
= reflect.Zero(reflect.PtrTo(.Type()))
}
}
if , := .Interface().(protoreflect.ProtoMessage); {
return protoreflect.ValueOfMessage(.ProtoReflect())
}
return protoreflect.ValueOfMessage(legacyWrapMessage())
}
func ( *messageConverter) ( protoreflect.Value) reflect.Value {
:= .Message()
var reflect.Value
if , := .(unwrapper); {
= reflect.ValueOf(.protoUnwrap())
} else {
= reflect.ValueOf(.Interface())
}
if .isNonPointer() {
if .Type() != reflect.PtrTo(.goType) {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), reflect.PtrTo(.goType)))
}
if !.IsNil() {
= .Elem()
} else {
= reflect.Zero(.Type().Elem())
}
}
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return
}
func ( *messageConverter) ( protoreflect.Value) bool {
:= .Message()
var reflect.Value
if , := .(unwrapper); {
= reflect.ValueOf(.protoUnwrap())
} else {
= reflect.ValueOf(.Interface())
}
if .isNonPointer() {
return .Type() == reflect.PtrTo(.goType)
}
return .Type() == .goType
}
func ( *messageConverter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *messageConverter) () protoreflect.Value {
if .isNonPointer() {
return .PBValueOf(reflect.New(.goType).Elem())
}
return .PBValueOf(reflect.New(.goType.Elem()))
}
func ( *messageConverter) () protoreflect.Value {
return .PBValueOf(reflect.Zero(.goType))
}
func ( *messageConverter) () bool {
return .goType.Kind() != reflect.Ptr
}