Protobuf 本身具有很强的反射机制,可以通过 type name 构造具体的 Message 对象。陈硕的文章《一种自动反射消息类型的 Google Protobuf 网络传输方案》中对 GPB 的反射机制做了详细的分析和源码解读。这里通过 protobuf-objectivec 版本的源码,分析此版本的反射机制。
typedef struct GPBCodedInputStreamState {
const uint8_t *bytes;
size_t bufferSize;
size_t bufferPos;
// For parsing subsections of an input stream you can put a hard limit on
// how much should be read. Normally the limit is the end of the stream,
// but you can adjust it to anywhere, and if you hit it you will be at the
// end of the stream, until you adjust the limit.
size_t currentLimit;
int32_t lastTag;
NSUInteger recursionDepth;
} GPBCodedInputStreamState;
@interface GPBCodedInputStream () {
@package
struct GPBCodedInputStreamState state_;
NSData *buffer_;
}
merge 操作内部实现比较复杂,首先会拿到一个当前 Message 对象的 Descriptor 实例,这个 Descriptor 实例主要保存 Message 的源文件 Descriptor 和每个 field 的 Descriptor,然后通过循环的方式对 Message 的每个 field 进行赋值。