版本 30.x 的新闻公告
以下公告仅针对 2025 年 3 月 4 日发布的 30.x 版本。有关按时间顺序排列的信息,请参阅新闻。
以下各节涵盖了计划在 2025 年第一季度发布的 v30 版本中的破坏性变更。其中还包括一些非破坏性但可能需要您采取行动的变更。这些描述了我们预期的变更实现方式,但由于软件的灵活性,其中一些变更可能不会落地,或者可能与本主题中的描述有所不同。
C++ 中的变更
C++ 的主版本将从 5.29.x 升级到 6.30.x。
描述符 API
v30 将更新描述符中(例如 full_name
)的返回类型为 absl::string_view
。这可以在描述符中节省内存。
v28 引入了 PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE
宏,您可以在此期间使用它来在破坏性发布之前启用更新后的返回类型。v30 版本将反转默认设置并移除该宏。
ctype 从 FieldDescriptor 选项中移除
v30 将停止从 FieldDescriptor
选项中公开 ctype
。您可以使用 v28 版本中添加的 FieldDescriptor::cpp_string_type()
API 来替代它。
使用获取的依赖项替换 CMake 子模块
v30 将移除子模块,并切换到 upb 旧的获取依赖项的 CMake 模式。
如果您使用已安装的包,则不会受到影响。这可能会破坏某些 CMake 工作流。
修改调试 API 以隐藏敏感字段
我们计划在 v30 中修改 Protobuf 调试 API(包括 Protobuf AbslStringify、proto2::ShortFormat
、proto2::Utf8Format
、Message::DebugString
、Message::ShortDebugString
、Message::Utf8DebugString
),以隐藏由 debug_redact
注解的敏感字段;这些 API 的输出将包含一个每个进程随机化的前缀,因此将不再能被 Protobuf TextFormat 解析器解析。
请阅读 2024 年 11 月 21 日发布的新闻文章了解更多信息。
移除一个与反射相关的函数
我们将移除以下与反射相关的函数:MutableRepeatedFieldRef<T>::Reserve()
。
即将对 RepeatedPtrField
进行的性能改进与此 API 不兼容。该改进预计将加速对 RepeatedPtrField
元素的重复访问,尤其特别是顺序访问。
移除已弃用的 API
v30 将移除以下公共运行时 API,这些 API 至少在一个次要或主要版本中已被标记为已弃用(例如 ABSL_DEPRECATED
),并且已经过时或被取代。
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
根据 基础 C++ 支持矩阵,此版本将停止支持 C++ 14 作为最低支持版本,并将其提高到 17。
根据我们的政策,我们不认为这是一个破坏性变更。
在 Arena 上清除 Oneof 消息后引入 ASAN 中毒
此变更添加了一个强化检查,影响使用 Arenas 的 C++ protobuf。在 protobuf arena 上分配的 Oneof 消息现在将在调试模式下被清除,并在 ASAN 模式下被中毒。调用 clear 后,将来尝试使用该内存区域将在 ASAN 中导致崩溃,作为 use-after-free 错误。
此实现需要 C++17。
放弃 C++ CocoaPods 发布
在 v30 中,我们将放弃我们的 C++ CocoaPods 发布,该发布自 v4.x.x 以来一直处于损坏状态。C++ 用户应直接使用我们的 GitHub release。
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
。
字段设置器验证变更
在 v30 中,Python 和 upb 的字段设置器将被修复,以在 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,这些 API 至少在一个次要或主要版本中已被标记为已弃用,并且已经过时或被取代。
反射方法
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 map 字段的 setdefault 行为变更
从 v30 开始,setdefault
对于 ScalarMap
将类似于 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,这些 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
属性
替代方案: -[GPBUnknownFields initFromMessage:
]、-[GPBMessage mergeUnknownFields:extensionRegistry:error:
] 和 -[GPBMessage clearUnknownFields
]
移除已弃用的旧版 Gencode 运行时 API
此版本将移除支持 3.22.x 版本之前 Objective-C gencode 的已弃用运行时方法。当旧的生成代码启动时,该库还将在运行时发出一条日志消息。
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: -[GPBExtensionDescriptor initWithExtensionDescription:]
替代方案: 使用当前版本的库重新生成。
其他变更
停用 MSVC + Bazel
我们将在 v34 中停止支持将 Bazel 和 MSVC 一起使用。从 v30 开始,我们将使用错误来毒化这种组合,除非您指定退出标志 --define=protobuf_allow_msvc=true
来消除它。
MSVC 的路径长度限制与 Bazel 的沙箱相结合,越来越难以支持。与其随机地让将 protobuf 安装到长路径中的用户中断,我们将完全禁止从 Bazel 使用 MSVC。我们将继续支持 CMake 与 MSVC,并开始支持 clang-cl 与 Bazel。有关任何反馈或讨论,请参阅 https://github.com/protocolbuffers/protobuf/issues/20085。
其他变更(非破坏性)
除了这些破坏性变更之外,还有一些其他值得注意的变更。虽然以下内容不被视为破坏性变更,但它们仍可能影响用户。
毒丸警告
v30 将更新毒丸,为在新的滚动升级策略下工作的旧 gencode + 新运行时组合发出警告,但会在*下一次*主版本升级中中断。例如,Java 4.x.x gencode 应该能与 5.x.x 运行时一起工作,但会警告即将与 6.x.x 运行时发生的中断。
C# 和 Ruby 中 UTF-8 强制执行的变更
v30 包含一个修复,使 UTF-8 强制执行在不同语言之间保持一致。在字符串字段中有错误的非 UTF8 数据的用户可能会更早地看到浮现的 UTF-8 强制执行错误。
Ruby 和 PHP 在 JSON 解析中的错误
v30 修复了根据 JSON 规范在解析数字字段中的字符串时的不一致性。
此修复不会伴随主版本升级,但 Ruby 和 PHP 现在将对数字字段中的非数字字符串(例如“”、“12abc”、“abc”)引发错误。v29.x 将包含针对这些错误情况的警告。