This change adds `Sized` as a supertrait of our `SealedInternal` trait, to
ensure that our codegen traits cannot be used as trait objects (i.e. with
`dyn`). I was thinking it would be prudent to do this early so that we don't
end up accidentally forced to support `dyn` usage.
Some of the traits already disallowed `dyn` as a result of having `Sized` as an
indirect supertrait or for other reasons, but a few traits did allow trait
objects.
If we ever do want to support some kind of type-erased message, I suspect we
will want to provide our own implementation. At least for C++, we already have
a vtable in the kernel, so it would seem wasteful to have Rust duplicate it.
PiperOrigin-RevId: 692195274
This makes it possible to match views by value:
```rust
expect_that!(
response.clients(),
unordered_elements_are![
proto_eq(proto!(Client { name: "Alice" }).as_view()),
proto_eq(proto!(Client { name: "Bob" }).as_view())
]
);
```
where `clients()` return an iterator over `ClientView` values.
PiperOrigin-RevId: 692192744
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
cpp extension added the API in https://github.com/protocolbuffers/protobuf/pull/7498
Pure python and upb do not support it and filtered out the test
This API does not exists in any other language except C++.
PiperOrigin-RevId: 691870623
.index() is dependent on the order specified in the .proto file.
Minitables create their own ordering, which represent the true index that we're interested in set_alias.
This can be fetched via .layout_index when we have a upb::FieldDefPtr.
PiperOrigin-RevId: 691825782
Export jsoncpp.BUILD. Otherwise the file can't be used from another package.
The problem was detected by Bazel 8 in WORKSPACE mode. This should be cherry-picked to 29. release.
PiperOrigin-RevId: 691587110
At the moment, hpb's public api solely returns Ptr<const Extension>. We'd like to support all non-msg types like int32, int64, bool etc.
These should not return a Ptr<...> but the underlying primitive itself.
We start by adding support for int32 and int64.
PiperOrigin-RevId: 691490444
Export the traits with a `Proto` prefix on them to minimize collisions (especially the high risk of confusing collision with the std prelude's AsMut).
Remove Message, MessageMut and MessageView from the prelude.
PiperOrigin-RevId: 691388401
Because not everything is supported in j2cl and j2objc some of the methods had to be marked as incompatible (reflection , String.format...)
PiperOrigin-RevId: 691368238
Message fields can never have implicit presence, but we have logic in
ClearField that deallocates the message field and reassigns nullptr if the
field is a "proto3" field.
This snippet is the remnants of an old implementation of message field
reflection when proto3 was first introduced (when the initial idea is to use
open structs for everything). During implementation however, we ended up
preserving explicit presence behavior for message fields.
PiperOrigin-RevId: 691199008
These have been moved to subdirectories, and the deleted files were just aliases. The public ones will be removed in a future breaking change.
PiperOrigin-RevId: 691136301