CGenerator: Protect against being invoked against "edition" syntax .proto files

The Google protobuf project is currently experimenting with a new syntax
for .proto files called "editions". Since protobuf-c is a proto2/proto3
compiler, after the previous commit reimplementing `FieldSyntax()`, the
protobuf compiler will abort like this if presented with an "editions"
syntax .proto file due to the safety check in `FieldSyntax()`:

    $ protoc --experimental_editions --c_out=. test.proto
    protoc-gen-c: ./protoc-c/c_helpers.h:178: int google::protobuf::compiler::c::FieldSyntax(const google::protobuf::FieldDescriptor*): Assertion `syntax == "proto2" || syntax == "proto3"' failed.
    --c_out: protoc-gen-c: Plugin killed by signal 6.

On protobuf 26, our `CodeGenerator` can implement certain methods to
declare that we "support" editions, and then reject any other edition
except proto2 and proto3, which have apparently been retroactively
declared to be "editions". Of course this needs to be wrapped in a
version guard.

With this protection in place, the protobuf compiler cleanly exits with
a nice error message like this:

    $ protoc --experimental_editions --c_out=. test.proto
    WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
    E0000 00:00:1710988958.296200   20022 descriptor.cc:4620] Invalid proto descriptor for file "test.proto":
    E0000 00:00:1710988958.296239   20022 descriptor.cc:4623]   test.proto: Edition 2023 is later than the maximum supported edition PROTO3
    --c_out: protoc-gen-c: Plugin failed with status code 1.
This commit is contained in:
Robert Edmonds 2024-03-20 22:43:30 -04:00
parent ee3d9e5423
commit 2480f4d9d2

View File

@ -93,6 +93,12 @@ class PROTOC_C_EXPORT CGenerator : public CodeGenerator {
const std::string& parameter, const std::string& parameter,
OutputDirectory* output_directory, OutputDirectory* output_directory,
std::string* error) const; std::string* error) const;
#if GOOGLE_PROTOBUF_VERSION >= 5026000
uint64_t GetSupportedFeatures() const { return CodeGenerator::FEATURE_SUPPORTS_EDITIONS; }
Edition GetMinimumEdition() const { return Edition::EDITION_PROTO2; }
Edition GetMaximumEdition() const { return Edition::EDITION_PROTO3; }
#endif
}; };
} // namespace c } // namespace c