The ultimate effect of this change will be that both the native flags and Starlark flags will continue to work with future versions of Bazel that lack the proto fragment, until such time as we deprecate or remove the flags in a Protobuf release. This decouples Bazel releases from Protobuf behavior changes.
1. Builds on the Bazel 8-compatible abstraction layer we submitted in cl/955468205 by setting `HAS_NATIVE_PROTO_FLAGS` properly in Bazel. We do this by adding a `rules.has_proto_fragment` setting to the `proto_bazel_features.bzl` mechanism: we know that the fragment no longer needs to be read in Bazel 9+, because we can use `flag_alias()` instead.
2. Adds `flag_alias()` declarations in MODULE.bazel for all compat layer flags. This will work in Bazel 9, but is ignored in Bazel 8.
This leads to a slight inconsistency. Consider the following set of flags set by a user:
```
--@protobuf//bazel/flags:protocopt=foo --protocopt=bar
```
In Bazel 9+, where the flag alias is respected, the final value of the flag will be `bar`. In Bazel 8, where we emulate `flag_alias()` by reconciling the two different values at analysis time, we always prefer the Starlark version (and cannot tell the relative order), so the final value of the flag will be `foo`.
To avoid this, prefer setting the Starlark version of the flag whenever possible.
PiperOrigin-RevId: 970834999
When trying to land https://github.com/protocolbuffers/protobuf/pull/28957, I ran into problems with the `@com_google_protobuf_previous_release` repo. The root cause of these problems was that this repo combines a previous version of all of our `.bzl` files (like `proto_library.bzl`) with the *current* version of our `MODULE.bazel` file.
This is a combination that no user will actually encounter, and when skew between the two causes issues, it is very difficult to debug and fix.
If we want to re-introduce these breaking change tests in the future, an alternative approach that would cause fewer problems is to use the examples module at https://github.com/protocolbuffers/protobuf/tree/main/examples. That module could include previous versions of the `.proto` files, as well as the breaking change tests to compare against the protos in `@com_google_protobuf`.
Since the examples module does not contain a copy of all our `.bzl` files, this design would avoid the `.bzl` skew that causes problems in the current setup.
PiperOrigin-RevId: 970790688
When constructing the custom JSON enum name map in C# JsonParser, remove the
ContainsKey check so that subsequent aliased enum values overwrite earlier ones,
aligning with the "last match wins" semantics used across C++, Java, PHP, and Python.
PiperOrigin-RevId: 970656172
This implementation is similar to our Java idea in cl/949670944,
basically the idea is that we will have a local map (dictionary) that
will be populated the very first time we try to parse into an enum
field. The lifetime of this dictionary will be tied to the Parser
instance, similar to the Java implementation.
BENCHMARKS (baseline stats are recorded at cl/952170250):
Python:
```
[BENCHMARK] ParseJsonDefault: med 10.06 us/op | p99 11.22 us/op | mean 10.10 ± 0.20 us/op
[BENCHMARK] ParseJsonCustom: med 20.33 us/op | p99 22.23 us/op | mean 20.40 ± 0.34 us/op
[BENCHMARK] ParseJsonUnknownIgnored: med 24.21 us/op | p99 26.25 us/op | mean 24.31 ± 0.44 us/op
[BENCHMARK] ParseRepeatedJsonDefault: med 1.94 us/item | p99 2.05 us/item | mean 1.95 ± 0.03 us/item
[BENCHMARK] ParseRepeatedJsonCustom: med 2.26 us/item | p99 2.45 us/item | mean 2.27 ± 0.03 us/item
[BENCHMARK] ParseRepeatedJsonUnknownIgnored: med 5.31 us/item | p99 5.52 us/item | mean 5.32 ± 0.05 us/item
```
Cpp:
```
[BENCHMARK] ParseJsonDefault: med 8.66 us/op | p99 9.21 us/op | mean 8.70 ± 0.13 us/op
[BENCHMARK] ParseJsonCustom: med 26.33 us/op | p99 29.71 us/op | mean 26.44 ± 0.69 us/op
[BENCHMARK] ParseJsonUnknownIgnored: med 28.46 us/op | p99 31.80 us/op | mean 28.59 ± 0.67 us/op
[BENCHMARK] ParseRepeatedJsonDefault: med 1.72 us/item | p99 2.19 us/item | mean 1.74 ± 0.06 us/item
[BENCHMARK] ParseRepeatedJsonCustom: med 2.12 us/item | p99 2.38 us/item | mean 2.13 ± 0.04 us/item
[BENCHMARK] ParseRepeatedJsonUnknownIgnored: med 4.61 us/item | p99 4.92 us/item | mean 4.62 ± 0.07 us/item
```
UPB:
```
[BENCHMARK] ParseJsonDefault: med 11.22 us/op | p99 12.29 us/op | mean 11.27 ± 0.21 us/op
[BENCHMARK] ParseJsonCustom: med 37.54 us/op | p99 39.25 us/op | mean 37.65 ± 0.46 us/op
[BENCHMARK] ParseJsonUnknownIgnored: med 41.18 us/op | p99 48.45 us/op | mean 41.30 ± 0.89 us/op
[BENCHMARK] ParseRepeatedJsonDefault: med 2.10 us/item | p99 2.19 us/item | mean 2.10 ± 0.02 us/item
[BENCHMARK] ParseRepeatedJsonCustom: med 2.58 us/item | p99 2.73 us/item | mean 2.59 ± 0.03 us/item
[BENCHMARK] ParseRepeatedJsonUnknownIgnored: med 5.70 us/item | p99 5.90 us/item | mean 5.71 ± 0.04 us/item
```
Seeing these benchmarks, we can see a very noticeable improvement in
`ParseRepeatedJsonCustom` and `ParseRepeatedJsonUnknownIgnored` cases --
which correspond to the pathological cases that we are worried about.
Singular fields are taking longer to parse in our microbenchmark because
the cache that we've added is tied to each Parser instance and must be
re-instantiated across every `Parse` call.
PiperOrigin-RevId: 970528683
Use Class.cast instead of unchecked casts to eliminate @SuppressWarnings("unchecked") in TextFormat.parse overloads.
Shouldn't be a performance problem - this is only available in full runtime (not android) where hotspot has a class.cast intrinsic (and text proto parsing is relatively slow anyway, this won't be the bottleneck).
PiperOrigin-RevId: 970171466
Use Collection<?> for the sizing check to eliminate unchecked cast warning and narrow @SuppressWarnings("unchecked") to the specific ProtobufList fast-path assignment.
PiperOrigin-RevId: 970165037
In AbstractMessageLite.toByteArray(), check if getSerializedSize() == 0 and return Internal.EMPTY_BYTE_ARRAY directly instead of allocating a new 0-byte array and CodedOutputStream wrappers.
PiperOrigin-RevId: 970010400
Use Class.cast instead of an unchecked generic cast to avoid compiler warnings and ensure runtime type safety.
Not a big deal but a nice opportunity to remove a warning.
This is only used in the full runtime AFAIK, where hotspot has an intrinsic for Class.cast so shouldn't be a performance issue.
PiperOrigin-RevId: 969794451
This change moves internal helper methods (PlacementNew_, InternalNewImpl_, and InternalGenerateClassData_) from the main message class into a nested `Helpers_` struct.
PiperOrigin-RevId: 967513868
Several functions in upb marked with UPB_NODISCARD had their return values ignored in test and wrapper call sites.
Check and assert the return values of upb_Message_SetString, upb_Message_SetInt32, upb_ExtensionRegistry_AddArray, _upb_Message_AddUnknown, upb_Array_New, and _upb_Array_ResizeUninitialized across upb and protobuf tests and wrappers.
PiperOrigin-RevId: 967461770
This moves `InternalGenerateParseTable_` to the nested `_Internals` class, which is only defined in `.pb.cc`, and renames it to `GenerateParseTable` (now that the `Internal` would be redundant).
PiperOrigin-RevId: 967383875