- はじめに — 発表より4日早く出ていたRC
- エディションという仕組みを一段落で
- protocがedition = "2026"を受け付け始めた地点
- 変わるデフォルト値①: enforce_naming_styleがSTYLE2026へ
- 変わるデフォルト値②: default_symbol_visibilityがSTRICTへ
- 変わるデフォルト値③: enforce_proto_limits — ここが本当の変化です
- 検査はprotocがオンにし、ランタイムはオフのままです
- 新たに入るもの(手短に)
- 正直なトレードオフと限界
- で、今何をすべきか
- おわりに
- 参考資料
はじめに — 発表より4日早く出ていたRC
2026年7月13日、protobuf.devのニュースページにEdition 2026の発表が掲載されました。3日前のことです。ところがGitHubのリリース一覧を見ると、v36.0-rc1はそれよりさらに4日早い7月9日にすでにpublished状態になっていました。発表文が「36.xで2026年第3四半期にリリース予定」と書いている間に、その36.xの最初のRCはすでに出ていたわけです。
本稿はその発表文を要約する記事ではありません。発表文は短く、いくつかの点で実際の実装とずれており、しかも最も興味深い変更を一つ丸ごと欠いています。そこでv36.0-rc1タグの実際のソース — descriptor.proto、descriptor.h、code_generator.h、command_line_interface.cc — を直接読んで確認した内容をまとめます。
先に結論から。Edition 2026は新しい文法を一つも追加しません。 発表文の最後の一文がそのまま成り立ちます — "There is no new or removed grammar in Edition 2026."代わりに、3つのデフォルト値を締め付けます。そしてそのうち一つは、protocが15年以上やってこなかったことです。
エディションという仕組みを一段落で
Protocol Buffers自体やバイナリシリアライゼーションフォーマットの比較はすでに扱ったので、エディションについては手短に触れるだけにします。以前はファイルの先頭にsyntax = "proto2"またはsyntax = "proto3"と書き、その一語がフィールドプレゼンス・enumの開閉・デフォルトのパッキングの有無など、互いに無関係な複数の挙動をまとめて決めていました。エディションはこの塊を個々の機能(feature) に分解し、ファイルの先頭にはedition = "2024"のように年だけを書かせます。各機能はエディションごとに異なるデフォルト値を持ち、必要ならファイル単位や特定の要素で個別に上書きできます。
肝心なのはここです — エディションを上げない限り何も変わりません。 デフォルト値はエディションに紐づいているため、edition = "2023"のままのファイルはEdition 2026のデフォルト変更を一切経験しません。新しいエディションは「これからはこうする方がよい」をデフォルトとして宣言する仕組みであって、既存のファイルを壊す仕組みではありません。
descriptor.protoのEdition enumを見ると、リリース済みのエディションはこう並んでいます。
// Editions that have been released. The specific values are arbitrary and
// should not be depended on, but they will always be time-ordered for easy
// comparison.
EDITION_2023 = 1000;
EDITION_2024 = 1001;
EDITION_2026 = 1002;
2025がありません。値は1000、1001、1002と連続しているので、飛ばされたのではなく、そもそも作られなかったということです。(コメント自体が「値そのものは任意であり依存すべきでない、ただし常に時系列順」と釘を刺しているので、年の間隔に意味を持たせる理由もありません。)
protocがedition = "2026"を受け付け始めた地点
「Edition 2026が出た」がちょうどどのリリースからなのかは、code_generator.hの一行で確認できます。
// The maximum edition supported by protoc.
constexpr auto ProtocMaximumEdition() { return Edition::EDITION_2026; }
この値をリリースタグごとに追うと、境界がくっきり見えます。
v32.0 (2025-08-14) ProtocMaximumEdition() = EDITION_2024
v33.0 (2025-10-15) ProtocMaximumEdition() = EDITION_2024
v34.0 (2026-02-25) ProtocMaximumEdition() = EDITION_2024
v35.0 (2026-05-19) ProtocMaximumEdition() = EDITION_2024
v35.1 (2026-06-11) ProtocMaximumEdition() = EDITION_2024 <- 現在のstable
v36.0-rc1 (2026-07-09) ProtocMaximumEdition() = EDITION_2026 <- ここが最初
つまりv36.0-rc1が、ファイルの先頭にedition = "2026"と書ける最初のprotocです。それより前のprotocに2026のファイルを渡すと、最大対応エディション超過として拒否されます。そして今日(2026-07-16)時点でstableは依然v35.1であり、v36.0はGAではなくRCです。
同じやり方で過去を検証すると、トラックレコードも確認できます。Edition 2024の発表は2025年6月27日に「32.xで2025年第3四半期に」リリースすると述べ、v32.0は2025年8月14日に出て、そこでProtocMaximumEdition()がEDITION_2024に上がりました。約束どおりでした。今回の発表文も同じ形式で「36.x、2026年第3四半期」と述べており、RCはすでに出ています。
変わるデフォルト値①: enforce_naming_styleがSTYLE2026へ
descriptor.protoのデフォルト値テーブルはこうなっています。
enum EnforceNamingStyle {
ENFORCE_NAMING_STYLE_UNKNOWN = 0;
STYLE2024 = 1;
STYLE_LEGACY = 2;
STYLE2026 = 3;
}
// edition_defaults:
// EDITION_LEGACY -> STYLE_LEGACY
// EDITION_2024 -> STYLE2024
// EDITION_2026 -> STYLE2026
発表文はこのルールをこう説明しています — フィールドxを持つメッセージの中で、has_x、set_x、get_x、clear_x、x_valueは禁止され、フィールド名にdescriptorは使えない。
ところが実際の実装(descriptor.cc、2026-04-07付コミット)を読むと、発表文より精密です。禁止プレフィックスはhas_、get_、set_、clear_の4つ、禁止サフィックスは_valueの1つですが、無条件禁止ではなく条件付きです。
if (absl::StartsWith(name, prefix)) {
absl::string_view without_prefix = name;
without_prefix.remove_prefix(prefix.size());
if ((message->FindFieldByName(without_prefix) != nullptr ||
message->FindOneofByName(without_prefix) != nullptr)) {
*error = absl::StrCat("should not begin with ", prefix,
" if a field named ", without_prefix,
" exists. This can cause collisions in "
"generated code.");
return false;
}
}
同じメッセージの中に対になるxが実在するときだけhas_xはエラーになります。xがなければhas_xという名前はそのまま通ります。つまりこれは命名規則というより衝突検査です — 生成コードでhas_x()アクセサとhas_xフィールドが同じシンボルとしてぶつかる状況だけを正確に狙っています。しかも対を探す際にはフィールドだけでなくoneof名まで調べ(FindOneofByName)、検査自体もフィールド・oneof両方に適用されます。一方descriptorは無条件で禁止です。
オプトアウトが2段階になっている点も発表文にはありません。ソースにはエラーメッセージ用の定数が2つあります。
constexpr absl::string_view kNamingStyleOptOutMessage =
" (features.enforce_naming_style = STYLE_LEGACY can be used to opt out of "
"this check)";
constexpr absl::string_view kNamingStyleCollisionsOptOutMessage =
" (features.enforce_naming_style = STYLE2024 can be used to opt out of "
"this check)";
STYLE2024まで下げると、2026で新設された衝突検査だけがオフになり、2024のスタイル検査は残ります。すべてオフにするにはSTYLE_LEGACYまで下げる必要があります。移行時に実際に使う手段は、たいてい前者です。
最後に些細ながら面白い欠点を一つ。上のenumではSTYLE_LEGACYが2、STYLE2024が1で、数値順と厳格さの順序が食い違っています。 そのため「このスタイル以上か」を判定するヘルパーに特殊ケースが埋め込まれています。
bool IsStyleOrGreater(const DescriptorT* descriptor,
FeatureSet::EnforceNamingStyle style) {
return internal::InternalFeatureHelper::GetFeatures(*descriptor)
.enforce_naming_style() >= style &&
// Required because STYLE_LEGACY comes after STYLE2024 in enum
// definition.
internal::InternalFeatureHelper::GetFeatures(*descriptor)
.enforce_naming_style() != FeatureSet::STYLE_LEGACY;
}
enum値の順序は後から変えられないため、コードで回避した痕跡です。プロトコルの進化を扱うプロジェクトが、自分自身のenumの進化に足を取られているわけですが、こういうものが残っているのはむしろ自然なことです。
変わるデフォルト値②: default_symbol_visibilityがSTRICTへ
Edition 2024でexport/localキーワードとdefault_symbol_visibility機能が導入され、当時のデフォルトはEXPORT_TOP_LEVEL — 最上位シンボルはexport、ネストしたシンボルはlocal — でした。Edition 2026はこれをSTRICTに引き上げます。
descriptor.protoのコメントが各値の意味をそのまま説明しています。
// Default pre-EDITION_2024, all UNSET visibility are export.
EXPORT_ALL = 1;
// All top-level symbols default to export, nested default to local.
EXPORT_TOP_LEVEL = 2;
// All symbols default to local.
LOCAL_ALL = 3;
// All symbols local by default. Nested types cannot be exported.
// With special case caveat for message { enum {} reserved 1 to max; }
// This is the recommended setting for new protos.
STRICT = 4;
STRICTで変わるのは3点です — すべてのシンボルがデフォルトでlocalになり、export/localキーワードは最上位のmessage/enum宣言にしか使えず、ネストしたシンボルにこのキーワードを付けると構文エラーになります。LOCAL_ALLとの違いはここにあります。LOCAL_ALLはデフォルトをlocalに変えるだけで、ネストした型をexportとして復活させる余地は残しますが、STRICTはその逃げ道自体をなくします。
ただし逃げ道が完全にないわけではなく、C++の名前空間汚染を避けるために使われてきた慣用句一つにカーブアウトがあります。最上位messageがlocalで、すべてのフィールドがreservedの場合に限り、ネストしたexport enumが許されます。
local message MyNamespaceMessage {
export enum Enum {
MY_VAL = 1;
}
// Ensure no fields are added to the message.
reserved 1 to max;
}
メッセージを純粋な名前空間の器としてしか使わない場合 — フィールドを一つも持たせないとreserved 1 to max;で釘を刺した場合 — だけを見逃す、という意味です。条件がここまで厳しいのは、これが一般的な回避策として使われるのを防ぐ意図に読めます。
この変更の根拠は1-1-1ベストプラクティスです。.protoファイル一つにメッセージ一つとし、そのファイルだけをインポートさせて依存関係の肥大化を防ぐという考え方です。これがなぜサイズの問題になるのかというと、シンボル可視性のドキュメントが説明するとおり、protobufはディスクリプタデータをFileDescriptorSet/FileDescriptor単位でまとめる仕組みになっているため、あるファイル内のすべての定義と、そのファイルがインポートしたものすべてが、丸ごとついてくるからです。
変わるデフォルト値③: enforce_proto_limits — ここが本当の変化です
そしてこれが7月13日の発表文に一言も出てこない機能です。発表文の「Changes to Existing Features」には前の2つしかなく、「New Features」にはenum値のJSONカスタム文字列、C++のnamespaceオプション、C++カスタムオプションの分離、C#のnullable参照型しかありません。ところがv36.0-rc1のdescriptor.protoにはこれが入っています。
message ProtoLimitsFeature {
enum EnforceProtoLimits {
PROTO_LIMITS_UNKNOWN = 0;
// Default pre-EDITION_2026: there are no limit enforcement at the protoc
// level. Practical limits still exist, but they will tend to fail while
// compiling protoc-generated code, and these limits tend to be language
// or toolchain specific.
LEGACY_NO_EXPLICIT_LIMITS = 1;
// A set of limits enforced by Edition 2026 by default. For a detailed
// list of all the limits please consult the Edition 2026 documentation.
PROTO_LIMITS2026 = 2;
}
}
あのコメントの2文目が、この機能が存在する理由のすべてです。上限は元々存在していました。 ただprotocはそれを知らず、そのため失敗は見当違いの場所で起きていました。descriptor.hのコメントはもっと率直です。
// Enforce protobuf limits at the descriptor level. Pre Edition 2026, there
// is no limit enforcement in the protobuf compiler when parsing proto files.
// As a result, it is possible to write a protobuf file that compiles in
// protoc, and code generation works as intended, but the code generation
// output is uncompilable because it runs into language-specific or
// compiler-specific limits.
//
// Starting in Edition 2026, certain limits will start to be enforced. The
// goal of this enforcement is to help ensure that any file that is accepted
// by the protobuf compiler will be compilable on standard tool chains.
void EnforceProtoLimits(bool enforce) { enforce_proto_limits_ = enforce; }
「protocではコンパイルが通り、コード生成も意図どおりに動くのに、生成されたコードのほうがコンパイルできない」という状況。protobufを本格的に運用したことがある人なら、この一文の意味がわかるはずです。enumに値を追加し続けるうち、ある日javacが定数関連のエラーを吐き、それが自分の.protoのせいだと気づくまでにしばらくかかる、あの経験です。
これまでこの上限がどう管理されてきたかを見ると、さらに興味深くなります。protobuf.devにはProto Limitsというドキュメントがあり、その文書は自身をこう紹介しています。
This information is a collection of discovered limitations by many engineers, but is not exhaustive and may be incorrect/outdated in some areas.
つまり多くのエンジニアが痛い目に遭いながら発見したものを集めた文書であり、網羅的でもなければ一部は誤っていたり古かったりする可能性があると自ら認めています。実際、その中の数字はこんな調子です — メッセージあたりのフィールドは65,535個が上限だが、Booleanのような単一フィールドだけのメッセージは「~2100個(proto2)」「~3100個(proto3、optional不使用)」で壊れ、enumは「もっとも低い上限がJavaで~1700個」。チルダ付きの民間伝承です。
Edition 2026はこの民間伝承を、protocが強制する数値に変えます。descriptor.hの定数はこうです。
// Edition 2026 introduces default limits for proto files as the descriptor gets
// built from protoc. To opt out of these limits for edition 2026, you may use
// features.enforce_proto_limits = LEGACY_NO_EXPLICIT_LIMITS.
inline constexpr int kLimit2026FieldsPerMessage = 1500;
inline constexpr int kLimit2026OneofsPerMessage = 1000;
inline constexpr int kLimit2026FieldsPerOneof = 1200;
inline constexpr int kLimit2026ValuesPerEnum = 1700;
この4つの数字は3か所で一致します — 上のヘッダ定数、この機能を追加したコミットメッセージ(2026-05-14付)、そしてFeature Settings for Editionsドキュメントのenforce_proto_limits節。3か所とも同じ値です。
Edition 2024以下 Edition 2026
メッセージあたりフィールド 上限なし(protoc基準) 1500
メッセージあたりoneof 上限なし 1000
oneofあたりフィールド 上限なし 1200
enumあたり値 上限なし 1700
ここで目を引くのはenumの1700です。Proto Limitsドキュメントの言う「Javaで~1700」とぴったり一致する数字です。フィールドの1500も、ドキュメントの「~2100(proto2)」より低く設定されています。つまり新しい上限は適当に決めたキリのいい数字ではなく、実際に壊れる地点より内側に引かれた線のように見えます。(ただし、protobuf側がこの選定根拠を公開文書で明かしているものを、私が確認した範囲では見つけられませんでした。数字が一致するという事実だけが確認済みで、因果関係は推測です。)
そして実務で痛い目を見るポイントが一つ。このオプトアウトはファイル単位ではかけられません。 descriptor.protoでこの機能のtargetsを見ると、ENUM、MESSAGE、FIELD、ONEOFはあってもFILEがありません。
optional ProtoLimitsFeature.EnforceProtoLimits enforce_proto_limits = 9 [
retention = RETENTION_SOURCE,
targets = TARGET_TYPE_ENUM,
targets = TARGET_TYPE_MESSAGE,
targets = TARGET_TYPE_FIELD,
targets = TARGET_TYPE_ONEOF,
feature_support = {
edition_introduced: EDITION_2026
},
...
];
Feature Settingsドキュメントも同じことをコードコメントで述べています — "Must be set at the level of the oversized message, enum, or oneof as this feature is not allowed at the file level."ファイルの先頭に一行書いて丸ごとオフにすることはできず、肥大化したメッセージ・enum・oneofを一つひとつ見つけて個別に付けなければなりません。巨大なレガシースキーマをEdition 2026に上げるとき、これがそのまま作業量になります。
もう一つ。上のfeature_supportのedition_introduced: EDITION_2026は、この機能がEdition 2026より前には設定自体が不可能であることを意味します。前の2つの機能はedition_introduced: EDITION_2024なのでEdition 2024のファイルでも触れますが、サイズ上限の検査は2026に上げて初めて出会えます。前もって試して備える道はありません。
検査はprotocがオンにし、ランタイムはオフのままです
この3つの検査は常に動いているわけではありません。command_line_interface.ccを見ると、protoc CLIが明示的にオンにしています。
descriptor_pool->EnforceSymbolVisibility(true);
descriptor_pool->EnforceNamingStyle(true);
descriptor_pool->EnforceProtoLimits(true);
一方DescriptorPoolのメンバのデフォルト値はオフです — descriptor.hではenforce_proto_limits_ = false;、enforce_symbol_visibility_ = false;と初期化されています。つまり、ランタイムでディスクリプタプールを直接組み立てるコード(動的スキーマ読み込みなど)は、この検査を自動では受けません。これは合理的です — すでにprotocを一度通過して存在しているディスクリプタを、ランタイムでさらに拒否しても得るものがないからです。
そして3つの機能はいずれもretention = RETENTION_SOURCEです。ソース上でのみ意味を持ち、生成されたディスクリプタには載って出てきません。コンパイル時のリントであって、ランタイムの挙動ではありません。
ここで必ず押さえておくべきこと — ワイヤーフォーマットは何一つ変わりません。 エディションはこれまでエンコーディングに手を触れたことがなく、Edition 2026も同じです。フィールド番号とワイヤータイプで回るバイト列はそのままです。本稿のどの内容も、すでにデプロイ済みのサービス間の互換性には影響しません。
新たに入るもの(手短に)
発表文が「New Features」として挙げているものは、おおむね各言語バインディング固有の話です。
- enum値のJSONカスタム文字列。 既存の
json_nameがキー名を変えていたのに対し、今度は値も変えられます —FOO_BAR = 5 [(pb.enumvalue.json).string = "custom_string_here"];。発表文が挙げる理由は衝突回避、移行支援、外部要件の充足です。 - C++の
namespaceオプション。option (pb.file.cpp).namespace = "clock_time";のように、生成バインディングの名前空間を.protoパッケージとは独立に指定できます。 - C++カスタムオプションが
descriptor.protoの外へ。 C++専用オプションが別ファイルに切り出され、import option "google/protobuf/cpp_features.proto";で取り込みます。この節にはrepeated_type = PROXYとRepeatedFieldProxyの話も混ざっていますが、発表文のMarkdownのコードフェンスが壊れており、どの節に属する内容なのか原文だけでは曖昧です。 - C#のnullable参照型。 opt-inで、
v36.0-rc1のリリースノートにも対応項目があります — "Advertise that C# supports Edition 2026, and move C# Nullable Reference Type support into that edition."
正直なトレードオフと限界
まだGAではありません。 今日時点でstableはv35.1であり、v36.0はrc1です。発表文自身がこう釘を刺しています。
These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic.
「着地しないかもしれないし、説明と違うかもしれない。」本稿の数字と挙動はすべてv36.0-rc1タグ時点のものであり、GAで変わる可能性があります。
発表文とコードが食い違っています。 enforce_proto_limitsはコードにもドキュメント(Feature Settings)にもありますが、7月13日の発表文にはありません。発表文だけを読んでEdition 2026を判断すると、最も影響の大きい変更を丸ごと見落とします。逆にFeature Settingsドキュメントのenforce_proto_limitsの例は、「肥大化したメッセージを維持するにはオーバーライドが必要」と書いておきながら、実際にはPROTO_LIMITS2026を設定する(オフにするのではなくオンにする)コードを示しています。ドキュメントが書かれたばかりで粗いのです。規範的な事実はdescriptor.protoのtargets/edition_defaultsで確認するのが安全です。
言語サポートは別途付いてきます。 ここに書いたことの大半はprotocとC++ランタイムの話です。各言語のランタイムがEdition 2026対応を宣言して初めて実際に使えるようになり(C#の項目がリリースノートに別途あるのはそのためです)、サードパーティ実装やprotocを使わないツールチェーンはまったく別の話です。
得られる利益は目に見える種類のものではありません。 この3つの機能のどれも、メッセージを小さくしたりパースを速くしたりはしません。すべてコンパイル時のリントです。得られるのは「後で妙なところで壊れていたはずのものが、今、明確なエラーとして壊れる」ということであり、それに価値を感じるチームもあれば感じないチームもあります。
で、今何をすべきか
大半の場合、今すぐやることはありません。 syntax = "proto2"/syntax = "proto3"を使っているなら、Edition 2026は今日のあなたとは無関係です。descriptor.protoのデフォルト値テーブル上、proto2/proto3/Edition 2023は3つの機能すべてがレガシー値(STYLE_LEGACY、EXPORT_ALL、LEGACY_NO_EXPLICIT_LIMITS)であり、エディションを上げない限りそのままです。急ぐ理由はありません。
すでにEdition 2024を使っていて2026を見据えているなら、順番はこう組むのが妥当です。名前衝突検査はSTYLE2024で、可視性は明示的なexport/local表記で、あらかじめ整理できます。一方サイズ上限は前述のとおり2026より前に試す方法がないので、スキーマに1500フィールドを超えるメッセージや1700値を超えるenumがあるかどうかは、数えてみるしかありません。あれば、それが移行コストの大半を占めることになります — ファイル単位ではオフにできないからです。
Edition 2026に上げる理由はないが検査だけ欲しい場合、おおむね方法がないか、あっても部分的です。これはエディションの設計上、意図された結果です — デフォルトの束を年単位で売るのがエディションだからです。
逆に価値がある場合は明確です。スキーマが大きく、複数言語向けに生成しており、「なぜJavaビルドだけ壊れるのか」を経験したことがある組織。そういう場所では、protocがスキーマを受け入れた瞬間に標準ツールチェーンでコンパイルできる保証は、かなりの価値があります。descriptor.hのコメントが掲げる目標がまさにそれです — "any file that is accepted by the protobuf compiler will be compilable on standard tool chains."
おわりに
Edition 2026は派手なリリースではありません。文法追加はゼロ、ワイヤーフォーマット変更もゼロ、性能改善もゼロです。代わりに3つのデフォルト値を締め付けます — 名前衝突を禁止し、シンボルをデフォルトでlocalにし、スキーマサイズに初めて線を引きます。
そしてそれこそが、エディションという仕組みが本来やろうとしていたことです。proto2/proto3の時代には、「このデフォルトは間違っている」とわかっていても変える方法がありませんでした。変えた瞬間、世界中の.protoが壊れるからです。エディションはデフォルト値を年に紐づけることで、古いファイルは古いデフォルトのままにし、新しいファイルからより良いデフォルトを与える道を作りました。Edition 2026は、その仕組みが実際に回った最初の事例に近いものです — 一度に3つ、それぞれにオプトアウトを付けて、既存のファイルには一切手を触れずに。
いちばん気に入っているのはサイズ上限のほうです。「多くのエンジニアが発見した、網羅的でも正しいとも限らない」wiki的なドキュメントにチルダ付きで書かれていた数字が、コンパイラが強制する4つの定数になりました。民間伝承が仕様になる瞬間は、たいてい静かで、たいていこういう形をしています。
ただし今日時点ではこれはまだRCであり、発表文は自分の機能を一つ欠かしており、ドキュメントの例にはバグがあります。確認はdescriptor.protoでしてください。発表文ではなく。
参考資料
- Changes Announced on July 13, 2026 — Edition 2026の発表 (原文Markdown)
- descriptor.proto @ v36.0-rc1 — Edition enum、
enforce_naming_style、default_symbol_visibility、enforce_proto_limitsのデフォルト値テーブル - descriptor.h @ v36.0-rc1 —
kLimit2026*定数とEnforceProtoLimitsのコメント - code_generator.h @ v36.0-rc1 —
ProtocMaximumEdition() - Feature Settings for Editions — 機能別エディションデフォルト値表
- Symbol Visibility — STRICTの正確なルールとカーブアウト
- Proto Limits — Edition 2026以前の「発見された上限」ドキュメント
- Protocol Buffers v36.0-rc1 リリース(2026-07-09)
- Changes Announced on June 27, 2025 — Edition 2024の発表(トラックレコード比較用)
- gRPC & Protocol Buffers 完全ガイド 2025:マイクロサービス通信の新しい標準(関連記事)
- バイナリシリアライゼーション完全ガイド 2025: Protobuf, Thrift, Avro, MessagePack, FlatBuffers, Cap'n Proto — 性能 vs 柔軟性の選択(関連記事)
현재 단락 (1/187)
2026年7月13日、protobuf.devのニュースページに[Edition 2026の発表](https://protobuf.dev/news/2026-07-13/)が掲載されました。3日前...