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 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#include <google/protobuf/io/coded_stream.h> 40#include <google/protobuf/io/zero_copy_stream_impl_lite.h> 41#include <google/protobuf/wire_format_lite.h> 42#include <google/protobuf/wire_format_lite_inl.h> 43 44using namespace std; 45 46namespace { 47// Helper methods to test parsing merge behavior. 48void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) { 49 GOOGLE_CHECK(message.optional_int32() == 3); 50 GOOGLE_CHECK(message.optional_int64() == 2); 51 GOOGLE_CHECK(message.optional_string() == "hello"); 52} 53 54void AssignParsingMergeMessages( 55 google::protobuf::unittest::TestAllTypesLite* msg1, 56 google::protobuf::unittest::TestAllTypesLite* msg2, 57 google::protobuf::unittest::TestAllTypesLite* msg3) { 58 msg1->set_optional_int32(1); 59 msg2->set_optional_int64(2); 60 msg3->set_optional_int32(3); 61 msg3->set_optional_string("hello"); 62} 63 64void SetAllTypesInEmptyMessageUnknownFields( 65 google::protobuf::unittest::TestEmptyMessageLite* empty_message) { 66 protobuf_unittest::TestAllTypesLite message; 67 google::protobuf::TestUtilLite::ExpectClear(message); 68 google::protobuf::TestUtilLite::SetAllFields(&message); 69 string data = message.SerializeAsString(); 70 empty_message->ParseFromString(data); 71} 72 73void SetSomeTypesInEmptyMessageUnknownFields( 74 google::protobuf::unittest::TestEmptyMessageLite* empty_message) { 75 protobuf_unittest::TestAllTypesLite message; 76 google::protobuf::TestUtilLite::ExpectClear(message); 77 message.set_optional_int32(101); 78 message.set_optional_int64(102); 79 message.set_optional_uint32(103); 80 message.set_optional_uint64(104); 81 string data = message.SerializeAsString(); 82 empty_message->ParseFromString(data); 83} 84 85} // namespace 86 87int main(int argc, char* argv[]) { 88 string data, data2, packed_data; 89 90 { 91 protobuf_unittest::TestAllTypesLite message, message2, message3; 92 google::protobuf::TestUtilLite::ExpectClear(message); 93 google::protobuf::TestUtilLite::SetAllFields(&message); 94 message2.CopyFrom(message); 95 data = message.SerializeAsString(); 96 message3.ParseFromString(data); 97 google::protobuf::TestUtilLite::ExpectAllFieldsSet(message); 98 google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2); 99 google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3); 100 google::protobuf::TestUtilLite::ModifyRepeatedFields(&message); 101 google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message); 102 message.Clear(); 103 google::protobuf::TestUtilLite::ExpectClear(message); 104 } 105 106 { 107 protobuf_unittest::TestAllExtensionsLite message, message2, message3; 108 google::protobuf::TestUtilLite::ExpectExtensionsClear(message); 109 google::protobuf::TestUtilLite::SetAllExtensions(&message); 110 message2.CopyFrom(message); 111 string extensions_data = message.SerializeAsString(); 112 message3.ParseFromString(extensions_data); 113 google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message); 114 google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2); 115 google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3); 116 google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message); 117 google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message); 118 message.Clear(); 119 google::protobuf::TestUtilLite::ExpectExtensionsClear(message); 120 } 121 122 { 123 protobuf_unittest::TestPackedTypesLite message, message2, message3; 124 google::protobuf::TestUtilLite::ExpectPackedClear(message); 125 google::protobuf::TestUtilLite::SetPackedFields(&message); 126 message2.CopyFrom(message); 127 packed_data = message.SerializeAsString(); 128 message3.ParseFromString(packed_data); 129 google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message); 130 google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2); 131 google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3); 132 google::protobuf::TestUtilLite::ModifyPackedFields(&message); 133 google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message); 134 message.Clear(); 135 google::protobuf::TestUtilLite::ExpectPackedClear(message); 136 } 137 138 { 139 protobuf_unittest::TestPackedExtensionsLite message, message2, message3; 140 google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); 141 google::protobuf::TestUtilLite::SetPackedExtensions(&message); 142 message2.CopyFrom(message); 143 string packed_extensions_data = message.SerializeAsString(); 144 GOOGLE_CHECK(packed_extensions_data == packed_data); 145 message3.ParseFromString(packed_extensions_data); 146 google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message); 147 google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2); 148 google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3); 149 google::protobuf::TestUtilLite::ModifyPackedExtensions(&message); 150 google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message); 151 message.Clear(); 152 google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); 153 } 154 155 { 156 // Test that if an optional or required message/group field appears multiple 157 // times in the input, they need to be merged. 158 google::protobuf::unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator; 159 google::protobuf::unittest::TestAllTypesLite* msg1; 160 google::protobuf::unittest::TestAllTypesLite* msg2; 161 google::protobuf::unittest::TestAllTypesLite* msg3; 162 163#define ASSIGN_REPEATED_FIELD(FIELD) \ 164 msg1 = generator.add_##FIELD(); \ 165 msg2 = generator.add_##FIELD(); \ 166 msg3 = generator.add_##FIELD(); \ 167 AssignParsingMergeMessages(msg1, msg2, msg3) 168 169 ASSIGN_REPEATED_FIELD(field1); 170 ASSIGN_REPEATED_FIELD(field2); 171 ASSIGN_REPEATED_FIELD(field3); 172 ASSIGN_REPEATED_FIELD(ext1); 173 ASSIGN_REPEATED_FIELD(ext2); 174 175#undef ASSIGN_REPEATED_FIELD 176#define ASSIGN_REPEATED_GROUP(FIELD) \ 177 msg1 = generator.add_##FIELD()->mutable_field1(); \ 178 msg2 = generator.add_##FIELD()->mutable_field1(); \ 179 msg3 = generator.add_##FIELD()->mutable_field1(); \ 180 AssignParsingMergeMessages(msg1, msg2, msg3) 181 182 ASSIGN_REPEATED_GROUP(group1); 183 ASSIGN_REPEATED_GROUP(group2); 184 185#undef ASSIGN_REPEATED_GROUP 186 187 string buffer; 188 generator.SerializeToString(&buffer); 189 google::protobuf::unittest::TestParsingMergeLite parsing_merge; 190 parsing_merge.ParseFromString(buffer); 191 192 // Required and optional fields should be merged. 193 ExpectMessageMerged(parsing_merge.required_all_types()); 194 ExpectMessageMerged(parsing_merge.optional_all_types()); 195 ExpectMessageMerged( 196 parsing_merge.optionalgroup().optional_group_all_types()); 197 ExpectMessageMerged(parsing_merge.GetExtension( 198 google::protobuf::unittest::TestParsingMergeLite::optional_ext)); 199 200 // Repeated fields should not be merged. 201 GOOGLE_CHECK(parsing_merge.repeated_all_types_size() == 3); 202 GOOGLE_CHECK(parsing_merge.repeatedgroup_size() == 3); 203 GOOGLE_CHECK(parsing_merge.ExtensionSize( 204 google::protobuf::unittest::TestParsingMergeLite::repeated_ext) == 3); 205 } 206 207 // Test unknown fields support for lite messages. 208 { 209 protobuf_unittest::TestAllTypesLite message, message2; 210 protobuf_unittest::TestEmptyMessageLite empty_message; 211 google::protobuf::TestUtilLite::ExpectClear(message); 212 google::protobuf::TestUtilLite::SetAllFields(&message); 213 data = message.SerializeAsString(); 214 empty_message.ParseFromString(data); 215 data.clear(); 216 data = empty_message.SerializeAsString(); 217 message2.ParseFromString(data); 218 data = message2.SerializeAsString(); 219 google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2); 220 message.Clear(); 221 google::protobuf::TestUtilLite::ExpectClear(message); 222 } 223 224 { 225 protobuf_unittest::TestAllExtensionsLite message, message2; 226 protobuf_unittest::TestEmptyMessageLite empty_message; 227 google::protobuf::TestUtilLite::ExpectExtensionsClear(message); 228 google::protobuf::TestUtilLite::SetAllExtensions(&message); 229 data = message.SerializeAsString(); 230 empty_message.ParseFromString(data); 231 data.clear(); 232 data = empty_message.SerializeAsString(); 233 message2.ParseFromString(data); 234 data = message2.SerializeAsString(); 235 google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2); 236 message.Clear(); 237 google::protobuf::TestUtilLite::ExpectExtensionsClear(message); 238 } 239 240 { 241 protobuf_unittest::TestPackedTypesLite message, message2; 242 protobuf_unittest::TestEmptyMessageLite empty_message; 243 google::protobuf::TestUtilLite::ExpectPackedClear(message); 244 google::protobuf::TestUtilLite::SetPackedFields(&message); 245 data = message.SerializeAsString(); 246 empty_message.ParseFromString(data); 247 data.clear(); 248 data = empty_message.SerializeAsString(); 249 message2.ParseFromString(data); 250 data = message2.SerializeAsString(); 251 google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2); 252 message.Clear(); 253 google::protobuf::TestUtilLite::ExpectPackedClear(message); 254 } 255 256 { 257 protobuf_unittest::TestPackedExtensionsLite message, message2; 258 protobuf_unittest::TestEmptyMessageLite empty_message; 259 google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); 260 google::protobuf::TestUtilLite::SetPackedExtensions(&message); 261 data = message.SerializeAsString(); 262 empty_message.ParseFromString(data); 263 data.clear(); 264 data = empty_message.SerializeAsString(); 265 message2.ParseFromString(data); 266 data = message2.SerializeAsString(); 267 google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2); 268 message.Clear(); 269 google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); 270 } 271 272 { 273 // Test Unknown fields swap 274 protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2; 275 SetAllTypesInEmptyMessageUnknownFields(&empty_message); 276 SetSomeTypesInEmptyMessageUnknownFields(&empty_message2); 277 data = empty_message.SerializeAsString(); 278 data2 = empty_message2.SerializeAsString(); 279 empty_message.Swap(&empty_message2); 280 GOOGLE_CHECK_EQ(data, empty_message2.SerializeAsString()); 281 GOOGLE_CHECK_EQ(data2, empty_message.SerializeAsString()); 282 } 283 284 { 285 // Test unknown fields swap with self 286 protobuf_unittest::TestEmptyMessageLite empty_message; 287 SetAllTypesInEmptyMessageUnknownFields(&empty_message); 288 data = empty_message.SerializeAsString(); 289 empty_message.Swap(&empty_message); 290 GOOGLE_CHECK_EQ(data, empty_message.SerializeAsString()); 291 } 292 293 { 294 // Test MergeFrom with unknown fields 295 protobuf_unittest::TestAllTypesLite message, message2; 296 protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2; 297 message.set_optional_int32(101); 298 message.add_repeated_int32(201); 299 message.set_optional_nested_enum(google::protobuf::unittest::TestAllTypesLite::BAZ); 300 message2.set_optional_int64(102); 301 message2.add_repeated_int64(202); 302 message2.set_optional_foreign_enum(google::protobuf::unittest::FOREIGN_LITE_BAZ); 303 304 data = message.SerializeAsString(); 305 empty_message.ParseFromString(data); 306 data = message2.SerializeAsString(); 307 empty_message2.ParseFromString(data); 308 message.MergeFrom(message2); 309 empty_message.MergeFrom(empty_message2); 310 311 data = empty_message.SerializeAsString(); 312 message2.ParseFromString(data); 313 // We do not compare the serialized output of a normal message and a lite 314 // message because the order of fields do not match. We convert lite message 315 // back into normal message, then compare. 316 GOOGLE_CHECK_EQ(message.SerializeAsString(), message2.SerializeAsString()); 317 } 318 319 { 320 // Test unknown enum value 321 protobuf_unittest::TestAllTypesLite message; 322 string buffer; 323 { 324 google::protobuf::io::StringOutputStream output_stream(&buffer); 325 google::protobuf::io::CodedOutputStream coded_output(&output_stream); 326 google::protobuf::internal::WireFormatLite::WriteTag( 327 protobuf_unittest::TestAllTypesLite::kOptionalNestedEnumFieldNumber, 328 google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output); 329 coded_output.WriteVarint32(10); 330 google::protobuf::internal::WireFormatLite::WriteTag( 331 protobuf_unittest::TestAllTypesLite::kRepeatedNestedEnumFieldNumber, 332 google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output); 333 coded_output.WriteVarint32(20); 334 } 335 message.ParseFromString(buffer); 336 data = message.SerializeAsString(); 337 GOOGLE_CHECK_EQ(data, buffer); 338 } 339 340 { 341 // Test Clear with unknown fields 342 protobuf_unittest::TestEmptyMessageLite empty_message; 343 SetAllTypesInEmptyMessageUnknownFields(&empty_message); 344 empty_message.Clear(); 345 GOOGLE_CHECK_EQ(0, empty_message.unknown_fields().size()); 346 } 347 348 cout << "PASS" << endl; 349 return 0; 350} 351