Okay, that makes sense. So basically, my enums won't change their format in
code when they are scoped, but they will behave correctly in C++. Is C++
the only language with the problem? I don't expect to need a C++ parser any
time soon, so if that's the only place where it's a problem today, maybe I
will just make top-level enums now and switch them to scoped when 2026
comes out.

-Max

On Mon, Jan 5, 2026 at 10:04 AM Em Rauch <[email protected]> wrote:

> So how would that look? Like say today I have:
>> message Wrapper {
>>     enum Foo {
>>         UNSPECIFIED = 1;
>>         BAR = 1;
>>     }
>> }
>> Today I would be referring to that as Wrapper::Foo::BAR, IIRC (I haven't
>> done C++ proto in a long time) or Wrapper.Foo.BAR in Python/Java (IIRC?).
>> What does "enum Foo" at the top level look like instead?
>
>
> Scoped enums would actually require no other behavior change in many of
> the languages like Java, as the gencode actually uses a language enum which
> is already scoped anyway. So in Java you're just going to get `Foo.BAR`
> like you want without us having to do much special there.
>
> The C++ case is actually fairly odd today, basically what happens with the
> wrapping type is that there's first an enum which manually prefixes
> everything with the nested scope basically like this (the C++ enum semantic
> is that all of the  constants inside are not scoped by the containing enum)
>
> enum Wrapper_Foo : int {
>    Wrapper_Foo_UNSPECIFIED = 0;
>    Wrapper_Foo_BAR = 1;
> }
>
> And then later the actual message class has `using` statements that expose
> the type and names under that scape, like:
>
> class Wrapper {
>    using Foo = Wrapper_Foo;
>    static constexpr Foo UNSPECIFIED = Wrapper_Foo_UNSPECIFIED;
>    static constexpr Foo BAR = Wrapper_Foo_BAR;
> }
>
> So today it is possible to write the enum type as either `Wrapper_Foo` or
> `Wrapper::Foo`, and possible to name the values as either `Wrapper::BAR` or
> `Wrapper_Foo_Bar`. You can see that this still would have the name
> collisions if you had 2 enums nested in the same message and the value
> names collided, since the values are also 'directly' underneath `Wrapper`
> without any `Foo` in them there.
>
> C++ the language added scoped enums all the way back in C++11 (they look
> like `enum class Foo {}`) so its far overdue for us to be able to have the
> gencode use it there, then we can start to emit it as:
>
> enum class Foo : int {
>    UNSPECIFIED = 0;
>    BAR = 1;
> }
>
> And you can finally write Foo::UNSPECIFIED like you naturally want to.
>
> All that to say, with scoped enums you will want to put them at top level
> instead of synthetically-nested in a message and the 'spelling'  won't
> match. It's also a possibility that we could have some sort of shim
> migration mode to facilitate people trying to incrementally move off the
> nested-message-to-scope-pattern onto proper-scoped-enums but I'm not
> exactly sure what it could look like to be a super smooth migration.
>
> On Mon, Jan 5, 2026 at 9:28 AM Max Kanat-Alexander <[email protected]>
> wrote:
>
>> Ha, thanks Em! Wasn't sure anybody would recognize my name, still. :)
>>
>> Scoped by default sounds good. And I think that timeline would work for
>> me, actually. And for what I'm working on, I can pick any edition I want;
>> it's essentially green-field work where I get to define the format.
>>
>> So how would that look? Like say today I have:
>>
>> message Wrapper {
>>     enum Foo {
>>         UNSPECIFIED = 1;
>>         BAR = 1;
>>     }
>> }
>>
>> Today I would be referring to that as Wrapper::Foo::BAR, IIRC (I haven't
>> done C++ proto in a long time) or Wrapper.Foo.BAR in Python/Java (IIRC?).
>> What does "enum Foo" at the top level look like instead?
>>
>> Basically I'm wondering: if I want to prepare for it now, can I name the
>> empty messages in a particular way that will help me stay
>> forward-compatible.
>>
>> Oh, and prototiller sounds cool. :)
>>
>> -Max
>>
>> On Mon, Jan 5, 2026 at 9:07 AM Em Rauch <[email protected]> wrote:
>>
>>> Always nice to recognize a xoogler name 🙂
>>>
>>> Broadly, the plan is for a future Edition number to have enums be
>>> treated as scoped by default, but with a feature setting that opts back in
>>> to current behavior for people who want to upgrade the Edition number of
>>> preexisting .proto files perfectly-behavior-preserving (behavior-preserving
>>> uprades should be tool assisted with a tool called Prototiller, whose OSS
>>> implementation is unfortunately still not stabilized yet as we are
>>> rewriting it to Go).
>>>
>>> Scoped enums is close to the top of the candidates list for Edition 2026
>>> which is targeted for 2026-Q3, but we don't have any firm commitments
>>> around Edition 2026 details at the moment.
>>>
>>> We don't intend to change the enum behavior on
>>> proto2/proto3/Edition-2023/Edition-2024 files (or even support an option
>>> there to do so), as our forward Editions strategy is to generally treat the
>>> behavior of older syntax IDL inputs as fixed as the way to avoid the
>>> ecosystem problems that come from even adding new options that old
>>> impls/infrastructure won't know about. So unfortunately anyone who plans to
>>> stay on Proto3 forever won't get the new goodness, you'll need to continue
>>> to just wrap each enum in an empty message if you want to avoid the stupid
>>> value name collision problems.
>>>
>>> > Is that actually on a roadmap anywhere? I don't see it in Issues.
>>>
>>> We mostly don't use Issues for tracking our roadmap work, primarily
>>> Issues is for handling external bugs/requests/discussion (unlike gRPC which
>>> has community-driven CNCF governance, Protobuf is still a Google project).
>>> If you want to open it on Issues so you can be notified when it moves
>>> forward, free to open and I'll tag the issue appropriately and we can try
>>> to remember to keep it up to date.
>>>
>>> Thanks!
>>>
>>> On Mon, Jan 5, 2026 at 8:49 AM Max Kanat-Alexander <[email protected]>
>>> wrote:
>>>
>>>> Hey proto team! :) The current docs say that scoped enums will be part
>>>> of a future edition. Is that actually on a roadmap anywhere? I don't see it
>>>> in Issues. I'm mostly just wondering if I should expect it by some vague
>>>> date.
>>>>
>>>> I'm playing around with defining a configuration language based on a
>>>> strict subset of textproto, and scoped enums would help a ton so that users
>>>> could just write `state: ACTIVE` instead of the unintuitive `state:
>>>> STATE_ACTIVE` in their config files. I know that I can accomplish that
>>>> today by nesting enums inside of messages, but what I'm curious about is if
>>>> the future potential implementation of scoped enums will break backwards
>>>> compatibility with that in some way.
>>>>
>>>> -Max
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Protocol Buffers" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to [email protected].
>>>> To view this discussion visit
>>>> https://groups.google.com/d/msgid/protobuf/25fac6eb-2e5f-43e3-bcd2-3ec3df783b56n%40googlegroups.com
>>>> <https://groups.google.com/d/msgid/protobuf/25fac6eb-2e5f-43e3-bcd2-3ec3df783b56n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/protobuf/CACHWaZnJc5BoPuM4cAOg8OchOOTC6s3P4dbJ71%2BiifqW00_qxQ%40mail.gmail.com.

Reply via email to