Some versions of gcc seem to advertise __cpp_nontype_template_args but not
support the argument in some cases.
Only attempt the template parameter if we are using the optimized .reloc
approach.
Fixes https://github.com/protocolbuffers/protobuf/issues/16868
PiperOrigin-RevId: 634787159
# Changes
Remove dead code path -- we don't allow enums to be map keys ([proto2 spec](https://protobuf.dev/programming-guides/proto2/#maps), [proto3 spec](https://protobuf.dev/programming-guides/proto3/#maps)). In other words the case block `case FieldDescriptor::TYPE_ENUM` is dead code. Potential enum type keys will be caught in `default: return lex.Invalid("unsupported map key type");` block below similar to other unsupported map key types like double.
# Motivation
While working on fixing `IgnoreUnknownEnumStringValueInMap` conformance tests for cpp ([related issue](https://github.com/protocolbuffers/protobuf/issues/7392)) I stumbled upon a bug where we pass the wrong `field` parameter to the enum parsing function.
In this scope:
* the variable `field` is a map field of the message that holds the map. This field is not of enum type, it's a repeated message of map entires.
* the variable `key_field` is the key field of the map message entry. This field is the enum type that we need to parse here.
The function is long, so I clarified it here:
```cpp
template <typename Traits>
absl::Status ParseMap(JsonLexer& lex, Field<Traits> field, Msg<Traits>& msg) {
(..)
return lex.VisitObject(
[&](LocationWith<MaybeOwnedString>& key) -> absl::Status {
(..)
return Traits::NewMsg(
field, msg,
[&](const Desc<Traits>& type, Msg<Traits>& entry) -> absl::Status {
auto key_field = Traits::KeyField(type);
switch (Traits::FieldType(key_field)) {
(..)
case FieldDescriptor::TYPE_ENUM: {
MaybeOwnedString key_str = key.value;
auto e = ParseEnumFromStr<Traits>(lex, key_str, /** bug here **/ field);
```
The correct reference should be `key_field`.
Instead of fixing the bug and leaving the dead code, it's better to remove the dead block alltogether.
Closes#16567
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/16567 from noom:anton--7392--fix-map-key-nit d992b8a2a6
PiperOrigin-RevId: 634516984
This is an edge case we can't handle properly today. Rather than allowing poorly defined behavior, we'll make this an error condition until we can actually support it. In the future, it may be necessary to upgrade feature files to newer editions.
Closes#16756
PiperOrigin-RevId: 634512378
enabled.
DownCastToGenerated injects the strong reference to T, which makes all instances of CheckTypeAndMergeFrom unique and not candidates for identical code folding.
The strong reference is not needed here in the member function.
PiperOrigin-RevId: 634033477
It is not sufficient to check schema_.HasHasbits() followed by naively skipping
repeated and oneof fields as that can miss proto3 messages with message fields
and other scalar fields without "optional" keyword.
Use internal::cpp::HasHasbits(const FieldDescriptor*) instead.
PiperOrigin-RevId: 633633184
The new functions work even when RTTI is not present.
Also, add an assertion in DownCast to make sure we don't use it for message types. Message types have dedicated cast functions that should be used instead.
PiperOrigin-RevId: 633236522
This prevents shadowing of `java.lang` package commonly used in protobuf gencode. Existing extensions named `java` may or may not previously fail to compile depending on if the contents of their .proto result in gencode using `java.lang`. This is needed to fix `java_features.proto` lite gencode since enum gencode uses `java.lang`. Fields named `java` should already be escaped.
*Warning: This may break user code for existing protos with extensions named `java`. References to the extension should be renamed to use `java_` e.g. registry.add(GeneratedClassName.java_)*
PiperOrigin-RevId: 632508249
The previous change claimed to do this in addition to `true` and `false`, but it was not actually in the code.
To reiterate the text from the earlier change, now actually reflected entirely in the code:
> The identifiers `true`, `false`, and `null` are effectively reserved words in Java, although for some reason they are listed separately from the "keywords" in the Java Language Specification.
>
> This doesn't matter for regular fields, because a proto field called `true` will be accessed with `getTrue` and `setTrue`. But for extensions, the generated Java code will have a public static field whose name is the same as the name of the extension field, with `_` appended if the name is a reserved word. Previously there was no `_` for `true` etc, so the generated code would not compile.
This change should not affect any existing client code in Java. If someone had tried to use an extension called `true` (etc), they would have found that the generated proto code did not compile. Now it is possible to reference such an extension as `true_`.
PiperOrigin-RevId: 632174190
instead of Reflection. This allows using these functions instead of
`dynamic_cast` for all generated types including LITE.
PiperOrigin-RevId: 632135009
The identifiers `true`, `false`, and `null` are effectively reserved words in Java, although for some reason they are listed separately from the "keywords" in the Java Language Specification.
This doesn't matter for regular fields, because a proto field called `true` will be accessed with `getTrue` and `setTrue`. But for extensions, the generated Java code will have a public static field whose name is the same as the name of the extension field, with `_` appended if the name is a reserved word. Previously there was no `_` for `true` etc, so the generated code would not compile.
PiperOrigin-RevId: 631599695
We modify set_<repeated_field> to accept the IntoProxied type as the value and move the value (avoid copying) whenever possible.
For UPB:
- We fuse the arena of Repeated<T> with the parent message arena.
- We use upb_Message_SetBaseField to set the upb_Array contained in the Repeated<T>.
For C++:
- We generate an additional setter thunk that moves the value.
- The move assignment operator of RepeatedField/RepeatedPtrField is specialized. In order to adhere to the layering check we need to add '#include' statements for all .proto imports to the generated thunks.pb.cc.
PiperOrigin-RevId: 631010333
This is equivalent to C++'s `_IsValid` functions. Since proto3 enums are open,
`is_known` seems to be a better name than the misleading `is_valid`.
C++-specific Protocol Buffers documentation already uses "known fields" and
"unknown enum values" expressions.
PiperOrigin-RevId: 630344180
Previously, we would allocate a boxed Integer when accessing repeated enums, because we used ArrayList<Integer>, which must box the int.
Use IntArrayList and the primitive "int getInt()" method instead.
PiperOrigin-RevId: 630229119
Instead of checking the resolved features, we should really be checking the has_presence helper. Repeated fields, oneofs, and extensions can trigger these conditions when they inherit IMPLICIT, even though it's ignored.
Closes#16664
PiperOrigin-RevId: 630206208
Map fields should remain length-prefixed for now, even if DELIMITED is inherited. Field presence will remain unchanged, but unit-tests are added to make sure proto2/proto3 behaviors stay consistent.
Closes#16549
PiperOrigin-RevId: 630191163
This can cause ODR violations in downstream users who link against both the bootstrapped proto and transitive C++ gencode of java_features.proto. Once protoc is split up, we can turn the bootstrapped proto into a real cc_proto_library target and avoid this problem altogether.
PiperOrigin-RevId: 630099889
Instead of _builder.getFoo() and _builder.setFoo(value), the generated code now uses _builder.foo and _builder.foo = value. When compiling against the Java Proto API, this makes no difference, since the Kotlin compiler treats Java methods getFoo/setFoo as defining a Kotlin property foo. But if a compatible proto API is implemented in Kotlin then there is no such equivalence. Such an implementation would have to define either both forms or just the one that the DSL uses. For a Kotlin API it is more natural to use properties.
Similarly, the generated Java methods getFoosList(), getFoosCount(), getFoosMap(), and getEnumValue() are accessed via property names (foosList, foosCount, foosMap, enumValue).
(This is the second application of this change. The first had to be rolled back because it didn't handle conflict-resolution names correctly.)
PiperOrigin-RevId: 629807104