|
23 | 23 | #include "absl/strings/str_cat.h" |
24 | 24 | #include "absl/types/span.h" |
25 | 25 | #include "google/protobuf/compiler/command_line_interface_tester.h" |
| 26 | +#include "google/protobuf/cpp_features.pb.h" |
26 | 27 | #include "google/protobuf/unittest_features.pb.h" |
27 | 28 | #include "google/protobuf/unittest_invalid_features.pb.h" |
28 | 29 |
|
@@ -2978,6 +2979,190 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) { |
2978 | 2979 | EXPECT_TRUE(descriptor_set.file(0).message_type(0).field(0).has_json_name()); |
2979 | 2980 | } |
2980 | 2981 |
|
| 2982 | +TEST_F(CommandLineInterfaceTest, ImportOption_DescriptorSetOut) { |
| 2983 | + CreateTempFile("google/protobuf/descriptor.proto", |
| 2984 | + google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); |
| 2985 | + CreateTempFile("custom_option.proto", R"schema( |
| 2986 | + edition = "2024"; |
| 2987 | + import "google/protobuf/descriptor.proto"; |
| 2988 | + extend google.protobuf.FileOptions { |
| 2989 | + int32 file_opt = 50000; |
| 2990 | + } |
| 2991 | + )schema"); |
| 2992 | + CreateTempFile("foo.proto", R"schema( |
| 2993 | + edition = "2024"; |
| 2994 | + import option "custom_option.proto"; |
| 2995 | + option (file_opt) = 99; |
| 2996 | + message Foo {} |
| 2997 | + )schema"); |
| 2998 | + |
| 2999 | + Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " |
| 3000 | + "--proto_path=$tmpdir foo.proto"); |
| 3001 | + |
| 3002 | + ExpectNoErrors(); |
| 3003 | + |
| 3004 | + FileDescriptorSet descriptor_set; |
| 3005 | + ReadDescriptorSet("descriptor_set", &descriptor_set); |
| 3006 | + ASSERT_FALSE(HasFatalFailure()); |
| 3007 | + ASSERT_EQ(descriptor_set.file_size(), 1); |
| 3008 | + EXPECT_EQ(descriptor_set.file(0).name(), "foo.proto"); |
| 3009 | + // Descriptor set should not have source code info. |
| 3010 | + EXPECT_FALSE(descriptor_set.file(0).has_source_code_info()); |
| 3011 | + // Descriptor set should have custom options. |
| 3012 | + ASSERT_EQ(descriptor_set.file(0).options().unknown_fields().field_count(), 1); |
| 3013 | + EXPECT_EQ(descriptor_set.file(0).options().unknown_fields().field(0).number(), |
| 3014 | + 50000); |
| 3015 | + EXPECT_EQ(descriptor_set.file(0).options().unknown_fields().field(0).varint(), |
| 3016 | + 99); |
| 3017 | +} |
| 3018 | + |
| 3019 | +TEST_F(CommandLineInterfaceTest, ImportOption_DescriptorSetOut_IncludeImports) { |
| 3020 | + CreateTempFile("google/protobuf/descriptor.proto", |
| 3021 | + google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); |
| 3022 | + CreateTempFile("custom_option.proto", R"schema( |
| 3023 | + edition = "2024"; |
| 3024 | + import "google/protobuf/descriptor.proto"; |
| 3025 | + extend google.protobuf.FileOptions { |
| 3026 | + int32 file_opt = 50000; |
| 3027 | + } |
| 3028 | + )schema"); |
| 3029 | + CreateTempFile("foo.proto", R"schema( |
| 3030 | + edition = "2024"; |
| 3031 | + import option "custom_option.proto"; |
| 3032 | + option (file_opt) = 99; |
| 3033 | + message Foo {} |
| 3034 | + )schema"); |
| 3035 | + |
| 3036 | + Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " |
| 3037 | + "--proto_path=$tmpdir foo.proto --include_imports"); |
| 3038 | + |
| 3039 | + ExpectNoErrors(); |
| 3040 | + |
| 3041 | + FileDescriptorSet descriptor_set; |
| 3042 | + ReadDescriptorSet("descriptor_set", &descriptor_set); |
| 3043 | + ASSERT_FALSE(HasFatalFailure()); |
| 3044 | + ASSERT_EQ(descriptor_set.file_size(), 3); |
| 3045 | + EXPECT_EQ(descriptor_set.file(0).name(), "google/protobuf/descriptor.proto"); |
| 3046 | + EXPECT_EQ(descriptor_set.file(1).name(), "custom_option.proto"); |
| 3047 | + EXPECT_EQ(descriptor_set.file(2).name(), "foo.proto"); |
| 3048 | + // Descriptor set should have custom options. |
| 3049 | + ASSERT_EQ(descriptor_set.file(2).options().unknown_fields().field_count(), 1); |
| 3050 | + EXPECT_EQ(descriptor_set.file(2).options().unknown_fields().field(0).number(), |
| 3051 | + 50000); |
| 3052 | + EXPECT_EQ(descriptor_set.file(2).options().unknown_fields().field(0).varint(), |
| 3053 | + 99); |
| 3054 | +} |
| 3055 | + |
| 3056 | +TEST_F(CommandLineInterfaceTest, ImportOption_DescriptorSetIn) { |
| 3057 | + FileDescriptorSet file_descriptor_set; |
| 3058 | + |
| 3059 | + DescriptorProto::descriptor()->file()->CopyTo(file_descriptor_set.add_file()); |
| 3060 | + pb::CppFeatures::descriptor()->file()->CopyTo(file_descriptor_set.add_file()); |
| 3061 | + |
| 3062 | + FileDescriptorProto* file = file_descriptor_set.add_file(); |
| 3063 | + file->set_syntax("editions"); |
| 3064 | + file->set_edition(Edition::EDITION_2024); |
| 3065 | + file->add_option_dependency(pb::CppFeatures::descriptor()->file()->name()); |
| 3066 | + file->set_name("foo.proto"); |
| 3067 | + DescriptorProto* message = file->add_message_type(); |
| 3068 | + message->set_name("Foo"); |
| 3069 | + FieldDescriptorProto* field = message->add_field(); |
| 3070 | + field->set_type(FieldDescriptorProto::TYPE_STRING); |
| 3071 | + field->set_name("a"); |
| 3072 | + field->set_number(1); |
| 3073 | + field->mutable_options() |
| 3074 | + ->mutable_features() |
| 3075 | + ->MutableExtension(pb::cpp) |
| 3076 | + ->set_string_type(pb::CppFeatures::VIEW); |
| 3077 | + |
| 3078 | + WriteDescriptorSet("foo.bin", &file_descriptor_set); |
| 3079 | + Run("protocol_compiler --test_out=$tmpdir " |
| 3080 | + "--descriptor_set_out=$tmpdir/descriptor_set " |
| 3081 | + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); |
| 3082 | + |
| 3083 | + ExpectNoErrors(); |
| 3084 | + |
| 3085 | + FileDescriptorSet descriptor_set; |
| 3086 | + ReadDescriptorSet("descriptor_set", &descriptor_set); |
| 3087 | + ASSERT_FALSE(HasFatalFailure()); |
| 3088 | + ASSERT_EQ(descriptor_set.file_size(), 1); |
| 3089 | + EXPECT_EQ(descriptor_set.file(0).name(), "foo.proto"); |
| 3090 | + // Descriptor set should have custom options set. |
| 3091 | + EXPECT_EQ(descriptor_set.file(0) |
| 3092 | + .message_type(0) |
| 3093 | + .field(0) |
| 3094 | + .options() |
| 3095 | + .features() |
| 3096 | + .GetExtension(pb::cpp) |
| 3097 | + .string_type(), |
| 3098 | + pb::CppFeatures::VIEW); |
| 3099 | +} |
| 3100 | + |
| 3101 | +TEST_F(CommandLineInterfaceTest, |
| 3102 | + ImportOption_DescriptorSetIn_MissingOptionDependency) { |
| 3103 | + FileDescriptorSet file_descriptor_set; |
| 3104 | + |
| 3105 | + FileDescriptorProto* file = file_descriptor_set.add_file(); |
| 3106 | + file->set_syntax("editions"); |
| 3107 | + file->set_edition(Edition::EDITION_2024); |
| 3108 | + file->add_option_dependency(pb::CppFeatures::descriptor()->file()->name()); |
| 3109 | + file->set_name("foo.proto"); |
| 3110 | + DescriptorProto* message = file->add_message_type(); |
| 3111 | + message->set_name("Foo"); |
| 3112 | + FieldDescriptorProto* field = message->add_field(); |
| 3113 | + field->set_type(FieldDescriptorProto::TYPE_STRING); |
| 3114 | + field->set_name("a"); |
| 3115 | + field->set_number(1); |
| 3116 | + field->mutable_options() |
| 3117 | + ->mutable_features() |
| 3118 | + ->MutableExtension(pb::cpp) |
| 3119 | + ->set_string_type(pb::CppFeatures::VIEW); |
| 3120 | + |
| 3121 | + WriteDescriptorSet("foo.bin", &file_descriptor_set); |
| 3122 | + Run("protocol_compiler --test_out=$tmpdir " |
| 3123 | + "--descriptor_set_out=$tmpdir/descriptor_set " |
| 3124 | + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); |
| 3125 | + |
| 3126 | + ExpectNoErrors(); |
| 3127 | + |
| 3128 | + FileDescriptorSet descriptor_set; |
| 3129 | + ReadDescriptorSet("descriptor_set", &descriptor_set); |
| 3130 | + ASSERT_FALSE(HasFatalFailure()); |
| 3131 | + ASSERT_EQ(descriptor_set.file_size(), 1); |
| 3132 | + EXPECT_EQ(descriptor_set.file(0).name(), "foo.proto"); |
| 3133 | + // Descriptor set should have custom options set. |
| 3134 | + EXPECT_EQ(descriptor_set.file(0) |
| 3135 | + .message_type(0) |
| 3136 | + .field(0) |
| 3137 | + .options() |
| 3138 | + .features() |
| 3139 | + .GetExtension(pb::cpp) |
| 3140 | + .string_type(), |
| 3141 | + pb::CppFeatures::VIEW); |
| 3142 | +} |
| 3143 | + |
| 3144 | +TEST_F(CommandLineInterfaceTest, ImportOption_DescriptorSetIn_MissingImport) { |
| 3145 | + FileDescriptorSet file_descriptor_set; |
| 3146 | + |
| 3147 | + CreateTempFile("foo.proto", |
| 3148 | + R"schema( |
| 3149 | + edition = "2024"; |
| 3150 | + import option "bar.proto"; |
| 3151 | + import option "google/protobuf/cpp_features.proto"; |
| 3152 | + option features.(pb.cpp).string_type = VIEW; |
| 3153 | + )schema"); |
| 3154 | + |
| 3155 | + WriteDescriptorSet("foo.bin", &file_descriptor_set); |
| 3156 | + Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir " |
| 3157 | + "--descriptor_set_out=$tmpdir/descriptor_set " |
| 3158 | + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); |
| 3159 | + |
| 3160 | + ExpectErrorSubstring("bar.proto: File not found"); |
| 3161 | + ExpectErrorSubstring( |
| 3162 | + "google/protobuf/cpp_features.proto: File not found"); |
| 3163 | + ExpectErrorSubstring("foo.proto:5:14: Option \"features.(pb.cpp)\" unknown"); |
| 3164 | +} |
| 3165 | + |
2981 | 3166 | TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) { |
2982 | 3167 | CreateTempFile("foo.proto", |
2983 | 3168 | "syntax = \"proto2\";\n" |
@@ -3250,32 +3435,6 @@ TEST_F(CommandLineInterfaceTest, OptionImportWithDebugRedactDeeplyNested) { |
3250 | 3435 | "option file_opt marked debug_redact"); |
3251 | 3436 | } |
3252 | 3437 |
|
3253 | | -TEST_F(CommandLineInterfaceTest, DisallowMissingOptionImportsDescriptorSetIn) { |
3254 | | - FileDescriptorSet file_descriptor_set; |
3255 | | - |
3256 | | - FileDescriptorProto* file = file_descriptor_set.add_file(); |
3257 | | - file->set_syntax("editions"); |
3258 | | - file->set_edition(Edition::EDITION_2024); |
3259 | | - file->set_name("foo.proto"); |
3260 | | - file->add_option_dependency("bar.proto"); |
3261 | | - file->add_message_type()->set_name("Foo"); |
3262 | | - |
3263 | | - // Add an unknown field to the file options to make it look like a custom |
3264 | | - // option. |
3265 | | - file->mutable_message_type(0) |
3266 | | - ->mutable_options() |
3267 | | - ->mutable_unknown_fields() |
3268 | | - ->AddVarint(123, 456); |
3269 | | - |
3270 | | - WriteDescriptorSet("foo.bin", &file_descriptor_set); |
3271 | | - |
3272 | | - Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " |
3273 | | - "--include_imports --descriptor_set_in=$tmpdir/foo.bin " |
3274 | | - "--proto_path=$tmpdir --experimental_editions foo.proto"); |
3275 | | - |
3276 | | - ExpectErrorSubstring("foo.proto: Import \"bar.proto\" was not found"); |
3277 | | -} |
3278 | | - |
3279 | 3438 | TEST_F(CommandLineInterfaceTest, DescriptorSetOptionRetention) { |
3280 | 3439 | // clang-format off |
3281 | 3440 | CreateTempFile( |
|
0 commit comments