1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 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 33#include <string> 34#include <iostream> 35 36#include <google/protobuf/stubs/common.h> 37#include <google/protobuf/test_util_lite.h> 38#include <google/protobuf/unittest_lite.pb.h> 39 40using namespace std; 41 42namespace { 43// Helper methods to test parsing merge behavior. 44void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) { 45 GOOGLE_CHECK(message.optional_int32() == 3); 46 GOOGLE_CHECK(message.optional_int64() == 2); 47 GOOGLE_CHECK(message.optional_string() == "hello"); 48} 49 50void AssignParsingMergeMessages( 51 google::protobuf::unittest::TestAllTypesLite* msg1, 52 google::protobuf::unittest::TestAllTypesLite* msg2, 53 google::protobuf::unittest::TestAllTypesLite* msg3) { 54 msg1->set_optional_int32(1); 55 msg2->set_optional_int64(2); 56 msg3->set_optional_int32(3); 57 msg3->set_optional_string("hello"); 58} 59 60} // namespace 61 62int main(int argc, char* argv[]) { 63 string data, packed_data; 64 65 { 66 protobuf_unittest::TestAllTypesLite message, message2, message3; 67 google::protobuf::TestUtilLite::ExpectClear(message); 68 google::protobuf::TestUtilLite::SetAllFields(&message); 69 message2.CopyFrom(message); 70 data = message.SerializeAsString(); 71 message3.ParseFromString(data); 72 google::protobuf::TestUtilLite::ExpectAllFieldsSet(message); 73 google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2); 74 google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3); 75 google::protobuf::TestUtilLite::ModifyRepeatedFields(&message); 76 google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message); 77 message.Clear(); 78 google::protobuf::TestUtilLite::ExpectClear(message); 79 } 80 81 { 82 protobuf_unittest::TestAllExtensionsLite message, message2, message3; 83 google::protobuf::TestUtilLite::ExpectExtensionsClear(message); 84 google::protobuf::TestUtilLite::SetAllExtensions(&message); 85 message2.CopyFrom(message); 86 string extensions_data = message.SerializeAsString(); 87 GOOGLE_CHECK(extensions_data == data); 88 message3.ParseFromString(extensions_data); 89 google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message); 90 google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2); 91 google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3); 92 google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message); 93 google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message); 94 message.Clear(); 95 google::protobuf::TestUtilLite::ExpectExtensionsClear(message); 96 } 97 98 { 99 protobuf_unittest::TestPackedTypesLite message, message2, message3; 100 google::protobuf::TestUtilLite::ExpectPackedClear(message); 101 google::protobuf::TestUtilLite::SetPackedFields(&message); 102 message2.CopyFrom(message); 103 packed_data = message.SerializeAsString(); 104 message3.ParseFromString(packed_data); 105 google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message); 106 google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2); 107 google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3); 108 google::protobuf::TestUtilLite::ModifyPackedFields(&message); 109 google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message); 110 message.Clear(); 111 google::protobuf::TestUtilLite::ExpectPackedClear(message); 112 } 113 114 { 115 protobuf_unittest::TestPackedExtensionsLite message, message2, message3; 116 google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); 117 google::protobuf::TestUtilLite::SetPackedExtensions(&message); 118 message2.CopyFrom(message); 119 string packed_extensions_data = message.SerializeAsString(); 120 GOOGLE_CHECK(packed_extensions_data == packed_data); 121 message3.ParseFromString(packed_extensions_data); 122 google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message); 123 google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2); 124 google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3); 125 google::protobuf::TestUtilLite::ModifyPackedExtensions(&message); 126 google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message); 127 message.Clear(); 128 google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); 129 } 130 131 { 132 // Test that if an optional or required message/group field appears multiple 133 // times in the input, they need to be merged. 134 google::protobuf::unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator; 135 google::protobuf::unittest::TestAllTypesLite* msg1; 136 google::protobuf::unittest::TestAllTypesLite* msg2; 137 google::protobuf::unittest::TestAllTypesLite* msg3; 138 139#define ASSIGN_REPEATED_FIELD(FIELD) \ 140 msg1 = generator.add_##FIELD(); \ 141 msg2 = generator.add_##FIELD(); \ 142 msg3 = generator.add_##FIELD(); \ 143 AssignParsingMergeMessages(msg1, msg2, msg3) 144 145 ASSIGN_REPEATED_FIELD(field1); 146 ASSIGN_REPEATED_FIELD(field2); 147 ASSIGN_REPEATED_FIELD(field3); 148 ASSIGN_REPEATED_FIELD(ext1); 149 ASSIGN_REPEATED_FIELD(ext2); 150 151#undef ASSIGN_REPEATED_FIELD 152#define ASSIGN_REPEATED_GROUP(FIELD) \ 153 msg1 = generator.add_##FIELD()->mutable_field1(); \ 154 msg2 = generator.add_##FIELD()->mutable_field1(); \ 155 msg3 = generator.add_##FIELD()->mutable_field1(); \ 156 AssignParsingMergeMessages(msg1, msg2, msg3) 157 158 ASSIGN_REPEATED_GROUP(group1); 159 ASSIGN_REPEATED_GROUP(group2); 160 161#undef ASSIGN_REPEATED_GROUP 162 163 string buffer; 164 generator.SerializeToString(&buffer); 165 google::protobuf::unittest::TestParsingMergeLite parsing_merge; 166 parsing_merge.ParseFromString(buffer); 167 168 // Required and optional fields should be merged. 169 ExpectMessageMerged(parsing_merge.required_all_types()); 170 ExpectMessageMerged(parsing_merge.optional_all_types()); 171 ExpectMessageMerged( 172 parsing_merge.optionalgroup().optional_group_all_types()); 173 ExpectMessageMerged(parsing_merge.GetExtension( 174 google::protobuf::unittest::TestParsingMergeLite::optional_ext)); 175 176 // Repeated fields should not be merged. 177 GOOGLE_CHECK(parsing_merge.repeated_all_types_size() == 3); 178 GOOGLE_CHECK(parsing_merge.repeatedgroup_size() == 3); 179 GOOGLE_CHECK(parsing_merge.ExtensionSize( 180 google::protobuf::unittest::TestParsingMergeLite::repeated_ext) == 3); 181 } 182 183 cout << "PASS" << endl; 184 return 0; 185} 186