reflect/protoreflect: add helper methods to FieldDescriptor
Added API:
FieldDescriptor.IsExtension
FieldDescriptor.IsList
FieldDescriptor.MapKey
FieldDescriptor.MapValue
FieldDescriptor.ContainingOneof
FieldDescriptor.ContainingMessage
Deprecated API (to be removed in subsequent CL):
FieldDescriptor.Oneof
FieldDescriptor.Extendee
These methods help cleanup several common usage patterns.
Change-Id: I9a3ffabc2edb2173c536509b22f330f98bba7cf3
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/176977
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/impl/legacy_extension.go b/internal/impl/legacy_extension.go
index a0ae3f0..7a8fea7 100644
--- a/internal/impl/legacy_extension.go
+++ b/internal/impl/legacy_extension.go
@@ -64,7 +64,7 @@
}
t := extensionTypeFromDesc(x.Desc)
d := t.Descriptor()
- if d.Cardinality() == pref.Repeated {
+ if d.IsList() {
return t.ValueOf(x.Value).List().Len() > 0
}
return true
@@ -105,7 +105,7 @@
}
t := extensionTypeFromDesc(x.Desc)
d := t.Descriptor()
- if d.Cardinality() == pref.Repeated {
+ if d.IsList() {
t.ValueOf(x.Value).List().Truncate(0)
return
}
@@ -153,7 +153,7 @@
func (p legacyExtensionTypes) Register(t pref.ExtensionType) {
d := t.Descriptor()
- if p.mi.PBType.Descriptor().FullName() != d.Extendee().FullName() {
+ if p.mi.PBType.Descriptor().FullName() != d.ContainingMessage().FullName() {
panic("extended type mismatch")
}
if !p.mi.PBType.Descriptor().ExtensionRanges().Has(d.Number()) {
@@ -164,7 +164,7 @@
panic("extension descriptor already registered")
}
x.Desc = extensionDescFromType(t)
- if d.Cardinality() == pref.Repeated {
+ if d.IsList() {
// If the field is repeated, initialize the entry with an empty list
// so that future Get operations can return a mutable and concrete list.
x.Value = t.InterfaceOf(t.New())
@@ -178,7 +178,7 @@
return
}
x := p.x.Get(d.Number())
- if d.Cardinality() == pref.Repeated {
+ if d.IsList() {
// Treat an empty repeated field as unpopulated.
v := reflect.ValueOf(x.Value)
if x.Value == nil || v.IsNil() || v.Elem().Len() == 0 {
diff --git a/internal/impl/legacy_test.go b/internal/impl/legacy_test.go
index 28ab672..d5d4e54 100644
--- a/internal/impl/legacy_test.go
+++ b/internal/impl/legacy_test.go
@@ -685,7 +685,7 @@
// Ignore New since it a constructor.
case "Options":
// Ignore descriptor options since protos are not cmperable.
- case "Oneof", "Extendee", "Enum", "Message":
+ case "ContainingOneof", "ContainingMessage", "Enum", "Message":
// Avoid descending into a dependency to avoid a cycle.
// Just record the full name if available.
//
@@ -694,6 +694,8 @@
if !v.IsNil() {
out[name] = v.Interface().(pref.Descriptor).FullName()
}
+ case "Oneof", "Extendee":
+ // TODO: Remove this.
default:
out[name] = m.Call(nil)[0].Interface()
}
diff --git a/internal/impl/message.go b/internal/impl/message.go
index 5c2ae28..a98e7bb 100644
--- a/internal/impl/message.go
+++ b/internal/impl/message.go
@@ -118,11 +118,11 @@
fs := si.fieldsByNumber[fd.Number()]
var fi fieldInfo
switch {
- case fd.Oneof() != nil:
- fi = fieldInfoForOneof(fd, si.oneofsByName[fd.Oneof().Name()], si.oneofWrappersByNumber[fd.Number()])
+ case fd.ContainingOneof() != nil:
+ fi = fieldInfoForOneof(fd, si.oneofsByName[fd.ContainingOneof().Name()], si.oneofWrappersByNumber[fd.Number()])
case fd.IsMap():
fi = fieldInfoForMap(fd, fs)
- case fd.Cardinality() == pref.Repeated:
+ case fd.IsList():
fi = fieldInfoForList(fd, fs)
case fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind:
fi = fieldInfoForMessage(fd, fs)
diff --git a/internal/impl/message_field.go b/internal/impl/message_field.go
index 8cd82fe..10405d0 100644
--- a/internal/impl/message_field.go
+++ b/internal/impl/message_field.go
@@ -90,8 +90,8 @@
if ft.Kind() != reflect.Map {
panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
}
- keyConv := pvalue.NewLegacyConverter(ft.Key(), fd.Message().Fields().ByNumber(1).Kind(), legacyWrapper)
- valConv := pvalue.NewLegacyConverter(ft.Elem(), fd.Message().Fields().ByNumber(2).Kind(), legacyWrapper)
+ keyConv := pvalue.NewLegacyConverter(ft.Key(), fd.MapKey().Kind(), legacyWrapper)
+ valConv := pvalue.NewLegacyConverter(ft.Elem(), fd.MapValue().Kind(), legacyWrapper)
fieldOffset := offsetOf(fs)
// TODO: Implement unsafe fast path?
return fieldInfo{