2025 年 6 月 27 日宣布的变更

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

2024 版本

我们计划在 2025 年第三季度于 32.x 版本中发布 Protobuf 2024 版本。

本文描述了我们预期的变更实现,但由于软件的灵活性,其中一些变更可能不会落地,或者可能与本文中的描述有所不同。

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

现有特性的变更

本节详细介绍了在 2024 版本中默认设置将发生变化的任何现有特性。

C++ string_type

string_type 特性最初在 2023 版本中发布,其默认值将在 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 语句不同,import option 仅导入在 .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 版本开始,不再允许弱导入(Weak imports)。

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

ctype 字段选项

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

java_multiple_files 文件选项

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