reflect/protoreflect, reflect/protoregistry: move descriptor lookup to registry
Drop the protoreflect.FileDescriptor.DescriptorByName method.
Descriptor lookup will always happen through a protoregistry.Files, which
is more generally useful (it's rare that you want to find a descriptor in a
specific file, as opposed to a package which may be composed of multiple files).
Split protoregistry.Files descriptor lookup into individual per-type functions
(enum, message, extension, service), matching the preg.Types API.
Drop the ability to look up enum values, message fields, and service methods
for now. This can be easily added later if needed, and is trivial to implement
in user code. (e.g., look up the service and then consult sd.Methods.ByName().)
Change-Id: I2b3d8ef888921a8464ba1434eddab20c7d3a458e
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/172118
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/fileinit/desc.go b/internal/fileinit/desc.go
index f305ee0..199e38d 100644
--- a/internal/fileinit/desc.go
+++ b/internal/fileinit/desc.go
@@ -246,7 +246,6 @@
fileLazy struct {
syntax pref.Syntax
imports fileImports
- byName map[pref.FullName]pref.Descriptor
options []byte
}
)
@@ -260,17 +259,16 @@
func (fd *fileDesc) Options() pref.ProtoMessage {
return unmarshalOptions(descopts.File, fd.lazyInit().options)
}
-func (fd *fileDesc) Path() string { return fd.path }
-func (fd *fileDesc) Package() pref.FullName { return fd.protoPackage }
-func (fd *fileDesc) Imports() pref.FileImports { return &fd.lazyInit().imports }
-func (fd *fileDesc) Enums() pref.EnumDescriptors { return &fd.enums }
-func (fd *fileDesc) Messages() pref.MessageDescriptors { return &fd.messages }
-func (fd *fileDesc) Extensions() pref.ExtensionDescriptors { return &fd.extensions }
-func (fd *fileDesc) Services() pref.ServiceDescriptors { return &fd.services }
-func (fd *fileDesc) DescriptorByName(s pref.FullName) pref.Descriptor { return fd.lazyInit().byName[s] }
-func (fd *fileDesc) Format(s fmt.State, r rune) { pfmt.FormatDesc(s, r, fd) }
-func (fd *fileDesc) ProtoType(pref.FileDescriptor) {}
-func (fd *fileDesc) ProtoInternal(pragma.DoNotImplement) {}
+func (fd *fileDesc) Path() string { return fd.path }
+func (fd *fileDesc) Package() pref.FullName { return fd.protoPackage }
+func (fd *fileDesc) Imports() pref.FileImports { return &fd.lazyInit().imports }
+func (fd *fileDesc) Enums() pref.EnumDescriptors { return &fd.enums }
+func (fd *fileDesc) Messages() pref.MessageDescriptors { return &fd.messages }
+func (fd *fileDesc) Extensions() pref.ExtensionDescriptors { return &fd.extensions }
+func (fd *fileDesc) Services() pref.ServiceDescriptors { return &fd.services }
+func (fd *fileDesc) Format(s fmt.State, r rune) { pfmt.FormatDesc(s, r, fd) }
+func (fd *fileDesc) ProtoType(pref.FileDescriptor) {}
+func (fd *fileDesc) ProtoInternal(pragma.DoNotImplement) {}
type (
enumDesc struct {
diff --git a/internal/fileinit/desc_lazy.go b/internal/fileinit/desc_lazy.go
index 7356b32..bbcc9d9 100644
--- a/internal/fileinit/desc_lazy.go
+++ b/internal/fileinit/desc_lazy.go
@@ -333,7 +333,7 @@
var hasSyntax bool
var enumIdx, messageIdx, extensionIdx, serviceIdx int
- fd.lazy = &fileLazy{byName: make(map[pref.FullName]pref.Descriptor)}
+ fd.lazy = &fileLazy{}
for len(b) > 0 {
num, typ, n := wire.ConsumeTag(b)
b = b[n:]
@@ -424,8 +424,6 @@
ed.lazy.values.list[i].unmarshalFull(b, nb, ed.parentFile, ed, i)
}
}
-
- ed.parentFile.lazy.byName[ed.FullName()] = ed
}
func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) {
@@ -480,8 +478,6 @@
b = b[m:]
}
}
-
- vd.parentFile.lazy.byName[vd.FullName()] = vd
}
func (md *messageDesc) unmarshalFull(b []byte, nb *nameBuilder) {
@@ -546,8 +542,6 @@
if isMapEntry != md.isMapEntry {
panic("mismatching map entry property")
}
-
- md.parentFile.lazy.byName[md.FullName()] = md.asDesc()
}
func (md *messageDesc) unmarshalOptions(b []byte, isMapEntry *bool) {
@@ -694,8 +688,6 @@
}
fd.messageType = ptype.PlaceholderMessage(pref.FullName(rawTypeName[1:]))
}
-
- fd.parentFile.lazy.byName[fd.FullName()] = fd
}
func (fd *fieldDesc) unmarshalOptions(b []byte) {
@@ -744,8 +736,6 @@
b = b[m:]
}
}
-
- od.parentFile.lazy.byName[od.FullName()] = od
}
func (xd *extensionDesc) unmarshalFull(b []byte, nb *nameBuilder) {
@@ -790,8 +780,6 @@
panic(err)
}
}
-
- xd.parentFile.lazy.byName[xd.FullName()] = xd
}
func (xd *extensionDesc) unmarshalOptions(b []byte) {
@@ -842,8 +830,6 @@
sd.lazy.methods.list[i].unmarshalFull(b, nb, sd.parentFile, sd, i)
}
}
-
- sd.parentFile.lazy.byName[sd.FullName()] = sd
}
func (md *methodDesc) unmarshalFull(b []byte, nb *nameBuilder, pf *fileDesc, pd pref.Descriptor, i int) {
@@ -878,6 +864,4 @@
b = b[m:]
}
}
-
- md.parentFile.lazy.byName[md.FullName()] = md
}
diff --git a/internal/fileinit/fileinit_test.go b/internal/fileinit/fileinit_test.go
index e900168..c116751 100644
--- a/internal/fileinit/fileinit_test.go
+++ b/internal/fileinit/fileinit_test.go
@@ -70,9 +70,9 @@
// Verify that message descriptors for map entries have no Go type info.
mapEntryName := protoreflect.FullName("goproto.proto.test.TestAllTypes.MapInt32Int32Entry")
- d := testpb.File_test_test_proto.DescriptorByName(mapEntryName)
- if _, ok := d.(protoreflect.MessageDescriptor); !ok {
- t.Errorf("message descriptor for %v not found", mapEntryName)
+ d := testpb.File_test_test_proto.Messages().ByName("TestAllTypes").Fields().ByName("map_int32_int32").MessageType()
+ if gotName, wantName := d.FullName(), mapEntryName; gotName != wantName {
+ t.Fatalf("looked up wrong descriptor: got %v, want %v", gotName, wantName)
}
if _, ok := d.(protoreflect.MessageType); ok {
t.Errorf("message descriptor for %v must not implement protoreflect.MessageType", mapEntryName)