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.dev.org.tw/editions/overview