Changes Announced on July 14, 2025

Changes announced for Protocol Buffers on July 14, 2025.

Deprecating FieldDescriptor Enums

We are announcing an upcoming change regarding the FieldDescriptor enum and its associated values representing optional, required, and 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 idiomatic 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.

Note that the method names in this topic may be spelled slightly differently in some languages.

  • For Protocol Buffer Editions fields:
    • Key Methods for 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 and isRequired for cardinality and hasPresence to check for explicit presence tracking in singular fields.
  • For proto2/proto3 fields: getLabel will eventually be removed, and is not recommended in the meantime.

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 field has explicit presence, 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.