2023 年 6 月 29 日宣佈的變更

2023 年 6 月 29 日針對 Protocol Buffers 宣佈的變更。

重點摘要: 我們計劃在 2023 年下半年將 Protobuf 版本發佈到開放原始碼專案。雖然在初始發佈時沒有要求從 proto2/proto3 語法移至版本語法,但我們鼓勵您在軟體專案的未來時程中規劃遷移。

Protobuf 版本

Protobuf 版本取代了我們用於 Protocol Buffers 的 proto2 和 proto3 標識。您不再於 proto 定義檔案的頂端新增 syntax = "proto2"syntax = "proto3",而是使用版本號碼,例如 edition = "2024",來指定檔案的預設行為。版本讓語言能夠隨著時間逐步發展。

版本將代表一組「特性」,每個特性都有預設值 (行為),您可覆寫這些特性,而不是舊版本中的硬式編碼行為。特性是檔案、訊息、欄位、列舉等選項,這些選項指定 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 的總覽。