github.com/Finschia/finschia-sdk@v0.48.1/server/grpc/gogoreflection/fix_registration.go (about)

     1  package gogoreflection
     2  
     3  import (
     4  	"bytes"
     5  	"compress/gzip"
     6  	"fmt"
     7  	"reflect"
     8  
     9  	_ "github.com/gogo/protobuf/gogoproto" // required so it does register the gogoproto file descriptor
    10  	gogoproto "github.com/gogo/protobuf/proto"
    11  	"github.com/golang/protobuf/proto" // nolint: staticcheck
    12  	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
    13  	_ "github.com/regen-network/cosmos-proto" // look above
    14  )
    15  
    16  var importsToFix = map[string]string{
    17  	"gogo.proto":   "gogoproto/gogo.proto",
    18  	"cosmos.proto": "cosmos_proto/cosmos.proto",
    19  }
    20  
    21  // fixRegistration is required because certain files register themselves in a way
    22  // but are imported by other files in a different way.
    23  // NOTE(fdymylja): This fix should not be needed and should be addressed in some CI.
    24  // Currently every cosmos-sdk proto file is importing gogo.proto as gogoproto/gogo.proto,
    25  // but gogo.proto registers itself as gogo.proto, same goes for cosmos.proto.
    26  func fixRegistration(registeredAs, importedAs string) error {
    27  	raw := gogoproto.FileDescriptor(registeredAs)
    28  	if len(raw) == 0 {
    29  		return fmt.Errorf("file descriptor not found for %s", registeredAs)
    30  	}
    31  
    32  	fd, err := decodeFileDesc(raw)
    33  	if err != nil {
    34  		return err
    35  	}
    36  
    37  	// fix name
    38  	*fd.Name = importedAs
    39  	fixedRaw, err := compress(fd)
    40  	if err != nil {
    41  		return fmt.Errorf("unable to compress: %w", err)
    42  	}
    43  	gogoproto.RegisterFile(importedAs, fixedRaw)
    44  	return nil
    45  }
    46  
    47  func init() {
    48  	// we need to fix the gogoproto filedesc to match the import path
    49  	// in theory this shouldn't be required, generally speaking
    50  	// proto files should be imported as their registration path
    51  
    52  	for registeredAs, importedAs := range importsToFix {
    53  		err := fixRegistration(registeredAs, importedAs)
    54  		if err != nil {
    55  			panic(err)
    56  		}
    57  	}
    58  }
    59  
    60  // compress compresses the given file descriptor
    61  // nolint: interfacer
    62  func compress(fd *dpb.FileDescriptorProto) ([]byte, error) {
    63  	fdBytes, err := proto.Marshal(fd)
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  	buf := new(bytes.Buffer)
    68  	cw := gzip.NewWriter(buf)
    69  	_, err = cw.Write(fdBytes)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	err = cw.Close()
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	return buf.Bytes(), nil
    78  }
    79  
    80  func getFileDescriptor(filePath string) []byte {
    81  	// since we got well known descriptors which are not registered into gogoproto registry
    82  	// but are instead registered into the proto one, we need to check both
    83  	fd := gogoproto.FileDescriptor(filePath)
    84  	if len(fd) != 0 {
    85  		return fd
    86  	}
    87  	//nolint: staticcheck
    88  	return proto.FileDescriptor(filePath)
    89  }
    90  
    91  func getMessageType(name string) reflect.Type {
    92  	typ := gogoproto.MessageType(name)
    93  	if typ != nil {
    94  		return typ
    95  	}
    96  	//nolint: staticcheck
    97  	return proto.MessageType(name)
    98  }
    99  
   100  func getExtension(extID int32, m proto.Message) *gogoproto.ExtensionDesc {
   101  	// check first in gogoproto registry
   102  	for id, desc := range gogoproto.RegisteredExtensions(m) {
   103  		if id == extID {
   104  			return desc
   105  		}
   106  	}
   107  	// check into proto registry
   108  	//nolint: staticcheck
   109  	for id, desc := range proto.RegisteredExtensions(m) {
   110  		if id == extID {
   111  			return &gogoproto.ExtensionDesc{
   112  				ExtendedType:  desc.ExtendedType,
   113  				ExtensionType: desc.ExtensionType,
   114  				Field:         desc.Field,
   115  				Name:          desc.Name,
   116  				Tag:           desc.Tag,
   117  				Filename:      desc.Filename,
   118  			}
   119  		}
   120  	}
   121  
   122  	return nil
   123  }
   124  
   125  func getExtensionsNumbers(m proto.Message) []int32 {
   126  	gogoProtoExts := gogoproto.RegisteredExtensions(m)
   127  	out := make([]int32, 0, len(gogoProtoExts))
   128  	for id := range gogoProtoExts {
   129  		out = append(out, id)
   130  	}
   131  	if len(out) != 0 {
   132  		return out
   133  	}
   134  	//nolint: staticcheck
   135  	protoExts := proto.RegisteredExtensions(m)
   136  	out = make([]int32, 0, len(protoExts))
   137  	for id := range protoExts {
   138  		out = append(out, id)
   139  	}
   140  	return out
   141  }