mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
#protobuf #rust Generate fields with imported types
Before this change if a field type was defined in a imported .proto file then our codegen would not generate the field. After this change such fields are correctly generated (see tests). This change is rather trivial as all the supporting infra has been implemented as part of the .proto -> crate mapping CLs. PiperOrigin-RevId: 601443383
This commit is contained in:
parent
5f51020f5d
commit
90015d3145
10 changed files with 221 additions and 36 deletions
|
|
@ -1,10 +1,10 @@
|
|||
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
|
||||
load(
|
||||
"//rust:defs.bzl",
|
||||
"rust_cc_proto_library",
|
||||
"rust_proto_library",
|
||||
"rust_upb_proto_library",
|
||||
)
|
||||
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
|
||||
|
||||
UNITTEST_PROTO_TARGET = "//src/google/protobuf:test_protos"
|
||||
|
||||
|
|
@ -440,3 +440,64 @@ rust_upb_proto_library(
|
|||
],
|
||||
deps = [":struct"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "imported_types_proto",
|
||||
testonly = True,
|
||||
srcs = ["imported_types.proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "imported_types_cc_proto",
|
||||
testonly = True,
|
||||
deps = [":imported_types_proto"],
|
||||
)
|
||||
|
||||
rust_cc_proto_library(
|
||||
name = "imported_types_cc_rust_proto",
|
||||
testonly = True,
|
||||
visibility = [
|
||||
"//rust/test/shared:__subpackages__",
|
||||
],
|
||||
deps = [":imported_types_cc_proto"],
|
||||
)
|
||||
|
||||
rust_upb_proto_library(
|
||||
name = "imported_types_upb_rust_proto",
|
||||
testonly = True,
|
||||
visibility = [
|
||||
"//rust/test/shared:__subpackages__",
|
||||
],
|
||||
deps = [":imported_types_proto"],
|
||||
)
|
||||
|
||||
proto_library(
|
||||
name = "fields_with_imported_types_proto",
|
||||
testonly = True,
|
||||
srcs = ["fields_with_imported_types.proto"],
|
||||
deps = [":imported_types_proto"],
|
||||
)
|
||||
|
||||
cc_proto_library(
|
||||
name = "fields_with_imported_types_cc_proto",
|
||||
testonly = True,
|
||||
deps = [":fields_with_imported_types_proto"],
|
||||
)
|
||||
|
||||
rust_cc_proto_library(
|
||||
name = "fields_with_imported_types_cc_rust_proto",
|
||||
testonly = True,
|
||||
visibility = [
|
||||
"//rust/test/shared:__subpackages__",
|
||||
],
|
||||
deps = [":fields_with_imported_types_cc_proto"],
|
||||
)
|
||||
|
||||
rust_upb_proto_library(
|
||||
name = "fields_with_imported_types_upb_rust_proto",
|
||||
testonly = True,
|
||||
visibility = [
|
||||
"//rust/test/shared:__subpackages__",
|
||||
],
|
||||
deps = [":fields_with_imported_types_proto"],
|
||||
)
|
||||
|
|
|
|||
22
rust/test/fields_with_imported_types.proto
Normal file
22
rust/test/fields_with_imported_types.proto
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2024 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 main;
|
||||
|
||||
import "google/protobuf/rust/test/imported_types.proto";
|
||||
|
||||
message MsgWithFieldsWithImportedTypes {
|
||||
optional imported_types.ImportedMessage imported_message_field = 1;
|
||||
optional imported_types.ImportedEnum imported_enum_field = 2;
|
||||
|
||||
oneof imported_types_oneof {
|
||||
imported_types.ImportedMessage imported_message_oneof = 3;
|
||||
imported_types.ImportedEnum imported_enum_oneof = 4;
|
||||
}
|
||||
}
|
||||
19
rust/test/imported_types.proto
Normal file
19
rust/test/imported_types.proto
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2024 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 imported_types;
|
||||
|
||||
message ImportedMessage {
|
||||
optional int32 num = 1;
|
||||
}
|
||||
|
||||
enum ImportedEnum {
|
||||
IMPORTED_ENUM_UNKNOWN = 0;
|
||||
IMPORTED_ENUM_BAR = 1;
|
||||
}
|
||||
|
|
@ -481,3 +481,33 @@ rust_test(
|
|||
"//rust/test:struct_upb_rust_proto",
|
||||
],
|
||||
)
|
||||
|
||||
rust_test(
|
||||
name = "fields_with_imported_types_cpp_test",
|
||||
srcs = ["fields_with_imported_types_test.rs"],
|
||||
tags = [
|
||||
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
|
||||
"not_build:arm",
|
||||
],
|
||||
deps = [
|
||||
"//rust:protobuf_cpp",
|
||||
"//rust/test:fields_with_imported_types_cc_rust_proto",
|
||||
"//rust/test:imported_types_cc_rust_proto",
|
||||
"@crate_index//:googletest",
|
||||
],
|
||||
)
|
||||
|
||||
rust_test(
|
||||
name = "fields_with_imported_types_upb_test",
|
||||
srcs = ["fields_with_imported_types_test.rs"],
|
||||
tags = [
|
||||
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
|
||||
"not_build:arm",
|
||||
],
|
||||
deps = [
|
||||
"//rust:protobuf_upb",
|
||||
"//rust/test:fields_with_imported_types_upb_rust_proto",
|
||||
"//rust/test:imported_types_upb_rust_proto",
|
||||
"@crate_index//:googletest",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
42
rust/test/shared/fields_with_imported_types_test.rs
Normal file
42
rust/test/shared/fields_with_imported_types_test.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2024 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 that fields with types that are defined in imported .proto
|
||||
/// files are generated. In particular where the imported .proto file is part of
|
||||
/// a separate proto_library target.
|
||||
use googletest::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn test_message_field_generated() {
|
||||
use fields_with_imported_types_proto::MsgWithFieldsWithImportedTypes;
|
||||
use imported_types_proto::ImportedMessageView;
|
||||
|
||||
let msg = MsgWithFieldsWithImportedTypes::new();
|
||||
assert_that!(msg.imported_message_field(), matches_pattern!(ImportedMessageView { .. }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum_field_generated() {
|
||||
use fields_with_imported_types_proto::MsgWithFieldsWithImportedTypes;
|
||||
use imported_types_proto::ImportedEnum;
|
||||
|
||||
let msg = MsgWithFieldsWithImportedTypes::new();
|
||||
assert_that!(msg.imported_enum_field(), eq(ImportedEnum::Unknown));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_oneof_message_field_generated() {
|
||||
use fields_with_imported_types_proto::MsgWithFieldsWithImportedTypes;
|
||||
use fields_with_imported_types_proto::MsgWithFieldsWithImportedTypes_::ImportedTypesOneof::not_set;
|
||||
use imported_types_proto::ImportedEnum;
|
||||
use imported_types_proto::ImportedMessageView;
|
||||
|
||||
let msg = MsgWithFieldsWithImportedTypes::new();
|
||||
assert_that!(msg.imported_message_oneof(), matches_pattern!(ImportedMessageView { .. }));
|
||||
assert_that!(msg.imported_enum_oneof(), eq(ImportedEnum::Unknown));
|
||||
assert_that!(msg.imported_types_oneof(), matches_pattern!(not_set(_)));
|
||||
}
|
||||
|
|
@ -64,12 +64,6 @@ std::unique_ptr<AccessorGenerator> AccessorGeneratorFor(
|
|||
}
|
||||
return std::make_unique<SingularScalar>();
|
||||
case FieldDescriptor::TYPE_ENUM:
|
||||
// TODO: support enums which are defined in other crates.
|
||||
if (!IsInCurrentlyGeneratingCrate(ctx, *field.enum_type())) {
|
||||
return std::make_unique<UnsupportedField>(
|
||||
"enum fields that are imported from another proto_library"
|
||||
" (defined in a separate Rust crate) are not supported");
|
||||
}
|
||||
if (field.is_repeated()) {
|
||||
return std::make_unique<RepeatedField>();
|
||||
}
|
||||
|
|
@ -81,12 +75,6 @@ std::unique_ptr<AccessorGenerator> AccessorGeneratorFor(
|
|||
}
|
||||
return std::make_unique<SingularString>();
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
// TODO: support messages which are defined in other crates.
|
||||
if (!IsInCurrentlyGeneratingCrate(ctx, *field.message_type())) {
|
||||
return std::make_unique<UnsupportedField>(
|
||||
"message fields that are imported from another proto_library"
|
||||
" (defined in a separate Rust crate) are not supported");
|
||||
}
|
||||
if (field.is_repeated()) {
|
||||
return std::make_unique<RepeatedField>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,22 @@ std::string ThunkName(Context& ctx, const Descriptor& msg,
|
|||
op);
|
||||
}
|
||||
|
||||
std::string GetFullyQualifiedPath(Context& ctx, const Descriptor& msg) {
|
||||
auto rel_path = GetCrateRelativeQualifiedPath(ctx, msg);
|
||||
if (IsInCurrentlyGeneratingCrate(ctx, msg)) {
|
||||
return absl::StrCat("crate::", rel_path);
|
||||
}
|
||||
return absl::StrCat(GetCrateName(ctx, *msg.file()), "::", rel_path);
|
||||
}
|
||||
|
||||
std::string GetFullyQualifiedPath(Context& ctx, const EnumDescriptor& enum_) {
|
||||
auto rel_path = GetCrateRelativeQualifiedPath(ctx, enum_);
|
||||
if (IsInCurrentlyGeneratingCrate(ctx, enum_)) {
|
||||
return absl::StrCat("crate::", rel_path);
|
||||
}
|
||||
return absl::StrCat(GetCrateName(ctx, *enum_.file()), "::", rel_path);
|
||||
}
|
||||
|
||||
std::string RsTypePath(Context& ctx, const FieldDescriptor& field) {
|
||||
switch (field.type()) {
|
||||
case FieldDescriptor::TYPE_BOOL:
|
||||
|
|
@ -194,13 +210,9 @@ std::string RsTypePath(Context& ctx, const FieldDescriptor& field) {
|
|||
case FieldDescriptor::TYPE_STRING:
|
||||
return "::__pb::ProtoStr";
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
// TODO: Fix depending on types from other proto_libraries.
|
||||
return absl::StrCat(
|
||||
"crate::", GetCrateRelativeQualifiedPath(ctx, *field.message_type()));
|
||||
return GetFullyQualifiedPath(ctx, *field.message_type());
|
||||
case FieldDescriptor::TYPE_ENUM:
|
||||
// TODO: Fix depending on types from other proto_libraries.
|
||||
return absl::StrCat(
|
||||
"crate::", GetCrateRelativeQualifiedPath(ctx, *field.enum_type()));
|
||||
return GetFullyQualifiedPath(ctx, *field.enum_type());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,16 +106,8 @@ std::string RsTypeNameView(Context& ctx, const FieldDescriptor& field) {
|
|||
case FieldDescriptor::TYPE_STRING:
|
||||
return "&'msg ::__pb::ProtoStr";
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
// TODO: support messages which are defined in other crates.
|
||||
if (!IsInCurrentlyGeneratingCrate(ctx, *field.message_type())) {
|
||||
return "";
|
||||
}
|
||||
return absl::StrCat("::__pb::View<'msg, ", RsTypePath(ctx, field), ">");
|
||||
case FieldDescriptor::TYPE_ENUM:
|
||||
// TODO: support enums which are defined in other crates.
|
||||
if (!IsInCurrentlyGeneratingCrate(ctx, *field.enum_type())) {
|
||||
return "";
|
||||
}
|
||||
return absl::StrCat("::__pb::View<'msg, ", RsTypePath(ctx, field), ">");
|
||||
case FieldDescriptor::TYPE_GROUP: // Not supported yet.
|
||||
return "";
|
||||
|
|
@ -151,16 +143,8 @@ std::string RsTypeNameMut(Context& ctx, const FieldDescriptor& field) {
|
|||
case FieldDescriptor::TYPE_STRING:
|
||||
return "::__pb::ProtoStrMut<'msg>";
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
// TODO: support messages which are defined in other crates.
|
||||
if (!IsInCurrentlyGeneratingCrate(ctx, *field.message_type())) {
|
||||
return "";
|
||||
}
|
||||
return absl::StrCat("::__pb::Mut<'msg, ", RsTypePath(ctx, field), ">");
|
||||
case FieldDescriptor::TYPE_ENUM:
|
||||
// TODO: support enums which are defined in other crates.
|
||||
if (!IsInCurrentlyGeneratingCrate(ctx, *field.enum_type())) {
|
||||
return "";
|
||||
}
|
||||
return absl::StrCat("::__pb::Mut<'msg, ", RsTypePath(ctx, field), ">");
|
||||
case FieldDescriptor::TYPE_GROUP: // Not supported yet.
|
||||
return "";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
|
||||
|
||||
exports_files(
|
||||
glob(["*.proto"]),
|
||||
glob(["*.proto"]) + ["rust_bazel_crate_mapping.txt"],
|
||||
visibility = [
|
||||
"//src/google/protobuf/editions:__pkg__",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
proto3_implicit_proto
|
||||
1
|
||||
third_party/protobuf/editions/codegen_tests/proto3_implicit.proto
|
||||
proto2_optional_proto
|
||||
1
|
||||
third_party/protobuf/editions/codegen_tests/proto2_optional.proto
|
||||
proto3_enum_proto
|
||||
1
|
||||
third_party/protobuf/editions/codegen_tests/proto3_enum.proto
|
||||
struct
|
||||
1
|
||||
google/protobuf/struct.proto
|
||||
wrappers
|
||||
1
|
||||
google/protobuf/wrappers.proto
|
||||
duration
|
||||
1
|
||||
google/protobuf/duration.proto
|
||||
timestamp
|
||||
1
|
||||
google/protobuf/timestamp.proto
|
||||
field_mask
|
||||
1
|
||||
google/protobuf/field_mask.proto
|
||||
any
|
||||
1
|
||||
google/protobuf/any.proto
|
||||
Loading…
Add table
Add a link
Reference in a new issue