Stop codegenning module for .proto package

PiperOrigin-RevId: 599856754
pull/15506/head
Marcel Hlopko 1 year ago committed by Copybara-Service
parent 39e8ca7faf
commit c1d174f7d2
  1. 12
      conformance/conformance_rust.rs
  2. 2
      rust/aspects.bzl
  3. 90
      rust/test/BUILD
  4. 4
      rust/test/cpp/interop/main.rs
  5. 12
      rust/test/import_public.proto
  6. 13
      rust/test/import_public2.proto
  7. 16
      rust/test/import_public_grandparent.proto
  8. 16
      rust/test/import_public_non_primary_src1.proto
  9. 16
      rust/test/import_public_non_primary_src2.proto
  10. 18
      rust/test/import_public_primary_src.proto
  11. 12
      rust/test/package_disabiguation1.proto
  12. 16
      rust/test/package_disabiguation2.proto
  13. 44
      rust/test/shared/BUILD
  14. 2
      rust/test/shared/accessors_map_test.rs
  15. 10
      rust/test/shared/accessors_proto3_test.rs
  16. 2
      rust/test/shared/accessors_repeated_test.rs
  17. 27
      rust/test/shared/accessors_test.rs
  18. 11
      rust/test/shared/child_parent_test.rs
  19. 2
      rust/test/shared/edition2023_test.rs
  20. 201
      rust/test/shared/enum_test.rs
  21. 35
      rust/test/shared/import_public_test.rs
  22. 12
      rust/test/shared/nested_types_test.rs
  23. 1
      rust/test/shared/package_disambiguation_test.rs
  24. 16
      rust/test/shared/package_test.rs
  25. 4
      rust/test/shared/reserved_test.rs
  26. 2
      rust/test/shared/serialization_test.rs
  27. 20
      rust/test/shared/simple_nested_test.rs
  28. 2
      src/google/protobuf/compiler/rust/context.h
  29. 179
      src/google/protobuf/compiler/rust/generator.cc
  30. 33
      src/google/protobuf/compiler/rust/naming.cc
  31. 2
      src/google/protobuf/compiler/rust/naming.h

@ -4,8 +4,8 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
use conformance_proto::conformance::{ConformanceRequest, ConformanceResponse}; use conformance_proto::{ConformanceRequest, ConformanceResponse};
use conformance_rust_overlay_hack_proto::conformance::ConformanceRequestRustOverlayHack; use conformance_rust_overlay_hack_proto::ConformanceRequestRustOverlayHack;
#[cfg(cpp_kernel)] #[cfg(cpp_kernel)]
use protobuf_cpp as kernel; use protobuf_cpp as kernel;
@ -16,10 +16,10 @@ use protobuf_upb as kernel;
use kernel::Optional::{Set, Unset}; use kernel::Optional::{Set, Unset};
use std::io::{self, ErrorKind, Read, Write}; use std::io::{self, ErrorKind, Read, Write};
use test_messages_proto2::protobuf_test_messages::proto2::TestAllTypesProto2; use test_messages_proto2::TestAllTypesProto2;
use test_messages_proto2_editions_proto::protobuf_test_messages::editions::proto2::TestAllTypesProto2 as EditionsTestAllTypesProto2; use test_messages_proto2_editions_proto::TestAllTypesProto2 as EditionsTestAllTypesProto2;
use test_messages_proto3::protobuf_test_messages::proto3::TestAllTypesProto3; use test_messages_proto3::TestAllTypesProto3;
use test_messages_proto3_editions_proto::protobuf_test_messages::editions::proto3::TestAllTypesProto3 as EditionsTestAllTypesProto3; use test_messages_proto3_editions_proto::TestAllTypesProto3 as EditionsTestAllTypesProto3;
/// Returns Some(i32) if a binary read can succeed from stdin. /// Returns Some(i32) if a binary read can succeed from stdin.
/// Returns None if we have reached an EOF. /// Returns None if we have reached an EOF.

@ -250,6 +250,8 @@ def _compile_rust(ctx, attr, src, extra_srcs, deps):
compile_data_targets = depset([]), compile_data_targets = depset([]),
owner = ctx.label, owner = ctx.label,
), ),
# Needed to make transitive public imports not violate layering.
force_all_deps_direct = True,
output_hash = output_hash, output_hash = output_hash,
) )

