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により、言語は時間の経過とともに段階的に進化することができます。

以前のバージョンでのハードコードされた動作の代わりに、Editionsは、機能ごとにデフォルト値(動作)を持つ「機能」のコレクションを表し、これをオーバーライドできます。機能とは、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ライフサイクルフローチャート

Editionsは年に1回程度のリリースが予定されています。Protobuf Editionsの詳細については、概要ページ(https://protobuf.dokyumento.jp/editions/overview)を参照してください。