Add support for proto dependencies to rust_proto_library

PiperOrigin-RevId: 514719215
pull/12054/head
Marcel Hlopko 2 years ago committed by Copybara-Service
parent edb4da6eaa
commit 26af540a7a
  1. 1
      rust/BUILD
  2. 3
      rust/defs.bzl
  3. 33
      rust/test/BUILD
  4. 40
      rust/test/child.proto
  5. 37
      rust/test/child_parent_test.rs
  6. 35
      rust/test/parent.proto
  7. 33
      rust/test/rust_proto_library_unit_test/child.proto
  8. 33
      rust/test/rust_proto_library_unit_test/parent.proto
  9. 34
      rust/test/rust_proto_library_unit_test/rust_proto_library_unit_test.bzl
  10. 25
      src/google/protobuf/compiler/rust/generator.cc

@ -1,6 +1,7 @@
# Protobuf Rust runtime packages. # Protobuf Rust runtime packages.
load("@rules_rust//rust:defs.bzl", "rust_library") load("@rules_rust//rust:defs.bzl", "rust_library")
load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain")
package(default_visibility = ["//src/google/protobuf:__subpackages__"]) package(default_visibility = ["//src/google/protobuf:__subpackages__"])

@ -155,12 +155,13 @@ def _rust_proto_aspect_impl(target, ctx):
build_info = None, build_info = None,
) )
proto_dep = getattr(ctx.rule.attr, "deps", [])
dep_variant_info = _compile_rust( dep_variant_info = _compile_rust(
ctx = ctx, ctx = ctx,
attr = ctx.rule.attr, attr = ctx.rule.attr,
src = gencode[0], src = gencode[0],
extra_srcs = gencode[1:], extra_srcs = gencode[1:],
deps = [dep_variant_info_for_runtime], deps = [dep_variant_info_for_runtime] + ([proto_dep[0][RustProtoInfo].dep_variant_info] if proto_dep else []),
) )
return [RustProtoInfo( return [RustProtoInfo(
dep_variant_info = dep_variant_info, dep_variant_info = dep_variant_info,

@ -14,3 +14,36 @@ rust_test(
tags = ["not_build:arm"], tags = ["not_build:arm"],
deps = [":hello_world_rs_proto"], deps = [":hello_world_rs_proto"],
) )
proto_library(
name = "parent_proto",
srcs = ["parent.proto"],
)
proto_library(
name = "child_proto",
srcs = ["child.proto"],
exports = [":parent_proto"],
deps = [":parent_proto"],
)
rust_proto_library(
name = "parent_rs_proto",
deps = [":parent_proto"],
)
rust_proto_library(
name = "child_rs_proto",
deps = [":child_proto"],
)
rust_test(
name = "child_parent_test",
srcs = ["child_parent_test.rs"],
# TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
tags = ["not_build:arm"],
deps = [
":child_rs_proto",
":parent_rs_proto",
],
)

@ -0,0 +1,40 @@
// 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.
syntax = "proto2";
package third_party_protobuf_rust_test;
// copybara:strip_begin(Replace import path for Bazel)
import public "google/protobuf/rust/test/parent.proto";
// copybara:strip_end_and_replace import public "rust/test/parent.proto";
message Child {}

@ -0,0 +1,37 @@
// 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.
fn main() {
let _child = child_proto::Child {};
let _parent = parent_proto::Parent {};
// Parent from child_proto crate should be the same type as Parent from
// parent_proto crate.
let _parent_from_child: child_proto::Parent = parent_proto::Parent {};
}

@ -0,0 +1,35 @@
// 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.
syntax = "proto2";
package third_party_protobuf_rust_test;
message Parent {}

@ -0,0 +1,33 @@
// 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.
syntax = "proto2";
package third_party_protobuf_rust_test_rust_proto_library_unit_test;

@ -0,0 +1,33 @@
// 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.
syntax = "proto2";
package third_party_protobuf_rust_test_rust_proto_library_unit_test;

@ -21,6 +21,8 @@ def _find_rust_lib_input(inputs, target_name):
)) ))
return input[0] return input[0]
####################################################################################################
def _rust_compilation_action_has_runtime_as_input_test_impl(ctx): def _rust_compilation_action_has_runtime_as_input_test_impl(ctx):
env = analysistest.begin(ctx) env = analysistest.begin(ctx)
target_under_test = analysistest.target_under_test(env) target_under_test = analysistest.target_under_test(env)
@ -46,16 +48,48 @@ def _test_rust_compilation_action_has_runtime_as_input():
tags = ["not_build:arm"], tags = ["not_build:arm"],
) )
####################################################################################################
def _rust_compilation_action_has_deps_as_inputs_test_impl(ctx):
env = analysistest.begin(ctx)
target_under_test = analysistest.target_under_test(env)
actions = target_under_test[ActionsInfo].actions
rustc_action = _find_action_with_mnemonic(actions, "Rustc")
_find_rust_lib_input(rustc_action.inputs, "parent")
return analysistest.end(env)
rust_compilation_action_has_deps_as_input_test = analysistest.make(
_rust_compilation_action_has_deps_as_inputs_test_impl,
)
def _test_rust_compilation_action_has_deps_as_input():
native.proto_library(name = "parent_proto", srcs = ["parent.proto"])
native.proto_library(name = "child_proto", srcs = ["child.proto"], deps = [":parent_proto"])
attach_aspect(name = "child_proto_with_aspect", dep = ":child_proto")
rust_compilation_action_has_deps_as_input_test(
name = "rust_compilation_action_has_deps_as_input_test",
target_under_test = ":child_proto_with_aspect",
# TODO(b/270274576): Enable testing on arm once we have a Rust Arm toolchain.
tags = ["not_build:arm"],
)
####################################################################################################
def rust_proto_library_unit_test(name): def rust_proto_library_unit_test(name):
"""Sets up rust_proto_library_unit_test test suite. """Sets up rust_proto_library_unit_test test suite.
Args: Args:
name: name of the test suite""" name: name of the test suite"""
_test_rust_compilation_action_has_runtime_as_input() _test_rust_compilation_action_has_runtime_as_input()
_test_rust_compilation_action_has_deps_as_input()
native.test_suite( native.test_suite(
name = name, name = name,
tests = [ tests = [
":rust_compilation_action_has_runtime_as_input_test", ":rust_compilation_action_has_runtime_as_input_test",
":rust_compilation_action_has_deps_as_input_test",
], ],
) )

