版本 30.x 的新闻公告

Protocol Buffers 版本 30.x 的公告变更。

以下公告专门针对版本 30.x。有关按时间顺序呈现的信息,请参阅新闻

以下部分涵盖了 v30 版本中计划的破坏性变更,预计于 2025 年第一季度发布。还包括一些非破坏性但可能需要您采取行动的变更。这些描述了我们预期实施的变更,但由于软件的灵活性,其中一些变更可能不会落地,或者可能与本主题中描述的方式有所不同。

C++ 中的变更

C++ 将其主版本从 5.29.x 提升到 6.30.x。

Descriptor API

v30 将更新 descriptor 中的返回类型(例如 full_name)为 absl::string_view。这可以节省 descriptor 的内存。

v28 引入了 PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE 宏,您在此期间可以使用它来在破坏性版本发布前启用更新的返回类型。v30 版本将翻转默认设置并移除该宏。

ctype 从 FieldDescriptor Options 中移除

v30 将停止从 FieldDescriptor 选项中暴露 ctype。您可以改用 v28 版本中添加的 FieldDescriptor::cpp_string_type() API。

将 CMake 子模块替换为 Fetch Deps

v30 将移除子模块,并切换到 upb 旧的 CMake 模式来获取依赖项。

如果您使用已安装的软件包,则不会受到影响。这可能会破坏一些 CMake 工作流程。

修改 Debug API 以隐藏敏感字段

我们计划在 v30 中修改 Protobuf debug API(包括 Protobuf AbslStringify、proto2::ShortFormatproto2::Utf8FormatMessage::DebugStringMessage::ShortDebugStringMessage::Utf8DebugString),以隐藏由 debug_redact 注解的敏感字段;这些 API 的输出将包含一个进程随机前缀,因此将不再能被 Protobuf TextFormat Parsers 解析。

阅读更多关于此信息,请参阅2024 年 11 月 21 日发布的新闻文章

移除一个与 Reflection 相关的功能

我们正在移除以下与 reflection 相关的功能:MutableRepeatedFieldRef<T>::Reserve()

RepeatedPtrField 中即将进行的性能改进与此 API 不兼容。这项改进预计将加速对 RepeatedPtrField 元素重复访问,特别是顺序访问。

移除已弃用的 API

v30 将移除以下已标记为弃用(例如 ABSL_DEPRECATED)至少一个次要或主要版本,且已过时或被替换的公共运行时 API。

Arena::CreateMessage

API: Arena::CreateMessage

替代: Arena::Create

Arena::GetArena

API: Arena::GetArena

替代: value->GetArena()

RepeatedPtrField::ClearedCount

API: RepeatedPtrField::ClearedCount

替代: 迁移到 Arenas(迁移指南)。

JsonOptions

API: JsonOptions

替代: JsonPrintOptions

放弃对 C++14 的支持

根据Foundational C++ 支持矩阵,此版本将放弃 C++ 14 作为最低支持版本,并将其提高到 17。

根据我们的策略,我们不认为这是一个破坏性变更。

在 Arena 上清除 Oneof 消息后引入 ASAN Poisoning

此变更增加了一项强化检查,会影响使用 Arena 的 C++ protobuf。现在,分配在 protobuf arena 上的 Oneof 消息将在 debug 模式下清除,并在 ASAN 模式下 poisoned。调用 clear 后,将来任何尝试使用该内存区域的操作都将在 ASAN 中导致崩溃,表现为 use-after-free 错误。

此实现需要 C++17。

放弃我们的 C++ CocoaPods 发布

在 v30 中,我们将放弃自 v4.x.x 起已损坏的 C++ CocoaPods 发布。C++ 用户应直接使用我们的GitHub 发布代替。

JRuby 中的变更

v30 将把 JRuby 的默认实现翻转为 FFI,这对于一些 JRuby 用户来说可能是破坏性的。

请注意,此变更不会导致 Ruby 主版本升级,因为 JRuby 不受官方支持

Python 中的变更

Python 将其主版本从 5.29.x 提升到 6.30.x。

放弃对 Python 3.8 的支持

