菜单

核心组件

相关源文件

本文档概述了构成 Protocol Buffers 基础的核心架构组件。它解释了这些组件如何协同工作,以实现结构化数据的定义、序列化和操作。有关特定组件的更详细信息,请参阅相应的子页面。

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 用于:

  • 提供表示常见数据结构的标准方法。
  • 实现不同 Protocol Buffers 实现之间的互操作性。
  • 提供有用的功能,如类型安全的动态值(Any 类型)。
  • 以一致的方式支持 JSON 映射。

有关 Well-Known Types 的更多信息,请参阅 Well-Known Types

来源: src/google/protobuf/generated_message_reflection.cc70-81

映射和动态消息

Maps 和 Dynamic Messages 是扩展 Protocol Buffers 灵活性的专用组件。

Map

Protocol Buffers 中的 Maps 提供了一种高效的键值映射机制。在底层,Maps 被实现为一种特殊类型的重复字段,其元素类型是 map entry 消息。

动态消息 (Dynamic Messages)

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 的双重性质:

  1. 编译时路径.proto 文件由编译器处理以生成特定语言的代码。
  2. 运行时路径:生成的代码和运行时库协同工作,提供序列化、解析和反射功能。

描述符系统充当了这两个路径之间的桥梁,提供了代码生成器和运行时组件所需的模式信息。

来源: 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 为特定场景增加了灵活性。

这些组件共同创建了一个强大、高效且灵活的数据交换框架,已成为许多平台和语言的标准。