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 }