根据我们官方的 Python 支持策略,我们将放弃对 Python 3.8 及更低版本的支持。这意味着最低支持的 Python 版本是 3.9。

移除 bazel/system_python.bzl 别名

v30 将移除遗留的 bazel/system_python.bzl 别名。

移除对 system_python.bzl 的直接引用,改为使用 protobuf_deps.bzl。如果需要直接引用,请使用 在 v5.27.0 中移至的 python/dist/system_python.bzl

字段 Setter 验证变更

Python 和 upb 的字段 setter 将在 v30 中修复,以在 2023 版本下验证封闭枚举。使用无效值更新封闭枚举字段将生成错误。

移除已弃用的 py_proto_library 宏

protobuf.bzl 中已弃用的内部 py_proto_library Bazel 宏将在 v30.x 中移除。

这应该被官方的 py_proto_library 替换,该库将在 v29.x 起移至 protobuf 的 bazel/py_proto_library。此实现之前在 v29.x 之前位于 rules_python 中。

移除已弃用的 API

v30 将移除以下已标记为弃用至少一个次要或主要版本,且已过时或被替换的公共运行时 API。

Reflection 方法

API: reflection.ParseMessage, reflection.MakeClass

替代: message_factory.GetMessageClass()

RPC 服务接口

API: service.RpcException, service.Service, service.RpcController, 以及 service.RpcChannel

替代: 从版本 2.3.0 开始,RPC 实现不应试图基于这些构建,而应提供代码生成器插件,生成特定于特定 RPC 实现的代码。

MessageFactory 和 SymbolDatabase 方法

API: MessageFactory.GetPrototype, MessageFactory.CreatePrototype, MessageFactory.GetMessages, SymbolDatabase.GetPrototype, SymbolDatabase.CreatePrototype, 和 SymbolDatabase.GetMessages

替代: message_factory.GetMessageClass()message_factory.GetMessageClassesForFiles()

GetDebugString

API: GetDebugString

替代

没有替代。它只存在于不再发布的 Python C++ 中。纯 Python 或 UPB 中不支持它。

Python setdefault 在 Map 字段上的行为变更

从 v30 开始,ScalarMapsetdefault 将类似于 dict,但必须设置键和值。MessageMaps 将拒绝使用 setdefault

Python 嵌套消息类 __qualname__ 包含外部消息名称

Python 嵌套消息类 __qualname__ 现在包含外部消息名称。在 v30 之前,对于嵌套消息,__qualname____name__ 的结果相同,即不包含外部消息名称。

例如

message Foo {
  message Bar {
    bool bool_field = 1;
  }
}
nested = test_pb2.Foo.Bar()
self.assertEqual('Bar', nested.__class__.__name__)
self.assertEqual('Foo.Bar', nested.__class__.__qualname__) # It was 'Bar' before

Objective-C 中的变更

这将是 Objective-C 的第一个破坏性发布.

Objective-C 将其主版本从 3.x.x 提升到 4.30.x。

大修未知字段处理 API,弃用大多数现有 API

v30 将弃用 GPBUnknownFieldSet,并将其替换为 GPBUnknownFields。新类型将保留原始输入或 API 调用中未知字段的顺序,以确保在将消息写回时保留顺序的任何语义意义。

作为其中的一部分,GPBUnknownField 类型也改变了其 API,几乎所有现有 API 都将被弃用并添加新 API。

已弃用的属性 API

  • varintList
  • fixed32List
  • fixed64List
  • lengthDelimitedList
  • groupList

已弃用的修改 API

  • addVarint
  • addFixed32
  • addFixed64
  • addLengthDelimited
  • addGroup

已弃用的初始化方法 initWithNumber:

新的属性 API

  • type
  • varint
  • fixed32
  • fixed64
  • lengthDelimited
  • group

此类型在其值中建模单个字段编号,而不是 分组 给定字段编号的所有值。创建新字段的 API 是 GPBUnknownFields 类上的 add* API。

v30 也将弃用 -[GPBMessage unknownFields]。取而代之的是新的 API 来提取和更新消息的未知字段。

