2025 年 6 月 27 日宣布的变更

于 2025 年 6 月 27 日宣布的 Protocol Buffers 变更。

2024 版本

我们计划在 2025 年第三季度发布 32.x 版本的 Protobuf 版本 (Editions)。

此处描述的是我们预期将要实施的变更,但由于软件的灵活性,其中一些变更可能不会落地,或者可能与本主题中的描述有所不同。

有关 2024 版本的更多文档将在版本的特性设置中发布,其中包括从 2023 版本迁移的信息。

对现有特性的更改

本节详细介绍在 2024 版本中将更改其默认设置的任何现有特性。

C++ string_type

最初在 2023 版本中发布的 string_type 特性的默认值将从 2024 版本中的 STRING 更改为 VIEW

有关此特性及其特性值的更多信息,请参阅 features.(pb.cpp).string_typeString View API

新特性

本节详细介绍将在 2024 版本中引入的任何新特性。

enforce_naming_style

feature.enforce_naming_style 启用严格的命名样式强制,以确保 proto 默认情况下可以往返转换,并提供一个特性值来选择退出以使用旧版命名样式。

default_symbol_visibility

此特性控制可导入符号(如消息和枚举)的默认符号可见性是

  • export:可通过 import 语句从其他 proto 引用
  • local:在当前文件之外不可引用

2024 版本中的默认特性值 EXPORT_TOP_LEVEL 确保顶层符号默认是导出的,而嵌套符号默认是本地的。

这可以与同样在 2024 版本中添加的 exportlocal 关键字一起使用,以明确注释符号的可见性。

符号可见性仅控制哪些符号可以从其他 proto 文件导入,但不影响代码生成。

C++: enum_name_uses_string_view

以前,所有生成的枚举类型都提供以下函数来从枚举值中获取标签,这在运行时构造 std::string 实例会产生显著开销

const std::string& Foo_Name(int);

2024 版本中的默认特性值将此签名迁移为返回 absl::string_view,以实现更好的存储解耦和潜在的内存/CPU 节省。

absl::string_view Foo_Name(int);

用户应按照迁移指南迁移其代码以处理新的返回类型。

更多信息请参阅String View API

Java: nest_in_file_class

此特性控制 Java 生成器是否将在生成的 Java 文件类中嵌套生成的类。

2024 版本中的默认值是默认在各自的文件中生成类,这也是之前 java_multiple_files = true 文件选项的默认行为。这取代了在 2024 版本中被移除的 java_multiple_files

默认的外部类名也更新为总是驼峰式 (camel-cased) 的 .proto 文件名并以 Proto 为后缀(例如,foo/bar_baz.proto -> BarBazProto)。您可以使用 java_outer_classname 文件选项覆盖此设置,并替换 2024 版本之前的默认值 BarBazBarBazOuterClass(取决于是否存在冲突)。

Java: large_enum

此特性允许创建大型 Java 枚举,突破了 Java 语言对标准常量限制所施加的枚举限制。

默认情况下未启用大型枚举的创建,但您可以使用此特性显式启用它。请注意,此特性复制了类似枚举的行为,但有一些显著差异(例如,不支持 switch 语句)。

语法更改

import option

2024 版本增加了对使用 import option 语法导入选项的支持。

与普通的 import 语句不同,选项导入仅导入在 .proto 文件中定义的自定义选项,而不导入其他符号。

这意味着消息和枚举被排除在选项导入之外。在下面的示例中,Bar 消息不能在 foo.proto 中用作字段类型,但类型为 Bar 的选项仍然可以设置。

选项导入也必须在任何其他 import 语句之后。

示例

// bar.proto
edition = "2024";

import "google/protobuf/descriptor.proto";

message Bar {
  bool bar = 1;
}

extend proto2.FileOptions {
  bool file_opt1 = 5000;
  Bar file_opt2 = 5001;
}
// foo.proto:
edition = "2024";

import option "bar.proto";

option (file_opt1) = true;
option (file_opt2) = {bar: true};

message Foo {
  // Bar bar = 1; // This is not allowed
}

选项导入不需要为其符号生成代码,因此必须在 proto_library 中作为 option_deps 提供,而不是 deps。这样可以避免生成无法访问的代码。

proto_library(
  name = "foo",
  srcs = ["foo.proto"],
  option_deps = [":custom_option"]
)

在导入 protobuf 语言特性和其他自定义选项时,强烈建议使用选项导入和 option_deps,以避免生成不必要的代码。

option_deps 需要 Bazel 8 或更高版本,因为 Bazel 7 中的 native.proto_library 不支持此功能。

这也取代了 import weak,后者在 2024 版本中被移除。

export / local 关键字

exportlocal 关键字在 2024 版本中添加,作为修饰符,用于修改可导入符号的符号可见性,使其不同于 default_symbol_visibility 特性指定的默认行为。

这控制了哪些符号可以从其他 proto 文件导入,但不影响代码生成。

在 2024 版本中,默认情况下可以在所有消息和枚举符号上设置这些关键字。但是,default_symbol_visibility 特性的某些值会进一步限制哪些符号是可导出的。

示例

// Top-level symbols are exported by default in Edition 2024
local message LocalMessage {
  // Nested symbols are local by default in Edition 2024
  export enum ExportedNestedEnum {
    UNKNOWN_EXPORTED_NESTED_ENUM_VALUE = 0;
  }
}

“import weak” 和 weak 字段选项

从 2024 版本开始,不再允许弱导入。

大多数以前依赖 import weak 来声明“弱依赖”以导入自定义选项而无需为 C++ 和 Go 生成代码的用户,应改为迁移到使用 import option

ctype 字段选项

从 2024 版本开始,不再允许使用 ctype 字段选项。请改用 features.(pb.cpp).string_type 特性。

java_multiple_files 文件选项

在 2024 版本中,java_multiple_files 文件选项已被移除,取而代之的是新的 features.nest_in_file_class Java 特性。