2023 年 6 月 29 日宣布的变更

2023 年 6 月 29 日为 Protocol Buffers 宣布的变更。

要点: 我们计划在 2023 年下半年将 Protobuf 版本发布到开源项目。虽然在初始版本发布时没有要求从 proto2/proto3 语法迁移到版本语法,但我们鼓励您在软件项目的未来时间线中规划迁移。

Protobuf 版本

Protobuf 版本取代了我们为 Protocol Buffers 使用的 proto2 和 proto3 指定。您可以使用版本号(例如 `edition = "2024"`)来指定文件的默认行为,而不是在 proto 定义文件的顶部添加 `syntax = "proto2"` 或 `syntax = "proto3"`。版本使语言能够随着时间的推移逐步发展。

版本将代表“特性”的集合,每个特性都有一个默认值(行为),您可以覆盖它,而不是旧版本中的硬编码行为。特性是文件、消息、字段、枚举等上的选项,用于指定 protoc、代码生成器和 protobuf 运行时的行为。当您的需求与您选择的版本默认行为不符时,您可以在这些不同级别(文件、消息、字段等)显式覆盖所需的行为。

版本不会破坏现有二进制文件,并且第一个版本将具有最小的破坏性;它将建立基线,并将 proto2 和 proto3 定义合并为新的单一定义格式。它不需要对您的代码进行任何更改。我们将提供一个名为 Prototiller 的工具来迁移 .proto 文件。以下示例显示了 proto2 定义文件和 proto3 文件,以及使用 Prototiller 将它们转换为 Protobuf 版本格式后的样子

Proto2 语法

// proto2 file
syntax = "proto2";

message Player {
  // in proto2, optional fields have explicit presence
  optional string name = 1;
  // proto2 still supports the problematic "required" field rule
  required int32 id = 2;
  // in proto2 this is not packed by default
  repeated int32 scores = 3;

  enum Handed {
    HANDED_UNSPECIFIED = 0,
    HANDED_LEFT = 1,
    HANDED_RIGHT = 2,
    HANDED_AMBIDEXTROUS = 3,
  }

  // in proto2 enums are closed
  optional Handed handed = 4;
}

版本语法

// Editions version of proto2 file
edition = "2023";

message Player {
  string name = 1;
  int32 id = 2 [features.field_presence = LEGACY_REQUIRED];
  repeated int32 scores = 3 [features.repeated_field_encoding = EXPANDED];

  enum Handed {
    // this overrides the default Edition 2023 behavior, which is OPEN
    option features.enum = CLOSED;
    HANDED_UNSPECIFIED = 0,
    HANDED_LEFT = 1,
    HANDED_RIGHT = 2,
    HANDED_AMBIDEXTROUS = 3,
  }

  Handed handed = 4;
}

以及类似的 proto3 定义文件可能如下所示

Proto3 语法

// proto3 file
syntax = "proto3";

message Player {
  // in proto3, optional fields have explicit presence
  optional string name = 1;
  // in proto3 no specified field rule defaults to implicit presence
  int32 id = 2;
  // in proto3 this is packed by default
  repeated int32 scores = 3;

  enum Handed {
    HANDED_UNSPECIFIED = 0,
    HANDED_LEFT = 1,
    HANDED_RIGHT = 2,
    HANDED_AMBIDEXTROUS = 3,
  }

  // in proto3 enums are open
  optional Handed handed = 4;
}

版本语法

// Editions version of proto3 file
edition = "2023";

message Player {
  string name = 1;
  int32 id = 2 [features.field_presence = IMPLICIT];
  repeated int32 scores = 3;

  enum Handed {
    HANDED_UNSPECIFIED = 0,
    HANDED_LEFT = 1,
    HANDED_RIGHT = 2,
    HANDED_AMBIDEXTROUS = 3,
  }

  Handed handed = 4;
}

虽然本主题中提供的示例展示了 proto2 和 proto3 到使用 Protobuf 版本的等效表示形式的直接转换,但您将能够混合和匹配设置以满足项目的需求。

特性具有由版本发布管理的生命周期。例如,`features.awesome_new_feature` 可能会在 2031 版本中添加,新行为将应用于所有未显式覆盖新行为的定义。在 2033 版本中,新特性被弃用。覆盖仍然有效,但开发者会收到警报,提示他们需要尽快适应新行为。在 2036 版本中,该特性被移除,新行为将应用于所有 proto;此时无法覆盖新行为。

Editions lifecycle
图 1:版本生命周期流程图

版本计划大约每年发布一次。有关 Protobuf 版本的更多信息,请参阅概述,网址为 https://protobuf.com.cn/editions/overview