移除已弃用的 API

v30 将移除以下已标记为弃用至少一个次要或主要版本,且已过时或被替换的公共运行时 API。

GPBFileDescriptor

API: -[GPBFileDescriptor syntax]

替代: 已过时。

GPBMessage mergeFrom:extensionRegistry

API: -[GPBMessage mergeFrom:extensionRegistry:]

替代: -[GPBMessage mergeFrom:extensionRegistry:error:]

GPBDuration timeIntervalSince1970

API: -[GPBDuration timeIntervalSince1970]

替代: -[GPBDuration timeInterval]

GPBTextFormatForUnknownFieldSet

API: GPBTextFormatForUnknownFieldSet()

替代: 已过时 - 使用 GPBTextFormatForMessage(),它包含所有未知字段。

GPBUnknownFieldSet

API: GPBUnknownFieldSet

替代: GPBUnknownFields

GPBMessage unknownFields

API: GPBMessage unknownFields property

替代: -[GPBUnknownFields initFromMessage:], -[GPBMessage mergeUnknownFields:extensionRegistry:error:], 和 -[GPBMessage clearUnknownFields]

移除旧 Gencode 的已弃用运行时 API

此版本将移除支持 3.22.x 版本之前 Objective-C 生成代码的已弃用运行时方法。当旧生成的代码启动时,库还将在运行时发出日志消息。

API: +[GPBFileDescriptor allocDescriptorForClass:file:fields:fieldCount:storageSize:flags:]

替代: 使用当前版本的库重新生成。

API: +[GPBFileDescriptor allocDescriptorForClass:rootClass:file:fields:fieldCount:storageSize:flags:]

替代: 使用当前版本的库重新生成。

API: +[GPBEnumDescriptor allocDescriptorForName:valueNames:values:count:enumVerifier:]

替代: 使用当前版本的库重新生成。

API: +[GPBEnumDescriptor allocDescriptorForName:valueNames:values:count:enumVerifier:extraTextFormatInfo:]

替代: 使用当前版本的库重新生成。

API: -[GPBExtensionDescriptor initWithExtensionDescription:]

替代: 使用当前版本的库重新生成。

其他变更

禁用 MSVC + Bazel

我们将在 v34 中放弃对同时使用 Bazel 和 MSVC 的支持。从 v30 开始,我们将对此组合发出错误提示,除非您指定 opt-out 标志 --define=protobuf_allow_msvc=true 来抑制它。

MSVC 的路径长度限制与 Bazel 的沙盒机制相结合,使得同时支持变得越来越困难。与其随机破坏将 protobuf 安装到长路径的用户,我们将完全禁止从 Bazel 使用 MSVC。我们将继续支持 MSVC 与 CMake 结合使用,并开始支持 clang-cl 与 Bazel 结合使用。如有任何反馈或讨论,请参阅 https://github.com/protocolbuffers/protobuf/issues/20085

其他变更(非破坏性)

除了这些破坏性变更之外,还有一些值得注意的其他变更。虽然以下变更不被视为破坏性变更,但它们可能仍然会影响用户。

Poison Pill 警告

v30 将更新 poison pills,对在新的滚动升级策略下工作但将在 下一个 主版本升级中损坏的旧 gencode + 新运行时组合发出警告。例如,Java 4.x.x gencode 应该可以与 5.x.x 运行时一起工作,但会警告即将与 6.x.x 运行时结合使用时将损坏。

C# 和 Ruby 中 UTF-8 强制执行的变更

v30 将包含一个修复,使 UTF-8 强制执行在不同语言之间保持一致。在字符串字段中包含不良非 UTF-8 数据的用户可能会更早地看到 UTF-8 强制执行错误。

Ruby 和 PHP 在 JSON 解析中的错误

v30 根据JSON 规范修复了 JSON 解析数字字段中字符串的不一致性。

此修复不会伴随主版本升级,但 Ruby 和 PHP 现在将在数字字段中对非数字字符串(例如“”, “12abc”, “abc”)引发错误。v29.x 将包含对这些错误情况的警告。