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

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

TL;DR: 2023年下半期に、Protobuf Editionsをオープンソースプロジェクトとしてリリースする予定です。最初のリリース時点でproto2/proto3構文からEditions構文に移行する義務はありませんが、ソフトウェアプロジェクトの今後のタイムラインで移行を計画することをお勧めします。

Protobuf エディション

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

古いバージョンでのハードコードされた動作の代わりに、エディションは各機能にデフォルト値(動作)を持つ「機能」のコレクションを表し、これを上書きすることができます。機能とは、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を使用した同等の表現で示していますが、プロジェクトのニーズに合わせて設定を組み合わせることができます。

機能には、エディションのリリースによって管理されるライフサイクルがあります。たとえば、features.awesome_new_featureはEdition 2031で追加され、新しい動作が新しい動作を明示的に上書きしないすべての定義に適用されます。Edition 2033では、新機能は非推奨になります。上書きは引き続き機能しますが、開発者はすぐに新しい動作に適応する必要があるという警告を受けます。Edition 2036では、機能が削除され、新しい動作がすべてのプロトに適用されます。この時点では新しい動作を上書きする方法はありません。

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

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