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
We can use memset for zero initialized objects, and memcpy for ones cloned from the prototype.
This permits creating objects from the parser without calling virtual functions.
For the cases where the efficient implementation can't be used, we generate a "placement new" style function to offload the memory allocation out of the code generation. This reduces code bloat even when we can't use the more efficient implementation.
Migrate many callers of `New` and similar to the new functionality. In particular, the parsing paths will use this.
Finally, make `New` non-virtual now that `MessageLite` can handle it directly. It reduces binary size.
PiperOrigin-RevId: 665411723
Our bootstrapping setup compiles multiple versions of the generated code for `descriptor.proto` and `plugin.proto`, one for each stage of the bootstrap. For source files (`.c`), we can always select the correct version of the file in the BUILD rules, but for header files we need to make sure the correct stage's file is always selected via `#include`.
Previously we used `cc_library(includes=[])` to make it appear as though our bootstrapped headers had the same names as the "real" headers. This allowed a lot of the code to be agnostic to whether a bootstrap header was being used, which simplified things because we did not have to change the code performing the `#include`.
Unfortunately, due to build system limitations, this sometimes led to the incorrect header getting included. This should not have been possible, because we had a clean BUILD graph that should have removed all ambiguity about which header should be available. But in non-sandboxed builds, the compiler was able to find headers that were not actually in `deps=[]`, and worse it preferred those headers over the headers that actually were in `deps=[]`. This led to unintended results and errors about layering check violations.
This CL fixes the problem by removing all use of `includes=[]`. We now spell a full pathname to all bootstrap headers, so this class of errors is no longer possible. Unfortunately this adds some complexity, as we have to hard-code these full paths in several places.
A nice improvement in this CL is that `bootstrap_upb_proto_library()` can now only be used for bootstrapping; it only exposes the `descriptor_bootstrap.h` / `plugin_bootstrap.h` files. Anyone wanting to use the normal `net/proto2/proto/descriptor.upb.h` file should depend on `//net/proto2/proto:descriptor_upb_c_proto` target instead.
PiperOrigin-RevId: 664953196
Using `field.full_name()` instead of constructing a thunk name based on the containing_type makes little difference for normal fields, but it will actually be unique for extension fields, whereas the prior approach would break if an extension field name and a regular field collided (or if 2 extensions for the same message had field names that collided).
PiperOrigin-RevId: 664910530
This builds off of our existing pattern for unused imports. We will still warn when any deprecated features are used in a proto file passed directly to protoc, but will avoid them in the following situations:
1) Transitive imports pulled from the filesystem or descriptors will not trigger warnings. This will keep warnings isolated to the upstream builds instead of alerting all downstream clients.
2) Dynamic pool builds will not log deprecation warnings by default.
PiperOrigin-RevId: 663396953
SerializeToString and SerializeToCord, for example, exercise codepaths that are
actually quite different, but a user would be reasonable to expect that strings
and cords are largely plug-and-play substitutable.
The templating around TYPED_TEST can eventually make it easy to add coverage
for other types as well, for example streams.
PiperOrigin-RevId: 661427989
Put the emission of braces and indentation into MayEmitIfNonDefaultCheck, this
allows for a slight beautification in the emitted code and reduces verbosity at
the call site.
Also this technically fixes the indent in some cases (specifically when
serializing some repeated fields) so that the opening braces are emitted "at
the right level".
(Previous implementations sometimes emit an extra space character.)
Compare:
{
// code ...
}
vs.
{
// code ...
}
PiperOrigin-RevId: 660236451
The arena and the heap representation are both aligned to 8 bytes so we can use the lowest 3 bits of the heap pointer to encode whether the RepeatedField is in SOO mode or not, and if it is in SOO mode, to record the size. Therefore, we can have SOO sizes from 0 to 3 and one bit for whether we're in SOO mode. Note that we also tried using 3 bits for SOO size with a sentinel value for not-SOO-mode, but that was slower.
PiperOrigin-RevId: 659578775
By "string APIs", I mean the following APIs:
- mutable_foo
- set_allocated_foo
- release_foo
See also: https://protobuf.dev/reference/cpp/cpp-generated/#implicit-string
Add the following test cases (for singular implicit-presence fields):
- A single call to mutable_foo() should not result in additional serialization
on the wire.
- Assigning an empty string to mutable_foo() should not result in additional
serialization on the wire.
- Calling set_allocated_foo() with an empty string should not result in
additional serialization on the wire.
- If a field is nonempty, release_foo() effectively clears the field (while
returning a pointer to the original data).
Adding coverage for these behaviours can increase confidence when we introduce
internal hasbits to help with presence tracking for implicit presence fields.
mutable_foo will in general set the hasbit, so the generated code will need to
check that field is nonempty before serializing.
PiperOrigin-RevId: 658562530