- 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
Our ASAN test runs have not had the heap checker enabled, so this has allowed a
few memory leaks to slip in. This CL fixes all of them so that we can turn on
the heap checker.
The first one takes place whenever we add an entry into a string-valued map
using the C++ kernel. The problem is that `InnerProtoString::into_raw()` gives
up ownership of the raw `std::string` pointer it holds, but then we never
delete that pointer. This CL fixes the problem by deleting the pointer in C++
right after we perform the map insertion. To simplify things, I created a
`MakeCleanup()` helper function that we always call in our map insertion
thunks, but it's a no-op in the cases where we don't need to free anything.
There were a couple similar memory leaks related to repeated field accessors in
the C++ kernel, and those were simple to fix just by adding the necessary
`delete` call.
Finally, there were two benign memory leaks in the upb kernel involving global
variables used for empty repeated fields and maps. It turned out that we did
not need to use `Box` at all here, so removing that simplified things and fixed
the leaks.
PiperOrigin-RevId: 652947042
General test for it is done in Rust, and then extensions are tested in UPB as they're not currently supported in Rust-upb.
PiperOrigin-RevId: 651113583
Calling into_proxied() already does a copy and before this change we were doing a second one.
I am not using set_allocated_<field(std::string* s) because the method is not generated when [features.(pb.cpp).string_type = VIEW] is specified.
PiperOrigin-RevId: 650612909
* The public Repeated::{push, set} and Map::insert methods now accept any value that implements IntoProxied<T>, allowing us to move owned values instead of copying them.
* This change also updates the FFI layer for strings/bytes in the repeated and maps thunks to accept a std::string* that can be moved rather than a PtrAndLen type that needs to be copied.
* Tests are updated to no longer .as_view() when setting a message / string on a repeated / map field. The IntoProxied trait makes calling .as_view() obsolete.
PiperOrigin-RevId: 650580788
This will mean that calling DebugString on a MessageLite* which is actually a full Message will get the debug info instead of the minimal output.
PiperOrigin-RevId: 649103508
This is currently true and required by the IntoProxied trait. In Rust all type parameters are explicitly marked `Sized`, except for `Self` [1]. By marking `Proxied` as `Sized` we can write `IntoProxied<Self>` in generic code without having to add 'where Self: Sized` clauses.
An implication of this change is that Proxied can no longer be used from a trait object i.e. `let x: dyn &Proxied = &foo` will not compile. We are not anticipating such use cases at this point.
[1] https://doc.rust-lang.org/std/marker/trait.Sized.html
PiperOrigin-RevId: 649010900
Besides unnecessary inconsistency on our C symbols, double underscores anywhere in the name are reserved for stdlib use. In practice its unlikely these symbols would ever hit a collision problem (maybe the prior name 'utf8_debug_string' with no prefix as having some risk), but safer to just standardize on this and have no concerns going forward.
PiperOrigin-RevId: 648709299
`Vec<u8>` is a more idiomatic Rust type to return for serialization.
For the C++ kernel, we are able to return this type with no extra copying. We
still use `SerializedData` type for FFI, but convert the result into a
`Vec<u8>` using a new `into_vec` method.
The upb kernel serializes onto an arena, so for upb we do need to copy the data
to get it into a `Vec<u8>`.
PiperOrigin-RevId: 644444571
New serialization test will verify the amount of bytes it takes to serialize a message with a field of type INT32 set to different values.
PiperOrigin-RevId: 641044189