News Announcements for Version 30.x

Changes announced for Protocol Buffers version 30.x.

The following announcements are specific to Version 30.x. For information presented chronologically, see News.

The following sections cover planned breaking changes in the v30 release, expected in 2025 Q1. Also included are some changes that aren’t breaking but may require action on your part. These describe changes as we anticipate them being implemented, but due to the flexible nature of software some of these changes may not land or may vary from how they are described in this topic.

Changes in C++

C++ will bump its major version from 5.29.x to 6.30.x.

Descriptor APIs

v30 will update return types in descriptor (such as full_name) to be absl::string_view. This opens up memory savings in descriptors.

v28 introduced the PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE macro, which you can use in the meantime to enable the updated return type ahead of the breaking release. The v30 release will flip the default and remove the macro.

ctype Removed from FieldDescriptor Options

v30 will stop exposing the ctype from FieldDescriptor options. You can use the FieldDescriptor::cpp_string_type() API, added in the v28 release, in its place.

Replace CMake Submodules with Fetched Deps

v30 will remove submodules and switches to upb’s old CMake pattern of fetching dependencies.

If you use installed packages, you won’t be affected. It could break some CMake workflows.

Modify Debug APIs to Redact Sensitive Fields

We are planning to modify the Protobuf debug APIs (including Protobuf AbslStringify, proto2::ShortFormat, proto2::Utf8Format, Message::DebugString, Message::ShortDebugString, Message::Utf8DebugString) in v30 to redact sensitive fields annotated by debug_redact; the outputs of these APIs will contain a per-process randomized prefix, and so will no longer be parseable by Protobuf TextFormat Parsers.

Read more about this in the news article released November 21, 2024.

Removing a a Reflection-related Function

We are removing the following reflection-related function: MutableRepeatedFieldRef<T>::Reserve().

An upcoming performance improvement in RepeatedPtrField is incompatible with this API. The improvement is projected to accelerate repeated access to the elements of RepeatedPtrField, in particular and especially sequential access.

Remove Deprecated APIs

v30 will remove the following public runtime APIs, which have been marked deprecated (such as ABSL_DEPRECATED) for at least one minor or major release and that are obsolete or replaced.

Arena::CreateMessage

API: Arena::CreateMessage

Replacement: Arena::Create

Arena::GetArena

API: Arena::GetArena

Replacement: value->GetArena()

RepeatedPtrField::ClearedCount

API: RepeatedPtrField::ClearedCount

Replacement: Migrate to Arenas (migration guide).

JsonOptions

API: JsonOptions

Replacement: JsonPrintOptions

Dropping C++14 Support

This release will drop C++ 14 as the minimum supported version and raise it to 17, as per the Foundational C++ Support matrix.

Per our policies, we do not consider this to be a breaking change.

Introduce ASAN Poisoning After Clearing Oneof Messages on Arena

This change adds a hardening check that affects C++ protobufs using Arenas. Oneof messages allocated on the protobuf arena will now be cleared in debug and poisoned in ASAN mode. After calling clear, future attempts to use the memory region will cause a crash in ASAN as a use-after-free error.

This implementation requires C++17.

Dropping our C++ CocoaPods release

In v30, we will be dropping our C++ CocoaPods release, which has been broken since v4.x.x. C++ users should use our GitHub release directly instead.

Changes in JRuby

v30 will flip the default implementation for JRuby to FFI, which may be breaking for some JRuby users.

Note that this change doesn’t create a Ruby major version bump because JRuby is not officially supported.

Changes in Python

Python will bump its major version from 5.29.x to 6.30.x.

Dropping Python 3.8 Support

As per our official Python support policy, we will be dropping support for Python 3.8 and lower. This means the minimum supported Python version is 3.9.

Remove bazel/system_python.bzl Alias

v30 will remove the legacy bazel/system_python.bzl alias.

Remove direct references to system_python.bzl in favor of using protobuf_deps.bzl instead. Use python/dist/system_python.bzl where it was moved in v5.27.0 if you need a direct reference.

Field Setter Validation Changes

Python’s and upb’s field setters will be fixed in v30 to validate closed enums under edition 2023. Closed enum fields updated with invalid values will generate errors.

Remove Deprecated py_proto_library Macro

The deprecated internal py_proto_library Bazel macro in protobuf.bzl will be removed in v30.x.

This should be replaced by the official py_proto_library which will be moved to protobuf in bazel/py_proto_library as of v29.x. This implementation was previously available in rules_python prior to v29.x.

Remove Deprecated APIs

v30 will remove the following public runtime APIs, which have been marked deprecated for at least one minor or major release and are obsolete or replaced.

Reflection Methods

APIs: reflection.ParseMessage, reflection.MakeClass

Replacement: message_factory.GetMessageClass()

RPC Service Interfaces

APIs: service.RpcException, service.Service, service.RpcController, and service.RpcChannel

