使用 protoc 生成的 pb2.py 的逆向工程 .proto 文件

Ser*_*nov 5 protocol-buffers grpc protoc grpc-python protobuf-python

是否可以使用 protoc 从生成的 pb2.py 中获取 proto 文件?gRPC 是否可以进行相同的逆向工程?

jpa*_*jpa 9

文件的格式_pb2.py因 protobuf-python 版本而异,但大多数都有一个名为serialized_pb内部的字段。这包含FileDescriptorProto.proto格式的文件的整个结构:

serialized_pb=b'\n\x0c...'
Run Code Online (Sandbox Code Playgroud)

这可以传递给protoc编译器以生成其他语言的标头。但是,必须首先将其放入 a 中FileDescriptorSet才能正确匹配格式。这可以使用 Python 来完成:

import google.protobuf.descriptor_pb2
fds = google.protobuf.descriptor_pb2.FileDescriptorSet()
fds.file.append(google.protobuf.descriptor_pb2.FileDescriptorProto())
fds.file[0].ParseFromString(b'\n\x0c... serialized_pb data ....')
open('myproto.txt', 'w').write(str(fds))
open('myproto.pb', 'wb').write(fds.SerializeToString())
Run Code Online (Sandbox Code Playgroud)

上面的代码片段将人类可读的版本保存为 ,并且格式名义上与tomyproto.txt兼容。文本表示如下:protocmyproto.pb

file {
  name: "XYZ.proto"
  dependency: "dependencyXYZ.proto"
  message_type {
    name: "MyMessage"
    field {
      name: "myfield"
      number: 1
     label: LABEL_OPTIONAL
     type: TYPE_INT32
    }
   ...
Run Code Online (Sandbox Code Playgroud)

例如,现在可以使用以下命令生成 C++ 标头:

protoc --cpp_out=. --descriptor_set_in=myproto.pb XYZ.proto
Run Code Online (Sandbox Code Playgroud)

请注意,XYZ.proto必须与描述符集中的文件名匹配,您可以在 中签入该文件名myproto.txt。但是,如果文件具有依赖性,则此方法很快就会变得困难,因为所有这些依赖性都必须收集在同一描述符集中。.proto在某些情况下,仅使用文本表示来手动重写文件可能更容易。