diff --git a/pkg/BUILD.bazel b/pkg/BUILD.bazel index 25513f5c08..89a46bf4be 100644 --- a/pkg/BUILD.bazel +++ b/pkg/BUILD.bazel @@ -386,6 +386,7 @@ cc_dist_library( "//src/google/protobuf/compiler/php", "//src/google/protobuf/compiler/python", "//src/google/protobuf/compiler/ruby", + "//src/google/protobuf/compiler/rust", ], dist_deps = [ ":protobuf", diff --git a/src/google/protobuf/compiler/BUILD.bazel b/src/google/protobuf/compiler/BUILD.bazel index cfbf714870..b1b544cede 100644 --- a/src/google/protobuf/compiler/BUILD.bazel +++ b/src/google/protobuf/compiler/BUILD.bazel @@ -115,6 +115,7 @@ cc_library( "//src/google/protobuf/compiler/php", "//src/google/protobuf/compiler/python", "//src/google/protobuf/compiler/ruby", + "//src/google/protobuf/compiler/rust", "@com_google_absl//absl/log:initialize", ], ) diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index ea9adfb1e3..f5a064b80d 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -39,6 +39,7 @@ #include "google/protobuf/compiler/python/generator.h" #include "google/protobuf/compiler/python/pyi_generator.h" #include "google/protobuf/compiler/ruby/ruby_generator.h" +#include "google/protobuf/compiler/rust/generator.h" // Must be included last. #include "google/protobuf/port_def.inc" @@ -112,6 +113,10 @@ int ProtobufMain(int argc, char* argv[]) { cli.RegisterGenerator("--objc_out", "--objc_opt", &objc_generator, "Generate Objective-C header and source."); + // Rust + rust::RustGenerator rust_generator; + cli.RegisterGenerator("--rust_out", &rust_generator, + "Generate Rust sources."); return cli.Run(argc, argv); } diff --git a/src/google/protobuf/compiler/rust/BUILD.bazel b/src/google/protobuf/compiler/rust/BUILD.bazel index 2a26dd5b62..faddffc6ed 100644 --- a/src/google/protobuf/compiler/rust/BUILD.bazel +++ b/src/google/protobuf/compiler/rust/BUILD.bazel @@ -7,6 +7,7 @@ load("//build_defs:cpp_opts.bzl", "COPTS") cc_library( name = "rust", + srcs = ["generator.cc"], hdrs = ["generator.h"], copts = COPTS, include_prefix = "google/protobuf/compiler/rust", diff --git a/src/google/protobuf/compiler/rust/generator.cc b/src/google/protobuf/compiler/rust/generator.cc new file mode 100644 index 0000000000..b9e7ccbc14 --- /dev/null +++ b/src/google/protobuf/compiler/rust/generator.cc @@ -0,0 +1,87 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "google/protobuf/compiler/rust/generator.h" + +#include +#include +#include + +#include "absl/algorithm/container.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/io/printer.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace rust { + +bool ExperimentalRustGeneratorEnabled( + const std::vector>& options) { + static constexpr std::pair kMagicValue = + {"experimental-codegen", "enabled"}; + + return absl::c_any_of( + options, [](std::pair pair) { + return pair == kMagicValue; + }); +} + +bool RustGenerator::Generate(const FileDescriptor* file, + const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const { + std::vector> options; + ParseGeneratorParameter(parameter, &options); + + if (!ExperimentalRustGeneratorEnabled(options)) { + *error = + "The Rust codegen is highly experimental. Future versions will break " + "existing code. Use at your own risk. You can opt-in by passing " + "'experimental-codegen=enabled' to '--rust_out'."; + return false; + } + + auto basename = StripProto(file->name()); + auto outfile = absl::WrapUnique( + generator_context->Open(absl::StrCat(basename, ".pb.rs"))); + + google::protobuf::io::Printer(outfile.get()).Emit(R"cc( + // TODO: Generate Bindings + )cc"); + return true; +} + +} // namespace rust +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/rust/generator.h b/src/google/protobuf/compiler/rust/generator.h index a01c6aead3..2d08bb68e7 100644 --- a/src/google/protobuf/compiler/rust/generator.h +++ b/src/google/protobuf/compiler/rust/generator.h @@ -33,7 +33,6 @@ #include -#include "absl/log/absl_check.h" #include "google/protobuf/compiler/code_generator.h" // Must be included last. @@ -53,10 +52,7 @@ class RustGenerator final : public google::protobuf::compiler::CodeGenerator { bool Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* generator_context, - std::string* error) const override { - ABSL_CHECK(false) << "not yet implemented"; - return false; - } + std::string* error) const override; uint64_t GetSupportedFeatures() const override { return FEATURE_PROTO3_OPTIONAL;