github.com/Big-big-orange/protoreflect@v0.0.0-20240408141420-285cedfdf6a4/desc/internal/registry.go (about)

     1  package internal
     2  
     3  import (
     4  	"google.golang.org/protobuf/reflect/protoreflect"
     5  	"google.golang.org/protobuf/reflect/protoregistry"
     6  	"google.golang.org/protobuf/types/dynamicpb"
     7  )
     8  
     9  // RegisterExtensionsFromImportedFile registers extensions in the given file as well
    10  // as those in its public imports. So if another file imports the given fd, this adds
    11  // all extensions made visible to that importing file.
    12  //
    13  // All extensions in the given file are made visible to the importing file, and so are
    14  // extensions in any public imports in the given file.
    15  func RegisterExtensionsFromImportedFile(reg *protoregistry.Types, fd protoreflect.FileDescriptor) {
    16  	registerTypesForFile(reg, fd, true, true)
    17  }
    18  
    19  // RegisterExtensionsVisibleToFile registers all extensions visible to the given file.
    20  // This includes all extensions defined in fd and as well as extensions defined in the
    21  // files that it imports (and any public imports thereof, etc).
    22  //
    23  // This is effectively the same as registering the extensions in fd and then calling
    24  // RegisterExtensionsFromImportedFile for each file imported by fd.
    25  func RegisterExtensionsVisibleToFile(reg *protoregistry.Types, fd protoreflect.FileDescriptor) {
    26  	registerTypesForFile(reg, fd, true, false)
    27  }
    28  
    29  // RegisterTypesVisibleToFile registers all types visible to the given file.
    30  // This is the same as RegisterExtensionsVisibleToFile but it also registers
    31  // message and enum types, not just extensions.
    32  func RegisterTypesVisibleToFile(reg *protoregistry.Types, fd protoreflect.FileDescriptor) {
    33  	registerTypesForFile(reg, fd, false, false)
    34  }
    35  
    36  func registerTypesForFile(reg *protoregistry.Types, fd protoreflect.FileDescriptor, extensionsOnly, publicImportsOnly bool) {
    37  	registerTypes(reg, fd, extensionsOnly)
    38  	for i := 0; i < fd.Imports().Len(); i++ {
    39  		imp := fd.Imports().Get(i)
    40  		if imp.IsPublic || !publicImportsOnly {
    41  			registerTypesForFile(reg, imp, extensionsOnly, true)
    42  		}
    43  	}
    44  }
    45  
    46  func registerTypes(reg *protoregistry.Types, elem fileOrMessage, extensionsOnly bool) {
    47  	for i := 0; i < elem.Extensions().Len(); i++ {
    48  		_ = reg.RegisterExtension(dynamicpb.NewExtensionType(elem.Extensions().Get(i)))
    49  	}
    50  	if !extensionsOnly {
    51  		for i := 0; i < elem.Messages().Len(); i++ {
    52  			_ = reg.RegisterMessage(dynamicpb.NewMessageType(elem.Messages().Get(i)))
    53  		}
    54  		for i := 0; i < elem.Enums().Len(); i++ {
    55  			_ = reg.RegisterEnum(dynamicpb.NewEnumType(elem.Enums().Get(i)))
    56  		}
    57  	}
    58  	for i := 0; i < elem.Messages().Len(); i++ {
    59  		registerTypes(reg, elem.Messages().Get(i), extensionsOnly)
    60  	}
    61  }
    62  
    63  type fileOrMessage interface {
    64  	Extensions() protoreflect.ExtensionDescriptors
    65  	Messages() protoreflect.MessageDescriptors
    66  	Enums() protoreflect.EnumDescriptors
    67  }