The proto
message A {
SomeMessage text_field = 1;
SomeMessage text = 2;
}
will fail java compilation with a name clash: `method getTextFieldBuilder() is already defined in class...` This is because the `text` field creates a private method (`get{Text}{FieldBuilder}`) which conflicts with the public getter (`get{TextField}{Builder}`) for field 1.
Unlike some name clashes, this one is with a private method and we can just rename the method in this file. Other name clash issues:
- https://github.com/protocolbuffers/protobuf/issues/15411
- https://github.com/protocolbuffers/protobuf/issues/17367
There's some precedent for the `internal` prefix with the protected `internalGetFieldAccessorTable` method on GeneratedMessage.
PiperOrigin-RevId: 694108040
Considering that protobuf depends on absl already, we don't need protobuf's
version of PREDICT_TRUE|FALSE. This CL shrinks port_def.inc.
PiperOrigin-RevId: 694015588
Instead of fetching dependencies by default, we will first look for a local installation and only fetch as a fallback. Two new options are added for forcing either of these behaviors. protobuf_FORCE_FETCH_DEPENDENCIES will always fetch dependencies, and protobuf_PREVENT_FETCH_DEPENDENCIES will never do so.
#test-continuous
PiperOrigin-RevId: 693898394
Packed repeated fields without cached_size use static_cast<int32_t> that may be confused
with bad field names. This change fixes it by using ::int32_t.
PiperOrigin-RevId: 693884622
With C++17 being baseline, PROTOBUF_NODISCARD is no longer necessary. Directly
using [[nodiscard]] makes port_def.inc smaller.
PiperOrigin-RevId: 693808783
Some uses put the `inline` keyword before the attribute, some put it after the
attribute, some didn't put it at all.
Clang is very permissive and it allowed code to work where it breaks in other
compilers. GCC doesn't like if you don't put the keyword, MSVC doesn't like if
the keyword is in the wrong place.
By moving the keyword into the macro we prevent this issue altogether.
PiperOrigin-RevId: 693469310
This CL deletes the per-message C++ functions for operating on repeated fields
and replaces them with functions in the runtime that can work with arbitrary
messages.
Similar to what we did with maps, this required refactoring the code to make it
work with `RepeatedPtrFieldBase`, the untyped base class of
`RepeatedPtrField<T>`. I added a `RustRepeatedMessageHelper` class to allow us
access to the protected methods we need.
This should save a bit of linker input code size, but I think more importantly
we are going to need this eventually to enable tree shaking to work well.
PiperOrigin-RevId: 693394959
I noticed that the use of `unsafe` here was not really necessary, so I tweaked
the code to remove it. If we avoid using `__unstable_leak_raw_message()` then
we don't need to unsafely create a `NonNull`.
PiperOrigin-RevId: 693357956
Allocate extension number 536000000 to Buf
Extension numbers will be allocated one at a time by request.
Once extension declarations are open-sourced for extensions in descriptor.proto, we will move these declarations into a separate config file to declutter descriptor.proto.
PiperOrigin-RevId: 692315472
As an optimization, string fields are initialized with a pointer to a global
immutable std::string instance and create a local std::string only when
"set". If a field has hasbits, it presents a possibility that the hasbit is set
but the string field is still pointing to the global empty string instance.
This can happen, for example, when the field is implicit-presence but hasbit
has been generated for it.
Maintaining an invariant that hasbit is set iff string is nondefault can
simplify the implementation of destructors and message.Clear(). The code would
not need to branch further after scanning hasbits, instead it can always assume
that a local std::string object exists as soon as it sees that the hasbit is
set.
However, this does require an else block in the merge implementation of
implicit-presence string fields. When hasbits are implemented for
implicit-presence string fields, merging from a non-present (i.e. empty) string
field requires a nondefault std::string instance to be created. On the other
hand, branches in Clear() can be eliminated. We think this is the right
tradeoff because:
1. The allocation of nondefault string instance can only happen when the source
proto has hasbit set but the field is empty. This is a relatively rare
scenario.
2. Clear() is called every time a protobuf object is "overwritten" via an
assignment operator or ParseFrom(). This happens probably more frequently than 1.
PiperOrigin-RevId: 691951661
N.B.:
- This change is not intended to affect any well-defined protobuf behaviour in
an observable way.
- The wire parsing codepath is not affected.
- This change only affects the C++ protobuf implementation (other languages are
not affected).
- sizeof proto3 message objects may increase in 32-bit increments to
accommodate hasbits.
- When profiled on some of Google's largest binaries, we have seen a code size
increase of ~0.1%, which we consider to be a reasonable increase.
There are quite a few terminologies in the title:
- **singular**: a field that is not repeated, not oneof, not extension, not lazy,
just a field with a simple primitive type (number or boolean), or
string/bytes.
- **proto3**: describes behaviour consistent to the "proto3" syntax.
This is equivalent to `edition = "2023"` with
`option features.field_presence = IMPLICIT;`.
- **implicit presence**: describes behaviour consistent with "non-optional"
fields in proto3. This is described in more detail in
https://protobuf.dev/programming-guides/field_presence/#presence-in-proto3-apis
This change enables C++ proto3 objects to generate hasbits for regular proto3
(i.e. non-`optional`) fields. This code change might make certain codepaths
negligibly more efficient, but large improvement or regression is unlikely. A
larger performance improvement is expected from generating hasbits for repeated
fields -- this change will pave the way for future work there.
Hasbits in C++ will have slightly different semantics for implicit presence
fields. In the past, all hasbits are true field presence indicators. If the
hasbit is set, the field is guaranteed to be present; if the hasbit is unset,
the field is guaranteed to be missing.
This change introduces a new hasbit mode that I will call "hint hasbits",
denoted by a newly-introduced enum, `internal::cpp::HasbitMode::kHintHasbit`.
For implicit presence fields, it may be possible to mutate the field and have
it end up as a zero field, especially with `mutable_foo` APIs. To handle those
cases correctly, we unconditionally set the hasbit when `mutable_foo` is
called, then we must do an additional check for field emptiness before
serializing the field onto the wire.
PiperOrigin-RevId: 691945237