1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// https://developers.google.com/protocol-buffers/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// Author: kenton@google.com (Kenton Varda) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34// 35// This test insures that google/protobuf/descriptor.pb.{h,cc} match exactly 36// what would be generated by the protocol compiler. These files are not 37// generated automatically at build time because they are compiled into the 38// protocol compiler itself. So, if they were auto-generated, you'd have a 39// chicken-and-egg problem. 40// 41// If this test fails, run the script 42// "generate_descriptor_proto.sh" and add 43// descriptor.pb.{h,cc} to your changelist. 44 45#include <map> 46 47#include <google/protobuf/compiler/cpp/cpp_generator.h> 48#include <google/protobuf/compiler/importer.h> 49#include <google/protobuf/descriptor.h> 50#include <google/protobuf/io/zero_copy_stream_impl.h> 51#include <google/protobuf/stubs/map_util.h> 52#include <google/protobuf/stubs/stl_util.h> 53#include <google/protobuf/stubs/strutil.h> 54#include <google/protobuf/stubs/substitute.h> 55 56#include <google/protobuf/testing/file.h> 57#include <google/protobuf/testing/file.h> 58#include <google/protobuf/testing/googletest.h> 59#include <gtest/gtest.h> 60 61namespace google { 62namespace protobuf { 63namespace compiler { 64namespace cpp { 65 66namespace { 67 68class MockErrorCollector : public MultiFileErrorCollector { 69 public: 70 MockErrorCollector() {} 71 ~MockErrorCollector() {} 72 73 string text_; 74 75 // implements ErrorCollector --------------------------------------- 76 void AddError(const string& filename, int line, int column, 77 const string& message) { 78 strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", 79 filename, line, column, message); 80 } 81}; 82 83class MockGeneratorContext : public GeneratorContext { 84 public: 85 MockGeneratorContext() {} 86 ~MockGeneratorContext() { 87 STLDeleteValues(&files_); 88 } 89 90 void ExpectFileMatches(const string& virtual_filename, 91 const string& physical_filename) { 92 string* expected_contents = FindPtrOrNull(files_, virtual_filename); 93 ASSERT_TRUE(expected_contents != NULL) 94 << "Generator failed to generate file: " << virtual_filename; 95 96 string actual_contents; 97 GOOGLE_CHECK_OK( 98 File::GetContents(TestSourceDir() + "/" + physical_filename, 99 &actual_contents, true)); 100 EXPECT_TRUE(actual_contents == *expected_contents) 101 << physical_filename << " needs to be regenerated. Please run " 102 "google/protobuf/compiler/release_compiler.sh and " 103 "generate_descriptor_proto.sh. Then add this file " 104 "to your CL."; 105 } 106 107 // implements GeneratorContext -------------------------------------- 108 109 virtual io::ZeroCopyOutputStream* Open(const string& filename) { 110 string** map_slot = &files_[filename]; 111 delete *map_slot; 112 *map_slot = new string; 113 114 return new io::StringOutputStream(*map_slot); 115 } 116 117 private: 118 map<string, string*> files_; 119}; 120 121TEST(BootstrapTest, GeneratedDescriptorMatches) { 122 MockErrorCollector error_collector; 123 DiskSourceTree source_tree; 124 source_tree.MapPath("", TestSourceDir()); 125 Importer importer(&source_tree, &error_collector); 126 const FileDescriptor* proto_file = 127 importer.Import("google/protobuf/descriptor.proto"); 128 const FileDescriptor* plugin_proto_file = 129 importer.Import("google/protobuf/compiler/plugin.proto"); 130 EXPECT_EQ("", error_collector.text_); 131 ASSERT_TRUE(proto_file != NULL); 132 ASSERT_TRUE(plugin_proto_file != NULL); 133 134 CppGenerator generator; 135 MockGeneratorContext context; 136 string error; 137 string parameter = "dllexport_decl=LIBPROTOBUF_EXPORT"; 138 ASSERT_TRUE(generator.Generate(proto_file, parameter, 139 &context, &error)); 140 parameter = "dllexport_decl=LIBPROTOC_EXPORT"; 141 ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter, 142 &context, &error)); 143 144 context.ExpectFileMatches("google/protobuf/descriptor.pb.h", 145 "google/protobuf/descriptor.pb.h"); 146 context.ExpectFileMatches("google/protobuf/descriptor.pb.cc", 147 "google/protobuf/descriptor.pb.cc"); 148 context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h", 149 "google/protobuf/compiler/plugin.pb.h"); 150 context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc", 151 "google/protobuf/compiler/plugin.pb.cc"); 152} 153 154} // namespace 155 156} // namespace cpp 157} // namespace compiler 158} // namespace protobuf 159} // namespace google 160