Replacement: Starting with version 2.3.0, RPC implementations should not try to build on these, but should instead provide code generator plugins which generate code specific to the particular RPC implementation.

MessageFactory and SymbolDatabase Methods

APIs: MessageFactory.GetPrototype, MessageFactory.CreatePrototype, MessageFactory.GetMessages, SymbolDatabase.GetPrototype, SymbolDatabase.CreatePrototype, and SymbolDatabase.GetMessages

Replacement: message_factory.GetMessageClass() and message_factory.GetMessageClassesForFiles().

GetDebugString

APIs: GetDebugString

Replacement:

No replacement. It’s only in Python C++ which is no longer released. It is not supported in pure Python or UPB.

Python setdefault Behavior Change for Map Fields

Starting in v30, setdefault will be similar to dict for ScalarMap, except that both key and value must be set. setdefault will be rejected for MessageMaps.

Python Nested Message Class __qualname__ Contains the Outer Message Name

Python nested message class __qualname__ now contains the outer message name. Prior to v30, __qualname__ has the same result with __name__ for nested message, in that the outer message name was not included.

For example:

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

Changes in Objective-C

This will be the first breaking release for Objective-C.

Objective-C will bump its major version from 3.x.x to 4.30.x.

Overhaul Unknown Field Handling APIs Deprecating Most of the Existing APIs

v30 will deprecate GPBUnknownFieldSet and replace it with GPBUnknownFields. The new type will preserve the ordering of unknown fields from the original input or API calls, to ensure any semantic meaning to the ordering is maintained when a message is written back out.

As part of this, the GPBUnknownField type also has its APIs changed, with almost all of the existing APIs becoming deprecated and new ones added.

Deprecated property APIs:

  • varintList
  • fixed32List
  • fixed64List
  • lengthDelimitedList
  • groupList

Deprecated modification APIs:

  • addVarint:
  • addFixed32:
  • addFixed64:
  • addLengthDelimited:
  • addGroup:

Deprecated initializer initWithNumber:.

New property APIs:

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

This type will model a single field number in its value, rather than grouping all the values for a given field number. The APIs for creating new fields are the add* APIs on the GPBUnknownFields class.

v30 will also deprecate -[GPBMessage unknownFields]. In its place, there will be new APIs to extract and update the unknown fields of the message.

Remove Deprecated APIs

v30 will remove the following public runtime APIs, which have been marked deprecated for at least one minor or major release and are obsolete or replaced.

GPBFileDescriptor

API: -[GPBFileDescriptor syntax]

Replacement: Obsolete.

GPBMessage mergeFrom:extensionRegistry

API: -[GPBMessage mergeFrom:extensionRegistry:]

Replacement: -[GPBMessage mergeFrom:extensionRegistry:error:]

GPBDuration timeIntervalSince1970

API: -[GPBDuration timeIntervalSince1970]

Replacement: -[GPBDuration timeInterval]

GPBTextFormatForUnknownFieldSet

API: GPBTextFormatForUnknownFieldSet()

Replacement: Obsolete - Use GPBTextFormatForMessage(), which includes any unknown fields.

GPBUnknownFieldSet

API: GPBUnknownFieldSet

Replacement: GPBUnknownFields

GPBMessage unknownFields

API: GPBMessage unknownFields property

Replacement: -[GPBUnknownFields initFromMessage:], -[GPBMessage mergeUnknownFields:extensionRegistry:error:], and -[GPBMessage clearUnknownFields]

Remove Deprecated Runtime APIs for Old Gencode

This release will remove deprecated runtime methods that support the Objective-C gencode from before the 3.22.x release. The library will also issue a log message at runtime when old generated code is starting up.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

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

Replacement: Regenerate with a current version of the library.

API: -[GPBExtensionDescriptor initWithExtensionDescription:]

Replacement: Regenerate with a current version of the library.

Other Changes

In addition to those breaking changes are some other changes worth noting. While the following are not considered breaking changes, they may still impact users.

Poison Pill Warnings

v30 will update poison pills to emit warnings for old gencode + new runtime combinations that work under the new rolling upgrade policy, but will break in the next major bump. For example, Java 4.x.x gencode should work against 5.x.x runtime but warn of upcoming breakage against 6.x.x runtime.

Changes to UTF-8 Enforcement in C# and Ruby

v30 will includes a fix to make UTF-8 enforcement consistent across languages. Users with bad non-UTF8 data in string fields may see surfaced UTF-8 enforcement errors earlier.

Ruby and PHP Errors in JSON Parsing

v30 fixes non-conformance in JSON parsing of strings in numeric fields per the JSON spec.

This fix will not be accompanied by a major version bump, but Ruby and PHP will now raise errors for non-numeric strings (e.g. “”, “12abc”, “abc”) in numeric fields. v29.x will include a warning for these error cases.