2023年6月29日に発表された変更点

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

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

Protobuf エディション

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

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

エディションは既存のバイナリを壊すことはなく、最初のエディションは最小限の混乱で済みます。これはベースラインを確立し、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 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 Editionsを使用した同等の表現に直接変換したものですが、プロジェクトのニーズに合わせて設定を組み合わせることができます。

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

Editions lifecycle
図1:エディションのライフサイクルフローチャート

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