2023年6月29日発表の変更点

2023年6月29日に発表された Protocol Buffers の変更点。

TL;DR: 2023年後半に Protobuf Editions をオープンソースプロジェクトにリリースする予定です。初期リリース時に proto2/proto3 構文から Editions 構文に移行する必要はありませんが、ソフトウェアプロジェクトの将来のタイムラインで移行を計画することを推奨します。

Protobuf Editions

Protobuf Editions は、これまで Protocol Buffers で使用してきた proto2 および proto3 の指定に代わるものです。proto 定義ファイルの先頭に syntax = "proto2"syntax = "proto3" を追加する代わりに、edition = "2024" のようなエディション番号を使用して、ファイルが持つデフォルトの動作を指定します。Editions により、言語を時間の経過とともに段階的に進化させることが可能になります。

以前のバージョンのハードコードされた動作の代わりに、editions は機能ごとにデフォルト値(動作)を持つ「機能」のコレクションを表し、これはオーバーライドできます。機能は、ファイル、メッセージ、フィールド、enum などのオプションであり、protoc、コードジェネレーター、および protobuf ランタイムの動作を指定します。ニーズが選択したエディションのデフォルトの動作と一致しない場合は、これらの異なるレベル(ファイル、メッセージ、フィールドなど)で目的の動作を明示的にオーバーライドできます。

Editions は既存のバイナリを壊すことはなく、最初のエディションは最小限の中断で済みます。ベースラインを確立し、proto2 と proto3 の定義を新しい単一の定義形式に結合します。コードの変更は必要ありません。Prototiller というツールを提供し、.proto ファイルを移行できるようにします。次の例は、proto2 定義ファイルと proto3 ファイル、および Prototiller を使用して Protobuf Editions 形式に変換した後のそれぞれの外観を示しています。

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 構文

// 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 構文

// 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 Editions を使用した同等の表現への直接的な翻訳を示していますが、プロジェクトのニーズに合わせて設定を組み合わせて使用することができます。

機能には、editions のリリースによって管理されるライフサイクルがあります。たとえば、features.awesome_new_feature は Edition 2031 で追加される可能性があり、新しい動作は新しい動作を明示的にオーバーライドしないすべての定義に適用されます。Edition 2033 では、新しい機能は非推奨になります。オーバーライドは引き続き機能しますが、開発者は新しい動作にすぐに適応する必要があるという事実に警告されます。Edition 2036 では、機能は削除され、新しい動作がすべての proto に適用されます。この時点では、新しい動作をオーバーライドする方法はありません。

Editions lifecycle
図1:Editions のライフサイクルフローチャート

Editions は、おおよそ年に一度リリースされる予定です。Protobuf Editions の詳細については、https://protobuf.dokyumento.jp/editions/overview の概要をご覧ください。