@ -232,6 +232,66 @@ rust_upb_proto_library(
deps = [":enums_proto"], deps = [":enums_proto"],
) )
proto_library(
name = "import_public_grandparent_proto",
testonly = True,
srcs = [":import_public_grandparent.proto"],
)
proto_library(
name = "import_public_primary_src_proto",
testonly = True,
srcs = ["import_public_primary_src.proto"],
exports = [":import_public_grandparent_proto"],
deps = [":import_public_grandparent_proto"],
)
proto_library(
name = "import_public_non_primary_src_proto",
testonly = True,
srcs = [
"import_public_non_primary_src1.proto",
"import_public_non_primary_src2.proto",
],
)
proto_library(
name = "import_public_proto",
testonly = True,
srcs = [
"import_public.proto",
"import_public2.proto",
],
exports = [
":import_public_non_primary_src_proto",
":import_public_primary_src_proto",
],
deps = [
":import_public_non_primary_src_proto",
":import_public_primary_src_proto",
],
)
cc_proto_library(
name = "import_public_cc_proto",
testonly = True,
deps = [":import_public_proto"],
)
rust_cc_proto_library(
name = "import_public_cc_rust_proto",
testonly = True,
visibility = ["//rust/test/shared:__subpackages__"],
deps = [":import_public_cc_proto"],
)
rust_upb_proto_library(
name = "import_public_upb_rust_proto",
testonly = True,
visibility = ["//rust/test/shared:__subpackages__"],
deps = [":import_public_proto"],
)
proto_library( proto_library(
name = "no_package_import_proto", name = "no_package_import_proto",
testonly = True, testonly = True,
@ -311,6 +371,36 @@ rust_upb_proto_library(
deps = [":package_proto"], deps = [":package_proto"],
) )
proto_library(
name = "package_disabiguation_proto",
testonly = True,
srcs = [
"package_disabiguation1.proto",
# TODO: b/321220129 - Uncomment once we support ambiguous messages.
# "package_disabiguation2.proto",
],
)
rust_upb_proto_library(
name = "package_disabiguation_upb_rust_proto",
testonly = True,
visibility = ["//rust/test/shared:__subpackages__"],
deps = [":package_disabiguation_proto"],
)
cc_proto_library(
name = "package_disabiguation_cc_proto",
testonly = True,
deps = [":package_disabiguation_proto"],
)
rust_cc_proto_library(
name = "package_disabiguation_cc_rust_proto",
testonly = True,
visibility = ["//rust/test/shared:__subpackages__"],
deps = [":package_disabiguation_cc_proto"],
)
proto_library( proto_library(
name = "reserved_proto", name = "reserved_proto",
testonly = True, testonly = True,

@ -8,8 +8,8 @@
use googletest::prelude::*; use googletest::prelude::*;
use protobuf_cpp::__internal::PtrAndLen; use protobuf_cpp::__internal::PtrAndLen;
use protobuf_cpp::__internal::RawMessage; use protobuf_cpp::__internal::RawMessage;
use unittest_proto::proto2_unittest::TestAllExtensions; use unittest_proto::TestAllExtensions;
use unittest_proto::proto2_unittest::TestAllTypes; use unittest_proto::TestAllTypes;
macro_rules! proto_assert_eq { macro_rules! proto_assert_eq {
($lhs:expr, $rhs:expr) => {{ ($lhs:expr, $rhs:expr) => {{

@ -0,0 +1,12 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
syntax = "proto2";
package import_public;
import public "google/protobuf/rust/test/import_public_primary_src.proto";

@ -0,0 +1,13 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
syntax = "proto2";
package import_public;
import public "google/protobuf/rust/test/import_public_non_primary_src1.proto";
import public "google/protobuf/rust/test/import_public_non_primary_src2.proto";

@ -0,0 +1,16 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
syntax = "proto2";
package grandparent;
message GrandparentMsg {}
enum GrandparentEnum {
GRANDPARENT_ENUM_UNSPECIFIED = 0;
}

@ -0,0 +1,16 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
syntax = "proto2";
package non_primary_src_testing_packages;
message NonPrimarySrcPubliclyImportedMsg1 {}
enum NonPrimarySrcPubliclyImportedEnum1 {
NON_PRIMARY_SRC_PUBLICLY_IMPORTED_ENUM1_UNSPECIFIED = 0;
}

@ -0,0 +1,16 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
syntax = "proto2";
package non_primary_src_testing_packages;
message NonPrimarySrcPubliclyImportedMsg2 {}
enum NonPrimarySrcPubliclyImportedEnum2 {
NON_PRIMARY_SRC_PUBLICLY_IMPORTED_ENUM2_UNSPECIFIED = 0;
}

@ -0,0 +1,18 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
syntax = "proto2";
package primary_src_testing_packages;
import public "google/protobuf/rust/test/import_public_grandparent.proto";
message PrimarySrcPubliclyImportedMsg {}
enum PrimarySrcPubliclyImportedEnum {
PRIMARY_SRC_PUBLICLY_IMPORTED_ENUM_UNSPECIFIED = 0;
}

@ -0,0 +1,12 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
syntax = "proto2";
package package1;
message YayConflict {}

@ -0,0 +1,16 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
syntax = "proto2";
package package2;
import "google/protobuf/rust/test/package_disabiguation1.proto";
message YayConflict {
optional .package1.YayConflict other_message = 1;
}

@ -130,6 +130,30 @@ rust_test(
], ],
) )
rust_test(
name = "import_public_cpp_test",
srcs = ["import_public_test.rs"],
tags = [
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
"not_build:arm",
],
deps = [
"//rust/test:import_public_cc_rust_proto",
],
)
rust_test(
name = "import_public_upb_test",
srcs = ["import_public_test.rs"],
tags = [
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
"not_build:arm",
],
deps = [
"//rust/test:import_public_upb_rust_proto",
],
)
rust_test( rust_test(
name = "package_cpp_test", name = "package_cpp_test",
srcs = ["package_test.rs"], srcs = ["package_test.rs"],
@ -158,6 +182,26 @@ rust_test(
], ],
) )
rust_test(
name = "package_disambiguation_cpp_test",
srcs = ["package_disambiguation_test.rs"],
tags = [
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
"not_build:arm",
],
deps = ["//rust/test:package_disabiguation_cc_rust_proto"],
)
rust_test(
name = "package_disambiguation_upb_test",
srcs = ["package_disambiguation_test.rs"],
tags = [
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
"not_build:arm",
],
deps = ["//rust/test:package_disabiguation_upb_rust_proto"],
)
rust_test( rust_test(
name = "reserved_cpp_test", name = "reserved_cpp_test",
srcs = ["reserved_test.rs"], srcs = ["reserved_test.rs"],

@ -6,7 +6,7 @@
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
use googletest::prelude::*; use googletest::prelude::*;
use map_unittest_proto::proto2_unittest::TestMap; use map_unittest_proto::TestMap;
use paste::paste; use paste::paste;
macro_rules! generate_map_primitives_tests { macro_rules! generate_map_primitives_tests {

@ -10,8 +10,8 @@
use googletest::prelude::*; use googletest::prelude::*;
use matchers::{is_set, is_unset}; use matchers::{is_set, is_unset};
use protobuf::Optional; use protobuf::Optional;
use unittest_proto3::proto3_unittest::{TestAllTypes, TestAllTypes_}; use unittest_proto3::{TestAllTypes, TestAllTypes_};
use unittest_proto3_optional::proto2_unittest::{TestProto3Optional, TestProto3Optional_}; use unittest_proto3_optional::{TestProto3Optional, TestProto3Optional_};
#[test] #[test]
fn test_fixed32_accessors() { fn test_fixed32_accessors() {
@ -235,7 +235,7 @@ fn test_optional_nested_enum_accessors() {
#[test] #[test]
fn test_foreign_enum_accessors() { fn test_foreign_enum_accessors() {
use unittest_proto3::proto3_unittest::ForeignEnum; use unittest_proto3::ForeignEnum;
let mut msg = TestAllTypes::new(); let mut msg = TestAllTypes::new();
assert_that!(msg.optional_foreign_enum(), eq(ForeignEnum::ForeignZero)); assert_that!(msg.optional_foreign_enum(), eq(ForeignEnum::ForeignZero));
@ -286,7 +286,7 @@ fn test_oneof_accessors() {
#[test] #[test]
fn test_oneof_enum_accessors() { fn test_oneof_enum_accessors() {
use unittest_proto3::proto3_unittest::{ use unittest_proto3::{
TestOneof2, TestOneof2,
TestOneof2_::{Foo, NestedEnum}, TestOneof2_::{Foo, NestedEnum},
}; };
@ -336,7 +336,7 @@ fn test_oneof_mut_accessors() {
#[test] #[test]
fn test_oneof_mut_enum_accessors() { fn test_oneof_mut_enum_accessors() {
use unittest_proto3::proto3_unittest::{ use unittest_proto3::{
TestOneof2, TestOneof2,
TestOneof2_::{FooMut, NestedEnum}, TestOneof2_::{FooMut, NestedEnum},
}; };

@ -8,7 +8,7 @@
use googletest::prelude::*; use googletest::prelude::*;
use paste::paste; use paste::paste;
use protobuf::ViewProxy; use protobuf::ViewProxy;
use unittest_proto::proto2_unittest::{TestAllTypes, TestAllTypes_, TestAllTypes_::NestedMessage}; use unittest_proto::{TestAllTypes, TestAllTypes_, TestAllTypes_::NestedMessage};
macro_rules! generate_repeated_numeric_test { macro_rules! generate_repeated_numeric_test {
($(($t: ty, $field: ident)),*) => { ($(($t: ty, $field: ident)),*) => {

@ -10,7 +10,7 @@
use googletest::prelude::*; use googletest::prelude::*;
use matchers::{is_set, is_unset}; use matchers::{is_set, is_unset};
use protobuf::Optional; use protobuf::Optional;
use unittest_proto::proto2_unittest::{TestAllTypes, TestAllTypes_}; use unittest_proto::{TestAllTypes, TestAllTypes_};
#[test] #[test]
fn test_default_accessors() { fn test_default_accessors() {
@ -728,7 +728,7 @@ fn test_default_nested_enum_accessors() {
#[test] #[test]
fn test_optional_foreign_enum_accessors() { fn test_optional_foreign_enum_accessors() {
use unittest_proto::proto2_unittest::ForeignEnum; use unittest_proto::ForeignEnum;
let mut msg = TestAllTypes::new(); let mut msg = TestAllTypes::new();
assert_that!(msg.optional_foreign_enum_opt(), eq(Optional::Unset(ForeignEnum::ForeignFoo))); assert_that!(msg.optional_foreign_enum_opt(), eq(Optional::Unset(ForeignEnum::ForeignFoo)));
@ -745,7 +745,7 @@ fn test_optional_foreign_enum_accessors() {
#[test] #[test]
fn test_default_foreign_enum_accessors() { fn test_default_foreign_enum_accessors() {
use unittest_proto::proto2_unittest::ForeignEnum; use unittest_proto::ForeignEnum;
let mut msg = TestAllTypes::new(); let mut msg = TestAllTypes::new();
assert_that!(msg.default_foreign_enum(), eq(ForeignEnum::ForeignBar)); assert_that!(msg.default_foreign_enum(), eq(ForeignEnum::ForeignBar));
@ -774,7 +774,7 @@ fn test_default_foreign_enum_accessors() {
#[test] #[test]
fn test_optional_import_enum_accessors() { fn test_optional_import_enum_accessors() {
use unittest_proto::proto2_unittest_import::ImportEnum; use unittest_proto::ImportEnum;
let mut msg = TestAllTypes::new(); let mut msg = TestAllTypes::new();
assert_that!(msg.optional_import_enum_opt(), eq(Optional::Unset(ImportEnum::ImportFoo))); assert_that!(msg.optional_import_enum_opt(), eq(Optional::Unset(ImportEnum::ImportFoo)));
@ -791,7 +791,7 @@ fn test_optional_import_enum_accessors() {
#[test] #[test]
fn test_default_import_enum_accessors() { fn test_default_import_enum_accessors() {
use unittest_proto::proto2_unittest_import::ImportEnum; use unittest_proto::ImportEnum;
let mut msg = TestAllTypes::new(); let mut msg = TestAllTypes::new();
assert_that!(msg.default_import_enum(), eq(ImportEnum::ImportBar)); assert_that!(msg.default_import_enum(), eq(ImportEnum::ImportBar));
@ -820,8 +820,8 @@ fn test_default_import_enum_accessors() {
#[test] #[test]
fn test_oneof_accessors() { fn test_oneof_accessors() {
use unittest_proto::proto2_unittest::TestOneof2; use unittest_proto::TestOneof2;
use unittest_proto::proto2_unittest::TestOneof2_::{Foo::*, NestedEnum}; use unittest_proto::TestOneof2_::{Foo::*, NestedEnum};
let mut msg = TestOneof2::new(); let mut msg = TestOneof2::new();
assert_that!(msg.foo(), matches_pattern!(not_set(_))); assert_that!(msg.foo(), matches_pattern!(not_set(_)));
@ -861,9 +861,10 @@ fn test_oneof_accessors() {
#[test] #[test]
fn test_oneof_mut_accessors() { fn test_oneof_mut_accessors() {
use unittest_proto::proto2_unittest::TestOneof2_::{Foo, FooMut::*, NestedEnum}; use unittest_proto::TestOneof2;
use unittest_proto::TestOneof2_::{Foo, FooMut::*, NestedEnum};
let mut msg = unittest_proto::proto2_unittest::TestOneof2::new(); let mut msg = TestOneof2::new();
assert_that!(msg.foo_mut(), matches_pattern!(not_set(_))); assert_that!(msg.foo_mut(), matches_pattern!(not_set(_)));
msg.foo_int_mut().set(7); msg.foo_int_mut().set(7);
@ -909,9 +910,9 @@ fn test_oneof_mut_accessors() {
#[test] #[test]
fn test_msg_oneof_default_accessors() { fn test_msg_oneof_default_accessors() {
use unittest_proto::proto2_unittest::TestOneof2_::{Bar::*, NestedEnum}; use unittest_proto::TestOneof2_::{Bar::*, NestedEnum};
let mut msg = unittest_proto::proto2_unittest::TestOneof2::new(); let mut msg = unittest_proto::TestOneof2::new();
assert_that!(msg.bar(), matches_pattern!(not_set(_))); assert_that!(msg.bar(), matches_pattern!(not_set(_)));
msg.bar_int_mut().set(7); msg.bar_int_mut().set(7);
@ -937,9 +938,9 @@ fn test_msg_oneof_default_accessors() {
#[test] #[test]
fn test_oneof_default_mut_accessors() { fn test_oneof_default_mut_accessors() {
use unittest_proto::proto2_unittest::TestOneof2_::{Bar, BarMut, BarMut::*, NestedEnum}; use unittest_proto::TestOneof2_::{Bar, BarMut, BarMut::*, NestedEnum};
let mut msg = unittest_proto::proto2_unittest::TestOneof2::new(); let mut msg = unittest_proto::TestOneof2::new();
assert_that!(msg.bar_mut(), matches_pattern!(not_set(_))); assert_that!(msg.bar_mut(), matches_pattern!(not_set(_)));
msg.bar_int_mut().set(7); msg.bar_int_mut().set(7);

@ -9,20 +9,19 @@ use googletest::prelude::*;
#[test] #[test]
fn test_canonical_types() { fn test_canonical_types() {
let _child = child_proto::child_package::Child::new(); let _child = child_proto::Child::new();
let _parent = parent_proto::parent_package::Parent::new(); let _parent = parent_proto::Parent::new();
// Parent from child_proto crate should be the same type as Parent from // Parent from child_proto crate should be the same type as Parent from
// parent_proto crate. // parent_proto crate.
let _parent_from_child: child_proto::child_package::Parent = let _parent_from_child: child_proto::Parent = parent_proto::Parent::new();
parent_proto::parent_package::Parent::new();
} }
#[test] #[test]
fn test_parent_serialization() { fn test_parent_serialization() {
assert_that!(*parent_proto::parent_package::Parent::new().serialize(), empty()); assert_that!(*parent_proto::Parent::new().serialize(), empty());
} }
#[test] #[test]
fn test_child_serialization() { fn test_child_serialization() {
assert_that!(*child_proto::child_package::Child::new().serialize(), empty()); assert_that!(*child_proto::Child::new().serialize(), empty());
} }

@ -13,7 +13,7 @@ use googletest::prelude::*;
#[test] #[test]
fn check_edition2023_works() { fn check_edition2023_works() {
let mut msg = edition2023_proto::test::EditionsMessage::new(); let mut msg = edition2023_proto::EditionsMessage::new();
// plain_field supports presence. // plain_field supports presence.
assert_that!(msg.plain_field_mut().or_default().get(), eq(0)); assert_that!(msg.plain_field_mut().or_default().get(), eq(0));

@ -7,214 +7,163 @@
//! Tests covering enum type generation. //! Tests covering enum type generation.
use enums_proto::enums; use enums_proto::*;
use googletest::prelude::*; use googletest::prelude::*;
use unittest_proto::proto2_unittest; use unittest_proto::*;
#[test] #[test]
fn test_nested_enum_values() { fn test_nested_enum_values() {
assert_that!(i32::from(proto2_unittest::TestAllTypes_::NestedEnum::Foo), eq(1)); assert_that!(i32::from(TestAllTypes_::NestedEnum::Foo), eq(1));
assert_that!(i32::from(proto2_unittest::TestAllTypes_::NestedEnum::Bar), eq(2)); assert_that!(i32::from(TestAllTypes_::NestedEnum::Bar), eq(2));
assert_that!(i32::from(proto2_unittest::TestAllTypes_::NestedEnum::Baz), eq(3)); assert_that!(i32::from(TestAllTypes_::NestedEnum::Baz), eq(3));
assert_that!(i32::from(proto2_unittest::TestAllTypes_::NestedEnum::Neg), eq(-1)); assert_that!(i32::from(TestAllTypes_::NestedEnum::Neg), eq(-1));
} }
#[test] #[test]
fn test_isolated_nested_enum() { fn test_isolated_nested_enum() {
// Ensure that the enum is generated even when it's the only nested type for the // Ensure that the enum is generated even when it's the only nested type for the
// message. // message.
assert_that!(i32::from(proto2_unittest::TestRequiredEnumNoMask_::NestedEnum::Foo), eq(2)); assert_that!(i32::from(TestRequiredEnumNoMask_::NestedEnum::Foo), eq(2));
} }
#[test] #[test]
fn test_enum_value_name_same_as_enum() { fn test_enum_value_name_same_as_enum() {
assert_that!(i32::from(enums::TestEnumValueNameSameAsEnum::TestEnumValueNameSameAsEnum), eq(1)); assert_that!(i32::from(TestEnumValueNameSameAsEnum::TestEnumValueNameSameAsEnum), eq(1));
} }
#[test] #[test]
fn test_enum_defaults() { fn test_enum_defaults() {
assert_that!(TestSparseEnum::default(), eq(TestSparseEnum::SparseA));
assert_that!(TestEnumWithDupValue::default(), eq(TestEnumWithDupValue::Foo1));
assert_that!(TestEnumWithDupValue::default(), eq(TestEnumWithDupValue::Foo2));
assert_that!( assert_that!(
proto2_unittest::TestSparseEnum::default(), TestEnumWithDuplicateStrippedPrefixNames::default(),
eq(proto2_unittest::TestSparseEnum::SparseA) eq(TestEnumWithDuplicateStrippedPrefixNames::Unknown)
);
assert_that!(
proto2_unittest::TestEnumWithDupValue::default(),
eq(proto2_unittest::TestEnumWithDupValue::Foo1)
);
assert_that!(
proto2_unittest::TestEnumWithDupValue::default(),
eq(proto2_unittest::TestEnumWithDupValue::Foo2)
);
assert_that!(
enums::TestEnumWithDuplicateStrippedPrefixNames::default(),
eq(enums::TestEnumWithDuplicateStrippedPrefixNames::Unknown)
);
assert_that!(
proto2_unittest::TestAllTypes_::NestedEnum::default(),
eq(proto2_unittest::TestAllTypes_::NestedEnum::Foo)
); );
assert_that!(TestAllTypes_::NestedEnum::default(), eq(TestAllTypes_::NestedEnum::Foo));
} }
#[test] #[test]
#[deny(unreachable_patterns)] #[deny(unreachable_patterns)]
#[allow(clippy::let_unit_value)] #[allow(clippy::let_unit_value)]
fn test_closed_enum_is_nonexhaustive() { fn test_closed_enum_is_nonexhaustive() {
let val = proto2_unittest::ForeignEnum::ForeignFoo; let val = ForeignEnum::ForeignFoo;
let _it_compiles: () = match val { let _it_compiles: () = match val {
proto2_unittest::ForeignEnum::ForeignFoo => (), ForeignEnum::ForeignFoo => (),
proto2_unittest::ForeignEnum::ForeignBar => (), ForeignEnum::ForeignBar => (),
proto2_unittest::ForeignEnum::ForeignBaz => (), ForeignEnum::ForeignBaz => (),
proto2_unittest::ForeignEnum::ForeignBax => (), ForeignEnum::ForeignBax => (),
_ => unreachable!(), _ => unreachable!(),
}; };
} }
#[test] #[test]
fn test_closed_enum_conversion() { fn test_closed_enum_conversion() {
assert_that!(i32::from(proto2_unittest::TestSparseEnum::SparseA), eq(123)); assert_that!(i32::from(TestSparseEnum::SparseA), eq(123));
assert_that!( assert_that!(TestSparseEnum::try_from(123), ok(eq(TestSparseEnum::SparseA)));
proto2_unittest::TestSparseEnum::try_from(123),
ok(eq(proto2_unittest::TestSparseEnum::SparseA))
);
assert_that!(i32::from(proto2_unittest::TestSparseEnum::SparseD), eq(-15)); assert_that!(i32::from(TestSparseEnum::SparseD), eq(-15));
assert_that!( assert_that!(TestSparseEnum::try_from(-15), ok(eq(TestSparseEnum::SparseD)));
proto2_unittest::TestSparseEnum::try_from(-15),
ok(eq(proto2_unittest::TestSparseEnum::SparseD))
);
assert_that!( assert_that!(TestSparseEnum::try_from(0), ok(eq(TestSparseEnum::SparseF)));
proto2_unittest::TestSparseEnum::try_from(0), assert_that!(TestSparseEnum::try_from(1), err(anything()));
ok(eq(proto2_unittest::TestSparseEnum::SparseF))
);
assert_that!(proto2_unittest::TestSparseEnum::try_from(1), err(anything()));
} }
#[test] #[test]
fn test_closed_aliased_enum_conversion() { fn test_closed_aliased_enum_conversion() {
assert_that!(i32::from(proto2_unittest::TestEnumWithDupValue::Foo1), eq(1)); assert_that!(i32::from(TestEnumWithDupValue::Foo1), eq(1));
assert_that!(i32::from(proto2_unittest::TestEnumWithDupValue::Foo2), eq(1)); assert_that!(i32::from(TestEnumWithDupValue::Foo2), eq(1));
assert_that!(i32::from(proto2_unittest::TestEnumWithDupValue::Bar1), eq(2)); assert_that!(i32::from(TestEnumWithDupValue::Bar1), eq(2));
assert_that!(i32::from(proto2_unittest::TestEnumWithDupValue::Bar2), eq(2)); assert_that!(i32::from(TestEnumWithDupValue::Bar2), eq(2));
assert_that!(i32::from(proto2_unittest::TestEnumWithDupValue::Baz), eq(3)); assert_that!(i32::from(TestEnumWithDupValue::Baz), eq(3));
assert_that!( assert_that!(TestEnumWithDupValue::try_from(1), ok(eq(TestEnumWithDupValue::Foo1)));
proto2_unittest::TestEnumWithDupValue::try_from(1), assert_that!(TestEnumWithDupValue::try_from(2), ok(eq(TestEnumWithDupValue::Bar1)));
ok(eq(proto2_unittest::TestEnumWithDupValue::Foo1)) assert_that!(TestEnumWithDupValue::try_from(3), ok(eq(TestEnumWithDupValue::Baz)));
); assert_that!(TestEnumWithDupValue::try_from(0), err(anything()));
assert_that!( assert_that!(TestEnumWithDupValue::try_from(4), err(anything()));
proto2_unittest::TestEnumWithDupValue::try_from(2),
ok(eq(proto2_unittest::TestEnumWithDupValue::Bar1)) assert_that!(TestEnumWithDupValue::Foo1, eq(TestEnumWithDupValue::Foo2));
); assert_that!(TestEnumWithDupValue::Bar1, eq(TestEnumWithDupValue::Bar2));
assert_that!(
proto2_unittest::TestEnumWithDupValue::try_from(3),
ok(eq(proto2_unittest::TestEnumWithDupValue::Baz))
);
assert_that!(proto2_unittest::TestEnumWithDupValue::try_from(0), err(anything()));
assert_that!(proto2_unittest::TestEnumWithDupValue::try_from(4), err(anything()));
assert_that!(
proto2_unittest::TestEnumWithDupValue::Foo1,
eq(proto2_unittest::TestEnumWithDupValue::Foo2)
);
assert_that!(
proto2_unittest::TestEnumWithDupValue::Bar1,
eq(proto2_unittest::TestEnumWithDupValue::Bar2)
);
} }
#[test] #[test]
#[deny(unreachable_patterns)] #[deny(unreachable_patterns)]
#[allow(clippy::let_unit_value)] #[allow(clippy::let_unit_value)]
fn test_open_enum_is_nonexhaustive() { fn test_open_enum_is_nonexhaustive() {
let val = enums::TestEnumValueNameSameAsEnum::Unknown; let val = TestEnumValueNameSameAsEnum::Unknown;
let _it_compiles: () = match val { let _it_compiles: () = match val {
enums::TestEnumValueNameSameAsEnum::Unknown => (), TestEnumValueNameSameAsEnum::Unknown => (),
enums::TestEnumValueNameSameAsEnum::TestEnumValueNameSameAsEnum => (), TestEnumValueNameSameAsEnum::TestEnumValueNameSameAsEnum => (),
_ => unreachable!(), _ => unreachable!(),
}; };
} }
#[test] #[test]
fn test_open_enum_conversion() { fn test_open_enum_conversion() {
assert_that!(i32::from(enums::TestEnumWithNumericNames::Unknown), eq(0)); assert_that!(i32::from(TestEnumWithNumericNames::Unknown), eq(0));
assert_that!(i32::from(enums::TestEnumWithNumericNames::_2020), eq(1)); assert_that!(i32::from(TestEnumWithNumericNames::_2020), eq(1));
assert_that!(i32::from(enums::TestEnumWithNumericNames::_2021), eq(2)); assert_that!(i32::from(TestEnumWithNumericNames::_2021), eq(2));
assert_that!(i32::from(enums::TestEnumWithNumericNames::_2022), eq(3)); assert_that!(i32::from(TestEnumWithNumericNames::_2022), eq(3));
assert_that!(TestEnumWithNumericNames::from(0), eq(TestEnumWithNumericNames::Unknown));
assert_that!(TestEnumWithNumericNames::from(1), eq(TestEnumWithNumericNames::_2020));
assert_that!(TestEnumWithNumericNames::from(2), eq(TestEnumWithNumericNames::_2021));
assert_that!(TestEnumWithNumericNames::from(3), eq(TestEnumWithNumericNames::_2022));
assert_that!( assert_that!(
enums::TestEnumWithNumericNames::from(0), TestEnumWithNumericNames::from(4),
eq(enums::TestEnumWithNumericNames::Unknown)
);
assert_that!(
enums::TestEnumWithNumericNames::from(1),
eq(enums::TestEnumWithNumericNames::_2020)
);
assert_that!(
enums::TestEnumWithNumericNames::from(2),
eq(enums::TestEnumWithNumericNames::_2021)
);
assert_that!(
enums::TestEnumWithNumericNames::from(3),
eq(enums::TestEnumWithNumericNames::_2022)
);
assert_that!(
enums::TestEnumWithNumericNames::from(4),
not(any![ not(any![
eq(enums::TestEnumWithNumericNames::Unknown), eq(TestEnumWithNumericNames::Unknown),
eq(enums::TestEnumWithNumericNames::_2020), eq(TestEnumWithNumericNames::_2020),
eq(enums::TestEnumWithNumericNames::_2021), eq(TestEnumWithNumericNames::_2021),
eq(enums::TestEnumWithNumericNames::_2022), eq(TestEnumWithNumericNames::_2022),
]) ])
); );
assert_that!(i32::from(enums::TestEnumWithNumericNames::from(-1)), eq(-1)); assert_that!(i32::from(TestEnumWithNumericNames::from(-1)), eq(-1));
} }
#[test] #[test]
fn test_open_aliased_enum_conversion() { fn test_open_aliased_enum_conversion() {
assert_that!(i32::from(enums::TestEnumWithDuplicateStrippedPrefixNames::Unknown), eq(0)); assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::Unknown), eq(0));
assert_that!(i32::from(enums::TestEnumWithDuplicateStrippedPrefixNames::Foo), eq(1)); assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::Foo), eq(1));
assert_that!(i32::from(enums::TestEnumWithDuplicateStrippedPrefixNames::Bar), eq(2)); assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::Bar), eq(2));
assert_that!( assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::DifferentNameAlias), eq(2));
i32::from(enums::TestEnumWithDuplicateStrippedPrefixNames::DifferentNameAlias),
eq(2)
);
assert_that!( assert_that!(
enums::TestEnumWithDuplicateStrippedPrefixNames::from(0), TestEnumWithDuplicateStrippedPrefixNames::from(0),
eq(enums::TestEnumWithDuplicateStrippedPrefixNames::Unknown) eq(TestEnumWithDuplicateStrippedPrefixNames::Unknown)
); );
assert_that!( assert_that!(
enums::TestEnumWithDuplicateStrippedPrefixNames::from(1), TestEnumWithDuplicateStrippedPrefixNames::from(1),
eq(enums::TestEnumWithDuplicateStrippedPrefixNames::Foo) eq(TestEnumWithDuplicateStrippedPrefixNames::Foo)
); );
assert_that!( assert_that!(
enums::TestEnumWithDuplicateStrippedPrefixNames::from(2), TestEnumWithDuplicateStrippedPrefixNames::from(2),
eq(enums::TestEnumWithDuplicateStrippedPrefixNames::Bar) eq(TestEnumWithDuplicateStrippedPrefixNames::Bar)
); );
assert_that!( assert_that!(
enums::TestEnumWithDuplicateStrippedPrefixNames::from(2), TestEnumWithDuplicateStrippedPrefixNames::from(2),
eq(enums::TestEnumWithDuplicateStrippedPrefixNames::DifferentNameAlias) eq(TestEnumWithDuplicateStrippedPrefixNames::DifferentNameAlias)
); );
assert_that!( assert_that!(
enums::TestEnumWithDuplicateStrippedPrefixNames::from(3), TestEnumWithDuplicateStrippedPrefixNames::from(3),
not(any![ not(any![
eq(enums::TestEnumWithDuplicateStrippedPrefixNames::Unknown), eq(TestEnumWithDuplicateStrippedPrefixNames::Unknown),
eq(enums::TestEnumWithDuplicateStrippedPrefixNames::Foo), eq(TestEnumWithDuplicateStrippedPrefixNames::Foo),
eq(enums::TestEnumWithDuplicateStrippedPrefixNames::Bar), eq(TestEnumWithDuplicateStrippedPrefixNames::Bar),
]) ])
); );
assert_that!(i32::from(enums::TestEnumWithDuplicateStrippedPrefixNames::from(5)), eq(5)); assert_that!(i32::from(TestEnumWithDuplicateStrippedPrefixNames::from(5)), eq(5));
} }
#[test] #[test]
fn test_enum_conversion_failure_display() { fn test_enum_conversion_failure_display() {
let err = proto2_unittest::TestSparseEnum::try_from(1).unwrap_err(); let err = TestSparseEnum::try_from(1).unwrap_err();
assert_that!(format!("{err}"), eq("1 is not a known value for TestSparseEnum")); assert_that!(format!("{err}"), eq("1 is not a known value for TestSparseEnum"));
} }
#[test] #[test]
fn test_enum_conversion_failure_impls_std_error() { fn test_enum_conversion_failure_impls_std_error() {
let err = proto2_unittest::TestSparseEnum::try_from(1).unwrap_err(); let err = TestSparseEnum::try_from(1).unwrap_err();
let _test_compiles: &dyn std::error::Error = &err; let _test_compiles: &dyn std::error::Error = &err;
} }

@ -0,0 +1,35 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
//! Tests covering codegen of import public statements.
#[test]
fn test_import_public_types_are_reexported() {
let _: import_public_proto::PrimarySrcPubliclyImportedMsg;
let _: import_public_proto::PrimarySrcPubliclyImportedMsgView;
let _: import_public_proto::PrimarySrcPubliclyImportedMsgMut;
let _: import_public_proto::PrimarySrcPubliclyImportedEnum;
let _: import_public_proto::GrandparentMsg;
let _: import_public_proto::GrandparentMsgView;
let _: import_public_proto::GrandparentMsgMut;
let _: import_public_proto::GrandparentEnum;
let _: import_public_proto::NonPrimarySrcPubliclyImportedMsg1;
let _: import_public_proto::NonPrimarySrcPubliclyImportedMsg1View;
let _: import_public_proto::NonPrimarySrcPubliclyImportedMsg1Mut;
let _: import_public_proto::NonPrimarySrcPubliclyImportedEnum1;
let _: import_public_proto::NonPrimarySrcPubliclyImportedMsg2;
let _: import_public_proto::NonPrimarySrcPubliclyImportedMsg2View;
let _: import_public_proto::NonPrimarySrcPubliclyImportedMsg2Mut;
let _: import_public_proto::NonPrimarySrcPubliclyImportedEnum2;
}

@ -9,15 +9,15 @@
#[test] #[test]
fn test_nested_messages_accessible() { fn test_nested_messages_accessible() {
let _parent: unittest_proto::proto2_unittest::TestAllTypes; let _parent: unittest_proto::TestAllTypes;
let _child: unittest_proto::proto2_unittest::TestAllTypes_::NestedMessage; let _child: unittest_proto::TestAllTypes_::NestedMessage;
unittest_proto::proto2_unittest::TestChildExtensionData_:: unittest_proto::TestChildExtensionData_::
NestedTestAllExtensionsData_::NestedDynamicExtensions::new(); NestedTestAllExtensionsData_::NestedDynamicExtensions::new();
} }
#[test] #[test]
fn test_nested_enums_accessible() { fn test_nested_enums_accessible() {
let _parent: unittest_proto::proto2_unittest::TestAllTypes; let _parent: unittest_proto::TestAllTypes;
let _child: unittest_proto::proto2_unittest::TestAllTypes_::NestedEnum; let _child: unittest_proto::TestAllTypes_::NestedEnum;
unittest_proto::proto2_unittest::TestDynamicExtensions_::DynamicEnumType::default(); unittest_proto::TestDynamicExtensions_::DynamicEnumType::default();
} }

@ -17,13 +17,13 @@ fn test_message_packages() {
let _: no_package_proto::ImportedMsgWithoutPackage; let _: no_package_proto::ImportedMsgWithoutPackage;
// package, message declared in the first .proto source // package, message declared in the first .proto source
let _: package_proto::testing_packages::MsgWithPackage; let _: package_proto::MsgWithPackage;
// package, message declared in the other .proto source with the same package // package, message declared in the other .proto source with the same package
let _: package_proto::testing_packages::OtherMsgWithPackage; let _: package_proto::OtherMsgWithPackage;
// package, message declared in the other .proto source with a different package // package, message declared in the other .proto source with a different package
let _: package_proto::testing_other_packages::OtherMsgInDifferentPackage; let _: package_proto::OtherMsgInDifferentPackage;
// package, import public of a message // package, import public of a message
let _: package_proto::testing_packages::ImportedMsgWithPackage; let _: package_proto::ImportedMsgWithPackage;
} }
#[test] #[test]
@ -36,11 +36,11 @@ fn test_enum_packages() {
let _: no_package_proto::ImportedEnumWithoutPackage; let _: no_package_proto::ImportedEnumWithoutPackage;
// package, enum declared in the first .proto source // package, enum declared in the first .proto source
let _: package_proto::testing_packages::EnumWithPackage; let _: package_proto::EnumWithPackage;
// package, enum declared in the other .proto source with the same package // package, enum declared in the other .proto source with the same package
let _: package_proto::testing_packages::OtherEnumWithPackage; let _: package_proto::OtherEnumWithPackage;
// package, enum declared in the other .proto source with a different package // package, enum declared in the other .proto source with a different package
let _: package_proto::testing_other_packages::OtherEnumInDifferentPackage; let _: package_proto::OtherEnumInDifferentPackage;
// package, import public of a enum // package, import public of a enum
let _: package_proto::testing_packages::ImportedEnumWithPackage; let _: package_proto::ImportedEnumWithPackage;
} }

@ -7,8 +7,8 @@
/// Test covering proto compilation with reserved words. /// Test covering proto compilation with reserved words.
use googletest::prelude::*; use googletest::prelude::*;
use reserved_proto::r#type::r#type::r#enum; use reserved_proto::r#enum;
use reserved_proto::r#type::r#type::Self__mangled_because_symbol_is_a_rust_raw_identifier; use reserved_proto::Self__mangled_because_symbol_is_a_rust_raw_identifier;
#[test] #[test]
fn test_reserved_keyword_in_accessors() { fn test_reserved_keyword_in_accessors() {

@ -6,7 +6,7 @@
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
use googletest::prelude::*; use googletest::prelude::*;
use unittest_proto::proto2_unittest::TestAllTypes; use unittest_proto::TestAllTypes;
#[test] #[test]
fn serialize_deserialize_message() { fn serialize_deserialize_message() {

@ -6,15 +6,15 @@
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
use googletest::prelude::*; use googletest::prelude::*;
use nested_proto::nest::Outer; use nested_proto::Outer_::InnerMut;
use nested_proto::nest::Outer_::InnerMut; use nested_proto::Outer_::InnerView;
use nested_proto::nest::Outer_::InnerView; use nested_proto::Outer_::Inner_::InnerEnum;
use nested_proto::nest::Outer_::Inner_::InnerEnum; use nested_proto::*;
#[test] #[test]
fn test_deeply_nested_message() { fn test_deeply_nested_message() {
let deep = nested_proto::nest::Outer_::Inner_::SuperInner_::DuperInner_::EvenMoreInner_ let deep =
::CantBelieveItsSoInner::new(); Outer_::Inner_::SuperInner_::DuperInner_::EvenMoreInner_::CantBelieveItsSoInner::new();
assert_that!(deep.num(), eq(0)); assert_that!(deep.num(), eq(0));
let outer_msg = Outer::new(); let outer_msg = Outer::new();
@ -23,7 +23,7 @@ fn test_deeply_nested_message() {
#[test] #[test]
fn test_deeply_nested_enum() { fn test_deeply_nested_enum() {
use nested_proto::nest::Outer_::Inner_::SuperInner_::DuperInner_::EvenMoreInner_::JustWayTooInner; use Outer_::Inner_::SuperInner_::DuperInner_::EvenMoreInner_::JustWayTooInner;
let deep = JustWayTooInner::default(); let deep = JustWayTooInner::default();
assert_that!(i32::from(deep), eq(0)); assert_that!(i32::from(deep), eq(0));
@ -144,13 +144,13 @@ fn test_nested_muts() {
fn test_msg_from_outside() { fn test_msg_from_outside() {
// let's make sure that we're not just working for messages nested inside // let's make sure that we're not just working for messages nested inside
// messages, messages from without and within should work // messages, messages from without and within should work
let outer = nested_proto::nest::Outer::new(); let outer = Outer::new();
assert_that!(outer.notinside().num(), eq(0)); assert_that!(outer.notinside().num(), eq(0));
} }
#[test] #[test]
fn test_recursive_view() { fn test_recursive_view() {
let rec = nested_proto::nest::Recursive::new(); let rec = nested_proto::Recursive::new();
assert_that!(rec.num(), eq(0)); assert_that!(rec.num(), eq(0));
assert_that!(rec.rec().num(), eq(0)); assert_that!(rec.rec().num(), eq(0));
assert_that!(rec.rec().rec().num(), eq(0)); // turtles all the way down... assert_that!(rec.rec().rec().num(), eq(0)); // turtles all the way down...
@ -163,7 +163,7 @@ fn test_recursive_view() {
#[test] #[test]
fn test_recursive_mut() { fn test_recursive_mut() {
let mut rec = nested_proto::nest::Recursive::new(); let mut rec = nested_proto::Recursive::new();
let mut one = rec.rec_mut(); let mut one = rec.rec_mut();
let mut two = one.rec_mut(); let mut two = one.rec_mut();
let mut three = two.rec_mut(); let mut three = two.rec_mut();

@ -13,8 +13,6 @@
#include <vector> #include <vector>
#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_map.h"
#include "absl/log/absl_check.h"
#include "absl/log/absl_log.h"
#include "absl/status/statusor.h" #include "absl/status/statusor.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/types/span.h" #include "absl/types/span.h"

@ -12,12 +12,11 @@
#include <vector> #include <vector>
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
#include "absl/status/status.h" #include "absl/status/status.h"
#include "absl/status/statusor.h" #include "absl/status/statusor.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/types/span.h" #include "absl/types/span.h"
#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/code_generator.h"
@ -38,51 +37,6 @@ namespace compiler {
namespace rust { namespace rust {
namespace { namespace {
// Emits openings for a tree of submodules for a given `pkg`.
//
// For example for `package.uses.dots.submodule.separator` this function
// generates:
// ```
// pub mod package {
// pub mod uses {
// pub mod dots {
// pub mod submodule {
// pub mod separator {
// ```
void EmitOpeningOfPackageModules(Context& ctx, absl::string_view pkg) {
if (pkg.empty()) return;
for (absl::string_view segment : absl::StrSplit(pkg, '.')) {
ctx.Emit({{"segment", RsSafeName(segment)}},
R"rs(
#[allow(non_snake_case)]
pub mod $segment$ {
)rs");
}
}
// Emits closing curly brace for a tree of submodules for a given `pkg`.
//
// For example for `package.uses.dots.submodule.separator` this function
// generates:
// ```
// } // mod separator
// } // mod submodule
// } // mod dots
// } // mod uses
// } // mod package
// ```
void EmitClosingOfPackageModules(Context& ctx, absl::string_view pkg) {
if (pkg.empty()) return;
std::vector<absl::string_view> segments = absl::StrSplit(pkg, '.');
absl::c_reverse(segments);
for (absl::string_view segment : segments) {
ctx.Emit({{"segment", RsSafeName(segment)}}, R"rs(
} // mod $segment$
)rs");
}
}
// Emits `pub use <internal submodule name>::Type` for all messages and enums of // Emits `pub use <internal submodule name>::Type` for all messages and enums of
// a `non_primary_src` into the `primary_file`. // a `non_primary_src` into the `primary_file`.
// //
@ -109,50 +63,58 @@ void EmitPubUseOfOwnTypes(Context& ctx, const FileDescriptor& primary_file,
} }
} }
// Emits `pub use <crate_name>::<public package>::Type` for all messages and // Emits `pub use <crate_name>::<modules for parent types>::Type` for all
// enums of a `dep` into the `primary_file`. This should only be called for // messages and enums of a `dep`. This should only be
// 'import public' deps. // called for 'import public' deps.
// void EmitPublicImportsForDepFile(Context& ctx, const FileDescriptor* dep) {
// `dep` is a primary src of a dependency of the current `proto_library`. absl::string_view crate_name = GetCrateName(ctx, *dep);
// TODO: Add support for public import of non-primary srcs of deps. for (int i = 0; i < dep->message_type_count(); ++i) {
void EmitPubUseForImportedTypes(Context& ctx, auto* msg = dep->message_type(i);
const FileDescriptor& primary_file, auto path = GetCrateRelativeQualifiedPath(ctx, *msg);
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);
auto path = GetCrateRelativeQualifiedPath(ctx, msg);
ctx.Emit({{"crate", crate_name}, {"pkg::Msg", path}}, ctx.Emit({{"crate", crate_name}, {"pkg::Msg", path}},
R"rs( R"rs(
pub use $crate$::$pkg::Msg$; pub use $crate$::$pkg::Msg$;
pub use $crate$::$pkg::Msg$View; pub use $crate$::$pkg::Msg$View;
)rs"); pub use $crate$::$pkg::Msg$Mut;
} )rs");
for (int i = 0; i < dep.enum_type_count(); ++i) { }
auto& enum_ = *dep.enum_type(i); for (int i = 0; i < dep->enum_type_count(); ++i) {
auto path = GetCrateRelativeQualifiedPath(ctx, enum_); auto* enum_ = dep->enum_type(i);
auto path = GetCrateRelativeQualifiedPath(ctx, *enum_);
ctx.Emit({{"crate", crate_name}, {"pkg::Enum", path}}, ctx.Emit({{"crate", crate_name}, {"pkg::Enum", path}},
R"rs( R"rs(
pub use $crate$::$pkg::Enum$; pub use $crate$::$pkg::Enum$;
)rs"); )rs");
} }
} }
// Emits all public imports of the current file // Emits public imports of all files coming from dependencies (imports of local
void EmitPublicImports(Context& ctx, const FileDescriptor& primary_file) { // files are implicitly public).
for (int i = 0; i < primary_file.public_dependency_count(); ++i) { //
auto& dep_file = *primary_file.public_dependency(i); // `import public` works transitively in C++ (although it doesn't respect
// If the publicly imported file is a src of the current `proto_library` // layering_check in clang). For Rust we actually make it layering clean because
// we don't need to emit `pub use` here, we already do it for all srcs in // Blaze compiles transitive proto deps as if they were direct.
// RustGenerator::Generate. In other words, all srcs are implicitly publicly //
// imported into the primary file for Protobuf Rust. // Note we don't reexport entire crates, only messages and enums from files that
// TODO: Handle the case where a non-primary src with the same // have been explicitly publicly imported. It may happen that a `proto_library`
// declared package as the primary src publicly imports a file that the // defines multiple files, but not all are publicly imported.
// primary doesn't. void EmitPublicImports(Context& ctx,
if (IsInCurrentlyGeneratingCrate(ctx, dep_file)) { const std::vector<const FileDescriptor*>& srcs) {
return; absl::flat_hash_set<const FileDescriptor*> files_in_current_target(
srcs.begin(), srcs.end());
std::vector<const FileDescriptor*> files_to_visit(srcs.begin(), srcs.end());
absl::c_reverse(files_to_visit);
while (!files_to_visit.empty()) {
const FileDescriptor* file = files_to_visit.back();
files_to_visit.pop_back();
if (!files_in_current_target.contains(file)) {
EmitPublicImportsForDepFile(ctx, file);
}
for (int i = 0; i < file->public_dependency_count(); ++i) {
files_to_visit.push_back(file->dependency(i));
} }
EmitPubUseForImportedTypes(ctx, primary_file, dep_file);
} }
} }
@ -179,35 +141,15 @@ void DeclareSubmodulesForNonPrimarySrcs(
} }
} }
// Emits `pub use <...>::Msg` for all messages in non primary sources into // Emits `pub use <...>::Msg` for all messages in non primary sources.
// their corresponding packages (each source file can declare a different void ReexportMessagesFromSubmodules(
// package).
//
// Returns the non-primary sources that should be reexported from the package of
// the primary file.
std::vector<const FileDescriptor*> ReexportMessagesFromSubmodules(
Context& ctx, const FileDescriptor& primary_file, Context& ctx, const FileDescriptor& primary_file,
absl::Span<const FileDescriptor* const> non_primary_srcs) { absl::Span<const FileDescriptor* const> non_primary_srcs) {
absl::btree_map<absl::string_view, std::vector<const FileDescriptor*>>
packages;
for (const FileDescriptor* file : non_primary_srcs) { for (const FileDescriptor* file : non_primary_srcs) {
packages[file->package()].push_back(file); EmitPubUseOfOwnTypes(ctx, primary_file, *file);
} }
for (const auto& pair : packages) {
// We will deal with messages for the package of the primary file later.
auto fds = pair.second;
absl::string_view package = fds[0]->package();
if (package == primary_file.package()) continue;
EmitOpeningOfPackageModules(ctx, package);
for (const FileDescriptor* c : fds) {
EmitPubUseOfOwnTypes(ctx, primary_file, *c);
}
EmitClosingOfPackageModules(ctx, package);
}
return packages[primary_file.package()];
} }
} // namespace } // namespace
bool RustGenerator::Generate(const FileDescriptor* file, bool RustGenerator::Generate(const FileDescriptor* file,
@ -256,29 +198,17 @@ bool RustGenerator::Generate(const FileDescriptor* file,
)rs"); )rs");
std::vector<const FileDescriptor*> file_contexts; std::vector<const FileDescriptor*> file_contexts(
for (const FileDescriptor* f : files_in_current_crate) { files_in_current_crate.begin(), files_in_current_crate.end());
file_contexts.push_back(f);
}
// Generating the primary file? // Generating the primary file?
if (file == &rust_generator_context.primary_file()) { if (file == &rust_generator_context.primary_file()) {
auto non_primary_srcs = absl::MakeConstSpan(file_contexts).subspan(1); auto non_primary_srcs = absl::MakeConstSpan(file_contexts).subspan(1);
DeclareSubmodulesForNonPrimarySrcs(ctx, *file, non_primary_srcs); DeclareSubmodulesForNonPrimarySrcs(ctx, *file, non_primary_srcs);
ReexportMessagesFromSubmodules(ctx, *file, non_primary_srcs);
std::vector<const FileDescriptor*> non_primary_srcs_in_primary_package = EmitPublicImports(ctx, file_contexts);
ReexportMessagesFromSubmodules(ctx, *file, non_primary_srcs);
EmitOpeningOfPackageModules(ctx, file->package());
for (const FileDescriptor* non_primary_file :
non_primary_srcs_in_primary_package) {
EmitPubUseOfOwnTypes(ctx, *file, *non_primary_file);
}
} }
EmitPublicImports(ctx, *file);
std::unique_ptr<io::ZeroCopyOutputStream> thunks_cc; std::unique_ptr<io::ZeroCopyOutputStream> thunks_cc;
std::unique_ptr<io::Printer> thunks_printer; std::unique_ptr<io::Printer> thunks_printer;
if (ctx.is_cpp()) { if (ctx.is_cpp()) {
@ -314,9 +244,6 @@ bool RustGenerator::Generate(const FileDescriptor* file,
ctx.printer().PrintRaw("\n"); ctx.printer().PrintRaw("\n");
} }
if (file == files_in_current_crate.front()) {
EmitClosingOfPackageModules(ctx, file->package());
}
return true; return true;
} }

@ -7,6 +7,7 @@
#include "google/protobuf/compiler/rust/naming.h" #include "google/protobuf/compiler/rust/naming.h"
#include <algorithm>
#include <string> #include <string>
#include <vector> #include <vector>
@ -17,7 +18,6 @@
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h" #include "absl/strings/str_join.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/strings/strip.h" #include "absl/strings/strip.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
@ -40,9 +40,8 @@ std::string GetUnderscoreDelimitedFullName(Context& ctx,
} }
} // namespace } // namespace
std::string GetCrateName(Context& ctx, const FileDescriptor& dep) { absl::string_view GetCrateName(Context& ctx, const FileDescriptor& dep) {
absl::string_view path = dep.name(); return ctx.generator_context().ImportPathToCrateName(dep.name());
return std::string(ctx.generator_context().ImportPathToCrateName(path));
} }
std::string GetRsFile(Context& ctx, const FileDescriptor& file) { std::string GetRsFile(Context& ctx, const FileDescriptor& file) {
@ -124,32 +123,20 @@ std::string ThunkMapOrRepeated(Context& ctx, const FieldDescriptor& field,
return thunkName; return thunkName;
} }
std::string RustModule(Context& ctx, const FileDescriptor& file, std::string RustModule(Context& ctx, const Descriptor* containing_type) {
const Descriptor* containing_type) {
std::vector<std::string> modules; std::vector<std::string> modules;
std::vector<std::string> package_modules =
absl::StrSplit(file.package(), '.', absl::SkipEmpty());
modules.reserve(package_modules.size());
for (const auto& module : package_modules) {
modules.push_back(RsSafeName(module));
}
// Innermost to outermost order. // Innermost to outermost order.
std::vector<std::string> modules_from_containing_types;
const Descriptor* parent = containing_type; const Descriptor* parent = containing_type;
while (parent != nullptr) { while (parent != nullptr) {
modules_from_containing_types.push_back(absl::StrCat(parent->name(), "_")); modules.push_back(absl::StrCat(parent->name(), "_"));
parent = parent->containing_type(); parent = parent->containing_type();
} }
// Add the modules from containing messages (rbegin/rend to get them in outer // Reverse the vector to get submodules in outer-to-inner order).
// to inner order). std::reverse(modules.begin(), modules.end());
modules.insert(modules.end(), modules_from_containing_types.rbegin(),
modules_from_containing_types.rend());
// If there is any modules at all, push an empty string on the end so that // If there are any modules at all, push an empty string on the end so that
// we get the trailing :: // we get the trailing ::
if (!modules.empty()) { if (!modules.empty()) {
modules.push_back(""); modules.push_back("");
@ -222,11 +209,11 @@ std::string RsTypePath(Context& ctx, const FieldDescriptor& field) {
} }
std::string RustModule(Context& ctx, const Descriptor& msg) { std::string RustModule(Context& ctx, const Descriptor& msg) {
return RustModule(ctx, *msg.file(), msg.containing_type()); return RustModule(ctx, msg.containing_type());
} }
std::string RustModule(Context& ctx, const EnumDescriptor& enum_) { std::string RustModule(Context& ctx, const EnumDescriptor& enum_) {
return RustModule(ctx, *enum_.file(), enum_.containing_type()); return RustModule(ctx, enum_.containing_type());
} }
std::string RustInternalModuleName(Context& ctx, const FileDescriptor& file) { std::string RustInternalModuleName(Context& ctx, const FileDescriptor& file) {

@ -20,7 +20,7 @@ namespace google {
namespace protobuf { namespace protobuf {
namespace compiler { namespace compiler {
namespace rust { namespace rust {
std::string GetCrateName(Context& ctx, const FileDescriptor& dep); absl::string_view GetCrateName(Context& ctx, const FileDescriptor& dep);
std::string GetRsFile(Context& ctx, const FileDescriptor& file); std::string GetRsFile(Context& ctx, const FileDescriptor& file);
std::string GetThunkCcFile(Context& ctx, const FileDescriptor& file); std::string GetThunkCcFile(Context& ctx, const FileDescriptor& file);

Loading…
Cancel
Save