@ -36,6 +36,7 @@
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.h"
#include "google/protobuf/io/printer.h" #include "google/protobuf/io/printer.h"
@ -56,6 +57,15 @@ bool ExperimentalRustGeneratorEnabled(
}); });
} }
std::string get_crate_name(const FileDescriptor* dependency) {
absl::string_view path = dependency->name();
auto basename = path.substr(path.rfind('/') + 1);
return absl::StrReplaceAll(basename, {
{".", "_"},
{"-", "_"},
});
}
bool RustGenerator::Generate(const FileDescriptor* file, bool RustGenerator::Generate(const FileDescriptor* file,
const std::string& parameter, const std::string& parameter,
GeneratorContext* generator_context, GeneratorContext* generator_context,
@ -88,6 +98,21 @@ bool RustGenerator::Generate(const FileDescriptor* file,
pub struct $Msg$ {} pub struct $Msg$ {}
)rs"); )rs");
} }
// TODO(b/270124215): Delete the following "placeholder impl" of `import
// public`. Also make sure to figure out how to map FileDescriptor#name to
// Rust crate names (currently Bazel labels).
for (int i = 0; i < file->public_dependency_count(); ++i) {
const FileDescriptor* dep = file->public_dependency(i);
std::string crate_name = get_crate_name(dep);
for (int j = 0; j < dep->message_type_count(); ++j) {
// TODO(b/270138878): Implement real logic
p.Emit(
{{"crate", crate_name}, {"type_name", dep->message_type(j)->name()}},
R"rs(
pub use $crate$::$type_name$;
)rs");
}
}
return true; return true;
} }

Loading…
Cancel
Save