Generate `pub use` for imported enums

PiperOrigin-RevId: 596762218
pull/15324/head
Alyssa Haroldsen 1 year ago committed by Copybara-Service
parent 17b0f3f6a4
commit 1eab5a0237
  1. 6
      rust/test/BUILD
  2. 7
      rust/test/nested.proto
  3. 13
      rust/test/no_package.proto
  4. 11
      rust/test/no_package_import.proto
  5. 11
      rust/test/no_package_other.proto
  6. 4
      rust/test/package.proto
  7. 4
      rust/test/package_import.proto
  8. 4
      rust/test/package_other.proto
  9. 4
      rust/test/package_other_different.proto
  10. 8
      rust/test/shared/BUILD
  11. 9
      rust/test/shared/nested_types_test.rs
  12. 37
      rust/test/shared/package_test.rs
  13. 11
      rust/test/shared/simple_nested_test.rs
  14. 43
      src/google/protobuf/compiler/rust/generator.cc

@ -236,6 +236,7 @@ proto_library(
name = "no_package_import_proto",
testonly = True,
srcs = ["no_package_import.proto"],
deps = ["//devtools/staticanalysis/pipeline/analyzers/proto_best_practices/proto:optouts_proto"],
)
proto_library(
@ -246,7 +247,10 @@ proto_library(
"no_package_other.proto",
],
exports = [":no_package_import_proto"],
deps = [":no_package_import_proto"],
deps = [
":no_package_import_proto",
"//devtools/staticanalysis/pipeline/analyzers/proto_best_practices/proto:optouts_proto",
],
)
cc_proto_library(

@ -38,6 +38,10 @@ message Outer {
message CantBelieveItsSoInner {
optional int32 num = 99;
}
enum JustWayTooInner {
JUST_WAY_TOO_INNER_UNSPECIFIED = 0;
}
}
}
}
@ -46,6 +50,9 @@ message Outer {
optional .nest.Outer.Inner.SuperInner.DuperInner.EvenMoreInner
.CantBelieveItsSoInner deep = 2;
optional .nest.Outer.Inner.SuperInner.DuperInner.EvenMoreInner.JustWayTooInner
deep_enum = 4;
optional NotInside notinside = 3;
}

@ -7,8 +7,17 @@
syntax = "proto2";
// package intentionally left unspecified.
import public "google/protobuf/rust/test/no_package_import.proto";
import "devtools/staticanalysis/pipeline/analyzers/proto_best_practices/proto/optouts.proto";
option (proto_best_practices.file_optouts) = {
// package intentionally left unspecified.
categories: GLOBAL_PACKAGE
};
message MsgWithoutPackage {}
enum EnumWithoutPackage {
ENUM_WITHOUT_PACKAGE_UNSPECIFIED = 0;
}

@ -7,6 +7,15 @@
syntax = "proto2";
// package intentionally left unspecified.
import "devtools/staticanalysis/pipeline/analyzers/proto_best_practices/proto/optouts.proto";
option (proto_best_practices.file_optouts) = {
// package intentionally left unspecified.
categories: GLOBAL_PACKAGE
};
message ImportedMsgWithoutPackage {}
enum ImportedEnumWithoutPackage {
IMPORTED_ENUM_WITHOUT_PACKAGE_UNSPECIFIED = 0;
}

@ -7,6 +7,15 @@
syntax = "proto2";
// package intentionally left unspecified.
import "devtools/staticanalysis/pipeline/analyzers/proto_best_practices/proto/optouts.proto";
option (proto_best_practices.file_optouts) = {
// package intentionally left unspecified.
categories: GLOBAL_PACKAGE
};
message OtherMsgWithoutPackage {}
enum OtherEnumWithoutPackage {
OTHER_ENUM_WITHOUT_PACKAGE_UNSPECIFIED = 0;
}

@ -12,3 +12,7 @@ package testing_packages;
import public "google/protobuf/rust/test/package_import.proto";
message MsgWithPackage {}
enum EnumWithPackage {
ENUM_WITH_PACKAGE_UNSPECIFIED = 0;
}

@ -10,3 +10,7 @@ syntax = "proto2";
package testing_packages;
message ImportedMsgWithPackage {}
enum ImportedEnumWithPackage {
IMPORTED_ENUM_WITH_PACKAGE_UNSPECIFIED = 0;
}

@ -10,3 +10,7 @@ syntax = "proto2";
package testing_packages;
message OtherMsgWithPackage {}
enum OtherEnumWithPackage {
OTHER_ENUM_WITH_PACKAGE_UNSPECIFIED = 0;
}

