Before this fix, the overload resolution rules would accidentally attempt to call the accessor named clear() instead of the fn that would actually clear the message (Rust automatically prefers an inherent impl fn over a trait impl fn if both exist with the same name).
PiperOrigin-RevId: 713309633
The unnecessary [< >] around the ident in that specific macro expansion makes it the name as a literal which would then later be reparsed back into an ident, which makes it lose the r# in the process and break.
PiperOrigin-RevId: 712562736
This was disabled because it couldn't pass with the upb C generated accessors. Now that we only use the upb minitables, this can be safely enabled.
PiperOrigin-RevId: 712560415
While in general Proto enum numbers are more of arbitary wire tag numbers, sometimes the ordering is used for semantic meaning, and this allows for the enums to be used in things that require ordering eg BTreeMap.
Rust defaults to language enums _not_ being Ord with the derive(Ord) opt in, but it is largely for reasons which don't apply to protobuf enums.
PiperOrigin-RevId: 709831238
Before this change, the way it works is that we emit one .rs file per input .proto file, and a multi-src proto_library are handled by considering the first file as specially the 'primary' one which specially re-exports everything defined in other files.
After this change, we instead emit the .rs file per .proto file equally, and then we additionally emit a generated.rs file which re-exports all of them.
PiperOrigin-RevId: 707569226
The specific format is something which you could more easily copy-paste back into a test, either:
`SomeEnumName::CorrespondingNamedConstant` or
`SomeEnumName::from(someint)` for open enums with an unrecognized value.
For now this is emitting the string literals for the names in a generated match statement in .rs; this makes it work for both cpp and upb kernels, as well as hopefully reduces bloat if there is no cross-language lto.
At a future time we could consider calling into C++ to get the enum names there, which is a more optimized path and could reduce having the names in the binary twice in some cases.
PiperOrigin-RevId: 705910092
This change updates the generated code to always prefix the names of crates
with `::` so that they can't conflict with local modules. I'm not aware of this
being an issue for anyone yet, but figured we might as well fix it proactively.
PiperOrigin-RevId: 703122266
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
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
This required making a shim file for a crate to be able to re-export either the _cpp or _upb impl so that it can be one crate that conditionally delegates to the intended one.
PiperOrigin-RevId: 688639897
There is an old convention that a `proto_library` target with empty `srcs`
should re-export its dependencies. This is sometimes useful as a way of
creating something like an alias target, except that it can point to multiple
dependencies rather than just one.
The `rust_proto_library` aspect currently cannot handle this pattern and will
raise an error if it encounters a `proto_library` without `srcs`. This CL fixes
that problem by updating the `RustProtoInfo` provider generated by the aspect
to include a list of `DepVariantInfo` instead of just one. In the typical case
the provider will have just one `DepVariantInfo`, but this gives us the ability
to return more than one in the case where we're exporting all the dependencies
of a `src`-less `proto_library`.
One thing this CL specifically does not attempt to do is add support for a
`rust_proto_library` directly wrapping a `proto_library` without `srcs`. The
reason for that is that it appears difficult to do in a way that would respect
the layering check. It's also not obvious that we would want to encourage this
pattern anyway. It's still valuable to support `src`-less `proto_library`
targets when they're somewhere else in the transitive dependencies. This way
you can freely create a `rust_proto_library` without having to fix up all your
transitive deps first.
PiperOrigin-RevId: 687344284
The immediate motivation for this is that it will facilitate writing a blanket
implementation of `ProxiedInMapValue` for C++-backed messages. The default
instance gives us access to the message vtable in cases where we don't already
have a message to work with.
However, it also seems generally useful just to have an implementation of
`Default`, so I implemented it for both C++ and upb-backed message views.
PiperOrigin-RevId: 677808048
This CL doesn't unbreak the bazel tests, but is yak shaving in prep for changes that will. This makes it more straightforward how the tests are broken by having bazel test rules name rust proto library targets that don't exist in bazel repo, instead of naming targets that do exist but are bogus.
Also correct unittest_edition target to match the order of words in the .proto file name (edition_unittest)
PiperOrigin-RevId: 674295376
This version works where both sides are the same message, messageview or messagemut type, but not any mix of them (e.g. cannot compare a message against its corresponding view).
PiperOrigin-RevId: 671091099
This simplifies upb by removing differences between google3 and OSS.
This also points upb at the protobuf license, instead of keeping a separate copy around for upb.
PiperOrigin-RevId: 669447145
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
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
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