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