`unsafe trait` means that the _implementation_ has constraints they need to meet for the behavior to be safe (which is the intent here, namely that it should always return the same value and always be a safe to deref value), unsafe on the fn means that the _caller_ of that fn has some constraints they need to meet for it to be safe (of which there are none in this case).
PiperOrigin-RevId: 668028628
These types are effectively two ways to spell the same type, but MapView/MapMut is more terse, especially where the unnamed lifetime was used which can now be implied (`View<'_, Map<K, V>>` can just be `MapView<K,V>`)
PiperOrigin-RevId: 667636945
We were really inconsistent on where we put Private or not and this tries to make a sensible consistent state of:
- For types that are exposed to application code, any pub methods which are only pub so they can be used by gencode (which is mostly anything that has any internal/runtime type anywhere on the parameters or return type list), have those methods have both a `Private` arg and doc(hidden)
- For structs that are only inside __runtime / __internal to begin with, put doc(hidden) on the types, and don't put Private on any of their methods since callers can't reach those types regardless.
Note that for exposed functions which also _accept_ another internal/runtime type in a parameter, the additional `Private` arg is superfluous since application code shouldn't ever be able to reach one of those internal types to be able to pass one in, but this keeps the pattern of keeping Private on it in those cases as well (the `Private` would still be the only guard on methods which only _return_ an internal type).
PiperOrigin-RevId: 667547566
Putting it into BUILD files unintentionally forces it on all our downstream users. Instead, we just want to enable this during testing and let them choose for themselves in their builds.
Note, that this expands the scope of -Werror to our entire repo for CI, so a bunch of fixes and opt-outs had to be applied to get this change passing.
Closed#14714
PiperOrigin-RevId: 666903224
This is useful/necessary when the caller wants to tie the View to a lifetime other than a stack frame, including 'static.
The documentation is clarified that the preexisting one should be preferred in most situations, and only use the new one where tying the View lifetime to a stack frame isn't suitable.
PiperOrigin-RevId: 666396427
Protobuf enums in C++ always have `int` as their backing type, so for the
purpose of use as a map value, we can just treat enums as 32-bit ints. This
allows us to delete the enum-specific generated C++ thunks.
PiperOrigin-RevId: 666043376
This change adds delete, clear, serialize, parse, copy_from, and merge_from
operations to the runtime. Since these operations can all be implemented easily
on the `MessageLite` interface, we can use a common implementation in the
runtime instead of generating per-message thunks for all of these.
I suspect this will also make it possible to remove some of our generated trait
implementations and replace them with blanket implementations, but I will leave
that for a future change.
PiperOrigin-RevId: 665910927
Before all invocations would try to create a library called protobuf_codegen_upb_gen_code. Now it should properly use the name of the crate currently being built.
PiperOrigin-RevId: 658414835
With the C++ kernel for Rust, we currently need to generate quite a few C++
thunks for operations on map fields. For each message we generate, we generate
these thunks for all possible map types that could have that message as a
value. These operations are for things such as insertion, removal, clearing,
iterating, etc.
The reason we do this is that templated types don't play well with FFI, so we
effectively need separate FFI endpoints for every possible combination of key
and value types used (or even potentially used) as a map field.
This CL fixes the problem by replacing the generated thunks with functions in
the runtime that can operate on `proto2::MessageLite*` without needing to care
about the specific message type.
The way it works is that we implement the operations using either
`UntypedMapBase` (the base class of all map types, which knows nothing about
the key and value types) or `KeyMapBase`, which knows the key type but not the
value type. I roughly followed the example of the table-driven parser, which
has a similar problem of needing to operate generically on maps without having
access to the concrete types.
I removed 54 thunks per message (that's 6 key types times 9 operations per
key), but had to add two new thunks per message:
- The `size_info` thunk looks up the `MapNodeSizeInfoT`, which is stored in a
small constant table. The important thing here is an offset indicating where
to look for the value in each map entry. This offset can be different for
every pair of key and value types, but we can safely assume that the result
does not depend on the signedness of the key. As a result we only need to
store four entries per message: one each for i32, i64, bool, and string.
- The `placement_new` thunk move-constructs a message in place. We need this
to be able to efficiently implement map insertion.
There are two big things that this CL does not address yet but which I plan to
follow up on:
- Enums still generate many map-related C++ thunks that could be replaced with
a common implementation. This should actually be much easier to handle than
messages, because every enum has the same representation as an i32.
- We still generate six `ProxiedInMapValue` implementations for every message,
but it should be possible to replace these with a blanket implementation that
works for all message types.
PiperOrigin-RevId: 657681421
The owned and mut interop traits have the corresponding to/from behaviors on cpp but are defined as empty on upb, while the view interop is implemented for both.
PiperOrigin-RevId: 657617187
The purpose of this trait is that it is declared as a supertrait of the traits that we don't want application code to implement (like "Proxied" and "MessageView"); application code can see those traits but not the supertrait, which enables them to use them but not implement them.
PiperOrigin-RevId: 657555025
I also added a blanket implementation of `IntoProxied<T> for T` so that we
don't have to duplicate this no-op implementation for all our types.
PiperOrigin-RevId: 656465755
Distinct from any clear_submsg(), this clears the message contents and doesn't affect presence on parent (and also allows for clearing owned messages which don't exist as a field to be cleared).
PiperOrigin-RevId: 656453234
Adds a new 'bzl' feature that is used to adjust import paths that need to change
in the Cargo build vs Blaze build.
This protobuf rust crate is a single crate that merges all of our current crates (protobuf, rust/upb, and utf8).
PiperOrigin-RevId: 656405153
- We introduce two new view types ProtoStringCow and ProtoBytesCow.
- In UPB, for cord field accessors we always return a Cow::Borrowed.
- In C++, for coed field accessors we check if the underlying absl::Cord is flat (contigous) and if so return a Cow::Borrowed. If it's not flat we copy the data to a ProtoString and return a Cow::Owned.
- We expect the absl::Cord to be flat almost all the time. We have experimentally verified that for small strings (<4 KiB) and less than 6 appends the cord is in fact flat [1].
- This change lifts the requirement of all ViewProxy types to be Copy. Our Cow types cannot be Copy because the owned types aren't copy.
[1] https://source.corp.google.com/piper///depot/google3/experimental/users/buchgr/cords/cords.cc
PiperOrigin-RevId: 655485943
When you have a `T: SomeTrait + ?Sized` and `trait SomeTrait:Sized`, the ?Sized has no effect (its not able to "remove" the requirement).
PiperOrigin-RevId: 654836513
This also changes MessageView and MessageMut to be subtraits of the ViewProxy and MutProxy (which also requires them to have lifetimes now, and a weird extra bounds on ViewProxy)
PiperOrigin-RevId: 654788207
Rather than two traits (MutProxy subtrait of ViewProxy), instead have three traits (MutProxy subtrait of Proxy, and ViewProxy subtrait of Proxy).
This makes things more consistent, including that (MutProxied subtraits Proxied) is now more parallel to (MutProxy subtraits Proxy).
ViewProxy is largely a marker trait here but leaves a spot for methods that should be on ViewProxies but not MutProxies if those do show up later.
PiperOrigin-RevId: 653661953
By changing the return type to `auto`, we can handle `std::string` and other
types in a single definition without needing a separate overload.
PiperOrigin-RevId: 653272253