@ -10,3 +10,7 @@ syntax = "proto2";
package testing_other_packages;
message OtherMsgInDifferentPackage {}
enum OtherEnumInDifferentPackage {
OTHER_ENUM_IN_DIFFERENT_PACKAGE_UNSPECIFIED = 0;
}

@ -187,8 +187,8 @@ rust_test(
)
rust_test(
name = "nested_messages_cpp_test",
srcs = ["nested_messages_test.rs"],
name = "nested_types_cpp_test",
srcs = ["nested_types_test.rs"],
tags = [
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
"not_build:arm",
@ -197,8 +197,8 @@ rust_test(
)
rust_test(
name = "nested_messages_upb_test",
srcs = ["nested_messages_test.rs"],
name = "nested_types_upb_test",
srcs = ["nested_types_test.rs"],
tags = [
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
"not_build:arm",

@ -5,7 +5,7 @@
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
/// Tests covering nested messages.
//! Tests covering nested types.
#[test]
fn test_nested_messages_accessible() {
@ -14,3 +14,10 @@ fn test_nested_messages_accessible() {
unittest_proto::proto2_unittest::TestChildExtensionData_::
NestedTestAllExtensionsData_::NestedDynamicExtensions::new();
}
#[test]
fn test_nested_enums_accessible() {
let _parent: unittest_proto::proto2_unittest::TestAllTypes;
let _child: unittest_proto::proto2_unittest::TestAllTypes_::NestedEnum;
unittest_proto::proto2_unittest::TestDynamicExtensions_::DynamicEnumType::default();
}

@ -5,23 +5,42 @@
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
/// Tests covering proto packages.
//! Tests covering proto packages.
#[test]
fn test_packages() {
fn test_message_packages() {
// empty package, message declared in the first .proto source
let _foo: no_package_proto::MsgWithoutPackage;
let _: no_package_proto::MsgWithoutPackage;
// empty package, message declared in other .proto source
let _foo: no_package_proto::OtherMsgWithoutPackage;
let _: no_package_proto::OtherMsgWithoutPackage;
// empty package, import public of a message
let _foo: no_package_proto::ImportedMsgWithoutPackage;
let _: no_package_proto::ImportedMsgWithoutPackage;
// package, message declared in the first .proto source
let _foo: package_proto::testing_packages::MsgWithPackage;
let _: package_proto::testing_packages::MsgWithPackage;
// package, message declared in the other .proto source with the same package
let _foo: package_proto::testing_packages::OtherMsgWithPackage;
let _: package_proto::testing_packages::OtherMsgWithPackage;
// package, message declared in the other .proto source with a different package
let _foo: package_proto::testing_other_packages::OtherMsgInDifferentPackage;
let _: package_proto::testing_other_packages::OtherMsgInDifferentPackage;
// package, import public of a message
let _foo: package_proto::testing_packages::ImportedMsgWithPackage;
let _: package_proto::testing_packages::ImportedMsgWithPackage;
}
#[test]
fn test_enum_packages() {
// empty package, enum declared in the first .proto source
let _: no_package_proto::EnumWithoutPackage;
// empty package, enum declared in other .proto source
let _: no_package_proto::OtherEnumWithoutPackage;
// empty package, import public of a enum
let _: no_package_proto::ImportedEnumWithoutPackage;
// package, enum declared in the first .proto source
let _: package_proto::testing_packages::EnumWithPackage;
// package, enum declared in the other .proto source with the same package
let _: package_proto::testing_packages::OtherEnumWithPackage;
// package, enum declared in the other .proto source with a different package
let _: package_proto::testing_other_packages::OtherEnumInDifferentPackage;
// package, import public of a enum
let _: package_proto::testing_packages::ImportedEnumWithPackage;
}

@ -11,7 +11,7 @@ use nested_proto::nest::Outer_::InnerMut;
use nested_proto::nest::Outer_::InnerView;
#[test]
fn test_deeply_nested_definition() {
fn test_deeply_nested_message() {
let deep = nested_proto::nest::Outer_::Inner_::SuperInner_::DuperInner_::EvenMoreInner_
::CantBelieveItsSoInner::new();
assert_that!(deep.num(), eq(0));
@ -20,6 +20,15 @@ fn test_deeply_nested_definition() {
assert_that!(outer_msg.deep().num(), eq(0));
}
#[test]
fn test_deeply_nested_enum() {
let deep = nested_proto::nest::Outer_::Inner_::SuperInner_::DuperInner_::EvenMoreInner_
::JustWayTooInner::default();
assert_that!(i32::from(deep), eq(0));
// TODO: Test deeply nested enum field access.
}
#[test]
fn test_nested_views() {
let outer_msg = Outer::new();

@ -83,15 +83,15 @@ void EmitClosingOfPackageModules(Context& ctx, absl::string_view pkg) {
}
}
// Emits `pub use <internal submodule name>::Msg` for all messages of a
// `non_primary_src` into the `primary_file`.
// Emits `pub use <internal submodule name>::Type` for all messages and enums of
// a `non_primary_src` into the `primary_file`.
//
// `non_primary_src` has to be a non-primary src of the current `proto_library`.
void EmitPubUseOfOwnMessages(Context& ctx, const FileDescriptor& primary_file,
const FileDescriptor& non_primary_src) {
void EmitPubUseOfOwnTypes(Context& ctx, const FileDescriptor& primary_file,
const FileDescriptor& non_primary_src) {
auto mod = RustInternalModuleName(ctx, non_primary_src);
for (int i = 0; i < non_primary_src.message_type_count(); ++i) {
auto& msg = *non_primary_src.message_type(i);
auto mod = RustInternalModuleName(ctx, non_primary_src);
ctx.Emit({{"mod", mod}, {"Msg", msg.name()}},
R"rs(
pub use crate::$mod$::$Msg$;
@ -100,17 +100,24 @@ void EmitPubUseOfOwnMessages(Context& ctx, const FileDescriptor& primary_file,
pub use crate::$mod$::$Msg$Mut;
)rs");
}
for (int i = 0; i < non_primary_src.enum_type_count(); ++i) {
auto& enum_ = *non_primary_src.enum_type(i);
ctx.Emit({{"mod", mod}, {"Enum", EnumRsName(enum_)}},
R"rs(
pub use crate::$mod$::$Enum$;
)rs");
}
}
// Emits `pub use <crate_name>::<public package>::Msg` for all messages of a
// `dep` into the `primary_file`. This should only be called for 'import public'
// deps.
// Emits `pub use <crate_name>::<public package>::Type` for all messages and
// enums of a `dep` into the `primary_file`. This should only be called for
// 'import public' deps.
//
// `dep` is a primary src of a dependency of the current `proto_library`.
// TODO: Add support for public import of non-primary srcs of deps.
void EmitPubUseForImportedMessages(Context& ctx,
const FileDescriptor& primary_file,
const FileDescriptor& dep) {
void EmitPubUseForImportedTypes(Context& ctx,
const FileDescriptor& primary_file,
const FileDescriptor& dep) {
std::string crate_name = GetCrateName(ctx, dep);
for (int i = 0; i < dep.message_type_count(); ++i) {
auto& msg = *dep.message_type(i);
@ -121,6 +128,14 @@ void EmitPubUseForImportedMessages(Context& ctx,
pub use $crate$::$pkg::Msg$View;
)rs");
}
for (int i = 0; i < dep.enum_type_count(); ++i) {
auto& enum_ = *dep.enum_type(i);
auto path = GetCrateRelativeQualifiedPath(ctx, enum_);
ctx.Emit({{"crate", crate_name}, {"pkg::Enum", path}},
R"rs(
pub use $crate$::$pkg::Enum$;
)rs");
}
}
// Emits all public imports of the current file
@ -137,7 +152,7 @@ void EmitPublicImports(Context& ctx, const FileDescriptor& primary_file) {
if (IsInCurrentlyGeneratingCrate(ctx, dep_file)) {
return;
}
EmitPubUseForImportedMessages(ctx, primary_file, dep_file);
EmitPubUseForImportedTypes(ctx, primary_file, dep_file);
}
}
@ -185,7 +200,7 @@ std::vector<const FileDescriptor*> ReexportMessagesFromSubmodules(
EmitOpeningOfPackageModules(ctx, package);
for (const FileDescriptor* c : fds) {
EmitPubUseOfOwnMessages(ctx, primary_file, *c);
EmitPubUseOfOwnTypes(ctx, primary_file, *c);
}
EmitClosingOfPackageModules(ctx, package);
}
@ -249,7 +264,7 @@ bool RustGenerator::Generate(const FileDescriptor* file,
for (const FileDescriptor* non_primary_file :
non_primary_srcs_in_primary_package) {
EmitPubUseOfOwnMessages(ctx, *file, *non_primary_file);
EmitPubUseOfOwnTypes(ctx, *file, *non_primary_file);
}
}

Loading…
Cancel
Save