reflect/protoreflect: add Enum.Type and Message.Type
CL/174938 removed these methods in favor of a method that returned
only the descriptors. This CL adds back in the Type methods alongside
the Descriptor methods.
In a vast majority of protobuf usages, only the descriptor information
is needed. However, there is a small percentage that legitimately needs
the Go type information. We should provide both, but document that the
descriptor-only information is preferred.
Change-Id: Ia0a098997fb1bd009994940ae8ea5257ccd87cae
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/184578
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/encoding/protojson/encode.go b/encoding/protojson/encode.go
index f17d3bb..5128ce4 100644
--- a/encoding/protojson/encode.go
+++ b/encoding/protojson/encode.go
@@ -256,12 +256,11 @@
if !fd.IsExtension() {
return true
}
- xt := fd.(pref.ExtensionType)
// If extended type is a MessageSet, set field name to be the message type name.
- name := xt.Descriptor().FullName()
- if isMessageSetExtension(xt) {
- name = xt.Descriptor().Message().FullName()
+ name := fd.FullName()
+ if isMessageSetExtension(fd) {
+ name = fd.Message().FullName()
}
// Use [name] format for JSON field name.
@@ -294,18 +293,17 @@
}
// isMessageSetExtension reports whether extension extends a message set.
-func isMessageSetExtension(xt pref.ExtensionType) bool {
- xd := xt.Descriptor()
- if xd.Name() != "message_set_extension" {
+func isMessageSetExtension(fd pref.FieldDescriptor) bool {
+ if fd.Name() != "message_set_extension" {
return false
}
- md := xd.Message()
+ md := fd.Message()
if md == nil {
return false
}
- if xd.FullName().Parent() != md.FullName() {
+ if fd.FullName().Parent() != md.FullName() {
return false
}
- xmd, ok := xd.ContainingMessage().(interface{ IsMessageSet() bool })
+ xmd, ok := fd.ContainingMessage().(interface{ IsMessageSet() bool })
return ok && xmd.IsMessageSet()
}
diff --git a/encoding/protojson/well_known_types.go b/encoding/protojson/well_known_types.go
index 77833d8..e744536 100644
--- a/encoding/protojson/well_known_types.go
+++ b/encoding/protojson/well_known_types.go
@@ -189,7 +189,7 @@
// If type of value has custom JSON encoding, marshal out a field "value"
// with corresponding custom JSON encoding of the embedded message as a
// field.
- if isCustomType(emt.Descriptor().FullName()) {
+ if isCustomType(emt.FullName()) {
o.encoder.WriteName("value")
return o.marshalCustomType(em)
}
@@ -235,7 +235,7 @@
// Create new message for the embedded message type and unmarshal into it.
em := emt.New()
- if isCustomType(emt.Descriptor().FullName()) {
+ if isCustomType(emt.FullName()) {
// If embedded message is a custom type, unmarshal the JSON "value" field
// into it.
if err := o.unmarshalAnyValue(em); err != nil {
diff --git a/encoding/prototext/encode.go b/encoding/prototext/encode.go
index 4d73041..7d244a9 100644
--- a/encoding/prototext/encode.go
+++ b/encoding/prototext/encode.go
@@ -252,17 +252,16 @@
if !fd.IsExtension() {
return true
}
- xt := fd.(pref.ExtensionType)
// If extended type is a MessageSet, set field name to be the message type name.
- name := xt.Descriptor().FullName()
- if isMessageSetExtension(xt) {
- name = xt.Descriptor().Message().FullName()
+ name := fd.FullName()
+ if isMessageSetExtension(fd) {
+ name = fd.Message().FullName()
}
// Use string type to produce [name] format.
tname := text.ValueOf(string(name))
- entries, err = o.appendField(entries, tname, v, xt)
+ entries, err = o.appendField(entries, tname, v, fd)
if err != nil {
return false
}
@@ -281,19 +280,18 @@
}
// isMessageSetExtension reports whether extension extends a message set.
-func isMessageSetExtension(xt pref.ExtensionType) bool {
- xd := xt.Descriptor()
- if xd.Name() != "message_set_extension" {
+func isMessageSetExtension(fd pref.FieldDescriptor) bool {
+ if fd.Name() != "message_set_extension" {
return false
}
- md := xd.Message()
+ md := fd.Message()
if md == nil {
return false
}
- if xd.FullName().Parent() != md.FullName() {
+ if fd.FullName().Parent() != md.FullName() {
return false
}
- xmd, ok := xd.ContainingMessage().(interface{ IsMessageSet() bool })
+ xmd, ok := fd.ContainingMessage().(interface{ IsMessageSet() bool })
return ok && xmd.IsMessageSet()
}
diff --git a/encoding/testprotos/pb2/test.pb.go b/encoding/testprotos/pb2/test.pb.go
index a9c102a..a9231e8 100644
--- a/encoding/testprotos/pb2/test.pb.go
+++ b/encoding/testprotos/pb2/test.pb.go
@@ -59,6 +59,10 @@
return file_pb2_test_proto_enumTypes[0].EnumDescriptor
}
+func (Enum) Type() protoreflect.EnumType {
+ return &file_pb2_test_proto_enumTypes[0]
+}
+
func (x Enum) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
@@ -112,6 +116,10 @@
return file_pb2_test_proto_enumTypes[1].EnumDescriptor
}
+func (Enums_NestedEnum) Type() protoreflect.EnumType {
+ return &file_pb2_test_proto_enumTypes[1]
+}
+
func (x Enums_NestedEnum) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
diff --git a/encoding/testprotos/pb3/test.pb.go b/encoding/testprotos/pb3/test.pb.go
index aaa20e0..56e5e4a 100644
--- a/encoding/testprotos/pb3/test.pb.go
+++ b/encoding/testprotos/pb3/test.pb.go
@@ -54,6 +54,10 @@
return file_pb3_test_proto_enumTypes[0].EnumDescriptor
}
+func (Enum) Type() protoreflect.EnumType {
+ return &file_pb3_test_proto_enumTypes[0]
+}
+
func (x Enum) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
@@ -100,6 +104,10 @@
return file_pb3_test_proto_enumTypes[1].EnumDescriptor
}
+func (Enums_NestedEnum) Type() protoreflect.EnumType {
+ return &file_pb3_test_proto_enumTypes[1]
+}
+
func (x Enums_NestedEnum) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}