From 5a76e633ea9b5adb215e93fdc11e1c0c08b3fc74 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 17 Nov 2016 16:48:38 -0800 Subject: Integrated internal changes from Google --- src/google/protobuf/descriptor_unittest.cc | 160 +++++++++++++++++++++++++++-- 1 file changed, 151 insertions(+), 9 deletions(-) (limited to 'src/google/protobuf/descriptor_unittest.cc') diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index f6b3f1c5..7ec75156 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -41,8 +41,11 @@ #include #include +#include #include #include +#include +#include #include #include #include @@ -55,6 +58,7 @@ #include #include #include +#include #include #include @@ -488,6 +492,65 @@ TEST_F(FileDescriptorTest, Syntax) { } } +void ExtractDebugString( + const FileDescriptor* file, std::set* visited, + std::vector >* debug_strings) { + if (!visited->insert(file->name()).second) { + return; + } + for (int i = 0; i < file->dependency_count(); ++i) { + ExtractDebugString(file->dependency(i), visited, debug_strings); + } + debug_strings->push_back(make_pair(file->name(), file->DebugString())); +} + +class SimpleErrorCollector : public google::protobuf::io::ErrorCollector { + public: + // implements ErrorCollector --------------------------------------- + void AddError(int line, int column, const string& message) { + last_error_ = StringPrintf("%d:%d:", line, column) + message; + } + + const string& last_error() { return last_error_; } + + private: + string last_error_; +}; +// Test that the result of FileDescriptor::DebugString() can be used to create +// the original descriptors. +TEST_F(FileDescriptorTest, DebugStringRoundTrip) { + std::set visited; + std::vector > debug_strings; + ExtractDebugString(protobuf_unittest::TestAllTypes::descriptor()->file(), + &visited, &debug_strings); + ExtractDebugString( + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file(), + &visited, &debug_strings); + ExtractDebugString(proto3_arena_unittest::TestAllTypes::descriptor()->file(), + &visited, &debug_strings); + ASSERT_GE(debug_strings.size(), 3); + + DescriptorPool pool; + for (int i = 0; i < debug_strings.size(); ++i) { + const string& name = debug_strings[i].first; + const string& content = debug_strings[i].second; + google::protobuf::io::ArrayInputStream input_stream(content.data(), content.size()); + SimpleErrorCollector error_collector; + google::protobuf::io::Tokenizer tokenizer(&input_stream, &error_collector); + google::protobuf::compiler::Parser parser; + parser.RecordErrorsTo(&error_collector); + FileDescriptorProto proto; + ASSERT_TRUE(parser.Parse(&tokenizer, &proto)) + << error_collector.last_error() << "\n" + << content; + ASSERT_EQ("", error_collector.last_error()); + proto.set_name(name); + const FileDescriptor* descriptor = pool.BuildFile(proto); + ASSERT_TRUE(descriptor != NULL) << proto.DebugString(); + EXPECT_EQ(content, descriptor->DebugString()); + } +} + // =================================================================== // Test simple flat messages and fields. @@ -1861,7 +1924,7 @@ TEST_F(ExtensionDescriptorTest, FindExtensionByName) { } TEST_F(ExtensionDescriptorTest, FindAllExtensions) { - vector extensions; + std::vector extensions; pool_.FindAllExtensions(foo_, &extensions); ASSERT_EQ(4, extensions.size()); EXPECT_EQ(10, extensions[0]->number()); @@ -2625,7 +2688,7 @@ TEST_P(AllowUnknownDependenciesTest, CustomOption) { // Verify that no extension options were set, but they were left as // uninterpreted_options. - vector fields; + std::vector fields; file->options().GetReflection()->ListFields(file->options(), &fields); ASSERT_EQ(2, fields.size()); EXPECT_TRUE(file->options().has_optimize_for()); @@ -3276,6 +3339,85 @@ TEST(CustomOptions, OptionsWithRequiredEnums) { EXPECT_EQ(protobuf_unittest::NewOptionType::NEW_VALUE, new_enum_opt.value()); } +// Test that FileDescriptor::DebugString() formats custom options correctly. +TEST(CustomOptions, DebugString) { + DescriptorPool pool; + + FileDescriptorProto file_proto; + MessageOptions::descriptor()->file()->CopyTo(&file_proto); + ASSERT_TRUE(pool.BuildFile(file_proto) != NULL); + + // Add "foo.proto": + // import "google/protobuf/descriptor.proto"; + // package "protobuf_unittest"; + // option (protobuf_unittest.cc_option1) = 1; + // option (protobuf_unittest.cc_option2) = 2; + // extend google.protobuf.FieldOptions { + // optional int32 cc_option1 = 7736974; + // optional int32 cc_option2 = 7736975; + // } + ASSERT_TRUE(TextFormat::ParseFromString( + "name: \"foo.proto\" " + "package: \"protobuf_unittest\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "options { " + " uninterpreted_option { " + " name { " + " name_part: \"protobuf_unittest.cc_option1\" " + " is_extension: true " + " } " + " positive_int_value: 1 " + " } " + " uninterpreted_option { " + " name { " + " name_part: \"protobuf_unittest.cc_option2\" " + " is_extension: true " + " } " + " positive_int_value: 2 " + " } " + "} " + "extension { " + " name: \"cc_option1\" " + " extendee: \".google.protobuf.FileOptions\" " + // This field number is intentionally chosen to be the same as + // (.fileopt1) defined in unittest_custom_options.proto (linked + // in this test binary). This is to test whether we are messing + // generated pool with custom descriptor pools when dealing with + // custom options. + " number: 7736974 " + " label: LABEL_OPTIONAL " + " type: TYPE_INT32 " + "}" + "extension { " + " name: \"cc_option2\" " + " extendee: \".google.protobuf.FileOptions\" " + " number: 7736975 " + " label: LABEL_OPTIONAL " + " type: TYPE_INT32 " + "}", + &file_proto)); + const FileDescriptor* descriptor = pool.BuildFile(file_proto); + ASSERT_TRUE(descriptor != NULL); + + EXPECT_EQ(2, descriptor->extension_count()); + + ASSERT_EQ( + "syntax = \"proto2\";\n" + "\n" + "import \"google/protobuf/descriptor.proto\";\n" + "package protobuf_unittest;\n" + "\n" + "option (.protobuf_unittest.cc_option1) = 1;\n" + "option (.protobuf_unittest.cc_option2) = 2;\n" + "\n" + "extend .google.protobuf.FileOptions {\n" + " optional int32 cc_option1 = 7736974;\n" + " optional int32 cc_option2 = 7736975;\n" + "}\n" + "\n", + descriptor->DebugString()); +} + // =================================================================== class ValidationErrorTest : public testing::Test { @@ -5169,7 +5311,7 @@ TEST_F(ValidationErrorTest, ErrorsReportedToLogError) { "message_type { name: \"Foo\" } ", &file_proto)); - vector errors; + std::vector errors; { ScopedMemoryLog log; @@ -5598,8 +5740,8 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { "}", "foo.proto: BAR__BAZ: NAME: When enum name is stripped and label is " "PascalCased (BarBaz), this value label conflicts with " - "FOO_ENUM_BAR_BAZ. This " - "will make the proto fail to compile for some languages, such as C#.\n"); + "FOO_ENUM_BAR_BAZ. This will make the proto fail to compile for some " + "languages, such as C#.\n"); BuildFileWithErrors( "syntax: 'proto3'" @@ -5611,8 +5753,8 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { "}", "foo.proto: BAR_BAZ: NAME: When enum name is stripped and label is " "PascalCased (BarBaz), this value label conflicts with " - "FOO_ENUM__BAR_BAZ. This " - "will make the proto fail to compile for some languages, such as C#.\n"); + "FOO_ENUM__BAR_BAZ. This will make the proto fail to compile for some " + "languages, such as C#.\n"); // This isn't an error because the underscore will cause the PascalCase to // differ by case (BarBaz vs. Barbaz). @@ -6159,7 +6301,7 @@ TEST_F(DatabaseBackedPoolTest, FindAllExtensions) { for (int i = 0; i < 2; ++i) { // Repeat the lookup twice, to check that we get consistent // results despite the fallback database lookup mutating the pool. - vector extensions; + std::vector extensions; pool.FindAllExtensions(foo, &extensions); ASSERT_EQ(1, extensions.size()); EXPECT_EQ(5, extensions[0]->number()); @@ -6170,7 +6312,7 @@ TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) { ErrorDescriptorDatabase error_database; DescriptorPool pool(&error_database); - vector errors; + std::vector errors; { ScopedMemoryLog log; -- cgit v1.2.3