package impl
import (
)
func ( reflect.Type, protoreflect.FieldDescriptor) Converter {
switch {
case .Kind() == reflect.Ptr && .Elem().Kind() == reflect.Slice:
return &listPtrConverter{, newSingularConverter(.Elem().Elem(), )}
case .Kind() == reflect.Slice:
return &listConverter{, newSingularConverter(.Elem(), )}
}
panic(fmt.Sprintf("invalid Go type %v for field %v", , .FullName()))
}
type listConverter struct {
goType reflect.Type
c Converter
}
func ( *listConverter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
:= reflect.New(.goType)
.Elem().Set()
return protoreflect.ValueOfList(&listReflect{, .c})
}
func ( *listConverter) ( protoreflect.Value) reflect.Value {
:= .List().(*listReflect).v
if .IsNil() {
return reflect.Zero(.goType)
}
return .Elem()
}
func ( *listConverter) ( protoreflect.Value) bool {
, := .Interface().(*listReflect)
if ! {
return false
}
return .v.Type().Elem() == .goType
}
func ( *listConverter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *listConverter) () protoreflect.Value {
return protoreflect.ValueOfList(&listReflect{reflect.New(.goType), .c})
}
func ( *listConverter) () protoreflect.Value {
return protoreflect.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(.goType)), .c})
}
type listPtrConverter struct {
goType reflect.Type
c Converter
}
func ( *listPtrConverter) ( reflect.Value) protoreflect.Value {
if .Type() != .goType {
panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
}
return protoreflect.ValueOfList(&listReflect{, .c})
}
func ( *listPtrConverter) ( protoreflect.Value) reflect.Value {
return .List().(*listReflect).v
}
func ( *listPtrConverter) ( protoreflect.Value) bool {
, := .Interface().(*listReflect)
if ! {
return false
}
return .v.Type() == .goType
}
func ( *listPtrConverter) ( reflect.Value) bool {
return .IsValid() && .Type() == .goType
}
func ( *listPtrConverter) () protoreflect.Value {
return .PBValueOf(reflect.New(.goType.Elem()))
}
func ( *listPtrConverter) () protoreflect.Value {
return .PBValueOf(reflect.Zero(.goType))
}
type listReflect struct {
v reflect.Value
conv Converter
}
func ( *listReflect) () int {
if .v.IsNil() {
return 0
}
return .v.Elem().Len()
}
func ( *listReflect) ( int) protoreflect.Value {
return .conv.PBValueOf(.v.Elem().Index())
}
func ( *listReflect) ( int, protoreflect.Value) {
.v.Elem().Index().Set(.conv.GoValueOf())
}
func ( *listReflect) ( protoreflect.Value) {
.v.Elem().Set(reflect.Append(.v.Elem(), .conv.GoValueOf()))
}
func ( *listReflect) () protoreflect.Value {
if , := .conv.(*messageConverter); ! {
panic("invalid AppendMutable on list with non-message type")
}
:= .NewElement()
.Append()
return
}
func ( *listReflect) ( int) {
.v.Elem().Set(.v.Elem().Slice(0, ))
}
func ( *listReflect) () protoreflect.Value {
return .conv.New()
}
func ( *listReflect) () bool {
return !.v.IsNil()
}
func ( *listReflect) () interface{} {
return .v.Interface()
}