如何获取protobuf消息中定义的变量的类型?

lon*_*bow 5 python protocol-buffers

我正在尝试使用 Python 进行一些从 protobuf 文件到 Objective-C 类的“翻译”。例如,给定 protobuf 消息:

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;
}
Run Code Online (Sandbox Code Playgroud)

我想将它翻译成一个 objc 类:

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int ID;
@property (nonatomic, copy) NSString *email; 
@end
Run Code Online (Sandbox Code Playgroud)

关键点是获取每个属性的名称和类型。例如,protobuf消息中的'可选字符串电子邮件',它的名称是'email',类型是'string',所以它在objective-c中应该是NSString *email。我按照官方教程,写了一个和教程中一样的addressbook.proto,并编译了它。然后我写了我的Python代码:

import addressbook_pb2 as addressbook

p = addressbook.Person()
all_fields = p.DESCRIPTOR.fields_by_name
# print "all fields: %s" %all_fields
field_keys = all_fields.keys()
# print "all keys: %s" %field_keys

for key in field_keys:
    one_field = all_fields[key]
    print one_field.label
Run Code Online (Sandbox Code Playgroud)

这只是给了我:

1
2
3
2
Run Code Online (Sandbox Code Playgroud)

所以我想 label 不是我需要的,而 field_keys 只是我期望的名称列表。我尝试了其他一些词,并在网上进行了一些搜索,但没有找到正确的答案。

如果没有办法获取类型,我还有另一个想法,那就是以纯粹的“Pythonic”方式读取和分析 protobuf 源文件的每一行,但如果没有必要,我真的不想这样做。

有谁能够帮助我?

lon*_*bow 0

感谢马克的回答,我找到了一些解决方案。这只是一个想法,但这对我来说是巨大的一步。

Python代码:

import addressbook_pb2 as addressbook

typeDict = {"1":"CGFloat", "2":"CGFloat", "3":"NSInteger", "4":"NSUinteger", "5":"NSInteger", "8":"BOOL", "9":"NSString", "13":"NSUinteger", "17":"NSInteger", "18":"NSInteger"}

attrDict = {"CGFloat":"assign", "NSInteger":"assign", "NSUinteger":"assign", "BOOL":"assign", "NSString":"copy"}

p = addressbook.Person()
all_fields = p.DESCRIPTOR.fields_by_name
field_keys = all_fields.keys()
for key in field_keys:
    one_field = all_fields[key]
    typeNumStr = str(one_field.type)
    className = typeDict.get(typeNumStr, "NSObject")
    attrStr = attrDict.get(className, "retain")
    propertyStr = "@property (nonatomic, %s) %s *%s" %(attrStr, className, key)
    print propertyStr
Run Code Online (Sandbox Code Playgroud)

对于地址簿示例,它打印:

@property (nonatomic, copy) NSString *email
@property (nonatomic, copy) NSString *name
@property (nonatomic, retain) NSObject *phone
@property (nonatomic, assign) NSInteger *id
Run Code Online (Sandbox Code Playgroud)

虽然不是最终的解决方案,但意义重大。谢谢你,马克!