Home | History | Annotate | Download | only in internal
      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 #include <google/protobuf/util/internal/protostream_objectwriter.h>
     32 
     33 #include <stddef.h>  // For size_t
     34 
     35 #include <google/protobuf/field_mask.pb.h>
     36 #include <google/protobuf/timestamp.pb.h>
     37 #include <google/protobuf/wrappers.pb.h>
     38 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
     39 #include <google/protobuf/descriptor.pb.h>
     40 #include <google/protobuf/descriptor.h>
     41 #include <google/protobuf/dynamic_message.h>
     42 #include <google/protobuf/message.h>
     43 #include <google/protobuf/util/internal/mock_error_listener.h>
     44 #include <google/protobuf/util/internal/testdata/books.pb.h>
     45 #include <google/protobuf/util/internal/testdata/field_mask.pb.h>
     46 #include <google/protobuf/util/internal/type_info_test_helper.h>
     47 #include <google/protobuf/util/internal/constants.h>
     48 #include <google/protobuf/util/message_differencer.h>
     49 #include <google/protobuf/stubs/bytestream.h>
     50 #include <google/protobuf/stubs/strutil.h>
     51 #include <google/protobuf/util/internal/testdata/anys.pb.h>
     52 #include <google/protobuf/util/internal/testdata/maps.pb.h>
     53 #include <google/protobuf/util/internal/testdata/oneofs.pb.h>
     54 #include <google/protobuf/util/internal/testdata/struct.pb.h>
     55 #include <google/protobuf/util/internal/testdata/timestamp_duration.pb.h>
     56 #include <gtest/gtest.h>
     57 
     58 
     59 namespace google {
     60 namespace protobuf {
     61 namespace util {
     62 namespace converter {
     63 
     64 using google::protobuf::testing::Author;
     65 using google::protobuf::testing::Book;
     66 using google::protobuf::testing::Book_Data;
     67 using google::protobuf::testing::Primitive;
     68 using google::protobuf::testing::Publisher;
     69 using google::protobuf::Descriptor;
     70 using google::protobuf::DescriptorPool;
     71 using google::protobuf::DynamicMessageFactory;
     72 using google::protobuf::FileDescriptorProto;
     73 using google::protobuf::Message;
     74 using google::protobuf::io::ArrayInputStream;
     75 using strings::GrowingArrayByteSink;
     76 using ::testing::_;
     77 using ::testing::Args;
     78 using google::protobuf::testing::anys::AnyM;
     79 using google::protobuf::testing::anys::AnyOut;
     80 using google::protobuf::testing::oneofs::OneOfsRequest;
     81 using google::protobuf::testing::FieldMaskTest;
     82 using google::protobuf::testing::maps::MapIn;
     83 using google::protobuf::testing::structs::StructType;
     84 using google::protobuf::testing::timestampduration::TimestampDuration;
     85 
     86 
     87 namespace {
     88 string GetTypeUrl(const Descriptor* descriptor) {
     89   return string(kTypeServiceBaseUrl) + "/" + descriptor->full_name();
     90 }
     91 }  // namespace
     92 
     93 #if __cplusplus >= 201103L
     94   using std::get;
     95 #else
     96   using std::tr1::get;
     97 #endif
     98 
     99 class BaseProtoStreamObjectWriterTest
    100     : public ::testing::TestWithParam<testing::TypeInfoSource> {
    101  protected:
    102   BaseProtoStreamObjectWriterTest()
    103       : helper_(GetParam()),
    104         listener_(),
    105         output_(new GrowingArrayByteSink(1000)),
    106         ow_() {}
    107 
    108   explicit BaseProtoStreamObjectWriterTest(const Descriptor* descriptor)
    109       : helper_(GetParam()),
    110         listener_(),
    111         output_(new GrowingArrayByteSink(1000)),
    112         ow_() {
    113     vector<const Descriptor*> descriptors;
    114     descriptors.push_back(descriptor);
    115     ResetTypeInfo(descriptors);
    116   }
    117 
    118   explicit BaseProtoStreamObjectWriterTest(
    119       vector<const Descriptor*> descriptors)
    120       : helper_(GetParam()),
    121         listener_(),
    122         output_(new GrowingArrayByteSink(1000)),
    123         ow_() {
    124     ResetTypeInfo(descriptors);
    125   }
    126 
    127   void ResetTypeInfo(vector<const Descriptor*> descriptors) {
    128     GOOGLE_CHECK(!descriptors.empty()) << "Must have at least one descriptor!";
    129     helper_.ResetTypeInfo(descriptors);
    130     ow_.reset(helper_.NewProtoWriter(GetTypeUrl(descriptors[0]), output_.get(),
    131                                      &listener_, options_));
    132   }
    133 
    134   void ResetTypeInfo(const Descriptor* descriptor) {
    135     vector<const Descriptor*> descriptors;
    136     descriptors.push_back(descriptor);
    137     ResetTypeInfo(descriptors);
    138   }
    139 
    140   virtual ~BaseProtoStreamObjectWriterTest() {}
    141 
    142   void CheckOutput(const Message& expected, int expected_length) {
    143     size_t nbytes;
    144     google::protobuf::scoped_array<char> buffer(output_->GetBuffer(&nbytes));
    145     if (expected_length >= 0) {
    146       EXPECT_EQ(expected_length, nbytes);
    147     }
    148     string str(buffer.get(), nbytes);
    149 
    150     std::stringbuf str_buf(str, std::ios_base::in);
    151     std::istream istream(&str_buf);
    152     google::protobuf::scoped_ptr<Message> message(expected.New());
    153     message->ParsePartialFromIstream(&istream);
    154 
    155     if (!MessageDifferencer::Equivalent(expected, *message)) {
    156       EXPECT_EQ(expected.DebugString(), message->DebugString());
    157     }
    158   }
    159 
    160   void CheckOutput(const Message& expected) { CheckOutput(expected, -1); }
    161 
    162   const google::protobuf::Type* GetType(const Descriptor* descriptor) {
    163     return helper_.GetTypeInfo()->GetTypeByTypeUrl(GetTypeUrl(descriptor));
    164   }
    165 
    166   testing::TypeInfoTestHelper helper_;
    167   MockErrorListener listener_;
    168   google::protobuf::scoped_ptr<GrowingArrayByteSink> output_;
    169   google::protobuf::scoped_ptr<ProtoStreamObjectWriter> ow_;
    170   ProtoStreamObjectWriter::Options options_;
    171 };
    172 
    173 MATCHER_P(HasObjectLocation, expected,
    174           "Verifies the expected object location") {
    175   string actual = get<0>(arg).ToString();
    176   if (actual.compare(expected) == 0) return true;
    177   *result_listener << "actual location is: " << actual;
    178   return false;
    179 }
    180 
    181 class ProtoStreamObjectWriterTest : public BaseProtoStreamObjectWriterTest {
    182  protected:
    183   ProtoStreamObjectWriterTest()
    184       : BaseProtoStreamObjectWriterTest(Book::descriptor()) {}
    185 
    186   virtual ~ProtoStreamObjectWriterTest() {}
    187 };
    188 
    189 INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
    190                         ProtoStreamObjectWriterTest,
    191                         ::testing::Values(
    192                             testing::USE_TYPE_RESOLVER));
    193 
    194 TEST_P(ProtoStreamObjectWriterTest, EmptyObject) {
    195   Book empty;
    196   ow_->StartObject("")->EndObject();
    197   CheckOutput(empty, 0);
    198 }
    199 
    200 TEST_P(ProtoStreamObjectWriterTest, SimpleObject) {
    201   string content("My content");
    202 
    203   Book book;
    204   book.set_title("My Title");
    205   book.set_length(222);
    206   book.set_content(content);
    207 
    208   ow_->StartObject("")
    209       ->RenderString("title", "My Title")
    210       ->RenderInt32("length", 222)
    211       ->RenderBytes("content", content)
    212       ->EndObject();
    213   CheckOutput(book);
    214 }
    215 
    216 TEST_P(ProtoStreamObjectWriterTest, SimpleMessage) {
    217   Book book;
    218   book.set_title("Some Book");
    219   book.set_length(102);
    220   Publisher* publisher = book.mutable_publisher();
    221   publisher->set_name("My Publisher");
    222   Author* robert = book.mutable_author();
    223   robert->set_alive(true);
    224   robert->set_name("robert");
    225   robert->add_pseudonym("bob");
    226   robert->add_pseudonym("bobby");
    227   robert->add_friend_()->set_name("john");
    228 
    229   ow_->StartObject("")
    230       ->RenderString("title", "Some Book")
    231       ->RenderInt32("length", 102)
    232       ->StartObject("publisher")
    233       ->RenderString("name", "My Publisher")
    234       ->EndObject()
    235       ->StartObject("author")
    236       ->RenderBool("alive", true)
    237       ->RenderString("name", "robert")
    238       ->StartList("pseudonym")
    239       ->RenderString("", "bob")
    240       ->RenderString("", "bobby")
    241       ->EndList()
    242       ->StartList("friend")
    243       ->StartObject("")
    244       ->RenderString("name", "john")
    245       ->EndObject()
    246       ->EndList()
    247       ->EndObject()
    248       ->EndObject();
    249   CheckOutput(book);
    250 }
    251 
    252 TEST_P(ProtoStreamObjectWriterTest, CustomJsonName) {
    253   Book book;
    254   Author* robert = book.mutable_author();
    255   robert->set_id(12345);
    256   robert->set_name("robert");
    257 
    258   ow_->StartObject("")
    259       ->StartObject("author")
    260       ->RenderUint64("@id", 12345)
    261       ->RenderString("name", "robert")
    262       ->EndObject()
    263       ->EndObject();
    264   CheckOutput(book);
    265 }
    266 
    267 TEST_P(ProtoStreamObjectWriterTest, PrimitiveFromStringConversion) {
    268   Primitive full;
    269   full.set_fix32(101);
    270   full.set_u32(102);
    271   full.set_i32(-103);
    272   full.set_sf32(-104);
    273   full.set_s32(-105);
    274   full.set_fix64(40000000001L);
    275   full.set_u64(40000000002L);
    276   full.set_i64(-40000000003L);
    277   full.set_sf64(-40000000004L);
    278   full.set_s64(-40000000005L);
    279   full.set_str("string1");
    280   full.set_bytes("Some Bytes");
    281   full.set_float_(3.14f);
    282   full.set_double_(-4.05L);
    283   full.set_bool_(true);
    284   full.add_rep_fix32(201);
    285   full.add_rep_u32(202);
    286   full.add_rep_i32(-203);
    287   full.add_rep_sf32(-204);
    288   full.add_rep_s32(-205);
    289   full.add_rep_fix64(80000000001L);
    290   full.add_rep_u64(80000000002L);
    291   full.add_rep_i64(-80000000003L);
    292   full.add_rep_sf64(-80000000004L);
    293   full.add_rep_s64(-80000000005L);
    294   full.add_rep_str("string2");
    295   full.add_rep_bytes("More Bytes");
    296   full.add_rep_float(6.14f);
    297   full.add_rep_double(-8.05L);
    298   full.add_rep_bool(false);
    299 
    300   ResetTypeInfo(Primitive::descriptor());
    301 
    302   ow_->StartObject("")
    303       ->RenderString("fix32", "101")
    304       ->RenderString("u32", "102")
    305       ->RenderString("i32", "-103")
    306       ->RenderString("sf32", "-104")
    307       ->RenderString("s32", "-105")
    308       ->RenderString("fix64", "40000000001")
    309       ->RenderString("u64", "40000000002")
    310       ->RenderString("i64", "-40000000003")
    311       ->RenderString("sf64", "-40000000004")
    312       ->RenderString("s64", "-40000000005")
    313       ->RenderString("str", "string1")
    314       ->RenderString("bytes", "U29tZSBCeXRlcw==")  // "Some Bytes"
    315       ->RenderString("float", "3.14")
    316       ->RenderString("double", "-4.05")
    317       ->RenderString("bool", "true")
    318       ->StartList("rep_fix32")
    319       ->RenderString("", "201")
    320       ->EndList()
    321       ->StartList("rep_u32")
    322       ->RenderString("", "202")
    323       ->EndList()
    324       ->StartList("rep_i32")
    325       ->RenderString("", "-203")
    326       ->EndList()
    327       ->StartList("rep_sf32")
    328       ->RenderString("", "-204")
    329       ->EndList()
    330       ->StartList("rep_s32")
    331       ->RenderString("", "-205")
    332       ->EndList()
    333       ->StartList("rep_fix64")
    334       ->RenderString("", "80000000001")
    335       ->EndList()
    336       ->StartList("rep_u64")
    337       ->RenderString("", "80000000002")
    338       ->EndList()
    339       ->StartList("rep_i64")
    340       ->RenderString("", "-80000000003")
    341       ->EndList()
    342       ->StartList("rep_sf64")
    343       ->RenderString("", "-80000000004")
    344       ->EndList()
    345       ->StartList("rep_s64")
    346       ->RenderString("", "-80000000005")
    347       ->EndList()
    348       ->StartList("rep_str")
    349       ->RenderString("", "string2")
    350       ->EndList()
    351       ->StartList("rep_bytes")
    352       ->RenderString("", "TW9yZSBCeXRlcw==")  // "More Bytes"
    353       ->EndList()
    354       ->StartList("rep_float")
    355       ->RenderString("", "6.14")
    356       ->EndList()
    357       ->StartList("rep_double")
    358       ->RenderString("", "-8.05")
    359       ->EndList()
    360       ->StartList("rep_bool")
    361       ->RenderString("", "false")
    362       ->EndList()
    363       ->EndObject();
    364   CheckOutput(full);
    365 }
    366 
    367 TEST_P(ProtoStreamObjectWriterTest, InfinityInputTest) {
    368   Primitive full;
    369   full.set_double_(std::numeric_limits<double>::infinity());
    370   full.set_float_(std::numeric_limits<float>::infinity());
    371   full.set_str("-Infinity");
    372 
    373   ResetTypeInfo(Primitive::descriptor());
    374 
    375   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT32"),
    376                                       StringPiece("\"Infinity\"")))
    377       .With(Args<0>(HasObjectLocation("i32")));
    378   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
    379                                       StringPiece("\"Infinity\"")))
    380       .With(Args<0>(HasObjectLocation("u32")));
    381   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_SFIXED64"),
    382                                       StringPiece("\"-Infinity\"")))
    383       .With(Args<0>(HasObjectLocation("sf64")));
    384   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_BOOL"),
    385                                       StringPiece("\"Infinity\"")))
    386       .With(Args<0>(HasObjectLocation("bool")));
    387 
    388   ow_->StartObject("")
    389       ->RenderString("double", "Infinity")
    390       ->RenderString("float", "Infinity")
    391       ->RenderString("i32", "Infinity")
    392       ->RenderString("u32", "Infinity")
    393       ->RenderString("sf64", "-Infinity")
    394       ->RenderString("str", "-Infinity")
    395       ->RenderString("bool", "Infinity")
    396       ->EndObject();
    397   CheckOutput(full);
    398 }
    399 
    400 TEST_P(ProtoStreamObjectWriterTest, NaNInputTest) {
    401   Primitive full;
    402   full.set_double_(std::numeric_limits<double>::quiet_NaN());
    403   full.set_float_(std::numeric_limits<float>::quiet_NaN());
    404   full.set_str("NaN");
    405 
    406   ResetTypeInfo(Primitive::descriptor());
    407 
    408   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT32"),
    409                                       StringPiece("\"NaN\"")))
    410       .With(Args<0>(HasObjectLocation("i32")));
    411   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
    412                                       StringPiece("\"NaN\"")))
    413       .With(Args<0>(HasObjectLocation("u32")));
    414   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_SFIXED64"),
    415                                       StringPiece("\"NaN\"")))
    416       .With(Args<0>(HasObjectLocation("sf64")));
    417   EXPECT_CALL(listener_,
    418               InvalidValue(_, StringPiece("TYPE_BOOL"), StringPiece("\"NaN\"")))
    419       .With(Args<0>(HasObjectLocation("bool")));
    420 
    421   ow_->StartObject("")
    422       ->RenderString("double", "NaN")
    423       ->RenderString("float", "NaN")
    424       ->RenderString("i32", "NaN")
    425       ->RenderString("u32", "NaN")
    426       ->RenderString("sf64", "NaN")
    427       ->RenderString("str", "NaN")
    428       ->RenderString("bool", "NaN")
    429       ->EndObject();
    430 
    431   CheckOutput(full);
    432 }
    433 
    434 TEST_P(ProtoStreamObjectWriterTest, ImplicitPrimitiveList) {
    435   Book expected;
    436   Author* author = expected.mutable_author();
    437   author->set_name("The Author");
    438   author->add_pseudonym("first");
    439   author->add_pseudonym("second");
    440 
    441   ow_->StartObject("")
    442       ->StartObject("author")
    443       ->RenderString("name", "The Author")
    444       ->RenderString("pseudonym", "first")
    445       ->RenderString("pseudonym", "second")
    446       ->EndObject()
    447       ->EndObject();
    448   CheckOutput(expected);
    449 }
    450 
    451 TEST_P(ProtoStreamObjectWriterTest,
    452        LastWriteWinsOnNonRepeatedPrimitiveFieldWithDuplicates) {
    453   Book expected;
    454   Author* author = expected.mutable_author();
    455   author->set_name("second");
    456 
    457   ow_->StartObject("")
    458       ->StartObject("author")
    459       ->RenderString("name", "first")
    460       ->RenderString("name", "second")
    461       ->EndObject()
    462       ->EndObject();
    463   CheckOutput(expected);
    464 }
    465 
    466 TEST_P(ProtoStreamObjectWriterTest, ExplicitPrimitiveList) {
    467   Book expected;
    468   Author* author = expected.mutable_author();
    469   author->set_name("The Author");
    470   author->add_pseudonym("first");
    471   author->add_pseudonym("second");
    472 
    473   ow_->StartObject("")
    474       ->StartObject("author")
    475       ->RenderString("name", "The Author")
    476       ->StartList("pseudonym")
    477       ->RenderString("", "first")
    478       ->RenderString("", "second")
    479       ->EndList()
    480       ->EndObject()
    481       ->EndObject();
    482   CheckOutput(expected);
    483 }
    484 
    485 TEST_P(ProtoStreamObjectWriterTest, NonRepeatedExplicitPrimitiveList) {
    486   Book expected;
    487   expected.set_allocated_author(new Author());
    488 
    489   EXPECT_CALL(
    490       listener_,
    491       InvalidName(
    492           _, StringPiece("name"),
    493           StringPiece("Proto field is not repeating, cannot start list.")))
    494       .With(Args<0>(HasObjectLocation("author")));
    495   ow_->StartObject("")
    496       ->StartObject("author")
    497       ->StartList("name")
    498       ->RenderString("", "first")
    499       ->RenderString("", "second")
    500       ->EndList()
    501       ->EndObject()
    502       ->EndObject();
    503   CheckOutput(expected);
    504 }
    505 
    506 TEST_P(ProtoStreamObjectWriterTest, ImplicitMessageList) {
    507   Book expected;
    508   Author* outer = expected.mutable_author();
    509   outer->set_name("outer");
    510   outer->set_alive(true);
    511   Author* first = outer->add_friend_();
    512   first->set_name("first");
    513   Author* second = outer->add_friend_();
    514   second->set_name("second");
    515 
    516   ow_->StartObject("")
    517       ->StartObject("author")
    518       ->RenderString("name", "outer")
    519       ->RenderBool("alive", true)
    520       ->StartObject("friend")
    521       ->RenderString("name", "first")
    522       ->EndObject()
    523       ->StartObject("friend")
    524       ->RenderString("name", "second")
    525       ->EndObject()
    526       ->EndObject()
    527       ->EndObject();
    528   CheckOutput(expected);
    529 }
    530 
    531 TEST_P(ProtoStreamObjectWriterTest,
    532        LastWriteWinsOnNonRepeatedMessageFieldWithDuplicates) {
    533   Book expected;
    534   Author* author = expected.mutable_author();
    535   author->set_name("The Author");
    536   Publisher* publisher = expected.mutable_publisher();
    537   publisher->set_name("second");
    538 
    539   ow_->StartObject("")
    540       ->StartObject("author")
    541       ->RenderString("name", "The Author")
    542       ->EndObject()
    543       ->StartObject("publisher")
    544       ->RenderString("name", "first")
    545       ->EndObject()
    546       ->StartObject("publisher")
    547       ->RenderString("name", "second")
    548       ->EndObject()
    549       ->EndObject();
    550   CheckOutput(expected);
    551 }
    552 
    553 TEST_P(ProtoStreamObjectWriterTest, ExplicitMessageList) {
    554   Book expected;
    555   Author* outer = expected.mutable_author();
    556   outer->set_name("outer");
    557   outer->set_alive(true);
    558   Author* first = outer->add_friend_();
    559   first->set_name("first");
    560   Author* second = outer->add_friend_();
    561   second->set_name("second");
    562 
    563   ow_->StartObject("")
    564       ->StartObject("author")
    565       ->RenderString("name", "outer")
    566       ->RenderBool("alive", true)
    567       ->StartList("friend")
    568       ->StartObject("")
    569       ->RenderString("name", "first")
    570       ->EndObject()
    571       ->StartObject("")
    572       ->RenderString("name", "second")
    573       ->EndObject()
    574       ->EndList()
    575       ->EndObject()
    576       ->EndObject();
    577   CheckOutput(expected);
    578 }
    579 
    580 TEST_P(ProtoStreamObjectWriterTest, NonRepeatedExplicitMessageList) {
    581   Book expected;
    582   Author* author = expected.mutable_author();
    583   author->set_name("The Author");
    584 
    585   EXPECT_CALL(
    586       listener_,
    587       InvalidName(
    588           _, StringPiece("publisher"),
    589           StringPiece("Proto field is not repeating, cannot start list.")))
    590       .With(Args<0>(HasObjectLocation("")));
    591   ow_->StartObject("")
    592       ->StartObject("author")
    593       ->RenderString("name", "The Author")
    594       ->EndObject()
    595       ->StartList("publisher")
    596       ->StartObject("")
    597       ->RenderString("name", "first")
    598       ->EndObject()
    599       ->StartObject("")
    600       ->RenderString("name", "second")
    601       ->EndObject()
    602       ->EndList()
    603       ->EndObject();
    604   CheckOutput(expected);
    605 }
    606 
    607 TEST_P(ProtoStreamObjectWriterTest, UnknownFieldAtRoot) {
    608   Book empty;
    609 
    610   EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
    611                                      StringPiece("Cannot find field.")))
    612       .With(Args<0>(HasObjectLocation("")));
    613   ow_->StartObject("")->RenderString("unknown", "Nope!")->EndObject();
    614   CheckOutput(empty, 0);
    615 }
    616 
    617 TEST_P(ProtoStreamObjectWriterTest, UnknownFieldAtAuthorFriend) {
    618   Book expected;
    619   Author* paul = expected.mutable_author();
    620   paul->set_name("Paul");
    621   Author* mark = paul->add_friend_();
    622   mark->set_name("Mark");
    623   Author* john = paul->add_friend_();
    624   john->set_name("John");
    625   Author* luke = paul->add_friend_();
    626   luke->set_name("Luke");
    627 
    628   EXPECT_CALL(listener_, InvalidName(_, StringPiece("address"),
    629                                      StringPiece("Cannot find field.")))
    630       .With(Args<0>(HasObjectLocation("author.friend[1]")));
    631   ow_->StartObject("")
    632       ->StartObject("author")
    633       ->RenderString("name", "Paul")
    634       ->StartList("friend")
    635       ->StartObject("")
    636       ->RenderString("name", "Mark")
    637       ->EndObject()
    638       ->StartObject("")
    639       ->RenderString("name", "John")
    640       ->RenderString("address", "Patmos")
    641       ->EndObject()
    642       ->StartObject("")
    643       ->RenderString("name", "Luke")
    644       ->EndObject()
    645       ->EndList()
    646       ->EndObject()
    647       ->EndObject();
    648   CheckOutput(expected);
    649 }
    650 
    651 TEST_P(ProtoStreamObjectWriterTest, UnknownObjectAtRoot) {
    652   Book empty;
    653 
    654   EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
    655                                      StringPiece("Cannot find field.")))
    656       .With(Args<0>(HasObjectLocation("")));
    657   ow_->StartObject("")->StartObject("unknown")->EndObject()->EndObject();
    658   CheckOutput(empty, 0);
    659 }
    660 
    661 TEST_P(ProtoStreamObjectWriterTest, UnknownObjectAtAuthor) {
    662   Book expected;
    663   Author* author = expected.mutable_author();
    664   author->set_name("William");
    665   author->add_pseudonym("Bill");
    666 
    667   EXPECT_CALL(listener_, InvalidName(_, StringPiece("wife"),
    668                                      StringPiece("Cannot find field.")))
    669       .With(Args<0>(HasObjectLocation("author")));
    670   ow_->StartObject("")
    671       ->StartObject("author")
    672       ->RenderString("name", "William")
    673       ->StartObject("wife")
    674       ->RenderString("name", "Hilary")
    675       ->EndObject()
    676       ->RenderString("pseudonym", "Bill")
    677       ->EndObject()
    678       ->EndObject();
    679   CheckOutput(expected);
    680 }
    681 
    682 TEST_P(ProtoStreamObjectWriterTest, UnknownListAtRoot) {
    683   Book empty;
    684 
    685   EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
    686                                      StringPiece("Cannot find field.")))
    687       .With(Args<0>(HasObjectLocation("")));
    688   ow_->StartObject("")->StartList("unknown")->EndList()->EndObject();
    689   CheckOutput(empty, 0);
    690 }
    691 
    692 TEST_P(ProtoStreamObjectWriterTest, UnknownListAtPublisher) {
    693   Book expected;
    694   expected.set_title("Brainwashing");
    695   Publisher* publisher = expected.mutable_publisher();
    696   publisher->set_name("propaganda");
    697 
    698   EXPECT_CALL(listener_, InvalidName(_, StringPiece("alliance"),
    699                                      StringPiece("Cannot find field.")))
    700       .With(Args<0>(HasObjectLocation("publisher")));
    701   ow_->StartObject("")
    702       ->StartObject("publisher")
    703       ->RenderString("name", "propaganda")
    704       ->StartList("alliance")
    705       ->EndList()
    706       ->EndObject()
    707       ->RenderString("title", "Brainwashing")
    708       ->EndObject();
    709   CheckOutput(expected);
    710 }
    711 
    712 TEST_P(ProtoStreamObjectWriterTest, MissingRequiredField) {
    713   Book expected;
    714   expected.set_title("My Title");
    715   expected.set_allocated_publisher(new Publisher());
    716 
    717   EXPECT_CALL(listener_, MissingField(_, StringPiece("name")))
    718       .With(Args<0>(HasObjectLocation("publisher")));
    719   ow_->StartObject("")
    720       ->StartObject("publisher")
    721       ->EndObject()
    722       ->RenderString("title", "My Title")
    723       ->EndObject();
    724   CheckOutput(expected);
    725 }
    726 
    727 TEST_P(ProtoStreamObjectWriterTest, InvalidFieldValueAtRoot) {
    728   Book empty;
    729 
    730   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
    731                                       StringPiece("\"garbage\"")))
    732       .With(Args<0>(HasObjectLocation("length")));
    733   ow_->StartObject("")->RenderString("length", "garbage")->EndObject();
    734   CheckOutput(empty, 0);
    735 }
    736 
    737 TEST_P(ProtoStreamObjectWriterTest, MultipleInvalidFieldValues) {
    738   Book expected;
    739   expected.set_title("My Title");
    740 
    741   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_UINT32"),
    742                                       StringPiece("\"-400\"")))
    743       .With(Args<0>(HasObjectLocation("length")));
    744   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT64"),
    745                                       StringPiece("\"3.14\"")))
    746       .With(Args<0>(HasObjectLocation("published")));
    747   ow_->StartObject("")
    748       ->RenderString("length", "-400")
    749       ->RenderString("published", "3.14")
    750       ->RenderString("title", "My Title")
    751       ->EndObject();
    752   CheckOutput(expected);
    753 }
    754 
    755 TEST_P(ProtoStreamObjectWriterTest, UnnamedFieldAtRoot) {
    756   Book empty;
    757 
    758   EXPECT_CALL(listener_,
    759               InvalidName(_, StringPiece(""),
    760                           StringPiece("Proto fields must have a name.")))
    761       .With(Args<0>(HasObjectLocation("")));
    762   ow_->StartObject("")->RenderFloat("", 3.14)->EndObject();
    763   CheckOutput(empty, 0);
    764 }
    765 
    766 TEST_P(ProtoStreamObjectWriterTest, UnnamedFieldAtAuthor) {
    767   Book expected;
    768   expected.set_title("noname");
    769   expected.set_allocated_author(new Author());
    770 
    771   EXPECT_CALL(listener_,
    772               InvalidName(_, StringPiece(""),
    773                           StringPiece("Proto fields must have a name.")))
    774       .With(Args<0>(HasObjectLocation("author")));
    775   ow_->StartObject("")
    776       ->StartObject("author")
    777       ->RenderInt32("", 123)
    778       ->EndObject()
    779       ->RenderString("title", "noname")
    780       ->EndObject();
    781   CheckOutput(expected);
    782 }
    783 
    784 TEST_P(ProtoStreamObjectWriterTest, UnnamedListAtRoot) {
    785   Book expected;
    786   expected.set_title("noname");
    787 
    788   EXPECT_CALL(listener_,
    789               InvalidName(_, StringPiece(""),
    790                           StringPiece("Proto fields must have a name.")))
    791       .With(Args<0>(HasObjectLocation("")));
    792   ow_->StartObject("")
    793       ->StartList("")
    794       ->EndList()
    795       ->RenderString("title", "noname")
    796       ->EndObject();
    797   CheckOutput(expected);
    798 }
    799 
    800 TEST_P(ProtoStreamObjectWriterTest, RootNamedObject) {
    801   Book expected;
    802   expected.set_title("Annie");
    803 
    804   EXPECT_CALL(listener_,
    805               InvalidName(_, StringPiece("oops"),
    806                           StringPiece("Root element should not be named.")))
    807       .With(Args<0>(HasObjectLocation("")));
    808   ow_->StartObject("oops")->RenderString("title", "Annie")->EndObject();
    809   CheckOutput(expected, 7);
    810 }
    811 
    812 TEST_P(ProtoStreamObjectWriterTest, RootNamedList) {
    813   Book empty;
    814 
    815   EXPECT_CALL(listener_,
    816               InvalidName(_, StringPiece("oops"),
    817                           StringPiece("Root element should not be named.")))
    818       .With(Args<0>(HasObjectLocation("")));
    819   ow_->StartList("oops")->RenderString("", "item")->EndList();
    820   CheckOutput(empty, 0);
    821 }
    822 
    823 TEST_P(ProtoStreamObjectWriterTest, RootUnnamedField) {
    824   Book empty;
    825 
    826   EXPECT_CALL(listener_,
    827               InvalidName(_, StringPiece(""),
    828                           StringPiece("Root element must be a message.")))
    829       .With(Args<0>(HasObjectLocation("")));
    830   ow_->RenderBool("", true);
    831   CheckOutput(empty, 0);
    832 }
    833 
    834 TEST_P(ProtoStreamObjectWriterTest, RootNamedField) {
    835   Book empty;
    836 
    837   EXPECT_CALL(listener_,
    838               InvalidName(_, StringPiece("oops"),
    839                           StringPiece("Root element must be a message.")))
    840       .With(Args<0>(HasObjectLocation("")));
    841   ow_->RenderBool("oops", true);
    842   CheckOutput(empty, 0);
    843 }
    844 
    845 TEST_P(ProtoStreamObjectWriterTest, NullValue) {
    846   Book empty;
    847 
    848   ow_->RenderNull("");
    849   CheckOutput(empty, 0);
    850 }
    851 
    852 TEST_P(ProtoStreamObjectWriterTest, NullValueForMessageField) {
    853   Book empty;
    854 
    855   ow_->RenderNull("author");
    856   CheckOutput(empty, 0);
    857 }
    858 
    859 TEST_P(ProtoStreamObjectWriterTest, NullValueForPrimitiveField) {
    860   Book empty;
    861 
    862   ow_->RenderNull("length");
    863   CheckOutput(empty, 0);
    864 }
    865 
    866 class ProtoStreamObjectWriterTimestampDurationTest
    867     : public BaseProtoStreamObjectWriterTest {
    868  protected:
    869   ProtoStreamObjectWriterTimestampDurationTest() {
    870     vector<const Descriptor*> descriptors;
    871     descriptors.push_back(TimestampDuration::descriptor());
    872     descriptors.push_back(google::protobuf::Timestamp::descriptor());
    873     descriptors.push_back(google::protobuf::Duration::descriptor());
    874     ResetTypeInfo(descriptors);
    875   }
    876 };
    877 
    878 INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
    879                         ProtoStreamObjectWriterTimestampDurationTest,
    880                         ::testing::Values(
    881                             testing::USE_TYPE_RESOLVER));
    882 
    883 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, ParseTimestamp) {
    884   TimestampDuration timestamp;
    885   google::protobuf::Timestamp* ts = timestamp.mutable_ts();
    886   ts->set_seconds(1448249855);
    887   ts->set_nanos(33155000);
    888 
    889   ow_->StartObject("")
    890       ->RenderString("ts", "2015-11-23T03:37:35.033155Z")
    891       ->EndObject();
    892   CheckOutput(timestamp);
    893 }
    894 
    895 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
    896        ParseTimestampYearNotZeroPadded) {
    897   TimestampDuration timestamp;
    898   google::protobuf::Timestamp* ts = timestamp.mutable_ts();
    899   ts->set_seconds(-61665654145);
    900   ts->set_nanos(33155000);
    901 
    902   ow_->StartObject("")
    903       ->RenderString("ts", "15-11-23T03:37:35.033155Z")
    904       ->EndObject();
    905   CheckOutput(timestamp);
    906 }
    907 
    908 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
    909        ParseTimestampYearZeroPadded) {
    910   TimestampDuration timestamp;
    911   google::protobuf::Timestamp* ts = timestamp.mutable_ts();
    912   ts->set_seconds(-61665654145);
    913   ts->set_nanos(33155000);
    914 
    915   ow_->StartObject("")
    916       ->RenderString("ts", "0015-11-23T03:37:35.033155Z")
    917       ->EndObject();
    918   CheckOutput(timestamp);
    919 }
    920 
    921 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
    922        ParseTimestampWithPositiveOffset) {
    923   TimestampDuration timestamp;
    924   google::protobuf::Timestamp* ts = timestamp.mutable_ts();
    925   ts->set_seconds(1448249855);
    926   ts->set_nanos(33155000);
    927 
    928   ow_->StartObject("")
    929       ->RenderString("ts", "2015-11-23T11:47:35.033155+08:10")
    930       ->EndObject();
    931   CheckOutput(timestamp);
    932 }
    933 
    934 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
    935        ParseTimestampWithNegativeOffset) {
    936   TimestampDuration timestamp;
    937   google::protobuf::Timestamp* ts = timestamp.mutable_ts();
    938   ts->set_seconds(1448249855);
    939   ts->set_nanos(33155000);
    940 
    941   ow_->StartObject("")
    942       ->RenderString("ts", "2015-11-22T19:47:35.033155-07:50")
    943       ->EndObject();
    944   CheckOutput(timestamp);
    945 }
    946 
    947 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
    948        TimestampWithInvalidOffset1) {
    949   TimestampDuration timestamp;
    950 
    951   EXPECT_CALL(
    952       listener_,
    953       InvalidValue(_,
    954                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
    955                    StringPiece("Field 'ts', Invalid time format: "
    956                                "2016-03-07T15:14:23+")));
    957 
    958   ow_->StartObject("")->RenderString("ts", "2016-03-07T15:14:23+")->EndObject();
    959   CheckOutput(timestamp);
    960 }
    961 
    962 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
    963        TimestampWithInvalidOffset2) {
    964   TimestampDuration timestamp;
    965 
    966   EXPECT_CALL(
    967       listener_,
    968       InvalidValue(_,
    969                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
    970                    StringPiece("Field 'ts', Invalid time format: "
    971                                "2016-03-07T15:14:23+08-10")));
    972 
    973   ow_->StartObject("")
    974       ->RenderString("ts", "2016-03-07T15:14:23+08-10")
    975       ->EndObject();
    976   CheckOutput(timestamp);
    977 }
    978 
    979 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
    980        TimestampWithInvalidOffset3) {
    981   TimestampDuration timestamp;
    982 
    983   EXPECT_CALL(
    984       listener_,
    985       InvalidValue(_,
    986                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
    987                    StringPiece("Field 'ts', Invalid time format: "
    988                                "2016-03-07T15:14:23+24:10")));
    989 
    990   ow_->StartObject("")
    991       ->RenderString("ts", "2016-03-07T15:14:23+24:10")
    992       ->EndObject();
    993   CheckOutput(timestamp);
    994 }
    995 
    996 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
    997        TimestampWithInvalidOffset4) {
    998   TimestampDuration timestamp;
    999 
   1000   EXPECT_CALL(
   1001       listener_,
   1002       InvalidValue(_,
   1003                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1004                    StringPiece("Field 'ts', Invalid time format: "
   1005                                "2016-03-07T15:14:23+04:60")));
   1006 
   1007   ow_->StartObject("")
   1008       ->RenderString("ts", "2016-03-07T15:14:23+04:60")
   1009       ->EndObject();
   1010   CheckOutput(timestamp);
   1011 }
   1012 
   1013 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError1) {
   1014   TimestampDuration timestamp;
   1015 
   1016   EXPECT_CALL(
   1017       listener_,
   1018       InvalidValue(_,
   1019                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1020                    StringPiece("Field 'ts', Invalid time format: ")));
   1021 
   1022   ow_->StartObject("")->RenderString("ts", "")->EndObject();
   1023   CheckOutput(timestamp);
   1024 }
   1025 
   1026 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError2) {
   1027   TimestampDuration timestamp;
   1028 
   1029   EXPECT_CALL(
   1030       listener_,
   1031       InvalidValue(_,
   1032                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1033                    StringPiece("Field 'ts', Invalid time format: Z")));
   1034 
   1035   ow_->StartObject("")->RenderString("ts", "Z")->EndObject();
   1036   CheckOutput(timestamp);
   1037 }
   1038 
   1039 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError3) {
   1040   TimestampDuration timestamp;
   1041 
   1042   EXPECT_CALL(
   1043       listener_,
   1044       InvalidValue(_,
   1045                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1046                    StringPiece("Field 'ts', Invalid time format: "
   1047                                "1970-01-01T00:00:00.ABZ")));
   1048 
   1049   ow_->StartObject("")
   1050       ->RenderString("ts", "1970-01-01T00:00:00.ABZ")
   1051       ->EndObject();
   1052   CheckOutput(timestamp);
   1053 }
   1054 
   1055 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError4) {
   1056   TimestampDuration timestamp;
   1057 
   1058   EXPECT_CALL(
   1059       listener_,
   1060       InvalidValue(_,
   1061                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1062                    StringPiece("Field 'ts', Invalid time format: "
   1063                                "-8031-10-18T00:00:00.000Z")));
   1064 
   1065   ow_->StartObject("")
   1066       ->RenderString("ts", "-8031-10-18T00:00:00.000Z")
   1067       ->EndObject();
   1068   CheckOutput(timestamp);
   1069 }
   1070 
   1071 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError5) {
   1072   TimestampDuration timestamp;
   1073 
   1074   EXPECT_CALL(
   1075       listener_,
   1076       InvalidValue(_,
   1077                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1078                    StringPiece("Field 'ts', Invalid time format: "
   1079                                "2015-11-23T03:37:35.033155   Z")));
   1080 
   1081   ow_->StartObject("")
   1082       // Whitespace in the Timestamp nanos is not allowed.
   1083       ->RenderString("ts", "2015-11-23T03:37:35.033155   Z")
   1084       ->EndObject();
   1085   CheckOutput(timestamp);
   1086 }
   1087 
   1088 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError6) {
   1089   TimestampDuration timestamp;
   1090 
   1091   EXPECT_CALL(
   1092       listener_,
   1093       InvalidValue(_,
   1094                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1095                    StringPiece("Field 'ts', Invalid time format: "
   1096                                "2015-11-23T03:37:35.033155 1234Z")));
   1097 
   1098   ow_->StartObject("")
   1099       // Whitespace in the Timestamp nanos is not allowed.
   1100       ->RenderString("ts", "2015-11-23T03:37:35.033155 1234Z")
   1101       ->EndObject();
   1102   CheckOutput(timestamp);
   1103 }
   1104 
   1105 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError7) {
   1106   TimestampDuration timestamp;
   1107 
   1108   EXPECT_CALL(
   1109       listener_,
   1110       InvalidValue(_,
   1111                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1112                    StringPiece("Field 'ts', Invalid time format: "
   1113                                "2015-11-23T03:37:35.033abc155Z")));
   1114 
   1115   ow_->StartObject("")
   1116       // Non-numeric characters in the Timestamp nanos is not allowed.
   1117       ->RenderString("ts", "2015-11-23T03:37:35.033abc155Z")
   1118       ->EndObject();
   1119   CheckOutput(timestamp);
   1120 }
   1121 
   1122 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError8) {
   1123   TimestampDuration timestamp;
   1124 
   1125   EXPECT_CALL(
   1126       listener_,
   1127       InvalidValue(_,
   1128                    StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1129                    StringPiece("Field 'ts', Invalid time format: "
   1130                                "0-12-31T23:59:59.000Z")));
   1131 
   1132   ow_->StartObject("")
   1133       ->RenderString("ts", "0-12-31T23:59:59.000Z")
   1134       ->EndObject();
   1135   CheckOutput(timestamp);
   1136 }
   1137 
   1138 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, ParseDuration) {
   1139   TimestampDuration duration;
   1140   google::protobuf::Duration* dur = duration.mutable_dur();
   1141   dur->set_seconds(1448216930);
   1142   dur->set_nanos(132262000);
   1143 
   1144   ow_->StartObject("")->RenderString("dur", "1448216930.132262s")->EndObject();
   1145   CheckOutput(duration);
   1146 }
   1147 
   1148 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError1) {
   1149   TimestampDuration duration;
   1150 
   1151   EXPECT_CALL(
   1152       listener_,
   1153       InvalidValue(
   1154           _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
   1155           StringPiece("Field 'dur', Illegal duration format; duration must "
   1156                       "end with 's'")));
   1157 
   1158   ow_->StartObject("")->RenderString("dur", "")->EndObject();
   1159   CheckOutput(duration);
   1160 }
   1161 
   1162 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError2) {
   1163   TimestampDuration duration;
   1164 
   1165   EXPECT_CALL(
   1166       listener_,
   1167       InvalidValue(
   1168           _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
   1169           StringPiece("Field 'dur', Invalid duration format, failed to parse "
   1170                       "seconds")));
   1171 
   1172   ow_->StartObject("")->RenderString("dur", "s")->EndObject();
   1173   CheckOutput(duration);
   1174 }
   1175 
   1176 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError3) {
   1177   TimestampDuration duration;
   1178 
   1179   EXPECT_CALL(
   1180       listener_,
   1181       InvalidValue(
   1182           _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
   1183           StringPiece("Field 'dur', Invalid duration format, failed to "
   1184                       "parse nano seconds")));
   1185 
   1186   ow_->StartObject("")->RenderString("dur", "123.DEFs")->EndObject();
   1187   CheckOutput(duration);
   1188 }
   1189 
   1190 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError4) {
   1191   TimestampDuration duration;
   1192 
   1193   EXPECT_CALL(
   1194       listener_,
   1195       InvalidValue(_,
   1196                    StringPiece("type.googleapis.com/google.protobuf.Duration"),
   1197                    StringPiece("Field 'dur', Duration value exceeds limits")));
   1198 
   1199   ow_->StartObject("")->RenderString("dur", "315576000002s")->EndObject();
   1200   CheckOutput(duration);
   1201 }
   1202 
   1203 TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError5) {
   1204   TimestampDuration duration;
   1205 
   1206   EXPECT_CALL(
   1207       listener_,
   1208       InvalidValue(_,
   1209                    StringPiece("type.googleapis.com/google.protobuf.Duration"),
   1210                    StringPiece("Field 'dur', Duration value exceeds limits")));
   1211 
   1212   ow_->StartObject("")->RenderString("dur", "0.1000000001s")->EndObject();
   1213   CheckOutput(duration);
   1214 }
   1215 
   1216 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
   1217        MismatchedTimestampTypeInput) {
   1218   TimestampDuration timestamp;
   1219   EXPECT_CALL(
   1220       listener_,
   1221       InvalidValue(
   1222           _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
   1223           StringPiece(
   1224               "Field 'ts', Invalid data type for timestamp, value is null")))
   1225       .With(Args<0>(HasObjectLocation("ts")));
   1226   ow_->StartObject("")->RenderNull("ts")->EndObject();
   1227   CheckOutput(timestamp);
   1228 }
   1229 
   1230 TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
   1231        MismatchedDurationTypeInput) {
   1232   TimestampDuration duration;
   1233   EXPECT_CALL(
   1234       listener_,
   1235       InvalidValue(
   1236           _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
   1237           StringPiece(
   1238               "Field 'dur', Invalid data type for duration, value is null")))
   1239       .With(Args<0>(HasObjectLocation("dur")));
   1240   ow_->StartObject("")->RenderNull("dur")->EndObject();
   1241   CheckOutput(duration);
   1242 }
   1243 
   1244 class ProtoStreamObjectWriterStructTest
   1245     : public BaseProtoStreamObjectWriterTest {
   1246  protected:
   1247   ProtoStreamObjectWriterStructTest() { ResetProtoWriter(); }
   1248 
   1249   // Resets ProtoWriter with current set of options and other state.
   1250   void ResetProtoWriter() {
   1251     vector<const Descriptor*> descriptors;
   1252     descriptors.push_back(StructType::descriptor());
   1253     descriptors.push_back(google::protobuf::Struct::descriptor());
   1254     ResetTypeInfo(descriptors);
   1255   }
   1256 };
   1257 
   1258 INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
   1259                         ProtoStreamObjectWriterStructTest,
   1260                         ::testing::Values(
   1261                             testing::USE_TYPE_RESOLVER));
   1262 
   1263 // TODO(skarvaje): Write tests for failure cases.
   1264 TEST_P(ProtoStreamObjectWriterStructTest, StructRenderSuccess) {
   1265   StructType struct_type;
   1266   google::protobuf::Struct* s = struct_type.mutable_object();
   1267   s->mutable_fields()->operator[]("k1").set_number_value(123);
   1268   s->mutable_fields()->operator[]("k2").set_bool_value(true);
   1269 
   1270   ow_->StartObject("")
   1271       ->StartObject("object")
   1272       ->RenderDouble("k1", 123)
   1273       ->RenderBool("k2", true)
   1274       ->EndObject()
   1275       ->EndObject();
   1276   CheckOutput(struct_type);
   1277 }
   1278 
   1279 TEST_P(ProtoStreamObjectWriterStructTest, StructNullInputSuccess) {
   1280   StructType struct_type;
   1281   EXPECT_CALL(listener_,
   1282               InvalidName(_, StringPiece(""),
   1283                           StringPiece("Proto fields must have a name.")))
   1284       .With(Args<0>(HasObjectLocation("")));
   1285   ow_->StartObject("")->RenderNull("")->EndObject();
   1286   CheckOutput(struct_type);
   1287 }
   1288 
   1289 TEST_P(ProtoStreamObjectWriterStructTest, StructInvalidInputFailure) {
   1290   StructType struct_type;
   1291   EXPECT_CALL(
   1292       listener_,
   1293       InvalidValue(_, StringPiece("type.googleapis.com/google.protobuf.Struct"),
   1294                    StringPiece("true")))
   1295       .With(Args<0>(HasObjectLocation("object")));
   1296 
   1297   ow_->StartObject("")->RenderBool("object", true)->EndObject();
   1298   CheckOutput(struct_type);
   1299 }
   1300 
   1301 TEST_P(ProtoStreamObjectWriterStructTest, SimpleRepeatedStructMapKeyTest) {
   1302   EXPECT_CALL(
   1303       listener_,
   1304       InvalidName(_, StringPiece("gBike"),
   1305                   StringPiece("Repeated map key: 'gBike' is already set.")));
   1306   ow_->StartObject("")
   1307       ->StartObject("object")
   1308       ->RenderString("gBike", "v1")
   1309       ->RenderString("gBike", "v2")
   1310       ->EndObject()
   1311       ->EndObject();
   1312 }
   1313 
   1314 TEST_P(ProtoStreamObjectWriterStructTest, RepeatedStructMapListKeyTest) {
   1315   EXPECT_CALL(
   1316       listener_,
   1317       InvalidName(_, StringPiece("k1"),
   1318                   StringPiece("Repeated map key: 'k1' is already set.")));
   1319   ow_->StartObject("")
   1320       ->StartObject("object")
   1321       ->RenderString("k1", "v1")
   1322       ->StartList("k1")
   1323       ->RenderString("", "v2")
   1324       ->EndList()
   1325       ->EndObject()
   1326       ->EndObject();
   1327 }
   1328 
   1329 TEST_P(ProtoStreamObjectWriterStructTest, RepeatedStructMapObjectKeyTest) {
   1330   EXPECT_CALL(
   1331       listener_,
   1332       InvalidName(_, StringPiece("k1"),
   1333                   StringPiece("Repeated map key: 'k1' is already set.")));
   1334   ow_->StartObject("")
   1335       ->StartObject("object")
   1336       ->StartObject("k1")
   1337       ->RenderString("sub_k1", "v1")
   1338       ->EndObject()
   1339       ->StartObject("k1")
   1340       ->RenderString("sub_k2", "v2")
   1341       ->EndObject()
   1342       ->EndObject()
   1343       ->EndObject();
   1344 }
   1345 
   1346 TEST_P(ProtoStreamObjectWriterStructTest, OptionStructIntAsStringsTest) {
   1347   StructType struct_type;
   1348   google::protobuf::Struct* s = struct_type.mutable_object();
   1349   s->mutable_fields()->operator[]("k1").set_number_value(123);
   1350   s->mutable_fields()->operator[]("k2").set_bool_value(true);
   1351   s->mutable_fields()->operator[]("k3").set_string_value("-222222222");
   1352   s->mutable_fields()->operator[]("k4").set_string_value("33333333");
   1353 
   1354   options_.struct_integers_as_strings = true;
   1355   ResetProtoWriter();
   1356 
   1357   ow_->StartObject("")
   1358       ->StartObject("object")
   1359       ->RenderDouble("k1", 123)
   1360       ->RenderBool("k2", true)
   1361       ->RenderInt64("k3", -222222222)
   1362       ->RenderUint64("k4", 33333333)
   1363       ->EndObject()
   1364       ->EndObject();
   1365   CheckOutput(struct_type);
   1366 }
   1367 
   1368 class ProtoStreamObjectWriterMapTest : public BaseProtoStreamObjectWriterTest {
   1369  protected:
   1370   ProtoStreamObjectWriterMapTest()
   1371       : BaseProtoStreamObjectWriterTest(MapIn::descriptor()) {}
   1372 };
   1373 
   1374 INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
   1375                         ProtoStreamObjectWriterMapTest,
   1376                         ::testing::Values(
   1377                             testing::USE_TYPE_RESOLVER));
   1378 
   1379 TEST_P(ProtoStreamObjectWriterMapTest, MapShouldNotAcceptList) {
   1380   MapIn mm;
   1381   EXPECT_CALL(
   1382       listener_,
   1383       InvalidValue(
   1384           _, StringPiece("Map"),
   1385           StringPiece("Cannot bind a list to map for field 'map_input'.")));
   1386   ow_->StartObject("")
   1387       ->StartList("map_input")
   1388       ->RenderString("a", "b")
   1389       ->EndList()
   1390       ->EndObject();
   1391   CheckOutput(mm);
   1392 }
   1393 
   1394 TEST_P(ProtoStreamObjectWriterMapTest, RepeatedMapKeyTest) {
   1395   EXPECT_CALL(
   1396       listener_,
   1397       InvalidName(_, StringPiece("k1"),
   1398                   StringPiece("Repeated map key: 'k1' is already set.")));
   1399   ow_->StartObject("")
   1400       ->RenderString("other", "test")
   1401       ->StartObject("map_input")
   1402       ->RenderString("k1", "v1")
   1403       ->RenderString("k1", "v2")
   1404       ->EndObject()
   1405       ->EndObject();
   1406 }
   1407 
   1408 class ProtoStreamObjectWriterAnyTest : public BaseProtoStreamObjectWriterTest {
   1409  protected:
   1410   ProtoStreamObjectWriterAnyTest() {
   1411     vector<const Descriptor*> descriptors;
   1412     descriptors.push_back(AnyOut::descriptor());
   1413     descriptors.push_back(google::protobuf::DoubleValue::descriptor());
   1414     descriptors.push_back(google::protobuf::Timestamp::descriptor());
   1415     descriptors.push_back(google::protobuf::Any::descriptor());
   1416     descriptors.push_back(google::protobuf::Value::descriptor());
   1417     descriptors.push_back(google::protobuf::Struct::descriptor());
   1418     ResetTypeInfo(descriptors);
   1419   }
   1420 };
   1421 
   1422 INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
   1423                         ProtoStreamObjectWriterAnyTest,
   1424                         ::testing::Values(
   1425                             testing::USE_TYPE_RESOLVER));
   1426 
   1427 TEST_P(ProtoStreamObjectWriterAnyTest, AnyRenderSuccess) {
   1428   AnyOut any;
   1429   google::protobuf::Any* any_type = any.mutable_any();
   1430   any_type->set_type_url("type.googleapis.com/google.protobuf.DoubleValue");
   1431   google::protobuf::DoubleValue d;
   1432   d.set_value(40.2);
   1433   any_type->set_value(d.SerializeAsString());
   1434 
   1435   ow_->StartObject("")
   1436       ->StartObject("any")
   1437       ->RenderString("@type", "type.googleapis.com/google.protobuf.DoubleValue")
   1438       ->RenderDouble("value", 40.2)
   1439       ->EndObject()
   1440       ->EndObject();
   1441   CheckOutput(any);
   1442 }
   1443 
   1444 TEST_P(ProtoStreamObjectWriterAnyTest, RecursiveAny) {
   1445   AnyOut out;
   1446   ::google::protobuf::Any* any = out.mutable_any();
   1447   any->set_type_url("type.googleapis.com/google.protobuf.Any");
   1448 
   1449   ::google::protobuf::Any nested_any;
   1450   nested_any.set_type_url(
   1451       "type.googleapis.com/google.protobuf.testing.anys.AnyM");
   1452 
   1453   AnyM m;
   1454   m.set_foo("foovalue");
   1455   nested_any.set_value(m.SerializeAsString());
   1456 
   1457   any->set_value(nested_any.SerializeAsString());
   1458 
   1459   ow_->StartObject("")
   1460       ->StartObject("any")
   1461       ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
   1462       ->StartObject("value")
   1463       ->RenderString("@type",
   1464                      "type.googleapis.com/google.protobuf.testing.anys.AnyM")
   1465       ->RenderString("foo", "foovalue")
   1466       ->EndObject()
   1467       ->EndObject()
   1468       ->EndObject();
   1469 }
   1470 
   1471 TEST_P(ProtoStreamObjectWriterAnyTest, DoubleRecursiveAny) {
   1472   AnyOut out;
   1473   ::google::protobuf::Any* any = out.mutable_any();
   1474   any->set_type_url("type.googleapis.com/google.protobuf.Any");
   1475 
   1476   ::google::protobuf::Any nested_any;
   1477   nested_any.set_type_url("type.googleapis.com/google.protobuf.Any");
   1478 
   1479   ::google::protobuf::Any second_nested_any;
   1480   second_nested_any.set_type_url(
   1481       "type.googleapis.com/google.protobuf.testing.anys.AnyM");
   1482 
   1483   AnyM m;
   1484   m.set_foo("foovalue");
   1485   second_nested_any.set_value(m.SerializeAsString());
   1486 
   1487   nested_any.set_value(second_nested_any.SerializeAsString());
   1488   any->set_value(nested_any.SerializeAsString());
   1489 
   1490   ow_->StartObject("")
   1491       ->StartObject("any")
   1492       ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
   1493       ->StartObject("value")
   1494       ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
   1495       ->StartObject("value")
   1496       ->RenderString("@type",
   1497                      "type.googleapis.com/google.protobuf.testing.anys.AnyM")
   1498       ->RenderString("foo", "foovalue")
   1499       ->EndObject()
   1500       ->EndObject()
   1501       ->EndObject()
   1502       ->EndObject();
   1503 }
   1504 
   1505 TEST_P(ProtoStreamObjectWriterAnyTest, EmptyAnyFromEmptyObject) {
   1506   AnyOut out;
   1507   out.mutable_any();
   1508 
   1509   ow_->StartObject("")->StartObject("any")->EndObject()->EndObject();
   1510 
   1511   CheckOutput(out, 2);
   1512 }
   1513 
   1514 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails1) {
   1515   AnyOut any;
   1516 
   1517   EXPECT_CALL(
   1518       listener_,
   1519       InvalidValue(_, StringPiece("Any"),
   1520                    StringPiece("Missing or invalid @type for any field in "
   1521                                "google.protobuf.testing.anys.AnyOut")));
   1522 
   1523   ow_->StartObject("")
   1524       ->StartObject("any")
   1525       ->StartObject("another")
   1526       ->EndObject()
   1527       ->EndObject()
   1528       ->EndObject();
   1529   CheckOutput(any);
   1530 }
   1531 
   1532 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails2) {
   1533   AnyOut any;
   1534 
   1535   EXPECT_CALL(
   1536       listener_,
   1537       InvalidValue(_, StringPiece("Any"),
   1538                    StringPiece("Missing or invalid @type for any field in "
   1539                                "google.protobuf.testing.anys.AnyOut")));
   1540 
   1541   ow_->StartObject("")
   1542       ->StartObject("any")
   1543       ->StartList("another")
   1544       ->EndObject()
   1545       ->EndObject()
   1546       ->EndObject();
   1547   CheckOutput(any);
   1548 }
   1549 
   1550 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails3) {
   1551   AnyOut any;
   1552 
   1553   EXPECT_CALL(
   1554       listener_,
   1555       InvalidValue(_, StringPiece("Any"),
   1556                    StringPiece("Missing or invalid @type for any field in "
   1557                                "google.protobuf.testing.anys.AnyOut")));
   1558 
   1559   ow_->StartObject("")
   1560       ->StartObject("any")
   1561       ->RenderString("value", "somevalue")
   1562       ->EndObject()
   1563       ->EndObject();
   1564   CheckOutput(any);
   1565 }
   1566 
   1567 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithInvalidTypeUrlFails) {
   1568   AnyOut any;
   1569 
   1570   EXPECT_CALL(listener_,
   1571               InvalidValue(
   1572                   _, StringPiece("Any"),
   1573                   StringPiece("Invalid type URL, type URLs must be of the form "
   1574                               "'type.googleapis.com/<typename>', got: "
   1575                               "type.other.com/some.Type")));
   1576 
   1577   ow_->StartObject("")
   1578       ->StartObject("any")
   1579       ->RenderString("@type", "type.other.com/some.Type")
   1580       ->RenderDouble("value", 40.2)
   1581       ->EndObject()
   1582       ->EndObject();
   1583   CheckOutput(any);
   1584 }
   1585 
   1586 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithUnknownTypeFails) {
   1587   AnyOut any;
   1588 
   1589   EXPECT_CALL(
   1590       listener_,
   1591       InvalidValue(_, StringPiece("Any"),
   1592                    StringPiece("Invalid type URL, unknown type: some.Type")));
   1593   ow_->StartObject("")
   1594       ->StartObject("any")
   1595       ->RenderString("@type", "type.googleapis.com/some.Type")
   1596       ->RenderDouble("value", 40.2)
   1597       ->EndObject()
   1598       ->EndObject();
   1599   CheckOutput(any);
   1600 }
   1601 
   1602 TEST_P(ProtoStreamObjectWriterAnyTest, AnyNullInputFails) {
   1603   AnyOut any;
   1604 
   1605   ow_->StartObject("")->RenderNull("any")->EndObject();
   1606   CheckOutput(any);
   1607 }
   1608 
   1609 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypeErrorTest) {
   1610   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
   1611                                       StringPiece("Invalid time format: ")));
   1612 
   1613   AnyOut any;
   1614   google::protobuf::Any* any_type = any.mutable_any();
   1615   any_type->set_type_url("type.googleapis.com/google.protobuf.Timestamp");
   1616 
   1617   ow_->StartObject("")
   1618       ->StartObject("any")
   1619       ->RenderString("@type", "type.googleapis.com/google.protobuf.Timestamp")
   1620       ->RenderString("value", "")
   1621       ->EndObject()
   1622       ->EndObject();
   1623   CheckOutput(any);
   1624 }
   1625 
   1626 // Test the following case:
   1627 //
   1628 // {
   1629 //   "any": {
   1630 //     "@type": "type.googleapis.com/google.protobuf.Value",
   1631 //     "value": "abc"
   1632 //   }
   1633 // }
   1634 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedPrimitiveValue) {
   1635   AnyOut out;
   1636   ::google::protobuf::Any* any = out.mutable_any();
   1637 
   1638   ::google::protobuf::Value value;
   1639   value.set_string_value("abc");
   1640   any->PackFrom(value);
   1641 
   1642   ow_->StartObject("")
   1643       ->StartObject("any")
   1644       ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
   1645       ->RenderString("value", "abc")
   1646       ->EndObject()
   1647       ->EndObject();
   1648   CheckOutput(out);
   1649 }
   1650 
   1651 // Test the following case:
   1652 //
   1653 // {
   1654 //   "any": {
   1655 //     "@type": "type.googleapis.com/google.protobuf.Value",
   1656 //     "value": {
   1657 //       "foo": "abc"
   1658 //     }
   1659 //   }
   1660 // }
   1661 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedObjectValue) {
   1662   AnyOut out;
   1663   ::google::protobuf::Any* any = out.mutable_any();
   1664 
   1665   ::google::protobuf::Value value;
   1666   (*value.mutable_struct_value()->mutable_fields())["foo"].set_string_value(
   1667       "abc");
   1668   any->PackFrom(value);
   1669 
   1670   ow_->StartObject("")
   1671       ->StartObject("any")
   1672       ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
   1673       ->StartObject("value")
   1674       ->RenderString("foo", "abc")
   1675       ->EndObject()
   1676       ->EndObject()
   1677       ->EndObject();
   1678   CheckOutput(out);
   1679 }
   1680 
   1681 // Test the following case:
   1682 //
   1683 // {
   1684 //   "any": {
   1685 //     "@type": "type.googleapis.com/google.protobuf.Value",
   1686 //     "value": ["hello"],
   1687 //   }
   1688 // }
   1689 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedArrayValue) {
   1690   AnyOut out;
   1691   ::google::protobuf::Any* any = out.mutable_any();
   1692 
   1693   ::google::protobuf::Value value;
   1694   value.mutable_list_value()->add_values()->set_string_value("hello");
   1695   any->PackFrom(value);
   1696 
   1697   ow_->StartObject("")
   1698       ->StartObject("any")
   1699       ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
   1700       ->StartList("value")
   1701       ->RenderString("", "hello")
   1702       ->EndList()
   1703       ->EndObject()
   1704       ->EndObject()
   1705       ->EndObject();
   1706   CheckOutput(out);
   1707 }
   1708 
   1709 // Test the following case:
   1710 //
   1711 // {
   1712 //   "any": {
   1713 //     "@type": "type.googleapis.com/google.protobuf.Value",
   1714 //     "not_value": ""
   1715 //   }
   1716 // }
   1717 TEST_P(ProtoStreamObjectWriterAnyTest,
   1718        AnyWellKnownTypesNoValueFieldForPrimitive) {
   1719   EXPECT_CALL(
   1720       listener_,
   1721       InvalidValue(
   1722           _, StringPiece("Any"),
   1723           StringPiece("Expect a \"value\" field for well-known types.")));
   1724   AnyOut any;
   1725   google::protobuf::Any* any_type = any.mutable_any();
   1726   any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
   1727 
   1728   ow_->StartObject("")
   1729       ->StartObject("any")
   1730       ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
   1731       ->RenderString("not_value", "")
   1732       ->EndObject()
   1733       ->EndObject();
   1734   CheckOutput(any);
   1735 }
   1736 
   1737 // Test the following case:
   1738 //
   1739 // {
   1740 //   "any": {
   1741 //     "@type": "type.googleapis.com/google.protobuf.Value",
   1742 //     "not_value": {}
   1743 //   }
   1744 // }
   1745 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesNoValueFieldForObject) {
   1746   EXPECT_CALL(
   1747       listener_,
   1748       InvalidValue(
   1749           _, StringPiece("Any"),
   1750           StringPiece("Expect a \"value\" field for well-known types.")));
   1751   AnyOut any;
   1752   google::protobuf::Any* any_type = any.mutable_any();
   1753   any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
   1754 
   1755   ow_->StartObject("")
   1756       ->StartObject("any")
   1757       ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
   1758       ->StartObject("not_value")
   1759       ->EndObject()
   1760       ->EndObject()
   1761       ->EndObject();
   1762   CheckOutput(any);
   1763 }
   1764 
   1765 // Test the following case:
   1766 //
   1767 // {
   1768 //   "any": {
   1769 //     "@type": "type.googleapis.com/google.protobuf.Value",
   1770 //     "not_value": [],
   1771 //   }
   1772 // }
   1773 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesNoValueFieldForArray) {
   1774   EXPECT_CALL(
   1775       listener_,
   1776       InvalidValue(
   1777           _, StringPiece("Any"),
   1778           StringPiece("Expect a \"value\" field for well-known types.")));
   1779   AnyOut any;
   1780   google::protobuf::Any* any_type = any.mutable_any();
   1781   any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
   1782 
   1783   ow_->StartObject("")
   1784       ->StartObject("any")
   1785       ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
   1786       ->StartList("not_value")
   1787       ->EndList()
   1788       ->EndObject()
   1789       ->EndObject()
   1790       ->EndObject();
   1791   CheckOutput(any);
   1792 }
   1793 
   1794 // Test the following case:
   1795 //
   1796 // {
   1797 //   "any": {
   1798 //     "@type": "type.googleapis.com/google.protobuf.Struct",
   1799 //     "value": "",
   1800 //   }
   1801 // }
   1802 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForStruct) {
   1803   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
   1804                                       StringPiece("Expect a JSON object.")));
   1805   AnyOut any;
   1806   google::protobuf::Any* any_type = any.mutable_any();
   1807   any_type->set_type_url("type.googleapis.com/google.protobuf.Struct");
   1808 
   1809   ow_->StartObject("")
   1810       ->StartObject("any")
   1811       ->RenderString("@type", "type.googleapis.com/google.protobuf.Struct")
   1812       ->RenderString("value", "")
   1813       ->EndObject()
   1814       ->EndObject();
   1815   CheckOutput(any);
   1816 }
   1817 
   1818 // Test the following case:
   1819 //
   1820 // {
   1821 //   "any": {
   1822 //     "@type": "type.googleapis.com/google.protobuf.Any",
   1823 //     "value": "",
   1824 //   }
   1825 // }
   1826 TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForAny) {
   1827   EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
   1828                                       StringPiece("Expect a JSON object.")));
   1829   AnyOut any;
   1830   google::protobuf::Any* any_type = any.mutable_any();
   1831   any_type->set_type_url("type.googleapis.com/google.protobuf.Any");
   1832 
   1833   ow_->StartObject("")
   1834       ->StartObject("any")
   1835       ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
   1836       ->RenderString("value", "")
   1837       ->EndObject()
   1838       ->EndObject();
   1839   CheckOutput(any);
   1840 }
   1841 
   1842 class ProtoStreamObjectWriterFieldMaskTest
   1843     : public BaseProtoStreamObjectWriterTest {
   1844  protected:
   1845   ProtoStreamObjectWriterFieldMaskTest() {
   1846     vector<const Descriptor*> descriptors;
   1847     descriptors.push_back(FieldMaskTest::descriptor());
   1848     descriptors.push_back(google::protobuf::FieldMask::descriptor());
   1849     ResetTypeInfo(descriptors);
   1850   }
   1851 };
   1852 
   1853 INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
   1854                         ProtoStreamObjectWriterFieldMaskTest,
   1855                         ::testing::Values(
   1856                             testing::USE_TYPE_RESOLVER));
   1857 
   1858 TEST_P(ProtoStreamObjectWriterFieldMaskTest, SimpleFieldMaskTest) {
   1859   FieldMaskTest expected;
   1860   expected.set_id("1");
   1861   expected.mutable_single_mask()->add_paths("path1");
   1862 
   1863   ow_->StartObject("");
   1864   ow_->RenderString("id", "1");
   1865   ow_->RenderString("single_mask", "path1");
   1866   ow_->EndObject();
   1867 
   1868   CheckOutput(expected);
   1869 }
   1870 
   1871 TEST_P(ProtoStreamObjectWriterFieldMaskTest, MutipleMasksInCompactForm) {
   1872   FieldMaskTest expected;
   1873   expected.set_id("1");
   1874   expected.mutable_single_mask()->add_paths("camel_case1");
   1875   expected.mutable_single_mask()->add_paths("camel_case2");
   1876   expected.mutable_single_mask()->add_paths("camel_case3");
   1877 
   1878   ow_->StartObject("");
   1879   ow_->RenderString("id", "1");
   1880   ow_->RenderString("single_mask", "camelCase1,camelCase2,camelCase3");
   1881   ow_->EndObject();
   1882 
   1883   CheckOutput(expected);
   1884 }
   1885 
   1886 TEST_P(ProtoStreamObjectWriterFieldMaskTest, RepeatedFieldMaskTest) {
   1887   FieldMaskTest expected;
   1888   expected.set_id("1");
   1889   google::protobuf::FieldMask* mask = expected.add_repeated_mask();
   1890   mask->add_paths("field1");
   1891   mask->add_paths("field2");
   1892   expected.add_repeated_mask()->add_paths("field3");
   1893 
   1894   ow_->StartObject("");
   1895   ow_->RenderString("id", "1");
   1896   ow_->StartList("repeated_mask");
   1897   ow_->RenderString("", "field1,field2");
   1898   ow_->RenderString("", "field3");
   1899   ow_->EndList();
   1900   ow_->EndObject();
   1901 
   1902   CheckOutput(expected);
   1903 }
   1904 
   1905 TEST_P(ProtoStreamObjectWriterFieldMaskTest, EmptyFieldMaskTest) {
   1906   FieldMaskTest expected;
   1907   expected.set_id("1");
   1908 
   1909   ow_->StartObject("");
   1910   ow_->RenderString("id", "1");
   1911   ow_->RenderString("single_mask", "");
   1912   ow_->EndObject();
   1913 
   1914   CheckOutput(expected);
   1915 }
   1916 
   1917 TEST_P(ProtoStreamObjectWriterFieldMaskTest, MaskUsingApiaryStyleShouldWork) {
   1918   FieldMaskTest expected;
   1919   expected.set_id("1");
   1920 
   1921   ow_->StartObject("");
   1922   ow_->RenderString("id", "1");
   1923   // Case1
   1924   ow_->RenderString("single_mask",
   1925                     "outerField(camelCase1,camelCase2,camelCase3)");
   1926   expected.mutable_single_mask()->add_paths("outer_field.camel_case1");
   1927   expected.mutable_single_mask()->add_paths("outer_field.camel_case2");
   1928   expected.mutable_single_mask()->add_paths("outer_field.camel_case3");
   1929 
   1930   ow_->StartList("repeated_mask");
   1931 
   1932   ow_->RenderString("", "a(field1,field2)");
   1933   google::protobuf::FieldMask* mask = expected.add_repeated_mask();
   1934   mask->add_paths("a.field1");
   1935   mask->add_paths("a.field2");
   1936 
   1937   ow_->RenderString("", "a(field3)");
   1938   mask = expected.add_repeated_mask();
   1939   mask->add_paths("a.field3");
   1940 
   1941   ow_->RenderString("", "a()");
   1942   expected.add_repeated_mask();
   1943 
   1944   ow_->RenderString("", "a(,)");
   1945   expected.add_repeated_mask();
   1946 
   1947   ow_->RenderString("", "a(field1(field2(field3)))");
   1948   mask = expected.add_repeated_mask();
   1949   mask->add_paths("a.field1.field2.field3");
   1950 
   1951   ow_->RenderString("", "a(field1(field2(field3,field4),field5),field6)");
   1952   mask = expected.add_repeated_mask();
   1953   mask->add_paths("a.field1.field2.field3");
   1954   mask->add_paths("a.field1.field2.field4");
   1955   mask->add_paths("a.field1.field5");
   1956   mask->add_paths("a.field6");
   1957 
   1958   ow_->RenderString("", "a(id,field1(id,field2(field3,field4),field5),field6)");
   1959   mask = expected.add_repeated_mask();
   1960   mask->add_paths("a.id");
   1961   mask->add_paths("a.field1.id");
   1962   mask->add_paths("a.field1.field2.field3");
   1963   mask->add_paths("a.field1.field2.field4");
   1964   mask->add_paths("a.field1.field5");
   1965   mask->add_paths("a.field6");
   1966 
   1967   ow_->RenderString("", "a(((field3,field4)))");
   1968   mask = expected.add_repeated_mask();
   1969   mask->add_paths("a.field3");
   1970   mask->add_paths("a.field4");
   1971 
   1972   ow_->EndList();
   1973   ow_->EndObject();
   1974 
   1975   CheckOutput(expected);
   1976 }
   1977 
   1978 TEST_P(ProtoStreamObjectWriterFieldMaskTest, MoreCloseThanOpenParentheses) {
   1979   EXPECT_CALL(
   1980       listener_,
   1981       InvalidValue(
   1982           _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
   1983           StringPiece("Field 'single_mask', Invalid FieldMask 'a(b,c))'. "
   1984                       "Cannot find matching '(' for all ')'.")));
   1985 
   1986   ow_->StartObject("");
   1987   ow_->RenderString("id", "1");
   1988   ow_->RenderString("single_mask", "a(b,c))");
   1989   ow_->EndObject();
   1990 }
   1991 
   1992 TEST_P(ProtoStreamObjectWriterFieldMaskTest, MoreOpenThanCloseParentheses) {
   1993   EXPECT_CALL(
   1994       listener_,
   1995       InvalidValue(
   1996           _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
   1997           StringPiece(
   1998               "Field 'single_mask', Invalid FieldMask 'a(((b,c)'. Cannot "
   1999               "find matching ')' for all '('.")));
   2000 
   2001   ow_->StartObject("");
   2002   ow_->RenderString("id", "1");
   2003   ow_->RenderString("single_mask", "a(((b,c)");
   2004   ow_->EndObject();
   2005 }
   2006 
   2007 TEST_P(ProtoStreamObjectWriterFieldMaskTest, PathWithMapKeyShouldWork) {
   2008   FieldMaskTest expected;
   2009   expected.mutable_single_mask()->add_paths("path.to.map[\"key1\"]");
   2010   expected.mutable_single_mask()->add_paths(
   2011       "path.to.map[\"e\\\"[]][scape\\\"\"]");
   2012   expected.mutable_single_mask()->add_paths("path.to.map[\"key2\"]");
   2013 
   2014   ow_->StartObject("");
   2015   ow_->RenderString("single_mask",
   2016                     "path.to.map[\"key1\"],path.to.map[\"e\\\"[]][scape\\\"\"],"
   2017                     "path.to.map[\"key2\"]");
   2018   ow_->EndObject();
   2019 
   2020   CheckOutput(expected);
   2021 }
   2022 
   2023 TEST_P(ProtoStreamObjectWriterFieldMaskTest,
   2024        MapKeyMustBeAtTheEndOfAPathSegment) {
   2025   EXPECT_CALL(
   2026       listener_,
   2027       InvalidValue(
   2028           _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
   2029           StringPiece("Field 'single_mask', Invalid FieldMask "
   2030                       "'path.to.map[\"key1\"]a,path.to.map[\"key2\"]'. "
   2031                       "Map keys should be at the end of a path segment.")));
   2032 
   2033   ow_->StartObject("");
   2034   ow_->RenderString("single_mask",
   2035                     "path.to.map[\"key1\"]a,path.to.map[\"key2\"]");
   2036   ow_->EndObject();
   2037 }
   2038 
   2039 TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustEnd) {
   2040   EXPECT_CALL(
   2041       listener_,
   2042       InvalidValue(_,
   2043                    StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
   2044                    StringPiece("Field 'single_mask', Invalid FieldMask "
   2045                                "'path.to.map[\"key1\"'. Map keys should be "
   2046                                "represented as [\"some_key\"].")));
   2047 
   2048   ow_->StartObject("");
   2049   ow_->RenderString("single_mask", "path.to.map[\"key1\"");
   2050   ow_->EndObject();
   2051 }
   2052 
   2053 TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustBeEscapedCorrectly) {
   2054   EXPECT_CALL(
   2055       listener_,
   2056       InvalidValue(_,
   2057                    StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
   2058                    StringPiece("Field 'single_mask', Invalid FieldMask "
   2059                                "'path.to.map[\"ke\"y1\"]'. Map keys should be "
   2060                                "represented as [\"some_key\"].")));
   2061 
   2062   ow_->StartObject("");
   2063   ow_->RenderString("single_mask", "path.to.map[\"ke\"y1\"]");
   2064   ow_->EndObject();
   2065 }
   2066 
   2067 TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyCanContainAnyChars) {
   2068   FieldMaskTest expected;
   2069   expected.mutable_single_mask()->add_paths(
   2070       // \xE5\xAD\x99 is the UTF-8 byte sequence for chinese character .
   2071       // We cannot embed non-ASCII characters in the code directly because
   2072       // some windows compilers will try to interpret them using the system's
   2073       // current encoding and end up with invalid UTF-8 byte sequence.
   2074       "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War\xE5\xAD\x99,./?><\\\\\"]");
   2075   expected.mutable_single_mask()->add_paths("path.to.map[\"key2\"]");
   2076 
   2077   ow_->StartObject("");
   2078   ow_->RenderString(
   2079       "single_mask",
   2080       "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War\xE5\xAD\x99,./?><\\\\\"],"
   2081       "path.to.map[\"key2\"]");
   2082   ow_->EndObject();
   2083 
   2084   CheckOutput(expected);
   2085 }
   2086 
   2087 class ProtoStreamObjectWriterOneOfsTest
   2088     : public BaseProtoStreamObjectWriterTest {
   2089  protected:
   2090   ProtoStreamObjectWriterOneOfsTest() {
   2091     vector<const Descriptor*> descriptors;
   2092     descriptors.push_back(OneOfsRequest::descriptor());
   2093     descriptors.push_back(google::protobuf::Struct::descriptor());
   2094     ResetTypeInfo(descriptors);
   2095   }
   2096 };
   2097 
   2098 INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
   2099                         ProtoStreamObjectWriterOneOfsTest,
   2100                         ::testing::Values(
   2101                             testing::USE_TYPE_RESOLVER));
   2102 
   2103 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2104        MultipleOneofsFailForPrimitiveTypesTest) {
   2105   EXPECT_CALL(
   2106       listener_,
   2107       InvalidValue(
   2108           _, StringPiece("oneof"),
   2109           StringPiece(
   2110               "oneof field 'data' is already set. Cannot set 'intData'")));
   2111 
   2112   ow_->StartObject("");
   2113   ow_->RenderString("strData", "blah");
   2114   ow_->RenderString("intData", "123");
   2115   ow_->EndObject();
   2116 }
   2117 
   2118 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2119        MultipleOneofsFailForMessageTypesPrimitiveFirstTest) {
   2120   // Test for setting primitive oneof field first and then message field.
   2121   EXPECT_CALL(listener_,
   2122               InvalidValue(_, StringPiece("oneof"),
   2123                            StringPiece("oneof field 'data' is already set. "
   2124                                        "Cannot set 'messageData'")));
   2125 
   2126   // JSON: { "strData": "blah", "messageData": { "dataValue": 123 } }
   2127   ow_->StartObject("");
   2128   ow_->RenderString("strData", "blah");
   2129   ow_->StartObject("messageData");
   2130   ow_->RenderInt32("dataValue", 123);
   2131   ow_->EndObject();
   2132   ow_->EndObject();
   2133 }
   2134 
   2135 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2136        MultipleOneofsFailForMessageTypesMessageFirstTest) {
   2137   // Test for setting message oneof field first and then primitive field.
   2138   EXPECT_CALL(listener_,
   2139               InvalidValue(_, StringPiece("oneof"),
   2140                            StringPiece("oneof field 'data' is already set. "
   2141                                        "Cannot set 'strData'")));
   2142 
   2143   // JSON: { "messageData": { "dataValue": 123 }, "strData": "blah" }
   2144   ow_->StartObject("");
   2145   ow_->StartObject("messageData");
   2146   ow_->RenderInt32("dataValue", 123);
   2147   ow_->EndObject();
   2148   ow_->RenderString("strData", "blah");
   2149   ow_->EndObject();
   2150 }
   2151 
   2152 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2153        MultipleOneofsFailForStructTypesPrimitiveFirstTest) {
   2154   EXPECT_CALL(listener_,
   2155               InvalidValue(_, StringPiece("oneof"),
   2156                            StringPiece("oneof field 'data' is already set. "
   2157                                        "Cannot set 'structData'")));
   2158 
   2159   // JSON: { "strData": "blah", "structData": { "a": "b" } }
   2160   ow_->StartObject("");
   2161   ow_->RenderString("strData", "blah");
   2162   ow_->StartObject("structData");
   2163   ow_->RenderString("a", "b");
   2164   ow_->EndObject();
   2165   ow_->EndObject();
   2166 }
   2167 
   2168 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2169        MultipleOneofsFailForStructTypesStructFirstTest) {
   2170   EXPECT_CALL(listener_,
   2171               InvalidValue(_, StringPiece("oneof"),
   2172                            StringPiece("oneof field 'data' is already set. "
   2173                                        "Cannot set 'strData'")));
   2174 
   2175   // JSON: { "structData": { "a": "b" }, "strData": "blah" }
   2176   ow_->StartObject("");
   2177   ow_->StartObject("structData");
   2178   ow_->RenderString("a", "b");
   2179   ow_->EndObject();
   2180   ow_->RenderString("strData", "blah");
   2181   ow_->EndObject();
   2182 }
   2183 
   2184 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2185        MultipleOneofsFailForStructValueTypesTest) {
   2186   EXPECT_CALL(listener_,
   2187               InvalidValue(_, StringPiece("oneof"),
   2188                            StringPiece("oneof field 'data' is already set. "
   2189                                        "Cannot set 'valueData'")));
   2190 
   2191   // JSON: { "messageData": { "dataValue": 123 }, "valueData": { "a": "b" } }
   2192   ow_->StartObject("");
   2193   ow_->StartObject("messageData");
   2194   ow_->RenderInt32("dataValue", 123);
   2195   ow_->EndObject();
   2196   ow_->StartObject("valueData");
   2197   ow_->RenderString("a", "b");
   2198   ow_->EndObject();
   2199   ow_->EndObject();
   2200 }
   2201 
   2202 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2203        MultipleOneofsFailForWellKnownTypesPrimitiveFirstTest) {
   2204   EXPECT_CALL(listener_,
   2205               InvalidValue(_, StringPiece("oneof"),
   2206                            StringPiece("oneof field 'data' is already set. "
   2207                                        "Cannot set 'tsData'")));
   2208 
   2209   // JSON: { "intData": 123, "tsData": "1970-01-02T01:00:00.000Z" }
   2210   ow_->StartObject("");
   2211   ow_->RenderInt32("intData", 123);
   2212   ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
   2213   ow_->EndObject();
   2214 }
   2215 
   2216 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2217        MultipleOneofsFailForWellKnownTypesWktFirstTest) {
   2218   EXPECT_CALL(listener_,
   2219               InvalidValue(_, StringPiece("oneof"),
   2220                            StringPiece("oneof field 'data' is already set. "
   2221                                        "Cannot set 'intData'")));
   2222 
   2223   // JSON: { "tsData": "1970-01-02T01:00:00.000Z", "intData": 123 }
   2224   ow_->StartObject("");
   2225   ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
   2226   ow_->RenderInt32("intData", 123);
   2227   ow_->EndObject();
   2228 }
   2229 
   2230 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2231        MultipleOneofsFailForWellKnownTypesAndMessageTest) {
   2232   EXPECT_CALL(listener_,
   2233               InvalidValue(_, StringPiece("oneof"),
   2234                            StringPiece("oneof field 'data' is already set. "
   2235                                        "Cannot set 'messageData'")));
   2236 
   2237   // JSON: { "tsData": "1970-01-02T01:00:00.000Z",
   2238   //         "messageData": { "dataValue": 123 } }
   2239   ow_->StartObject("");
   2240   ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
   2241   ow_->StartObject("messageData");
   2242   ow_->RenderInt32("dataValue", 123);
   2243   ow_->EndObject();
   2244   ow_->EndObject();
   2245 }
   2246 
   2247 TEST_P(ProtoStreamObjectWriterOneOfsTest,
   2248        MultipleOneofsFailForOneofWithinAnyTest) {
   2249   EXPECT_CALL(listener_,
   2250               InvalidValue(_, StringPiece("oneof"),
   2251                            StringPiece("oneof field 'data' is already set. "
   2252                                        "Cannot set 'intData'")));
   2253 
   2254   using google::protobuf::testing::oneofs::OneOfsRequest;
   2255   // JSON:
   2256   // { "anyData":
   2257   //    { "@type":
   2258   //       "type.googleapis.com/google.protobuf.testing.oneofs.OneOfsRequest",
   2259   //     "strData": "blah",
   2260   //     "intData": 123
   2261   //    }
   2262   // }
   2263   ow_->StartObject("");
   2264   ow_->StartObject("anyData");
   2265   ow_->RenderString(
   2266       "@type",
   2267       "type.googleapis.com/google.protobuf.testing.oneofs.OneOfsRequest");
   2268   ow_->RenderString("strData", "blah");
   2269   ow_->RenderInt32("intData", 123);
   2270   ow_->EndObject();
   2271   ow_->EndObject();
   2272 }
   2273 
   2274 }  // namespace converter
   2275 }  // namespace util
   2276 }  // namespace protobuf
   2277 }  // namespace google
   2278