diff options
Diffstat (limited to 'src/google/protobuf/compiler/mock_code_generator.cc')
-rw-r--r-- | src/google/protobuf/compiler/mock_code_generator.cc | 97 |
1 files changed, 83 insertions, 14 deletions
diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index e82e6ae1..e150f97d 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -35,32 +35,39 @@ #include <stdlib.h> #include <iostream> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <vector> -#include <google/protobuf/compiler/plugin.pb.h> + +#include <google/protobuf/stubs/strutil.h> + #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/testing/file.h> #include <google/protobuf/testing/file.h> #include <google/protobuf/testing/file.h> +#include <google/protobuf/compiler/plugin.pb.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/descriptor.h> -#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/text_format.h> #include <google/protobuf/stubs/substitute.h> #include <gtest/gtest.h> +#ifdef major +#undef major +#endif +#ifdef minor +#undef minor +#endif + namespace google { namespace protobuf { namespace compiler { // Returns the list of the names of files in all_files in the form of a // comma-separated string. -string CommaSeparatedList(const std::vector<const FileDescriptor*> all_files) { +string CommaSeparatedList(const std::vector<const FileDescriptor*>& all_files) { std::vector<string> names; for (size_t i = 0; i < all_files.size(); i++) { names.push_back(all_files[i]->name()); @@ -93,8 +100,7 @@ void MockCodeGenerator::ExpectGenerated( File::GetContents(output_directory + "/" + GetOutputFileName(name, file), &content, true)); - std::vector<string> lines = - Split(content, "\n", true); + std::vector<string> lines = Split(content, "\n", true); while (!lines.empty() && lines.back().empty()) { lines.pop_back(); @@ -128,11 +134,48 @@ void MockCodeGenerator::ExpectGenerated( } } +namespace { +void CheckSingleAnnotation(const string& expected_file, + const string& expected_text, + const string& file_content, + const GeneratedCodeInfo::Annotation& annotation) { + EXPECT_EQ(expected_file, annotation.source_file()); + ASSERT_GE(file_content.size(), annotation.begin()); + ASSERT_GE(file_content.size(), annotation.end()); + ASSERT_LE(annotation.begin(), annotation.end()); + EXPECT_EQ(expected_text.size(), annotation.end() - annotation.begin()); + EXPECT_EQ(expected_text, + file_content.substr(annotation.begin(), expected_text.size())); +} +} // anonymous namespace + +void MockCodeGenerator::CheckGeneratedAnnotations( + const string& name, const string& file, const string& output_directory) { + string file_content; + GOOGLE_CHECK_OK( + File::GetContents(output_directory + "/" + GetOutputFileName(name, file), + &file_content, true)); + string meta_content; + GOOGLE_CHECK_OK(File::GetContents( + output_directory + "/" + GetOutputFileName(name, file) + ".meta", + &meta_content, true)); + GeneratedCodeInfo annotations; + GOOGLE_CHECK(TextFormat::ParseFromString(meta_content, &annotations)); + ASSERT_EQ(3, annotations.annotation_size()); + CheckSingleAnnotation("first_annotation", "first", file_content, + annotations.annotation(0)); + CheckSingleAnnotation("second_annotation", "second", file_content, + annotations.annotation(1)); + CheckSingleAnnotation("third_annotation", "third", file_content, + annotations.annotation(2)); +} + bool MockCodeGenerator::Generate( const FileDescriptor* file, const string& parameter, GeneratorContext* context, string* error) const { + bool annotate = false; for (int i = 0; i < file->message_type_count(); i++) { if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) { string command = StripPrefixString(file->message_type(i)->name(), @@ -161,6 +204,8 @@ bool MockCodeGenerator::Generate( std::cerr << "Saw json_name: " << field_descriptor_proto.has_json_name() << std::endl; abort(); + } else if (command == "Annotate") { + annotate = true; } else if (command == "ShowVersionNumber") { Version compiler_version; context->GetCompilerVersion(&compiler_version); @@ -183,7 +228,7 @@ bool MockCodeGenerator::Generate( for (size_t i = 0; i < insert_into.size(); i++) { { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert( + std::unique_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert( GetOutputFileName(insert_into[i], file), kFirstInsertionPointName)); io::Printer printer(output.get(), '$'); printer.PrintRaw(GetOutputFileContent(name_, "first_insert", @@ -195,7 +240,7 @@ bool MockCodeGenerator::Generate( } { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->OpenForInsert(GetOutputFileName(insert_into[i], file), kSecondInsertionPointName)); io::Printer printer(output.get(), '$'); @@ -208,19 +253,43 @@ bool MockCodeGenerator::Generate( } } } else { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->Open(GetOutputFileName(name_, file))); - io::Printer printer(output.get(), '$'); - printer.PrintRaw(GetOutputFileContent(name_, parameter, - file, context)); + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( + &annotations); + io::Printer printer(output.get(), '$', + annotate ? &annotation_collector : NULL); + printer.PrintRaw(GetOutputFileContent(name_, parameter, file, context)); + string annotate_suffix = "_annotation"; + if (annotate) { + printer.Print("$p$", "p", "first"); + printer.Annotate("p", "first" + annotate_suffix); + } printer.PrintRaw(kFirstInsertionPoint); + if (annotate) { + printer.Print("$p$", "p", "second"); + printer.Annotate("p", "second" + annotate_suffix); + } printer.PrintRaw(kSecondInsertionPoint); + if (annotate) { + printer.Print("$p$", "p", "third"); + printer.Annotate("p", "third" + annotate_suffix); + } if (printer.failed()) { *error = "MockCodeGenerator detected write error."; return false; } + if (annotate) { + std::unique_ptr<io::ZeroCopyOutputStream> meta_output( + context->Open(GetOutputFileName(name_, file) + ".meta")); + if (!TextFormat::Print(annotations, meta_output.get())) { + *error = "MockCodeGenerator couldn't write .meta"; + return false; + } + } } return true; |