News Announcements for Version 31.x

Changes announced for Protocol Buffers version 31.x.

The following announcements are specific to Version 31.x, which was released May 14, 2025. For information presented chronologically, see News.

The following sections cover planned breaking changes in the v31 release, expected in 2025 Q2. 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.

Dropping Ruby 3.0 Support

As per our official Ruby support policy, we will be dropping support for Ruby 3.0. The minimum supported Ruby version will be 3.1.

Deprecating Label Enums

We are announcing an upcoming change regarding the FieldDescriptor.label enum and its associated values: FieldDescriptor.LABEL_OPTIONAL, FieldDescriptor.LABEL_REQUIRED, and FieldDescriptor.LABEL_REPEATED. These are being deprecated as we encourage the use of more precise accessor methods.

Background

While at one time the FieldDescriptor.label enum served a purpose, the evolution of Protocol Buffers has introduced more explicit ways to determine a field’s cardinality (singular/repeated) and presence semantics.

  • In proto2, optional, required, and repeated are explicit keywords.
  • In proto3, required is no longer supported. All scalar fields are implicitly “optional” in the sense that they have default values if not set. The optional keyword was later reintroduced in proto3 to explicitly track presence for scalar fields (distinguishing between an unset field and a field set to its default value).
  • In edition 2023 we removed the optional and required keywords and use features to control those behaviors.

The label enum conflates these distinct concepts (cardinality, requiredness, and explicit presence tracking), leading to potential confusion, especially with proto3’s field presence model.

Impact and Migration

The FieldDescriptor.label field will eventually be removed from the API to maintain backward compatibility. Note that the method names in this topic may be spelled slightly differently in some languages.

  • For Protocol Buffer Editions fields:
    • Behavior: The getLabel method will be simplified:
      • It will return FieldDescriptor.LABEL_OPTIONAL for all singular fields.
      • It will return FieldDescriptor.LABEL_REPEATED for all repeated fields.
    • Key Methods for Editions:
      • hasOptionalKeyword will always return false (as the optional keyword’s role in presence is superseded by feature-based presence in Editions).
      • hasPresence becomes the primary method to determine if a singular field tracks presence, reflecting the features.field_presence setting for that field.
    • Migration: Rely on isRepeated for cardinality and hasPresence to check for explicit presence tracking in singular fields.
  • For proto3 fields: getLabel will eventually be removed, and is not recommended in the meantime. Update your code to use hasOptionalKeyword and getRealContainingOneof instead.
  • For proto2 fields: getLabel will continue to reflect LABEL_OPTIONAL, LABEL_REQUIRED, or LABEL_REPEATED as defined in the .proto file for the time being.

All users of Protocol Buffers who interact with FieldDescriptor objects in their code (for example for code generation, reflection, and dynamic message handling) should migrate away from using FieldDescriptor.label directly.

Instead, update your code to use the following methods:

  • To check if a field is repeated: field.isRepeated
  • To check if a field is required (proto2 and editions only): field.isRequired
  • To check if a singular proto3 field has explicit presence, use hasPresence
  • To check if a singular field has explicit presence via a oneof, use hasPresence

Timeline

This deprecation is effective immediately. While getLabel will continue to function, we recommend migrating your code proactively to ensure future compatibility and clarity. This change will lead to a more robust and understandable experience for developers using Protocol Buffers.