package impl
import (
)
type opaqueStructInfo struct {
structInfo
}
func ( reflect.Type) bool {
if .Kind() == reflect.Struct && .NumField() > 0 {
:= .Field(0).Tag.Get("protogen")
return strings.HasPrefix(, "opaque.")
}
return false
}
func ( *MessageInfo) bool {
:= .GoReflectType.Elem()
:= opaqueStructInfo{
structInfo: .makeStructInfo(),
}
if !isOpaque() {
return false
}
defer atomic.StoreUint32(&.initDone, 1)
.fields = map[protoreflect.FieldNumber]*fieldInfo{}
:= .Desc.Fields()
for := 0; < .Len(); ++ {
:= .Get()
:= .fieldsByNumber[.Number()]
var fieldInfo
, := usePresenceForField(, )
switch {
case .ContainingOneof() != nil && !.ContainingOneof().IsSynthetic():
= fieldInfoForOneof(, .oneofsByName[.ContainingOneof().Name()], .Exporter, .oneofWrappersByNumber[.Number()])
case .IsMap():
= .fieldInfoForMapOpaque(, , )
case .IsList() && .Message() == nil && :
= .fieldInfoForScalarListOpaque(, , )
case .IsList() && .Message() == nil:
= fieldInfoForList(, , .Exporter)
case .IsList() && :
= .fieldInfoForMessageListOpaque(, , )
case .IsList():
= .fieldInfoForMessageListOpaqueNoPresence(, , )
case .Message() != nil && :
= .fieldInfoForMessageOpaque(, , )
case .Message() != nil:
= fieldInfoForMessage(, , .Exporter)
default:
= .fieldInfoForScalarOpaque(, , )
}
.fields[.Number()] = &
}
.oneofs = map[protoreflect.Name]*oneofInfo{}
for := 0; < .Desc.Oneofs().Len(); ++ {
:= .Desc.Oneofs().Get()
.oneofs[.Name()] = makeOneofInfoOpaque(, , .structInfo, .Exporter)
}
.denseFields = make([]*fieldInfo, .Len()*2)
for := 0; < .Len(); ++ {
if := .Get(); int(.Number()) < len(.denseFields) {
.denseFields[.Number()] = .fields[.Number()]
}
}
for := 0; < .Len(); {
:= .Get()
if := .ContainingOneof(); != nil && !.ContainingOneof().IsSynthetic() {
.rangeInfos = append(.rangeInfos, .oneofs[.Name()])
+= .Fields().Len()
} else {
.rangeInfos = append(.rangeInfos, .fields[.Number()])
++
}
}
.makeExtensionFieldsFunc(, .structInfo)
.makeUnknownFieldsFunc(, .structInfo)
.makeOpaqueCoderMethods(, )
.makeFieldTypes(.structInfo)
return true
}
func ( *MessageInfo, protoreflect.OneofDescriptor, structInfo, exporter) *oneofInfo {
:= &oneofInfo{oneofDesc: }
if .IsSynthetic() {
:= .Fields().Get(0)
, := presenceIndex(.Desc, )
.which = func( pointer) protoreflect.FieldNumber {
if .IsNil() {
return 0
}
if !.present(, ) {
return 0
}
return .Fields().Get(0).Number()
}
return
}
return makeOneofInfo(, , )
}
func ( *MessageInfo) ( opaqueStructInfo, protoreflect.FieldDescriptor, reflect.StructField) fieldInfo {
:= .Type
if .Kind() != reflect.Map {
panic(fmt.Sprintf("invalid type: got %v, want map kind", ))
}
:= offsetOf()
:= NewConverter(, )
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
:= .Apply().AsValueOf(.Type).Elem()
return .Len() > 0
},
clear: func( pointer) {
:= .Apply().AsValueOf(.Type).Elem()
.Set(reflect.Zero(.Type()))
},
get: func( pointer) protoreflect.Value {
if .IsNil() {
return .Zero()
}
:= .Apply().AsValueOf(.Type).Elem()
if .Len() == 0 {
return .Zero()
}
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= .GoValueOf()
if .IsNil() {
panic(fmt.Sprintf("invalid value: setting map field to read-only value"))
}
:= .Apply().AsValueOf(.Type).Elem()
.Set()
},
mutable: func( pointer) protoreflect.Value {
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() {
.Set(reflect.MakeMap(.Type))
}
return .PBValueOf()
},
newField: func() protoreflect.Value {
return .New()
},
}
}
func ( *MessageInfo) ( opaqueStructInfo, protoreflect.FieldDescriptor, reflect.StructField) fieldInfo {
:= .Type
if .Kind() != reflect.Slice {
panic(fmt.Sprintf("invalid type: got %v, want slice kind", ))
}
:= NewConverter(reflect.PtrTo(), )
:= offsetOf()
, := presenceIndex(.Desc, )
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
:= .Apply().AsValueOf(.Type).Elem()
return .Len() > 0
},
clear: func( pointer) {
:= .Apply().AsValueOf(.Type).Elem()
.Set(reflect.Zero(.Type()))
},
get: func( pointer) protoreflect.Value {
if .IsNil() {
return .Zero()
}
:= .Apply().AsValueOf(.Type)
if .Elem().Len() == 0 {
return .Zero()
}
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= .GoValueOf()
if .IsNil() {
panic(fmt.Sprintf("invalid value: setting repeated field to read-only value"))
}
.setPresent(, )
:= .Apply().AsValueOf(.Type).Elem()
.Set(.Elem())
},
mutable: func( pointer) protoreflect.Value {
.setPresent(, )
return .PBValueOf(.Apply().AsValueOf(.Type))
},
newField: func() protoreflect.Value {
return .New()
},
}
}
func ( *MessageInfo) ( opaqueStructInfo, protoreflect.FieldDescriptor, reflect.StructField) fieldInfo {
:= .Type
if .Kind() != reflect.Ptr || .Elem().Kind() != reflect.Slice {
panic(fmt.Sprintf("invalid type: got %v, want slice kind", ))
}
:= NewConverter(, )
:= offsetOf()
, := presenceIndex(.Desc, )
:= .Number()
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
if !.present(, ) {
return false
}
:= .Apply().AtomicGetPointer()
if .IsNil() {
.lazyUnmarshal(, )
= .Apply().AtomicGetPointer()
}
:= .AsValueOf(.Type.Elem())
return .Elem().Len() > 0
},
clear: func( pointer) {
:= .Apply()
:= .AtomicGetPointer()
if .IsNil() {
= .AtomicSetPointerIfNil(pointerOfValue(reflect.New(.Type.Elem())))
.setPresent(, )
}
:= .AsValueOf(.Type.Elem())
.Elem().Set(reflect.Zero(.Type().Elem()))
},
get: func( pointer) protoreflect.Value {
if .IsNil() {
return .Zero()
}
if !.present(, ) {
return .Zero()
}
:= .Apply().AtomicGetPointer()
if .IsNil() {
.lazyUnmarshal(, )
= .Apply().AtomicGetPointer()
}
:= .AsValueOf(.Type.Elem())
if .Elem().Len() == 0 {
return .Zero()
}
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= .Apply()
:= .AtomicGetPointer()
if .IsNil() {
= .AtomicSetPointerIfNil(pointerOfValue(reflect.New(.Type.Elem())))
.setPresent(, )
}
:= .AsValueOf(.Type.Elem())
:= .GoValueOf()
if .IsNil() {
panic(fmt.Sprintf("invalid value: setting repeated field to read-only value"))
} else {
.Elem().Set(.Elem())
}
},
mutable: func( pointer) protoreflect.Value {
:= .Apply()
:= .AtomicGetPointer()
if .IsNil() {
if .present(, ) {
.lazyUnmarshal(, )
= .Apply().AtomicGetPointer()
} else {
= .AtomicSetPointerIfNil(pointerOfValue(reflect.New(.Type.Elem())))
.setPresent(, )
}
}
:= .AsValueOf(.Type.Elem())
return .PBValueOf()
},
newField: func() protoreflect.Value {
return .New()
},
}
}
func ( *MessageInfo) ( opaqueStructInfo, protoreflect.FieldDescriptor, reflect.StructField) fieldInfo {
:= .Type
if .Kind() != reflect.Ptr || .Elem().Kind() != reflect.Slice {
panic(fmt.Sprintf("invalid type: got %v, want slice kind", ))
}
:= NewConverter(, )
:= offsetOf()
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
:= .Apply().AtomicGetPointer()
if .IsNil() {
return false
}
:= .AsValueOf(.Type.Elem())
return .Elem().Len() > 0
},
clear: func( pointer) {
:= .Apply().AtomicGetPointer()
if !.IsNil() {
:= .AsValueOf(.Type.Elem())
.Elem().Set(reflect.Zero(.Type().Elem()))
}
},
get: func( pointer) protoreflect.Value {
if .IsNil() {
return .Zero()
}
:= .Apply().AtomicGetPointer()
if .IsNil() {
return .Zero()
}
:= .AsValueOf(.Type.Elem())
if .Elem().Len() == 0 {
return .Zero()
}
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() {
.Set(reflect.New(.Type.Elem()))
}
:= .GoValueOf()
if .IsNil() {
panic(fmt.Sprintf("invalid value: setting repeated field to read-only value"))
} else {
.Elem().Set(.Elem())
}
},
mutable: func( pointer) protoreflect.Value {
:= .Apply().AsValueOf(.Type).Elem()
if .IsNil() {
.Set(reflect.New(.Type.Elem()))
}
return .PBValueOf()
},
newField: func() protoreflect.Value {
return .New()
},
}
}
func ( *MessageInfo) ( opaqueStructInfo, protoreflect.FieldDescriptor, reflect.StructField) fieldInfo {
:= .Type
:= .HasPresence()
if := .ContainingOneof(); != nil && .IsSynthetic() {
= true
}
:= false
if && .Kind() == reflect.Ptr {
= .Elem()
= true
}
:= NewConverter(, )
:= offsetOf()
, := presenceIndex(.Desc, )
var func( pointer) protoreflect.Value
if ! {
= getterForDirectScalar(, , , )
} else {
= getterForOpaqueNullableScalar(, , , , , )
}
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
if {
return .present(, )
}
:= .Apply().AsValueOf(.Type).Elem()
switch .Kind() {
case reflect.Bool:
return .Bool()
case reflect.Int32, reflect.Int64:
return .Int() != 0
case reflect.Uint32, reflect.Uint64:
return .Uint() != 0
case reflect.Float32, reflect.Float64:
return .Float() != 0 || math.Signbit(.Float())
case reflect.String, reflect.Slice:
return .Len() > 0
default:
panic(fmt.Sprintf("invalid type: %v", .Type()))
}
},
clear: func( pointer) {
if {
.clearPresent(, )
}
:= .Apply().AsValueOf(.Type).Elem()
.Set(reflect.Zero(.Type()))
},
get: ,
set: func( pointer, protoreflect.Value) {
:= .Apply().AsValueOf(.Type).Elem()
if {
if .IsNil() {
.Set(reflect.New())
}
= .Elem()
}
.Set(.GoValueOf())
if && .Kind() == reflect.Slice && .IsNil() {
.Set(emptyBytes)
}
if {
.setPresent(, )
}
},
newField: func() protoreflect.Value {
return .New()
},
}
}
func ( *MessageInfo) ( opaqueStructInfo, protoreflect.FieldDescriptor, reflect.StructField) fieldInfo {
:= .Type
:= NewConverter(, )
:= offsetOf()
, := presenceIndex(.Desc, )
:= .Number()
:= .Type.Elem()
return fieldInfo{
fieldDesc: ,
has: func( pointer) bool {
if .IsNil() {
return false
}
return .present(, )
},
clear: func( pointer) {
.clearPresent(, )
.Apply().AtomicSetNilPointer()
},
get: func( pointer) protoreflect.Value {
if .IsNil() || !.present(, ) {
return .Zero()
}
:= .Apply()
:= .AtomicGetPointer()
if .IsNil() {
.lazyUnmarshal(, )
= .AtomicGetPointer()
}
:= .AsValueOf()
return .PBValueOf()
},
set: func( pointer, protoreflect.Value) {
:= pointerOfValue(.GoValueOf())
if .IsNil() {
panic("invalid nil pointer")
}
.Apply().AtomicSetPointer()
.setPresent(, )
},
mutable: func( pointer) protoreflect.Value {
:= .Apply()
:= .AtomicGetPointer()
if .IsNil() {
if .present(, ) {
.lazyUnmarshal(, )
= .AtomicGetPointer()
} else {
= pointerOfValue(.GoValueOf(.New()))
.AtomicSetPointer()
.setPresent(, )
}
}
return .PBValueOf(.AsValueOf(.Type.Elem()))
},
newMessage: func() protoreflect.Message {
return .New().Message()
},
newField: func() protoreflect.Value {
return .New()
},
}
}
type presenceList struct {
pvalueList
setPresence func(bool)
}
type pvalueList interface {
protoreflect.List
}
func ( presenceList) ( protoreflect.Value) {
.pvalueList.Append()
.setPresence(true)
}
func ( presenceList) ( int) {
.pvalueList.Truncate()
.setPresence( > 0)
}
func ( protoreflect.MessageDescriptor, protoreflect.FieldDescriptor) (uint32, presenceSize) {
:= false
var , uint32
for := 0; < .Fields().Len(); ++ {
:= .Fields().Get()
if == {
= true
=
}
if .ContainingOneof() == nil || isLastOneofField() {
++
}
}
if ! {
panic(fmt.Sprintf("BUG: %v not in %v", .Name(), .FullName()))
}
return , presenceSize()
}
func ( protoreflect.FieldDescriptor) bool {
:= .ContainingOneof().Fields()
return .Get(.Len()-1) ==
}
func ( *MessageInfo) ( pointer, uint32) {
.Apply(.presenceOffset).PresenceInfo().SetPresent(, .presenceSize)
}
func ( *MessageInfo) ( pointer, uint32) {
.Apply(.presenceOffset).PresenceInfo().ClearPresent()
}
func ( *MessageInfo) ( pointer, uint32) bool {
return .Apply(.presenceOffset).PresenceInfo().Present()
}
func ( opaqueStructInfo, protoreflect.FieldDescriptor) (, bool) {
:= .(interface{ () bool }).()
:= .HasPresence() && .Message() == nil && (.ContainingOneof() == nil || .ContainingOneof().IsSynthetic())
switch {
case .ContainingOneof() != nil && !.ContainingOneof().IsSynthetic():
return false, false
case .IsMap():
return false, false
case .Kind() == protoreflect.MessageKind || .Kind() == protoreflect.GroupKind:
return ,
default:
return || ( && .HasPresence()), false
}
}