1b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// Protocol Buffers - Google's data interchange format
265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// Copyright 2008 Google Inc.  All rights reserved.
365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// http://code.google.com/p/protobuf/
465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//
565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// Redistribution and use in source and binary forms, with or without
665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// modification, are permitted provided that the following conditions are
765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// met:
865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//
965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//     * Redistributions of source code must retain the above copyright
1065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// notice, this list of conditions and the following disclaimer.
1165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//     * Redistributions in binary form must reproduce the above
1265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// copyright notice, this list of conditions and the following disclaimer
1365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// in the documentation and/or other materials provided with the
1465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// distribution.
1565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//     * Neither the name of Google Inc. nor the names of its
1665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// contributors may be used to endorse or promote products derived from
1765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// this software without specific prior written permission.
1865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//
1965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
3165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// Author: kenton@google.com (Kenton Varda)
3265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//  Based on original Protocol Buffers design by
3365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//  Sanjay Ghemawat, Jeff Dean, and others.
3465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
3565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include <google/protobuf/message.h>
3665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
3765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include <sys/types.h>
3865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include <sys/stat.h>
39a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#include <fcntl.h>
4065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#ifdef _MSC_VER
418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#include <io.h>
428f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#else
438f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#include <unistd.h>
448f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#endif
458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#include <sstream>
468f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#include <fstream>
478f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
488f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#include <google/protobuf/stubs/common.h>
4965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include <google/protobuf/io/zero_copy_stream_impl.h>
5065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include <google/protobuf/io/coded_stream.h>
5165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include <google/protobuf/descriptor.h>
528f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#include <google/protobuf/descriptor.pb.h>
538f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#include <google/protobuf/unittest.pb.h>
548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#include <google/protobuf/test_util.h>
5565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
568f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org#include <google/protobuf/testing/googletest.h>
5765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include <gtest/gtest.h>
5865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
5965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace google {
6065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace protobuf {
61a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
62c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifndef O_BINARY
63c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#ifdef _O_BINARY
64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#define O_BINARY _O_BINARY
65c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#else
66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#define O_BINARY 0     // If this isn't defined, the platform doesn't need it.
67c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comTEST(MessageTest, SerializeHelpers) {
71c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
72c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //   like a waste of time.
73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  protobuf_unittest::TestAllTypes message;
75c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  TestUtil::SetAllFields(&message);
76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  stringstream stream;
77c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
78c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  string str1("foo");
79c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  string str2("bar");
80a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
818e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_TRUE(message.SerializeToString(&str1));
824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  EXPECT_TRUE(message.AppendToString(&str2));
834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  EXPECT_TRUE(message.SerializeToOstream(&stream));
844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
858e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_EQ(str1.size() + 3, str2.size());
868e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_EQ("bar", str2.substr(0, 3));
87030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  // Don't use EXPECT_EQ because we don't want to dump raw binary data to
888e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // stdout.
898e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_TRUE(str2.substr(3) == str1);
908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
918e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // GCC gives some sort of error if we try to just do stream.str() == str1.
928e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  string temp = stream.str();
938e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_TRUE(temp == str1);
948e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
9540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  EXPECT_TRUE(message.SerializeAsString() == str1);
968e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
97030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org}
988e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
998e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgTEST(MessageTest, SerializeToBrokenOstream) {
1008e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  ofstream out;
10140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  protobuf_unittest::TestAllTypes message;
1028e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  message.set_optional_int32(123);
10340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
1048e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_FALSE(message.SerializeToOstream(&out));
1058e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
1068e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgTEST(MessageTest, ParseFromFileDescriptor) {
1088e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  string filename = TestSourceDir() +
1098e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                    "/google/protobuf/testdata/golden_message";
1108e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int file = open(filename.c_str(), O_RDONLY | O_BINARY);
1118e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1128e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  unittest::TestAllTypes message;
1138e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_TRUE(message.ParseFromFileDescriptor(file));
1148e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  TestUtil::ExpectAllFieldsSet(message);
1158e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1168e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_GE(close(file), 0);
1178e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
1188e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1198e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgTEST(MessageTest, ParsePackedFromFileDescriptor) {
1208e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  string filename =
1218e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org      TestSourceDir() +
1228432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      "/google/protobuf/testdata/golden_packed_fields_message";
1238432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  int file = open(filename.c_str(), O_RDONLY | O_BINARY);
1248432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
1258e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  unittest::TestPackedTypes message;
1268e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_TRUE(message.ParseFromFileDescriptor(file));
1278e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  TestUtil::ExpectPackedFieldsSet(message);
1288e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1298e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  EXPECT_GE(close(file), 0);
1308e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org}
1318e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1328e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgTEST(MessageTest, ParseHelpers) {
13340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // TODO(kenton):  Test more helpers?  They're all two-liners so it seems
1348e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  //   like a waste of time.
1358e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  string data;
13640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
1378e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  {
1388e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    // Set up.
13904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org    protobuf_unittest::TestAllTypes message;
14040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    TestUtil::SetAllFields(&message);
1418e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    message.SerializeToString(&data);
1428e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
1438e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1448e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  {
1452c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    // Test ParseFromString.
1462c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    protobuf_unittest::TestAllTypes message;
1472c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    EXPECT_TRUE(message.ParseFromString(data));
1482c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    TestUtil::ExpectAllFieldsSet(message);
1492c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  }
1502c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1512c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  {
1522c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    // Test ParseFromIstream.
1532c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    protobuf_unittest::TestAllTypes message;
1542c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    stringstream stream(data);
1552c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    EXPECT_TRUE(message.ParseFromIstream(&stream));
1562c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    EXPECT_TRUE(stream.eof());
1572c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    TestUtil::ExpectAllFieldsSet(message);
1582c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  }
1592c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1602c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  {
1612c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    // Test ParseFromBoundedZeroCopyStream.
1622c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    string data_with_junk(data);
1632c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    data_with_junk.append("some junk on the end");
1642c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
1652c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    protobuf_unittest::TestAllTypes message;
1662c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
1672c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    TestUtil::ExpectAllFieldsSet(message);
1682c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  }
1692c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1702c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  {
1712c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
1722c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    // EOF is reached before the expected number of bytes.
1732c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    io::ArrayInputStream stream(data.data(), data.size());
1742c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    protobuf_unittest::TestAllTypes message;
1752c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    EXPECT_FALSE(
1762c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org      message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
1772c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  }
1782c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org}
1792c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1802c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgTEST(MessageTest, ParseFailsIfNotInitialized) {
1812c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  unittest::TestRequired message;
1822c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  vector<string> errors;
1832c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1842c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  {
1852c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    ScopedMemoryLog log;
1862c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    EXPECT_FALSE(message.ParseFromString(""));
1872c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org    errors = log.GetMessages(ERROR);
1882c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  }
1892c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1902c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  ASSERT_EQ(1, errors.size());
1912c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" "
1922c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org            "because it is missing required fields: a, b, c",
1932c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org            errors[0]);
1942c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org}
1952c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1962c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgTEST(MessageTest, BypassInitializationCheckOnParse) {
1972c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  unittest::TestRequired message;
1982c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  io::ArrayInputStream raw_input(NULL, 0);
1992c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  io::CodedInputStream input(&raw_input);
2002c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  EXPECT_TRUE(message.MergePartialFromCodedStream(&input));
2012c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org}
2022c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
2032c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgTEST(MessageTest, InitializationErrorString) {
2042c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  unittest::TestRequired message;
2052c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  EXPECT_EQ("a, b, c", message.InitializationErrorString());
2062c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org}
2072c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
2082c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org#ifdef PROTOBUF_HAS_DEATH_TEST
20965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
21065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgTEST(MessageTest, SerializeFailsIfNotInitialized) {
21165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  unittest::TestRequired message;
2123a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  string data;
2133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)),
2143a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    "Can't serialize message of type \"protobuf_unittest.TestRequired\" because "
2153a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    "it is missing required fields: a, b, c");
2163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
2173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
2183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgTEST(MessageTest, CheckInitialized) {
21965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  unittest::TestRequired message;
22065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_DEATH(message.CheckInitialized(),
22165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    "Message of type \"protobuf_unittest.TestRequired\" is missing required "
222a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    "fields: a, b, c");
22365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
2243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
22565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#endif  // PROTOBUF_HAS_DEATH_TEST
22665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
22765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgTEST(MessageTest, BypassInitializationCheckOnSerialize) {
2283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  unittest::TestRequired message;
22965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  io::ArrayOutputStream raw_output(NULL, 0);
23065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  io::CodedOutputStream output(&raw_output);
23165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_TRUE(message.SerializePartialToCodedStream(&output));
2323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org}
2333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
2343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgTEST(MessageTest, FindInitializationErrors) {
2353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  unittest::TestRequired message;
2363a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  vector<string> errors;
2373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  message.FindInitializationErrors(&errors);
2383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  ASSERT_EQ(3, errors.size());
2393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  EXPECT_EQ("a", errors[0]);
2403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  EXPECT_EQ("b", errors[1]);
2413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  EXPECT_EQ("c", errors[2]);
24265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
24365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
24465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgTEST(MessageTest, ParseFailsOnInvalidMessageEnd) {
245a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  unittest::TestAllTypes message;
24665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
24765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // Control case.
24865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_TRUE(message.ParseFromArray("", 0));
24965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
25065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // The byte is a valid varint, but not a valid tag (zero).
25165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_FALSE(message.ParseFromArray("\0", 1));
25265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
25365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // The byte is a malformed varint.
25465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_FALSE(message.ParseFromArray("\200", 1));
25565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
25665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // The byte is an endgroup tag, but we aren't parsing a group.
25765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_FALSE(message.ParseFromArray("\014", 1));
258a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org}
25965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
26065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace {
26165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
2621c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.orgvoid ExpectMessageMerged(const unittest::TestAllTypes& message) {
26365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_EQ(3, message.optional_int32());
26465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_EQ(2, message.optional_int64());
26565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_EQ("hello", message.optional_string());
26665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
26765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
26865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgvoid AssignParsingMergeMessages(
26965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    unittest::TestAllTypes* msg1,
27065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    unittest::TestAllTypes* msg2,
2711c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    unittest::TestAllTypes* msg3) {
2721c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  msg1->set_optional_int32(1);
2731c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  msg2->set_optional_int64(2);
2741c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  msg3->set_optional_int32(3);
2751c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  msg3->set_optional_string("hello");
2761c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}
2771c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
2781c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}  // namespace
27965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
2801c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org// Test that if an optional or required message/group field appears multiple
2811c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org// times in the input, they need to be merged.
2821c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.orgTEST(MessageTest, ParsingMerge) {
2831c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  unittest::TestParsingMerge::RepeatedFieldsGenerator generator;
2841c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  unittest::TestAllTypes* msg1;
2851c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  unittest::TestAllTypes* msg2;
2861c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  unittest::TestAllTypes* msg3;
2871c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
2881c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org#define ASSIGN_REPEATED_FIELD(FIELD)                \
2891c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  msg1 = generator.add_##FIELD();                   \
2901c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  msg2 = generator.add_##FIELD();                   \
2911c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  msg3 = generator.add_##FIELD();                   \
29265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  AssignParsingMergeMessages(msg1, msg2, msg3)
29365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
29465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ASSIGN_REPEATED_FIELD(field1);
29565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ASSIGN_REPEATED_FIELD(field2);
29665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ASSIGN_REPEATED_FIELD(field3);
29765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ASSIGN_REPEATED_FIELD(ext1);
298a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ASSIGN_REPEATED_FIELD(ext2);
29965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
30065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#undef ASSIGN_REPEATED_FIELD
30165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#define ASSIGN_REPEATED_GROUP(FIELD)                \
30265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  msg1 = generator.add_##FIELD()->mutable_field1(); \
30365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  msg2 = generator.add_##FIELD()->mutable_field1(); \
30465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  msg3 = generator.add_##FIELD()->mutable_field1(); \
30565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  AssignParsingMergeMessages(msg1, msg2, msg3)
30665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSIGN_REPEATED_GROUP(group1);
3088432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  ASSIGN_REPEATED_GROUP(group2);
309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
31065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#undef ASSIGN_REPEATED_GROUP
31165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
31265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  string buffer;
31365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  generator.SerializeToString(&buffer);
31465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  unittest::TestParsingMerge parsing_merge;
31565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  parsing_merge.ParseFromString(buffer);
31665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
31765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // Required and optional fields should be merged.
31865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ExpectMessageMerged(parsing_merge.required_all_types());
31965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ExpectMessageMerged(parsing_merge.optional_all_types());
32065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ExpectMessageMerged(
32165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      parsing_merge.optionalgroup().optional_group_all_types());
32265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  ExpectMessageMerged(
32365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      parsing_merge.GetExtension(unittest::TestParsingMerge::optional_ext));
32465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
32565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // Repeated fields should not be merged.
32665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_EQ(3, parsing_merge.repeated_all_types_size());
32765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_EQ(3, parsing_merge.repeatedgroup_size());
32865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_EQ(3, parsing_merge.ExtensionSize(
32965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      unittest::TestParsingMerge::repeated_ext));
33065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
33165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
332a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgTEST(MessageFactoryTest, GeneratedFactoryLookup) {
33365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_EQ(
33465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    MessageFactory::generated_factory()->GetPrototype(
33565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      protobuf_unittest::TestAllTypes::descriptor()),
33665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    &protobuf_unittest::TestAllTypes::default_instance());
33765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
33865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
33965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgTEST(MessageFactoryTest, GeneratedFactoryUnknownType) {
34065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // Construct a new descriptor.
34165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  DescriptorPool pool;
34265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  FileDescriptorProto file;
34365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  file.set_name("foo.proto");
34465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  file.add_message_type()->set_name("Foo");
34565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  const Descriptor* descriptor = pool.BuildFile(file)->message_type(0);
34665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
34765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // Trying to construct it should return NULL.
34865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  EXPECT_TRUE(
34965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL);
35065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}
35165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
35265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
35365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}  // namespace protobuf
35465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}  // namespace google
35565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org