本文档提供了 Protocol Buffer 消息在 protobuf 库中如何处理的技术概述。它涵盖了协议缓冲区消息的解析、序列化、访问和操作的核心机制。本文档侧重于消息的运行时处理,而不是代码生成过程(该过程已单独介绍)。
消息处理系统负责
来源:src/google/protobuf/message.h244-412 src/google/protobuf/message_lite.h502-672 src/google/protobuf/message.cc65-101
消息处理系统围绕两个主要接口构建
来源:src/google/protobuf/message_lite.h502-672 src/google/protobuf/message.h244-412 src/google/protobuf/dynamic_message.cc13-167
解析系统将序列化的 Protocol Buffer 数据转换为内存中的消息对象。
Protocol Buffers 采用表驱动的解析方法以实现最佳性能
来源:src/google/protobuf/parse_context.h65-93 src/google/protobuf/generated_message_tctable_lite.cc194-198 src/google/protobuf/message_lite.cc101-104
解析使用在编译时生成的表来优化字段查找和处理
来源:src/google/protobuf/generated_message_tctable_lite.cc194-341 src/google/protobuf/compiler/cpp/parse_function_generator.cc149-195
Protocol Buffers 支持各种字段类型,每种类型在解析和序列化期间都有特定的处理方式。
每个字段的存储由其类型、基数(singular/repeated)和其他属性决定
来源:src/google/protobuf/generated_message_tctable_impl.h74-270 src/google/protobuf/generated_message_reflection.cc416-533
字段可以具有影响其存储和处理的各种基数
| 基数 | 描述 | 存储类型 |
|---|---|---|
| Singular(单数) | 具有 0 或 1 个值的字段 | 直接值存储 |
| 可选 | 具有可选存在性的字段 | 直接值 + has 位 |
| Repeated(复数) | 具有 0 个或多个值的字段 | RepeatedField/RepeatedPtrField |
| Oneof(联合) | 互斥字段 | 联合存储 + case 枚举 |
来源:src/google/protobuf/generated_message_tctable_impl.h108-117
Map 字段需要特殊处理,因为它们代表键值集合。
Map 使用哈希表实现,具有专门的编码/解码过程
来源:src/google/protobuf/map.h57-547 src/google/protobuf/map_field.h1-64 src/google/protobuf/dynamic_message.cc89-163
Map 在解析和序列化期间通过专门的流程进行处理
来源:src/google/protobuf/map.h250-451 src/google/protobuf/map_field.h1-64
反射系统支持消息字段的运行时检查和操作。
来源:src/google/protobuf/message.h369-375 src/google/protobuf/generated_message_reflection.h15-67 src/google/protobuf/generated_message_reflection.cc343-546
反射系统允许对消息字段进行通用访问
来源: src/google/protobuf/message.h426-527 src/google/protobuf/message.cc92-101
序列化过程将内存中的消息对象转换回序列化的二进制格式。
来源: src/google/protobuf/message_lite.cc105-127 src/google/protobuf/message.cc79-90
消息使用标签-长度-值(tag-length-value)的方法进行序列化
| 字段组件 | 描述 |
|---|---|
| 标签 | 字段编号和线类型(varint 编码) |
| 线类型 | 编码类型(varint、fixed32、fixed64、length-delimited) |
| 值 | 字段值根据线类型进行编码 |
来源: src/google/protobuf/generated_message_reflection.cc543-603
Protocol Buffers 库使用 Arena 分配来优化消息的内存管理。
来源: src/google/protobuf/message_lite.h56-78 src/google/protobuf/message_lite.cc53-75
Protocol Buffers 消息处理系统为处理结构化数据提供了一个强大的框架。它通过以下方式平衡了性能和灵活性:
该系统构成了 Protocol Buffers 的核心运行时,通过紧凑的线格式实现了高性能的跨语言数据互换。