Я написал такой код, чтобы проанализировать и распечатать BLOB-объект.
Ключи logi c на самом деле получены из https://github.com/grpc/grpc-go/blob/759de4dd00c25745b6f3d7a9fdfb32beaf1d838e/reflection/serverreflection.go#L202 -L226
package main
import (
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
"io/ioutil"
proto "github.com/golang/protobuf/proto"
dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
_ [here write path to your generated go source]
// include the line above if you want to use proto.FileDescriptor,
// leave if you just copy-paste the bytes below
)
func main() {
// here write the path that is used in the generated file
// in init(), as an argument to proto.RegisterFile
// (or just copypaste the bytes instead of using proto.FileDescriptor)
bytes := proto.FileDescriptor(XXX)
fd, err := decodeFileDesc(bytes)
if err != nil {
panic(err)
}
b, err := json.MarshalIndent(fd,""," ")
if err != nil {
panic(err)
}
fmt.Println(string(b))
}
// decompress does gzip decompression.
func decompress(b []byte) ([]byte, error) {
r, err := gzip.NewReader(bytes.NewReader(b))
if err != nil {
return nil, fmt.Errorf("bad gzipped descriptor: %v", err)
}
out, err := ioutil.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("bad gzipped descriptor: %v", err)
}
return out, nil
}
func decodeFileDesc(enc []byte) (*dpb.FileDescriptorProto, error) {
raw, err := decompress(enc)
if err != nil {
return nil, fmt.Errorf("failed to decompress enc: %v", err)
}
fd := new(dpb.FileDescriptorProto)
if err := proto.Unmarshal(raw, fd); err != nil {
return nil, fmt.Errorf("bad descriptor: %v", err)
}
return fd, nil
}
Это печатает данные из файла прото, как JSON.
. Как Мар c Гравелл упоминает в комментарии к другому ответу, сжатие gzip недетерминировано c, поэтому один и тот же файл прото может создать разные сжатые FileDescriptorProto на двух разных компьютерах.