版本 30.x 的新聞公告

針對 Protocol Buffers 版本 30.x 公告的變更。

以下公告是針對版本 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 將移除下列公用執行階段 API,這些 API 已標示為棄用(例如 ABSL_DEPRECATED)至少一個小版本或主要版本,並且已過時或被取代。

Arena::CreateMessage

API: Arena::CreateMessage

替代: Arena::Create

Arena::GetArena

API: Arena::GetArena

替代: value->GetArena()

RepeatedPtrField::ClearedCount

API: RepeatedPtrField::ClearedCount

替代: 移轉至 Arena(移轉指南)。

JsonOptions

API: JsonOptions

替代: JsonPrintOptions

停止支援 C++14

此版本將停止支援 C++ 14 作為最低支援版本,並將其提升至 17,根據基礎 C++ 支援矩陣

根據我們的政策,我們不認為這是一項重大變更。

在 Arena 上清除 Oneof 訊息後引入 ASAN Poisoning

此變更新增了強化檢查,會影響使用 Arena 的 C++ protobuf。在 protobuf arena 上配置的 Oneof 訊息現在將在除錯模式下清除,並在 ASAN 模式下中毒。在呼叫清除後,未來嘗試使用記憶體區域將會在 ASAN 中造成當機,因為使用了釋放後的記憶體錯誤。

此實作需要 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

欄位設定器驗證變更

Python 和 upb 的欄位設定器將在 v30 中修正,以驗證 2023 版下的封閉列舉。使用無效值更新的封閉列舉欄位將產生錯誤。

移除已棄用的 py_proto_library 巨集

已棄用的內部 py_proto_library Bazel 巨集將在 v30.x 中從 protobuf.bzl 中移除。

這應該由官方 py_proto_library 取代,該巨集將從 v29.x 開始移至 bazel/py_proto_library 中的 protobuf。此實作先前在 v29.x 之前的 rules_python 中提供。

移除已棄用的 API

v30 將移除下列公用執行階段 API,這些 API 已標示為棄用至少一個小版本或主要版本,並且已過時或被取代。

反射方法

API: reflection.ParseMessagereflection.MakeClass

替代: message_factory.GetMessageClass()

RPC 服務介面

API: service.RpcExceptionservice.Serviceservice.RpcControllerservice.RpcChannel

替代: 從 2.3.0 版開始,RPC 實作不應嘗試以此為基礎建置,而應提供程式碼產生器外掛程式,以產生特定於特定 RPC 實作的程式碼。

MessageFactory 和 SymbolDatabase 方法

API: MessageFactory.GetPrototypeMessageFactory.CreatePrototypeMessageFactory.GetMessagesSymbolDatabase.GetPrototypeSymbolDatabase.CreatePrototypeSymbolDatabase.GetMessages

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

GetDebugString

API: GetDebugString

替代

沒有替代方案。它只在不再發行的 Python C++ 中。在純 Python 或 UPB 中不支援。

Python Map 欄位的 setdefault 行為變更

從 v30 開始,setdefault 將類似於 ScalarMapdict,只是必須同時設定鍵和值。將拒絕 MessageMapssetdefault

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: +[GPBEnumDescriptor allocDescriptorForName:valueNames:values:count:enumVerifier:extraTextFormatInfo:]

替代方案: 使用最新版本的函式庫重新產生。

API: -[GPBExtensionDescriptor initWithExtensionDescription:]

替代方案: 使用最新版本的函式庫重新產生。

其他變更

除了這些重大變更之外,還有一些其他值得注意的變更。雖然以下變更不被視為重大變更,但仍可能影響使用者。

Poison Pill 警告

v30 版本將更新 poison pill 以針對在新的滾動升級原則下可運作,但在下一個主要版本中會中斷的舊 gencode + 新執行階段組合發出警告。例如,Java 4.x.x gencode 應可與 5.x.x 執行階段搭配運作,但會警告即將與 6.x.x 執行階段中斷。

C# 和 Ruby 中 UTF-8 強制執行的變更

v30 版本將包含修復程式,以使 UTF-8 強制執行在各種語言中保持一致。在字串欄位中有不良的非 UTF-8 資料的使用者可能會更早看到浮現的 UTF-8 強制執行錯誤。

JSON 剖析中的 Ruby 和 PHP 錯誤

v30 版本修正了 JSON 字串在數值欄位中解析時,不符合 JSON 規格 的問題。

此修正程式不會伴隨主要版本升級,但 Ruby 和 PHP 現在會針對數值欄位中的非數值字串(例如「」、「12abc」、「abc」)引發錯誤。v29.x 版本將包含這些錯誤情況的警告。