本文档概述了构成 Protocol Buffers 基础的核心架构组件。它解释了这些组件如何协同工作,以实现结构化数据的定义、序列化和操作。有关特定组件的更详细信息,请参阅相应的子页面。
Protocol Buffers (protobuf) 是一种语言无关、平台无关且可扩展的结构化数据序列化机制。该系统由几个相互关联的组件组成,它们共同协作提供完整的数据序列化和反序列化解决方案。
来源: src/google/protobuf/descriptor.h13-29 src/google/protobuf/compiler/command_line_interface.cc70-82
Descriptor System 是 Protocol Buffers 的基石,它提供了关于消息类型、字段、枚举以及其他在 .proto 文件中定义的元素元数据。这些元数据在编译(用于代码生成)和运行时(用于反射)都会用到。
DescriptorPool 类维护着一组 FileDescriptor 对象,并作为所有描述符的中央注册表。它负责解析类型名称和管理消息类型之间的依赖关系。
描述符本身在创建后是不可变的,并提供有关相应 Protocol Buffer 元素的详细信息。
Descriptor:表示消息类型,包含其字段和嵌套类型。FieldDescriptor:表示消息中的一个字段。EnumDescriptor:表示枚举类型及其值。ServiceDescriptor:表示服务(用于 RPC)。有关描述符系统和编译管道的更多详细信息,请参阅 描述符与编译管道。
来源: src/google/protobuf/descriptor.h378-768 src/google/protobuf/descriptor.cc662-1002
Message Processing System 负责在运行时表示 Protocol Buffers 消息,将它们从序列化格式解析出来,然后再序列化回去。
消息系统围绕两个关键的基类构建:
MessageLite:一个轻量级的基类,提供核心的解析和序列化功能。Message:扩展了 MessageLite,增加了反射支持等附加功能。生成的消息类通过特定类型的实现来扩展这些基类,而 DynamicMessage 类则提供了根据描述符在运行时创建消息的方法。
解析和序列化组件负责处理二进制/文本格式与消息对象之间的转换,而反射系统则支持消息的运行时内省和操作。
有关消息处理的更多详细信息,请参阅 消息处理系统。
来源: src/google/protobuf/message.h127-186 src/google/protobuf/message_lite.h62-134 src/google/protobuf/parse_context.h47-55
Protocol Buffers 通过 Arena 分配器提供了一个优化的内存管理系统。Arena 分配是一种内存管理策略,它从预先分配的大块内存中分配对象,显著减少了内存分配/释放的开销。
基于 Arena 的内存管理的关键特性包括:
有关内存管理的更多信息,请参阅 内存管理。
来源: src/google/protobuf/arena.h src/google/protobuf/generated_message_reflection.cc83
Protocol Buffers 包含一组预定义的、称为“Well-Known Types”(WKTs)的消息类型。这些类型为常见数据结构和模式提供了标准解决方案。
这些 Well-Known Types 用于:
有关 Well-Known Types 的更多信息,请参阅 Well-Known Types。
来源: src/google/protobuf/generated_message_reflection.cc70-81
Maps 和 Dynamic Messages 是扩展 Protocol Buffers 灵活性的专用组件。
Protocol Buffers 中的 Maps 提供了一种高效的键值映射机制。在底层,Maps 被实现为一种特殊类型的重复字段,其元素类型是 map entry 消息。
Dynamic Messages 提供了一种无需生成代码即可创建和操作 Protocol Buffers 消息的方法,通过在运行时使用描述符。
有关 Maps 和 Dynamic Messages 的更多信息,请参阅 Maps 和 Dynamic Messages。
来源: src/google/protobuf/message.h76-77 src/google/protobuf/compiler/cpp/message.cc420-444
Protocol Buffers 的核心组件被设计成无缝协同工作。下图说明了这些组件之间的关键交互:
这说明了 Protocol Buffers 的双重性质:
.proto 文件由编译器处理以生成特定语言的代码。描述符系统充当了这两个路径之间的桥梁,提供了代码生成器和运行时组件所需的模式信息。
来源: src/google/protobuf/descriptor.cc79-88 src/google/protobuf/compiler/command_line_interface.cc309-337
Protocol Buffers 的核心组件构成了一个内聚的系统,能够实现高效的结构化数据序列化、解析和操作。Descriptor System 提供了元数据基础,而 Message Processing System 负责运行时表示。Memory Management System 优化了性能,Well-Known Types 为常见的用例提供了标准化解决方案。Maps 和 Dynamic Messages 为特定场景增加了灵活性。
这些组件共同创建了一个强大、高效且灵活的数据交换框架,已成为许多平台和语言的标准。