~ubuntu-branches/ubuntu/oneiric/mozc/oneiric

« back to all changes in this revision

Viewing changes to protobuf/files/src/google/protobuf/descriptor_unittest.cc

  • Committer: Bazaar Package Importer
  • Author(s): Nobuhiro Iwamatsu
  • Date: 2010-07-14 03:26:47 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100714032647-13qjisj6m8cm8jdx
Tags: 0.12.410.102-1
* New upstream release (Closes: #588971).
  - Add mozc-server, mozc-utils-gui and scim-mozc packages.
* Update debian/rules.
  Add --gypdir option to build_mozc.py.
* Update debian/control.
  - Bumped standards-version to 3.9.0.
  - Update description.
* Add mozc icon (Closes: #588972).
* Add patch which revises issue 18.
  ibus_mozc_issue18.patch
* kFreeBSD build support.
  support_kfreebsd.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Protocol Buffers - Google's data interchange format
2
 
// Copyright 2008 Google Inc.  All rights reserved.
3
 
// http://code.google.com/p/protobuf/
4
 
//
5
 
// Redistribution and use in source and binary forms, with or without
6
 
// modification, are permitted provided that the following conditions are
7
 
// met:
8
 
//
9
 
//     * Redistributions of source code must retain the above copyright
10
 
// notice, this list of conditions and the following disclaimer.
11
 
//     * Redistributions in binary form must reproduce the above
12
 
// copyright notice, this list of conditions and the following disclaimer
13
 
// in the documentation and/or other materials provided with the
14
 
// distribution.
15
 
//     * Neither the name of Google Inc. nor the names of its
16
 
// contributors may be used to endorse or promote products derived from
17
 
// this software without specific prior written permission.
18
 
//
19
 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
 
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
 
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
 
 
31
 
// Author: kenton@google.com (Kenton Varda)
32
 
//  Based on original Protocol Buffers design by
33
 
//  Sanjay Ghemawat, Jeff Dean, and others.
34
 
//
35
 
// This file makes extensive use of RFC 3092.  :)
36
 
 
37
 
#include <vector>
38
 
 
39
 
#include <google/protobuf/descriptor.h>
40
 
#include <google/protobuf/descriptor_database.h>
41
 
#include <google/protobuf/dynamic_message.h>
42
 
#include <google/protobuf/descriptor.pb.h>
43
 
#include <google/protobuf/text_format.h>
44
 
#include <google/protobuf/unittest.pb.h>
45
 
#include <google/protobuf/unittest_custom_options.pb.h>
46
 
#include <google/protobuf/stubs/strutil.h>
47
 
#include <google/protobuf/stubs/substitute.h>
48
 
 
49
 
#include <google/protobuf/stubs/common.h>
50
 
#include <google/protobuf/testing/googletest.h>
51
 
#include <gtest/gtest.h>
52
 
 
53
 
namespace google {
54
 
namespace protobuf {
55
 
 
56
 
// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
57
 
namespace descriptor_unittest {
58
 
 
59
 
// Some helpers to make assembling descriptors faster.
60
 
DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) {
61
 
  DescriptorProto* result = file->add_message_type();
62
 
  result->set_name(name);
63
 
  return result;
64
 
}
65
 
 
66
 
DescriptorProto* AddNestedMessage(DescriptorProto* parent, const string& name) {
67
 
  DescriptorProto* result = parent->add_nested_type();
68
 
  result->set_name(name);
69
 
  return result;
70
 
}
71
 
 
72
 
EnumDescriptorProto* AddEnum(FileDescriptorProto* file, const string& name) {
73
 
  EnumDescriptorProto* result = file->add_enum_type();
74
 
  result->set_name(name);
75
 
  return result;
76
 
}
77
 
 
78
 
EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent,
79
 
                                   const string& name) {
80
 
  EnumDescriptorProto* result = parent->add_enum_type();
81
 
  result->set_name(name);
82
 
  return result;
83
 
}
84
 
 
85
 
ServiceDescriptorProto* AddService(FileDescriptorProto* file,
86
 
                                   const string& name) {
87
 
  ServiceDescriptorProto* result = file->add_service();
88
 
  result->set_name(name);
89
 
  return result;
90
 
}
91
 
 
92
 
FieldDescriptorProto* AddField(DescriptorProto* parent,
93
 
                               const string& name, int number,
94
 
                               FieldDescriptorProto::Label label,
95
 
                               FieldDescriptorProto::Type type) {
96
 
  FieldDescriptorProto* result = parent->add_field();
97
 
  result->set_name(name);
98
 
  result->set_number(number);
99
 
  result->set_label(label);
100
 
  result->set_type(type);
101
 
  return result;
102
 
}
103
 
 
104
 
FieldDescriptorProto* AddExtension(FileDescriptorProto* file,
105
 
                                   const string& extendee,
106
 
                                   const string& name, int number,
107
 
                                   FieldDescriptorProto::Label label,
108
 
                                   FieldDescriptorProto::Type type) {
109
 
  FieldDescriptorProto* result = file->add_extension();
110
 
  result->set_name(name);
111
 
  result->set_number(number);
112
 
  result->set_label(label);
113
 
  result->set_type(type);
114
 
  result->set_extendee(extendee);
115
 
  return result;
116
 
}
117
 
 
118
 
FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent,
119
 
                                         const string& extendee,
120
 
                                         const string& name, int number,
121
 
                                         FieldDescriptorProto::Label label,
122
 
                                         FieldDescriptorProto::Type type) {
123
 
  FieldDescriptorProto* result = parent->add_extension();
124
 
  result->set_name(name);
125
 
  result->set_number(number);
126
 
  result->set_label(label);
127
 
  result->set_type(type);
128
 
  result->set_extendee(extendee);
129
 
  return result;
130
 
}
131
 
 
132
 
DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent,
133
 
                                                   int start, int end) {
134
 
  DescriptorProto::ExtensionRange* result = parent->add_extension_range();
135
 
  result->set_start(start);
136
 
  result->set_end(end);
137
 
  return result;
138
 
}
139
 
 
140
 
EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto,
141
 
                                       const string& name, int number) {
142
 
  EnumValueDescriptorProto* result = enum_proto->add_value();
143
 
  result->set_name(name);
144
 
  result->set_number(number);
145
 
  return result;
146
 
}
147
 
 
148
 
MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service,
149
 
                                 const string& name,
150
 
                                 const string& input_type,
151
 
                                 const string& output_type) {
152
 
  MethodDescriptorProto* result = service->add_method();
153
 
  result->set_name(name);
154
 
  result->set_input_type(input_type);
155
 
  result->set_output_type(output_type);
156
 
  return result;
157
 
}
158
 
 
159
 
// Empty enums technically aren't allowed.  We need to insert a dummy value
160
 
// into them.
161
 
void AddEmptyEnum(FileDescriptorProto* file, const string& name) {
162
 
  AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
163
 
}
164
 
 
165
 
// ===================================================================
166
 
 
167
 
// Test simple files.
168
 
class FileDescriptorTest : public testing::Test {
169
 
 protected:
170
 
  virtual void SetUp() {
171
 
    // Build descriptors for the following definitions:
172
 
    //
173
 
    //   // in "foo.proto"
174
 
    //   message FooMessage { extensions 1; }
175
 
    //   enum FooEnum {FOO_ENUM_VALUE = 1;}
176
 
    //   service FooService {}
177
 
    //   extend FooMessage { optional int32 foo_extension = 1; }
178
 
    //
179
 
    //   // in "bar.proto"
180
 
    //   package bar_package;
181
 
    //   message BarMessage { extensions 1; }
182
 
    //   enum BarEnum {BAR_ENUM_VALUE = 1;}
183
 
    //   service BarService {}
184
 
    //   extend BarMessage { optional int32 bar_extension = 1; }
185
 
    //
186
 
    // Also, we have an empty file "baz.proto".  This file's purpose is to
187
 
    // make sure that even though it has the same package as foo.proto,
188
 
    // searching it for members of foo.proto won't work.
189
 
 
190
 
    FileDescriptorProto foo_file;
191
 
    foo_file.set_name("foo.proto");
192
 
    AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2);
193
 
    AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1);
194
 
    AddService(&foo_file, "FooService");
195
 
    AddExtension(&foo_file, "FooMessage", "foo_extension", 1,
196
 
                 FieldDescriptorProto::LABEL_OPTIONAL,
197
 
                 FieldDescriptorProto::TYPE_INT32);
198
 
 
199
 
    FileDescriptorProto bar_file;
200
 
    bar_file.set_name("bar.proto");
201
 
    bar_file.set_package("bar_package");
202
 
    bar_file.add_dependency("foo.proto");
203
 
    AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2);
204
 
    AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1);
205
 
    AddService(&bar_file, "BarService");
206
 
    AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1,
207
 
                 FieldDescriptorProto::LABEL_OPTIONAL,
208
 
                 FieldDescriptorProto::TYPE_INT32);
209
 
 
210
 
    FileDescriptorProto baz_file;
211
 
    baz_file.set_name("baz.proto");
212
 
 
213
 
    // Build the descriptors and get the pointers.
214
 
    foo_file_ = pool_.BuildFile(foo_file);
215
 
    ASSERT_TRUE(foo_file_ != NULL);
216
 
 
217
 
    bar_file_ = pool_.BuildFile(bar_file);
218
 
    ASSERT_TRUE(bar_file_ != NULL);
219
 
 
220
 
    baz_file_ = pool_.BuildFile(baz_file);
221
 
    ASSERT_TRUE(baz_file_ != NULL);
222
 
 
223
 
    ASSERT_EQ(1, foo_file_->message_type_count());
224
 
    foo_message_ = foo_file_->message_type(0);
225
 
    ASSERT_EQ(1, foo_file_->enum_type_count());
226
 
    foo_enum_ = foo_file_->enum_type(0);
227
 
    ASSERT_EQ(1, foo_enum_->value_count());
228
 
    foo_enum_value_ = foo_enum_->value(0);
229
 
    ASSERT_EQ(1, foo_file_->service_count());
230
 
    foo_service_ = foo_file_->service(0);
231
 
    ASSERT_EQ(1, foo_file_->extension_count());
232
 
    foo_extension_ = foo_file_->extension(0);
233
 
 
234
 
    ASSERT_EQ(1, bar_file_->message_type_count());
235
 
    bar_message_ = bar_file_->message_type(0);
236
 
    ASSERT_EQ(1, bar_file_->enum_type_count());
237
 
    bar_enum_ = bar_file_->enum_type(0);
238
 
    ASSERT_EQ(1, bar_enum_->value_count());
239
 
    bar_enum_value_ = bar_enum_->value(0);
240
 
    ASSERT_EQ(1, bar_file_->service_count());
241
 
    bar_service_ = bar_file_->service(0);
242
 
    ASSERT_EQ(1, bar_file_->extension_count());
243
 
    bar_extension_ = bar_file_->extension(0);
244
 
  }
245
 
 
246
 
  DescriptorPool pool_;
247
 
 
248
 
  const FileDescriptor* foo_file_;
249
 
  const FileDescriptor* bar_file_;
250
 
  const FileDescriptor* baz_file_;
251
 
 
252
 
  const Descriptor*          foo_message_;
253
 
  const EnumDescriptor*      foo_enum_;
254
 
  const EnumValueDescriptor* foo_enum_value_;
255
 
  const ServiceDescriptor*   foo_service_;
256
 
  const FieldDescriptor*     foo_extension_;
257
 
 
258
 
  const Descriptor*          bar_message_;
259
 
  const EnumDescriptor*      bar_enum_;
260
 
  const EnumValueDescriptor* bar_enum_value_;
261
 
  const ServiceDescriptor*   bar_service_;
262
 
  const FieldDescriptor*     bar_extension_;
263
 
};
264
 
 
265
 
TEST_F(FileDescriptorTest, Name) {
266
 
  EXPECT_EQ("foo.proto", foo_file_->name());
267
 
  EXPECT_EQ("bar.proto", bar_file_->name());
268
 
  EXPECT_EQ("baz.proto", baz_file_->name());
269
 
}
270
 
 
271
 
TEST_F(FileDescriptorTest, Package) {
272
 
  EXPECT_EQ("", foo_file_->package());
273
 
  EXPECT_EQ("bar_package", bar_file_->package());
274
 
}
275
 
 
276
 
TEST_F(FileDescriptorTest, Dependencies) {
277
 
  EXPECT_EQ(0, foo_file_->dependency_count());
278
 
  EXPECT_EQ(1, bar_file_->dependency_count());
279
 
  EXPECT_EQ(foo_file_, bar_file_->dependency(0));
280
 
}
281
 
 
282
 
TEST_F(FileDescriptorTest, FindMessageTypeByName) {
283
 
  EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage"));
284
 
  EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage"));
285
 
 
286
 
  EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == NULL);
287
 
  EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == NULL);
288
 
  EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == NULL);
289
 
 
290
 
  EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == NULL);
291
 
  EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == NULL);
292
 
}
293
 
 
294
 
TEST_F(FileDescriptorTest, FindEnumTypeByName) {
295
 
  EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum"));
296
 
  EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum"));
297
 
 
298
 
  EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == NULL);
299
 
  EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == NULL);
300
 
  EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == NULL);
301
 
 
302
 
  EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == NULL);
303
 
  EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == NULL);
304
 
}
305
 
 
306
 
TEST_F(FileDescriptorTest, FindEnumValueByName) {
307
 
  EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE"));
308
 
  EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE"));
309
 
 
310
 
  EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == NULL);
311
 
  EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
312
 
  EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
313
 
 
314
 
  EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
315
 
  EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == NULL);
316
 
}
317
 
 
318
 
TEST_F(FileDescriptorTest, FindServiceByName) {
319
 
  EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService"));
320
 
  EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService"));
321
 
 
322
 
  EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == NULL);
323
 
  EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == NULL);
324
 
  EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == NULL);
325
 
 
326
 
  EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == NULL);
327
 
  EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == NULL);
328
 
}
329
 
 
330
 
TEST_F(FileDescriptorTest, FindExtensionByName) {
331
 
  EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension"));
332
 
  EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension"));
333
 
 
334
 
  EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == NULL);
335
 
  EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == NULL);
336
 
  EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == NULL);
337
 
 
338
 
  EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == NULL);
339
 
  EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == NULL);
340
 
}
341
 
 
342
 
TEST_F(FileDescriptorTest, FindExtensionByNumber) {
343
 
  EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1));
344
 
  EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1));
345
 
 
346
 
  EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL);
347
 
}
348
 
 
349
 
TEST_F(FileDescriptorTest, BuildAgain) {
350
 
  // Test that if te call BuildFile again on the same input we get the same
351
 
  // FileDescriptor back.
352
 
  FileDescriptorProto file;
353
 
  foo_file_->CopyTo(&file);
354
 
  EXPECT_EQ(foo_file_, pool_.BuildFile(file));
355
 
 
356
 
  // But if we change the file then it won't work.
357
 
  file.set_package("some.other.package");
358
 
  EXPECT_TRUE(pool_.BuildFile(file) == NULL);
359
 
}
360
 
 
361
 
// ===================================================================
362
 
 
363
 
// Test simple flat messages and fields.
364
 
class DescriptorTest : public testing::Test {
365
 
 protected:
366
 
  virtual void SetUp() {
367
 
    // Build descriptors for the following definitions:
368
 
    //
369
 
    //   // in "foo.proto"
370
 
    //   message TestForeign {}
371
 
    //   enum TestEnum {}
372
 
    //
373
 
    //   message TestMessage {
374
 
    //     required string      foo = 1;
375
 
    //     optional TestEnum    bar = 6;
376
 
    //     repeated TestForeign baz = 500000000;
377
 
    //     optional group       qux = 15 {}
378
 
    //   }
379
 
    //
380
 
    //   // in "bar.proto"
381
 
    //   package corge.grault;
382
 
    //   message TestMessage2 {
383
 
    //     required string foo = 1;
384
 
    //     required string bar = 2;
385
 
    //     required string quux = 6;
386
 
    //   }
387
 
    //
388
 
    // We cheat and use TestForeign as the type for qux rather than create
389
 
    // an actual nested type.
390
 
    //
391
 
    // Since all primitive types (including string) use the same building
392
 
    // code, there's no need to test each one individually.
393
 
    //
394
 
    // TestMessage2 is primarily here to test FindFieldByName and friends.
395
 
    // All messages created from the same DescriptorPool share the same lookup
396
 
    // table, so we need to insure that they don't interfere.
397
 
 
398
 
    FileDescriptorProto foo_file;
399
 
    foo_file.set_name("foo.proto");
400
 
    AddMessage(&foo_file, "TestForeign");
401
 
    AddEmptyEnum(&foo_file, "TestEnum");
402
 
 
403
 
    DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
404
 
    AddField(message, "foo", 1,
405
 
             FieldDescriptorProto::LABEL_REQUIRED,
406
 
             FieldDescriptorProto::TYPE_STRING);
407
 
    AddField(message, "bar", 6,
408
 
             FieldDescriptorProto::LABEL_OPTIONAL,
409
 
             FieldDescriptorProto::TYPE_ENUM)
410
 
      ->set_type_name("TestEnum");
411
 
    AddField(message, "baz", 500000000,
412
 
             FieldDescriptorProto::LABEL_REPEATED,
413
 
             FieldDescriptorProto::TYPE_MESSAGE)
414
 
      ->set_type_name("TestForeign");
415
 
    AddField(message, "qux", 15,
416
 
             FieldDescriptorProto::LABEL_OPTIONAL,
417
 
             FieldDescriptorProto::TYPE_GROUP)
418
 
      ->set_type_name("TestForeign");
419
 
 
420
 
    FileDescriptorProto bar_file;
421
 
    bar_file.set_name("bar.proto");
422
 
    bar_file.set_package("corge.grault");
423
 
 
424
 
    DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
425
 
    AddField(message2, "foo", 1,
426
 
             FieldDescriptorProto::LABEL_REQUIRED,
427
 
             FieldDescriptorProto::TYPE_STRING);
428
 
    AddField(message2, "bar", 2,
429
 
             FieldDescriptorProto::LABEL_REQUIRED,
430
 
             FieldDescriptorProto::TYPE_STRING);
431
 
    AddField(message2, "quux", 6,
432
 
             FieldDescriptorProto::LABEL_REQUIRED,
433
 
             FieldDescriptorProto::TYPE_STRING);
434
 
 
435
 
    // Build the descriptors and get the pointers.
436
 
    foo_file_ = pool_.BuildFile(foo_file);
437
 
    ASSERT_TRUE(foo_file_ != NULL);
438
 
 
439
 
    bar_file_ = pool_.BuildFile(bar_file);
440
 
    ASSERT_TRUE(bar_file_ != NULL);
441
 
 
442
 
    ASSERT_EQ(1, foo_file_->enum_type_count());
443
 
    enum_ = foo_file_->enum_type(0);
444
 
 
445
 
    ASSERT_EQ(2, foo_file_->message_type_count());
446
 
    foreign_ = foo_file_->message_type(0);
447
 
    message_ = foo_file_->message_type(1);
448
 
 
449
 
    ASSERT_EQ(4, message_->field_count());
450
 
    foo_ = message_->field(0);
451
 
    bar_ = message_->field(1);
452
 
    baz_ = message_->field(2);
453
 
    qux_ = message_->field(3);
454
 
 
455
 
    ASSERT_EQ(1, bar_file_->message_type_count());
456
 
    message2_ = bar_file_->message_type(0);
457
 
 
458
 
    ASSERT_EQ(3, message2_->field_count());
459
 
    foo2_  = message2_->field(0);
460
 
    bar2_  = message2_->field(1);
461
 
    quux2_ = message2_->field(2);
462
 
  }
463
 
 
464
 
  DescriptorPool pool_;
465
 
 
466
 
  const FileDescriptor* foo_file_;
467
 
  const FileDescriptor* bar_file_;
468
 
 
469
 
  const Descriptor* message_;
470
 
  const Descriptor* message2_;
471
 
  const Descriptor* foreign_;
472
 
  const EnumDescriptor* enum_;
473
 
 
474
 
  const FieldDescriptor* foo_;
475
 
  const FieldDescriptor* bar_;
476
 
  const FieldDescriptor* baz_;
477
 
  const FieldDescriptor* qux_;
478
 
 
479
 
  const FieldDescriptor* foo2_;
480
 
  const FieldDescriptor* bar2_;
481
 
  const FieldDescriptor* quux2_;
482
 
};
483
 
 
484
 
TEST_F(DescriptorTest, Name) {
485
 
  EXPECT_EQ("TestMessage", message_->name());
486
 
  EXPECT_EQ("TestMessage", message_->full_name());
487
 
  EXPECT_EQ(foo_file_, message_->file());
488
 
 
489
 
  EXPECT_EQ("TestMessage2", message2_->name());
490
 
  EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name());
491
 
  EXPECT_EQ(bar_file_, message2_->file());
492
 
}
493
 
 
494
 
TEST_F(DescriptorTest, ContainingType) {
495
 
  EXPECT_TRUE(message_->containing_type() == NULL);
496
 
  EXPECT_TRUE(message2_->containing_type() == NULL);
497
 
}
498
 
 
499
 
TEST_F(DescriptorTest, FieldsByIndex) {
500
 
  ASSERT_EQ(4, message_->field_count());
501
 
  EXPECT_EQ(foo_, message_->field(0));
502
 
  EXPECT_EQ(bar_, message_->field(1));
503
 
  EXPECT_EQ(baz_, message_->field(2));
504
 
  EXPECT_EQ(qux_, message_->field(3));
505
 
}
506
 
 
507
 
TEST_F(DescriptorTest, FindFieldByName) {
508
 
  // All messages in the same DescriptorPool share a single lookup table for
509
 
  // fields.  So, in addition to testing that FindFieldByName finds the fields
510
 
  // of the message, we need to test that it does *not* find the fields of
511
 
  // *other* messages.
512
 
 
513
 
  EXPECT_EQ(foo_, message_->FindFieldByName("foo"));
514
 
  EXPECT_EQ(bar_, message_->FindFieldByName("bar"));
515
 
  EXPECT_EQ(baz_, message_->FindFieldByName("baz"));
516
 
  EXPECT_EQ(qux_, message_->FindFieldByName("qux"));
517
 
  EXPECT_TRUE(message_->FindFieldByName("no_such_field") == NULL);
518
 
  EXPECT_TRUE(message_->FindFieldByName("quux") == NULL);
519
 
 
520
 
  EXPECT_EQ(foo2_ , message2_->FindFieldByName("foo" ));
521
 
  EXPECT_EQ(bar2_ , message2_->FindFieldByName("bar" ));
522
 
  EXPECT_EQ(quux2_, message2_->FindFieldByName("quux"));
523
 
  EXPECT_TRUE(message2_->FindFieldByName("baz") == NULL);
524
 
  EXPECT_TRUE(message2_->FindFieldByName("qux") == NULL);
525
 
}
526
 
 
527
 
TEST_F(DescriptorTest, FindFieldByNumber) {
528
 
  EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
529
 
  EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
530
 
  EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
531
 
  EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
532
 
  EXPECT_TRUE(message_->FindFieldByNumber(837592) == NULL);
533
 
  EXPECT_TRUE(message_->FindFieldByNumber(2) == NULL);
534
 
 
535
 
  EXPECT_EQ(foo2_ , message2_->FindFieldByNumber(1));
536
 
  EXPECT_EQ(bar2_ , message2_->FindFieldByNumber(2));
537
 
  EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
538
 
  EXPECT_TRUE(message2_->FindFieldByNumber(15) == NULL);
539
 
  EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == NULL);
540
 
}
541
 
 
542
 
TEST_F(DescriptorTest, FieldName) {
543
 
  EXPECT_EQ("foo", foo_->name());
544
 
  EXPECT_EQ("bar", bar_->name());
545
 
  EXPECT_EQ("baz", baz_->name());
546
 
  EXPECT_EQ("qux", qux_->name());
547
 
}
548
 
 
549
 
TEST_F(DescriptorTest, FieldFullName) {
550
 
  EXPECT_EQ("TestMessage.foo", foo_->full_name());
551
 
  EXPECT_EQ("TestMessage.bar", bar_->full_name());
552
 
  EXPECT_EQ("TestMessage.baz", baz_->full_name());
553
 
  EXPECT_EQ("TestMessage.qux", qux_->full_name());
554
 
 
555
 
  EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name());
556
 
  EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name());
557
 
  EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name());
558
 
}
559
 
 
560
 
TEST_F(DescriptorTest, FieldFile) {
561
 
  EXPECT_EQ(foo_file_, foo_->file());
562
 
  EXPECT_EQ(foo_file_, bar_->file());
563
 
  EXPECT_EQ(foo_file_, baz_->file());
564
 
  EXPECT_EQ(foo_file_, qux_->file());
565
 
 
566
 
  EXPECT_EQ(bar_file_, foo2_->file());
567
 
  EXPECT_EQ(bar_file_, bar2_->file());
568
 
  EXPECT_EQ(bar_file_, quux2_->file());
569
 
}
570
 
 
571
 
TEST_F(DescriptorTest, FieldIndex) {
572
 
  EXPECT_EQ(0, foo_->index());
573
 
  EXPECT_EQ(1, bar_->index());
574
 
  EXPECT_EQ(2, baz_->index());
575
 
  EXPECT_EQ(3, qux_->index());
576
 
}
577
 
 
578
 
TEST_F(DescriptorTest, FieldNumber) {
579
 
  EXPECT_EQ(        1, foo_->number());
580
 
  EXPECT_EQ(        6, bar_->number());
581
 
  EXPECT_EQ(500000000, baz_->number());
582
 
  EXPECT_EQ(       15, qux_->number());
583
 
}
584
 
 
585
 
TEST_F(DescriptorTest, FieldType) {
586
 
  EXPECT_EQ(FieldDescriptor::TYPE_STRING , foo_->type());
587
 
  EXPECT_EQ(FieldDescriptor::TYPE_ENUM   , bar_->type());
588
 
  EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type());
589
 
  EXPECT_EQ(FieldDescriptor::TYPE_GROUP  , qux_->type());
590
 
}
591
 
 
592
 
TEST_F(DescriptorTest, FieldLabel) {
593
 
  EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label());
594
 
  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label());
595
 
  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label());
596
 
  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label());
597
 
 
598
 
  EXPECT_TRUE (foo_->is_required());
599
 
  EXPECT_FALSE(foo_->is_optional());
600
 
  EXPECT_FALSE(foo_->is_repeated());
601
 
 
602
 
  EXPECT_FALSE(bar_->is_required());
603
 
  EXPECT_TRUE (bar_->is_optional());
604
 
  EXPECT_FALSE(bar_->is_repeated());
605
 
 
606
 
  EXPECT_FALSE(baz_->is_required());
607
 
  EXPECT_FALSE(baz_->is_optional());
608
 
  EXPECT_TRUE (baz_->is_repeated());
609
 
}
610
 
 
611
 
TEST_F(DescriptorTest, FieldHasDefault) {
612
 
  EXPECT_FALSE(foo_->has_default_value());
613
 
  EXPECT_FALSE(bar_->has_default_value());
614
 
  EXPECT_FALSE(baz_->has_default_value());
615
 
  EXPECT_FALSE(qux_->has_default_value());
616
 
}
617
 
 
618
 
TEST_F(DescriptorTest, FieldContainingType) {
619
 
  EXPECT_EQ(message_, foo_->containing_type());
620
 
  EXPECT_EQ(message_, bar_->containing_type());
621
 
  EXPECT_EQ(message_, baz_->containing_type());
622
 
  EXPECT_EQ(message_, qux_->containing_type());
623
 
 
624
 
  EXPECT_EQ(message2_, foo2_ ->containing_type());
625
 
  EXPECT_EQ(message2_, bar2_ ->containing_type());
626
 
  EXPECT_EQ(message2_, quux2_->containing_type());
627
 
}
628
 
 
629
 
TEST_F(DescriptorTest, FieldMessageType) {
630
 
  EXPECT_TRUE(foo_->message_type() == NULL);
631
 
  EXPECT_TRUE(bar_->message_type() == NULL);
632
 
 
633
 
  EXPECT_EQ(foreign_, baz_->message_type());
634
 
  EXPECT_EQ(foreign_, qux_->message_type());
635
 
}
636
 
 
637
 
TEST_F(DescriptorTest, FieldEnumType) {
638
 
  EXPECT_TRUE(foo_->enum_type() == NULL);
639
 
  EXPECT_TRUE(baz_->enum_type() == NULL);
640
 
  EXPECT_TRUE(qux_->enum_type() == NULL);
641
 
 
642
 
  EXPECT_EQ(enum_, bar_->enum_type());
643
 
}
644
 
 
645
 
// ===================================================================
646
 
 
647
 
class StylizedFieldNamesTest : public testing::Test {
648
 
 protected:
649
 
  void SetUp() {
650
 
    FileDescriptorProto file;
651
 
    file.set_name("foo.proto");
652
 
 
653
 
    AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
654
 
 
655
 
    DescriptorProto* message = AddMessage(&file, "TestMessage");
656
 
    AddField(message, "foo_foo", 1,
657
 
             FieldDescriptorProto::LABEL_OPTIONAL,
658
 
             FieldDescriptorProto::TYPE_INT32);
659
 
    AddField(message, "FooBar", 2,
660
 
             FieldDescriptorProto::LABEL_OPTIONAL,
661
 
             FieldDescriptorProto::TYPE_INT32);
662
 
    AddField(message, "fooBaz", 3,
663
 
             FieldDescriptorProto::LABEL_OPTIONAL,
664
 
             FieldDescriptorProto::TYPE_INT32);
665
 
    AddField(message, "fooFoo", 4,  // Camel-case conflict with foo_foo.
666
 
             FieldDescriptorProto::LABEL_OPTIONAL,
667
 
             FieldDescriptorProto::TYPE_INT32);
668
 
    AddField(message, "foobar", 5,  // Lower-case conflict with FooBar.
669
 
             FieldDescriptorProto::LABEL_OPTIONAL,
670
 
             FieldDescriptorProto::TYPE_INT32);
671
 
 
672
 
    AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
673
 
                       FieldDescriptorProto::LABEL_OPTIONAL,
674
 
                       FieldDescriptorProto::TYPE_INT32);
675
 
    AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
676
 
                       FieldDescriptorProto::LABEL_OPTIONAL,
677
 
                       FieldDescriptorProto::TYPE_INT32);
678
 
    AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
679
 
                       FieldDescriptorProto::LABEL_OPTIONAL,
680
 
                       FieldDescriptorProto::TYPE_INT32);
681
 
    AddNestedExtension(message, "ExtendableMessage", "barFoo", 4,  // Conflict
682
 
                       FieldDescriptorProto::LABEL_OPTIONAL,
683
 
                       FieldDescriptorProto::TYPE_INT32);
684
 
    AddNestedExtension(message, "ExtendableMessage", "barbar", 5,  // Conflict
685
 
                       FieldDescriptorProto::LABEL_OPTIONAL,
686
 
                       FieldDescriptorProto::TYPE_INT32);
687
 
 
688
 
    AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
689
 
                 FieldDescriptorProto::LABEL_OPTIONAL,
690
 
                 FieldDescriptorProto::TYPE_INT32);
691
 
    AddExtension(&file, "ExtendableMessage", "BazBar", 12,
692
 
                 FieldDescriptorProto::LABEL_OPTIONAL,
693
 
                 FieldDescriptorProto::TYPE_INT32);
694
 
    AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
695
 
                 FieldDescriptorProto::LABEL_OPTIONAL,
696
 
                 FieldDescriptorProto::TYPE_INT32);
697
 
    AddExtension(&file, "ExtendableMessage", "bazFoo", 14,  // Conflict
698
 
                 FieldDescriptorProto::LABEL_OPTIONAL,
699
 
                 FieldDescriptorProto::TYPE_INT32);
700
 
    AddExtension(&file, "ExtendableMessage", "bazbar", 15,  // Conflict
701
 
                 FieldDescriptorProto::LABEL_OPTIONAL,
702
 
                 FieldDescriptorProto::TYPE_INT32);
703
 
 
704
 
    file_ = pool_.BuildFile(file);
705
 
    ASSERT_TRUE(file_ != NULL);
706
 
    ASSERT_EQ(2, file_->message_type_count());
707
 
    message_ = file_->message_type(1);
708
 
    ASSERT_EQ("TestMessage", message_->name());
709
 
    ASSERT_EQ(5, message_->field_count());
710
 
    ASSERT_EQ(5, message_->extension_count());
711
 
    ASSERT_EQ(5, file_->extension_count());
712
 
  }
713
 
 
714
 
  DescriptorPool pool_;
715
 
  const FileDescriptor* file_;
716
 
  const Descriptor* message_;
717
 
};
718
 
 
719
 
TEST_F(StylizedFieldNamesTest, LowercaseName) {
720
 
  EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
721
 
  EXPECT_EQ("foobar" , message_->field(1)->lowercase_name());
722
 
  EXPECT_EQ("foobaz" , message_->field(2)->lowercase_name());
723
 
  EXPECT_EQ("foofoo" , message_->field(3)->lowercase_name());
724
 
  EXPECT_EQ("foobar" , message_->field(4)->lowercase_name());
725
 
 
726
 
  EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
727
 
  EXPECT_EQ("barbar" , message_->extension(1)->lowercase_name());
728
 
  EXPECT_EQ("barbaz" , message_->extension(2)->lowercase_name());
729
 
  EXPECT_EQ("barfoo" , message_->extension(3)->lowercase_name());
730
 
  EXPECT_EQ("barbar" , message_->extension(4)->lowercase_name());
731
 
 
732
 
  EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
733
 
  EXPECT_EQ("bazbar" , file_->extension(1)->lowercase_name());
734
 
  EXPECT_EQ("bazbaz" , file_->extension(2)->lowercase_name());
735
 
  EXPECT_EQ("bazfoo" , file_->extension(3)->lowercase_name());
736
 
  EXPECT_EQ("bazbar" , file_->extension(4)->lowercase_name());
737
 
}
738
 
 
739
 
TEST_F(StylizedFieldNamesTest, CamelcaseName) {
740
 
  EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
741
 
  EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
742
 
  EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
743
 
  EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
744
 
  EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
745
 
 
746
 
  EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
747
 
  EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
748
 
  EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
749
 
  EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
750
 
  EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
751
 
 
752
 
  EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
753
 
  EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
754
 
  EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
755
 
  EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
756
 
  EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
757
 
}
758
 
 
759
 
TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
760
 
  EXPECT_EQ(message_->field(0),
761
 
            message_->FindFieldByLowercaseName("foo_foo"));
762
 
  EXPECT_EQ(message_->field(1),
763
 
            message_->FindFieldByLowercaseName("foobar"));
764
 
  EXPECT_EQ(message_->field(2),
765
 
            message_->FindFieldByLowercaseName("foobaz"));
766
 
  EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == NULL);
767
 
  EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == NULL);
768
 
  EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == NULL);
769
 
  EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == NULL);
770
 
 
771
 
  EXPECT_EQ(message_->extension(0),
772
 
            message_->FindExtensionByLowercaseName("bar_foo"));
773
 
  EXPECT_EQ(message_->extension(1),
774
 
            message_->FindExtensionByLowercaseName("barbar"));
775
 
  EXPECT_EQ(message_->extension(2),
776
 
            message_->FindExtensionByLowercaseName("barbaz"));
777
 
  EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == NULL);
778
 
  EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == NULL);
779
 
  EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == NULL);
780
 
  EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == NULL);
781
 
 
782
 
  EXPECT_EQ(file_->extension(0),
783
 
            file_->FindExtensionByLowercaseName("baz_foo"));
784
 
  EXPECT_EQ(file_->extension(1),
785
 
            file_->FindExtensionByLowercaseName("bazbar"));
786
 
  EXPECT_EQ(file_->extension(2),
787
 
            file_->FindExtensionByLowercaseName("bazbaz"));
788
 
  EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == NULL);
789
 
  EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == NULL);
790
 
  EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == NULL);
791
 
}
792
 
 
793
 
TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
794
 
  EXPECT_EQ(message_->field(0),
795
 
            message_->FindFieldByCamelcaseName("fooFoo"));
796
 
  EXPECT_EQ(message_->field(1),
797
 
            message_->FindFieldByCamelcaseName("fooBar"));
798
 
  EXPECT_EQ(message_->field(2),
799
 
            message_->FindFieldByCamelcaseName("fooBaz"));
800
 
  EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == NULL);
801
 
  EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == NULL);
802
 
  EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == NULL);
803
 
  EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == NULL);
804
 
 
805
 
  EXPECT_EQ(message_->extension(0),
806
 
            message_->FindExtensionByCamelcaseName("barFoo"));
807
 
  EXPECT_EQ(message_->extension(1),
808
 
            message_->FindExtensionByCamelcaseName("barBar"));
809
 
  EXPECT_EQ(message_->extension(2),
810
 
            message_->FindExtensionByCamelcaseName("barBaz"));
811
 
  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == NULL);
812
 
  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == NULL);
813
 
  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == NULL);
814
 
  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
815
 
 
816
 
  EXPECT_EQ(file_->extension(0),
817
 
            file_->FindExtensionByCamelcaseName("bazFoo"));
818
 
  EXPECT_EQ(file_->extension(1),
819
 
            file_->FindExtensionByCamelcaseName("bazBar"));
820
 
  EXPECT_EQ(file_->extension(2),
821
 
            file_->FindExtensionByCamelcaseName("bazBaz"));
822
 
  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == NULL);
823
 
  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == NULL);
824
 
  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
825
 
}
826
 
 
827
 
// ===================================================================
828
 
 
829
 
// Test enum descriptors.
830
 
class EnumDescriptorTest : public testing::Test {
831
 
 protected:
832
 
  virtual void SetUp() {
833
 
    // Build descriptors for the following definitions:
834
 
    //
835
 
    //   // in "foo.proto"
836
 
    //   enum TestEnum {
837
 
    //     FOO = 1;
838
 
    //     BAR = 2;
839
 
    //   }
840
 
    //
841
 
    //   // in "bar.proto"
842
 
    //   package corge.grault;
843
 
    //   enum TestEnum2 {
844
 
    //     FOO = 1;
845
 
    //     BAZ = 3;
846
 
    //   }
847
 
    //
848
 
    // TestEnum2 is primarily here to test FindValueByName and friends.
849
 
    // All enums created from the same DescriptorPool share the same lookup
850
 
    // table, so we need to insure that they don't interfere.
851
 
 
852
 
    // TestEnum
853
 
    FileDescriptorProto foo_file;
854
 
    foo_file.set_name("foo.proto");
855
 
 
856
 
    EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum");
857
 
    AddEnumValue(enum_proto, "FOO", 1);
858
 
    AddEnumValue(enum_proto, "BAR", 2);
859
 
 
860
 
    // TestEnum2
861
 
    FileDescriptorProto bar_file;
862
 
    bar_file.set_name("bar.proto");
863
 
    bar_file.set_package("corge.grault");
864
 
 
865
 
    EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2");
866
 
    AddEnumValue(enum2_proto, "FOO", 1);
867
 
    AddEnumValue(enum2_proto, "BAZ", 3);
868
 
 
869
 
    // Build the descriptors and get the pointers.
870
 
    foo_file_ = pool_.BuildFile(foo_file);
871
 
    ASSERT_TRUE(foo_file_ != NULL);
872
 
 
873
 
    bar_file_ = pool_.BuildFile(bar_file);
874
 
    ASSERT_TRUE(bar_file_ != NULL);
875
 
 
876
 
    ASSERT_EQ(1, foo_file_->enum_type_count());
877
 
    enum_ = foo_file_->enum_type(0);
878
 
 
879
 
    ASSERT_EQ(2, enum_->value_count());
880
 
    foo_ = enum_->value(0);
881
 
    bar_ = enum_->value(1);
882
 
 
883
 
    ASSERT_EQ(1, bar_file_->enum_type_count());
884
 
    enum2_ = bar_file_->enum_type(0);
885
 
 
886
 
    ASSERT_EQ(2, enum2_->value_count());
887
 
    foo2_ = enum2_->value(0);
888
 
    baz2_ = enum2_->value(1);
889
 
  }
890
 
 
891
 
  DescriptorPool pool_;
892
 
 
893
 
  const FileDescriptor* foo_file_;
894
 
  const FileDescriptor* bar_file_;
895
 
 
896
 
  const EnumDescriptor* enum_;
897
 
  const EnumDescriptor* enum2_;
898
 
 
899
 
  const EnumValueDescriptor* foo_;
900
 
  const EnumValueDescriptor* bar_;
901
 
 
902
 
  const EnumValueDescriptor* foo2_;
903
 
  const EnumValueDescriptor* baz2_;
904
 
};
905
 
 
906
 
TEST_F(EnumDescriptorTest, Name) {
907
 
  EXPECT_EQ("TestEnum", enum_->name());
908
 
  EXPECT_EQ("TestEnum", enum_->full_name());
909
 
  EXPECT_EQ(foo_file_, enum_->file());
910
 
 
911
 
  EXPECT_EQ("TestEnum2", enum2_->name());
912
 
  EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name());
913
 
  EXPECT_EQ(bar_file_, enum2_->file());
914
 
}
915
 
 
916
 
TEST_F(EnumDescriptorTest, ContainingType) {
917
 
  EXPECT_TRUE(enum_->containing_type() == NULL);
918
 
  EXPECT_TRUE(enum2_->containing_type() == NULL);
919
 
}
920
 
 
921
 
TEST_F(EnumDescriptorTest, ValuesByIndex) {
922
 
  ASSERT_EQ(2, enum_->value_count());
923
 
  EXPECT_EQ(foo_, enum_->value(0));
924
 
  EXPECT_EQ(bar_, enum_->value(1));
925
 
}
926
 
 
927
 
TEST_F(EnumDescriptorTest, FindValueByName) {
928
 
  EXPECT_EQ(foo_ , enum_ ->FindValueByName("FOO"));
929
 
  EXPECT_EQ(bar_ , enum_ ->FindValueByName("BAR"));
930
 
  EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO"));
931
 
  EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ"));
932
 
 
933
 
  EXPECT_TRUE(enum_ ->FindValueByName("NO_SUCH_VALUE") == NULL);
934
 
  EXPECT_TRUE(enum_ ->FindValueByName("BAZ"          ) == NULL);
935
 
  EXPECT_TRUE(enum2_->FindValueByName("BAR"          ) == NULL);
936
 
}
937
 
 
938
 
TEST_F(EnumDescriptorTest, FindValueByNumber) {
939
 
  EXPECT_EQ(foo_ , enum_ ->FindValueByNumber(1));
940
 
  EXPECT_EQ(bar_ , enum_ ->FindValueByNumber(2));
941
 
  EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
942
 
  EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
943
 
 
944
 
  EXPECT_TRUE(enum_ ->FindValueByNumber(416) == NULL);
945
 
  EXPECT_TRUE(enum_ ->FindValueByNumber(3) == NULL);
946
 
  EXPECT_TRUE(enum2_->FindValueByNumber(2) == NULL);
947
 
}
948
 
 
949
 
TEST_F(EnumDescriptorTest, ValueName) {
950
 
  EXPECT_EQ("FOO", foo_->name());
951
 
  EXPECT_EQ("BAR", bar_->name());
952
 
}
953
 
 
954
 
TEST_F(EnumDescriptorTest, ValueFullName) {
955
 
  EXPECT_EQ("FOO", foo_->full_name());
956
 
  EXPECT_EQ("BAR", bar_->full_name());
957
 
  EXPECT_EQ("corge.grault.FOO", foo2_->full_name());
958
 
  EXPECT_EQ("corge.grault.BAZ", baz2_->full_name());
959
 
}
960
 
 
961
 
TEST_F(EnumDescriptorTest, ValueIndex) {
962
 
  EXPECT_EQ(0, foo_->index());
963
 
  EXPECT_EQ(1, bar_->index());
964
 
}
965
 
 
966
 
TEST_F(EnumDescriptorTest, ValueNumber) {
967
 
  EXPECT_EQ(1, foo_->number());
968
 
  EXPECT_EQ(2, bar_->number());
969
 
}
970
 
 
971
 
TEST_F(EnumDescriptorTest, ValueType) {
972
 
  EXPECT_EQ(enum_ , foo_ ->type());
973
 
  EXPECT_EQ(enum_ , bar_ ->type());
974
 
  EXPECT_EQ(enum2_, foo2_->type());
975
 
  EXPECT_EQ(enum2_, baz2_->type());
976
 
}
977
 
 
978
 
// ===================================================================
979
 
 
980
 
// Test service descriptors.
981
 
class ServiceDescriptorTest : public testing::Test {
982
 
 protected:
983
 
  virtual void SetUp() {
984
 
    // Build descriptors for the following messages and service:
985
 
    //    // in "foo.proto"
986
 
    //    message FooRequest  {}
987
 
    //    message FooResponse {}
988
 
    //    message BarRequest  {}
989
 
    //    message BarResponse {}
990
 
    //    message BazRequest  {}
991
 
    //    message BazResponse {}
992
 
    //
993
 
    //    service TestService {
994
 
    //      rpc Foo(FooRequest) returns (FooResponse);
995
 
    //      rpc Bar(BarRequest) returns (BarResponse);
996
 
    //    }
997
 
    //
998
 
    //    // in "bar.proto"
999
 
    //    package corge.grault
1000
 
    //    service TestService2 {
1001
 
    //      rpc Foo(FooRequest) returns (FooResponse);
1002
 
    //      rpc Baz(BazRequest) returns (BazResponse);
1003
 
    //    }
1004
 
 
1005
 
    FileDescriptorProto foo_file;
1006
 
    foo_file.set_name("foo.proto");
1007
 
 
1008
 
    AddMessage(&foo_file, "FooRequest");
1009
 
    AddMessage(&foo_file, "FooResponse");
1010
 
    AddMessage(&foo_file, "BarRequest");
1011
 
    AddMessage(&foo_file, "BarResponse");
1012
 
    AddMessage(&foo_file, "BazRequest");
1013
 
    AddMessage(&foo_file, "BazResponse");
1014
 
 
1015
 
    ServiceDescriptorProto* service = AddService(&foo_file, "TestService");
1016
 
    AddMethod(service, "Foo", "FooRequest", "FooResponse");
1017
 
    AddMethod(service, "Bar", "BarRequest", "BarResponse");
1018
 
 
1019
 
    FileDescriptorProto bar_file;
1020
 
    bar_file.set_name("bar.proto");
1021
 
    bar_file.set_package("corge.grault");
1022
 
    bar_file.add_dependency("foo.proto");
1023
 
 
1024
 
    ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2");
1025
 
    AddMethod(service2, "Foo", "FooRequest", "FooResponse");
1026
 
    AddMethod(service2, "Baz", "BazRequest", "BazResponse");
1027
 
 
1028
 
    // Build the descriptors and get the pointers.
1029
 
    foo_file_ = pool_.BuildFile(foo_file);
1030
 
    ASSERT_TRUE(foo_file_ != NULL);
1031
 
 
1032
 
    bar_file_ = pool_.BuildFile(bar_file);
1033
 
    ASSERT_TRUE(bar_file_ != NULL);
1034
 
 
1035
 
    ASSERT_EQ(6, foo_file_->message_type_count());
1036
 
    foo_request_  = foo_file_->message_type(0);
1037
 
    foo_response_ = foo_file_->message_type(1);
1038
 
    bar_request_  = foo_file_->message_type(2);
1039
 
    bar_response_ = foo_file_->message_type(3);
1040
 
    baz_request_  = foo_file_->message_type(4);
1041
 
    baz_response_ = foo_file_->message_type(5);
1042
 
 
1043
 
    ASSERT_EQ(1, foo_file_->service_count());
1044
 
    service_ = foo_file_->service(0);
1045
 
 
1046
 
    ASSERT_EQ(2, service_->method_count());
1047
 
    foo_ = service_->method(0);
1048
 
    bar_ = service_->method(1);
1049
 
 
1050
 
    ASSERT_EQ(1, bar_file_->service_count());
1051
 
    service2_ = bar_file_->service(0);
1052
 
 
1053
 
    ASSERT_EQ(2, service2_->method_count());
1054
 
    foo2_ = service2_->method(0);
1055
 
    baz2_ = service2_->method(1);
1056
 
  }
1057
 
 
1058
 
  DescriptorPool pool_;
1059
 
 
1060
 
  const FileDescriptor* foo_file_;
1061
 
  const FileDescriptor* bar_file_;
1062
 
 
1063
 
  const Descriptor* foo_request_;
1064
 
  const Descriptor* foo_response_;
1065
 
  const Descriptor* bar_request_;
1066
 
  const Descriptor* bar_response_;
1067
 
  const Descriptor* baz_request_;
1068
 
  const Descriptor* baz_response_;
1069
 
 
1070
 
  const ServiceDescriptor* service_;
1071
 
  const ServiceDescriptor* service2_;
1072
 
 
1073
 
  const MethodDescriptor* foo_;
1074
 
  const MethodDescriptor* bar_;
1075
 
 
1076
 
  const MethodDescriptor* foo2_;
1077
 
  const MethodDescriptor* baz2_;
1078
 
};
1079
 
 
1080
 
TEST_F(ServiceDescriptorTest, Name) {
1081
 
  EXPECT_EQ("TestService", service_->name());
1082
 
  EXPECT_EQ("TestService", service_->full_name());
1083
 
  EXPECT_EQ(foo_file_, service_->file());
1084
 
 
1085
 
  EXPECT_EQ("TestService2", service2_->name());
1086
 
  EXPECT_EQ("corge.grault.TestService2", service2_->full_name());
1087
 
  EXPECT_EQ(bar_file_, service2_->file());
1088
 
}
1089
 
 
1090
 
TEST_F(ServiceDescriptorTest, MethodsByIndex) {
1091
 
  ASSERT_EQ(2, service_->method_count());
1092
 
  EXPECT_EQ(foo_, service_->method(0));
1093
 
  EXPECT_EQ(bar_, service_->method(1));
1094
 
}
1095
 
 
1096
 
TEST_F(ServiceDescriptorTest, FindMethodByName) {
1097
 
  EXPECT_EQ(foo_ , service_ ->FindMethodByName("Foo"));
1098
 
  EXPECT_EQ(bar_ , service_ ->FindMethodByName("Bar"));
1099
 
  EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo"));
1100
 
  EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz"));
1101
 
 
1102
 
  EXPECT_TRUE(service_ ->FindMethodByName("NoSuchMethod") == NULL);
1103
 
  EXPECT_TRUE(service_ ->FindMethodByName("Baz"         ) == NULL);
1104
 
  EXPECT_TRUE(service2_->FindMethodByName("Bar"         ) == NULL);
1105
 
}
1106
 
 
1107
 
TEST_F(ServiceDescriptorTest, MethodName) {
1108
 
  EXPECT_EQ("Foo", foo_->name());
1109
 
  EXPECT_EQ("Bar", bar_->name());
1110
 
}
1111
 
 
1112
 
TEST_F(ServiceDescriptorTest, MethodFullName) {
1113
 
  EXPECT_EQ("TestService.Foo", foo_->full_name());
1114
 
  EXPECT_EQ("TestService.Bar", bar_->full_name());
1115
 
  EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name());
1116
 
  EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name());
1117
 
}
1118
 
 
1119
 
TEST_F(ServiceDescriptorTest, MethodIndex) {
1120
 
  EXPECT_EQ(0, foo_->index());
1121
 
  EXPECT_EQ(1, bar_->index());
1122
 
}
1123
 
 
1124
 
TEST_F(ServiceDescriptorTest, MethodParent) {
1125
 
  EXPECT_EQ(service_, foo_->service());
1126
 
  EXPECT_EQ(service_, bar_->service());
1127
 
}
1128
 
 
1129
 
TEST_F(ServiceDescriptorTest, MethodInputType) {
1130
 
  EXPECT_EQ(foo_request_, foo_->input_type());
1131
 
  EXPECT_EQ(bar_request_, bar_->input_type());
1132
 
}
1133
 
 
1134
 
TEST_F(ServiceDescriptorTest, MethodOutputType) {
1135
 
  EXPECT_EQ(foo_response_, foo_->output_type());
1136
 
  EXPECT_EQ(bar_response_, bar_->output_type());
1137
 
}
1138
 
 
1139
 
// ===================================================================
1140
 
 
1141
 
// Test nested types.
1142
 
class NestedDescriptorTest : public testing::Test {
1143
 
 protected:
1144
 
  virtual void SetUp() {
1145
 
    // Build descriptors for the following definitions:
1146
 
    //
1147
 
    //   // in "foo.proto"
1148
 
    //   message TestMessage {
1149
 
    //     message Foo {}
1150
 
    //     message Bar {}
1151
 
    //     enum Baz { A = 1; }
1152
 
    //     enum Qux { B = 1; }
1153
 
    //   }
1154
 
    //
1155
 
    //   // in "bar.proto"
1156
 
    //   package corge.grault;
1157
 
    //   message TestMessage2 {
1158
 
    //     message Foo {}
1159
 
    //     message Baz {}
1160
 
    //     enum Qux  { A = 1; }
1161
 
    //     enum Quux { C = 1; }
1162
 
    //   }
1163
 
    //
1164
 
    // TestMessage2 is primarily here to test FindNestedTypeByName and friends.
1165
 
    // All messages created from the same DescriptorPool share the same lookup
1166
 
    // table, so we need to insure that they don't interfere.
1167
 
    //
1168
 
    // We add enum values to the enums in order to test searching for enum
1169
 
    // values across a message's scope.
1170
 
 
1171
 
    FileDescriptorProto foo_file;
1172
 
    foo_file.set_name("foo.proto");
1173
 
 
1174
 
    DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
1175
 
    AddNestedMessage(message, "Foo");
1176
 
    AddNestedMessage(message, "Bar");
1177
 
    EnumDescriptorProto* baz = AddNestedEnum(message, "Baz");
1178
 
    AddEnumValue(baz, "A", 1);
1179
 
    EnumDescriptorProto* qux = AddNestedEnum(message, "Qux");
1180
 
    AddEnumValue(qux, "B", 1);
1181
 
 
1182
 
    FileDescriptorProto bar_file;
1183
 
    bar_file.set_name("bar.proto");
1184
 
    bar_file.set_package("corge.grault");
1185
 
 
1186
 
    DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
1187
 
    AddNestedMessage(message2, "Foo");
1188
 
    AddNestedMessage(message2, "Baz");
1189
 
    EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux");
1190
 
    AddEnumValue(qux2, "A", 1);
1191
 
    EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux");
1192
 
    AddEnumValue(quux2, "C", 1);
1193
 
 
1194
 
    // Build the descriptors and get the pointers.
1195
 
    foo_file_ = pool_.BuildFile(foo_file);
1196
 
    ASSERT_TRUE(foo_file_ != NULL);
1197
 
 
1198
 
    bar_file_ = pool_.BuildFile(bar_file);
1199
 
    ASSERT_TRUE(bar_file_ != NULL);
1200
 
 
1201
 
    ASSERT_EQ(1, foo_file_->message_type_count());
1202
 
    message_ = foo_file_->message_type(0);
1203
 
 
1204
 
    ASSERT_EQ(2, message_->nested_type_count());
1205
 
    foo_ = message_->nested_type(0);
1206
 
    bar_ = message_->nested_type(1);
1207
 
 
1208
 
    ASSERT_EQ(2, message_->enum_type_count());
1209
 
    baz_ = message_->enum_type(0);
1210
 
    qux_ = message_->enum_type(1);
1211
 
 
1212
 
    ASSERT_EQ(1, baz_->value_count());
1213
 
    a_ = baz_->value(0);
1214
 
    ASSERT_EQ(1, qux_->value_count());
1215
 
    b_ = qux_->value(0);
1216
 
 
1217
 
    ASSERT_EQ(1, bar_file_->message_type_count());
1218
 
    message2_ = bar_file_->message_type(0);
1219
 
 
1220
 
    ASSERT_EQ(2, message2_->nested_type_count());
1221
 
    foo2_ = message2_->nested_type(0);
1222
 
    baz2_ = message2_->nested_type(1);
1223
 
 
1224
 
    ASSERT_EQ(2, message2_->enum_type_count());
1225
 
    qux2_ = message2_->enum_type(0);
1226
 
    quux2_ = message2_->enum_type(1);
1227
 
 
1228
 
    ASSERT_EQ(1, qux2_->value_count());
1229
 
    a2_ = qux2_->value(0);
1230
 
    ASSERT_EQ(1, quux2_->value_count());
1231
 
    c2_ = quux2_->value(0);
1232
 
  }
1233
 
 
1234
 
  DescriptorPool pool_;
1235
 
 
1236
 
  const FileDescriptor* foo_file_;
1237
 
  const FileDescriptor* bar_file_;
1238
 
 
1239
 
  const Descriptor* message_;
1240
 
  const Descriptor* message2_;
1241
 
 
1242
 
  const Descriptor* foo_;
1243
 
  const Descriptor* bar_;
1244
 
  const EnumDescriptor* baz_;
1245
 
  const EnumDescriptor* qux_;
1246
 
  const EnumValueDescriptor* a_;
1247
 
  const EnumValueDescriptor* b_;
1248
 
 
1249
 
  const Descriptor* foo2_;
1250
 
  const Descriptor* baz2_;
1251
 
  const EnumDescriptor* qux2_;
1252
 
  const EnumDescriptor* quux2_;
1253
 
  const EnumValueDescriptor* a2_;
1254
 
  const EnumValueDescriptor* c2_;
1255
 
};
1256
 
 
1257
 
TEST_F(NestedDescriptorTest, MessageName) {
1258
 
  EXPECT_EQ("Foo", foo_ ->name());
1259
 
  EXPECT_EQ("Bar", bar_ ->name());
1260
 
  EXPECT_EQ("Foo", foo2_->name());
1261
 
  EXPECT_EQ("Baz", baz2_->name());
1262
 
 
1263
 
  EXPECT_EQ("TestMessage.Foo", foo_->full_name());
1264
 
  EXPECT_EQ("TestMessage.Bar", bar_->full_name());
1265
 
  EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name());
1266
 
  EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name());
1267
 
}
1268
 
 
1269
 
TEST_F(NestedDescriptorTest, MessageContainingType) {
1270
 
  EXPECT_EQ(message_ , foo_ ->containing_type());
1271
 
  EXPECT_EQ(message_ , bar_ ->containing_type());
1272
 
  EXPECT_EQ(message2_, foo2_->containing_type());
1273
 
  EXPECT_EQ(message2_, baz2_->containing_type());
1274
 
}
1275
 
 
1276
 
TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
1277
 
  ASSERT_EQ(2, message_->nested_type_count());
1278
 
  EXPECT_EQ(foo_, message_->nested_type(0));
1279
 
  EXPECT_EQ(bar_, message_->nested_type(1));
1280
 
}
1281
 
 
1282
 
TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
1283
 
  EXPECT_TRUE(message_->FindFieldByName("Foo") == NULL);
1284
 
  EXPECT_TRUE(message_->FindFieldByName("Qux") == NULL);
1285
 
  EXPECT_TRUE(message_->FindExtensionByName("Foo") == NULL);
1286
 
  EXPECT_TRUE(message_->FindExtensionByName("Qux") == NULL);
1287
 
}
1288
 
 
1289
 
TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
1290
 
  EXPECT_EQ(foo_ , message_ ->FindNestedTypeByName("Foo"));
1291
 
  EXPECT_EQ(bar_ , message_ ->FindNestedTypeByName("Bar"));
1292
 
  EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo"));
1293
 
  EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz"));
1294
 
 
1295
 
  EXPECT_TRUE(message_ ->FindNestedTypeByName("NoSuchType") == NULL);
1296
 
  EXPECT_TRUE(message_ ->FindNestedTypeByName("Baz"       ) == NULL);
1297
 
  EXPECT_TRUE(message2_->FindNestedTypeByName("Bar"       ) == NULL);
1298
 
 
1299
 
  EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == NULL);
1300
 
}
1301
 
 
1302
 
TEST_F(NestedDescriptorTest, EnumName) {
1303
 
  EXPECT_EQ("Baz" , baz_ ->name());
1304
 
  EXPECT_EQ("Qux" , qux_ ->name());
1305
 
  EXPECT_EQ("Qux" , qux2_->name());
1306
 
  EXPECT_EQ("Quux", quux2_->name());
1307
 
 
1308
 
  EXPECT_EQ("TestMessage.Baz", baz_->full_name());
1309
 
  EXPECT_EQ("TestMessage.Qux", qux_->full_name());
1310
 
  EXPECT_EQ("corge.grault.TestMessage2.Qux" , qux2_ ->full_name());
1311
 
  EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name());
1312
 
}
1313
 
 
1314
 
TEST_F(NestedDescriptorTest, EnumContainingType) {
1315
 
  EXPECT_EQ(message_ , baz_  ->containing_type());
1316
 
  EXPECT_EQ(message_ , qux_  ->containing_type());
1317
 
  EXPECT_EQ(message2_, qux2_ ->containing_type());
1318
 
  EXPECT_EQ(message2_, quux2_->containing_type());
1319
 
}
1320
 
 
1321
 
TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
1322
 
  ASSERT_EQ(2, message_->nested_type_count());
1323
 
  EXPECT_EQ(foo_, message_->nested_type(0));
1324
 
  EXPECT_EQ(bar_, message_->nested_type(1));
1325
 
}
1326
 
 
1327
 
TEST_F(NestedDescriptorTest, FindEnumTypeByName) {
1328
 
  EXPECT_EQ(baz_  , message_ ->FindEnumTypeByName("Baz" ));
1329
 
  EXPECT_EQ(qux_  , message_ ->FindEnumTypeByName("Qux" ));
1330
 
  EXPECT_EQ(qux2_ , message2_->FindEnumTypeByName("Qux" ));
1331
 
  EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux"));
1332
 
 
1333
 
  EXPECT_TRUE(message_ ->FindEnumTypeByName("NoSuchType") == NULL);
1334
 
  EXPECT_TRUE(message_ ->FindEnumTypeByName("Quux"      ) == NULL);
1335
 
  EXPECT_TRUE(message2_->FindEnumTypeByName("Baz"       ) == NULL);
1336
 
 
1337
 
  EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == NULL);
1338
 
}
1339
 
 
1340
 
TEST_F(NestedDescriptorTest, FindEnumValueByName) {
1341
 
  EXPECT_EQ(a_ , message_ ->FindEnumValueByName("A"));
1342
 
  EXPECT_EQ(b_ , message_ ->FindEnumValueByName("B"));
1343
 
  EXPECT_EQ(a2_, message2_->FindEnumValueByName("A"));
1344
 
  EXPECT_EQ(c2_, message2_->FindEnumValueByName("C"));
1345
 
 
1346
 
  EXPECT_TRUE(message_ ->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
1347
 
  EXPECT_TRUE(message_ ->FindEnumValueByName("C"            ) == NULL);
1348
 
  EXPECT_TRUE(message2_->FindEnumValueByName("B"            ) == NULL);
1349
 
 
1350
 
  EXPECT_TRUE(message_->FindEnumValueByName("Foo") == NULL);
1351
 
}
1352
 
 
1353
 
// ===================================================================
1354
 
 
1355
 
// Test extensions.
1356
 
class ExtensionDescriptorTest : public testing::Test {
1357
 
 protected:
1358
 
  virtual void SetUp() {
1359
 
    // Build descriptors for the following definitions:
1360
 
    //
1361
 
    //   enum Baz {}
1362
 
    //   message Qux {}
1363
 
    //
1364
 
    //   message Foo {
1365
 
    //     extensions 10 to 19;
1366
 
    //     extensions 30 to 39;
1367
 
    //   }
1368
 
    //   extends Foo with optional int32 foo_int32 = 10;
1369
 
    //   extends Foo with repeated TestEnum foo_enum = 19;
1370
 
    //   message Bar {
1371
 
    //     extends Foo with optional Qux foo_message = 30;
1372
 
    //     // (using Qux as the group type)
1373
 
    //     extends Foo with repeated group foo_group = 39;
1374
 
    //   }
1375
 
 
1376
 
    FileDescriptorProto foo_file;
1377
 
    foo_file.set_name("foo.proto");
1378
 
 
1379
 
    AddEmptyEnum(&foo_file, "Baz");
1380
 
    AddMessage(&foo_file, "Qux");
1381
 
 
1382
 
    DescriptorProto* foo = AddMessage(&foo_file, "Foo");
1383
 
    AddExtensionRange(foo, 10, 20);
1384
 
    AddExtensionRange(foo, 30, 40);
1385
 
 
1386
 
    AddExtension(&foo_file, "Foo", "foo_int32", 10,
1387
 
                 FieldDescriptorProto::LABEL_OPTIONAL,
1388
 
                 FieldDescriptorProto::TYPE_INT32);
1389
 
    AddExtension(&foo_file, "Foo", "foo_enum", 19,
1390
 
                 FieldDescriptorProto::LABEL_REPEATED,
1391
 
                 FieldDescriptorProto::TYPE_ENUM)
1392
 
      ->set_type_name("Baz");
1393
 
 
1394
 
    DescriptorProto* bar = AddMessage(&foo_file, "Bar");
1395
 
    AddNestedExtension(bar, "Foo", "foo_message", 30,
1396
 
                       FieldDescriptorProto::LABEL_OPTIONAL,
1397
 
                       FieldDescriptorProto::TYPE_MESSAGE)
1398
 
      ->set_type_name("Qux");
1399
 
    AddNestedExtension(bar, "Foo", "foo_group", 39,
1400
 
                       FieldDescriptorProto::LABEL_REPEATED,
1401
 
                       FieldDescriptorProto::TYPE_GROUP)
1402
 
      ->set_type_name("Qux");
1403
 
 
1404
 
    // Build the descriptors and get the pointers.
1405
 
    foo_file_ = pool_.BuildFile(foo_file);
1406
 
    ASSERT_TRUE(foo_file_ != NULL);
1407
 
 
1408
 
    ASSERT_EQ(1, foo_file_->enum_type_count());
1409
 
    baz_ = foo_file_->enum_type(0);
1410
 
 
1411
 
    ASSERT_EQ(3, foo_file_->message_type_count());
1412
 
    qux_ = foo_file_->message_type(0);
1413
 
    foo_ = foo_file_->message_type(1);
1414
 
    bar_ = foo_file_->message_type(2);
1415
 
  }
1416
 
 
1417
 
  DescriptorPool pool_;
1418
 
 
1419
 
  const FileDescriptor* foo_file_;
1420
 
 
1421
 
  const Descriptor* foo_;
1422
 
  const Descriptor* bar_;
1423
 
  const EnumDescriptor* baz_;
1424
 
  const Descriptor* qux_;
1425
 
};
1426
 
 
1427
 
TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
1428
 
  EXPECT_EQ(0, bar_->extension_range_count());
1429
 
  ASSERT_EQ(2, foo_->extension_range_count());
1430
 
 
1431
 
  EXPECT_EQ(10, foo_->extension_range(0)->start);
1432
 
  EXPECT_EQ(30, foo_->extension_range(1)->start);
1433
 
 
1434
 
  EXPECT_EQ(20, foo_->extension_range(0)->end);
1435
 
  EXPECT_EQ(40, foo_->extension_range(1)->end);
1436
 
};
1437
 
 
1438
 
TEST_F(ExtensionDescriptorTest, Extensions) {
1439
 
  EXPECT_EQ(0, foo_->extension_count());
1440
 
  ASSERT_EQ(2, foo_file_->extension_count());
1441
 
  ASSERT_EQ(2, bar_->extension_count());
1442
 
 
1443
 
  EXPECT_TRUE(foo_file_->extension(0)->is_extension());
1444
 
  EXPECT_TRUE(foo_file_->extension(1)->is_extension());
1445
 
  EXPECT_TRUE(bar_->extension(0)->is_extension());
1446
 
  EXPECT_TRUE(bar_->extension(1)->is_extension());
1447
 
 
1448
 
  EXPECT_EQ("foo_int32"  , foo_file_->extension(0)->name());
1449
 
  EXPECT_EQ("foo_enum"   , foo_file_->extension(1)->name());
1450
 
  EXPECT_EQ("foo_message", bar_->extension(0)->name());
1451
 
  EXPECT_EQ("foo_group"  , bar_->extension(1)->name());
1452
 
 
1453
 
  EXPECT_EQ(10, foo_file_->extension(0)->number());
1454
 
  EXPECT_EQ(19, foo_file_->extension(1)->number());
1455
 
  EXPECT_EQ(30, bar_->extension(0)->number());
1456
 
  EXPECT_EQ(39, bar_->extension(1)->number());
1457
 
 
1458
 
  EXPECT_EQ(FieldDescriptor::TYPE_INT32  , foo_file_->extension(0)->type());
1459
 
  EXPECT_EQ(FieldDescriptor::TYPE_ENUM   , foo_file_->extension(1)->type());
1460
 
  EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type());
1461
 
  EXPECT_EQ(FieldDescriptor::TYPE_GROUP  , bar_->extension(1)->type());
1462
 
 
1463
 
  EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
1464
 
  EXPECT_EQ(qux_, bar_->extension(0)->message_type());
1465
 
  EXPECT_EQ(qux_, bar_->extension(1)->message_type());
1466
 
 
1467
 
  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label());
1468
 
  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label());
1469
 
  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label());
1470
 
  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label());
1471
 
 
1472
 
  EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
1473
 
  EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
1474
 
  EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
1475
 
  EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
1476
 
 
1477
 
  EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == NULL);
1478
 
  EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == NULL);
1479
 
  EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
1480
 
  EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
1481
 
};
1482
 
 
1483
 
TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
1484
 
  EXPECT_FALSE(foo_->IsExtensionNumber( 9));
1485
 
  EXPECT_TRUE (foo_->IsExtensionNumber(10));
1486
 
  EXPECT_TRUE (foo_->IsExtensionNumber(19));
1487
 
  EXPECT_FALSE(foo_->IsExtensionNumber(20));
1488
 
  EXPECT_FALSE(foo_->IsExtensionNumber(29));
1489
 
  EXPECT_TRUE (foo_->IsExtensionNumber(30));
1490
 
  EXPECT_TRUE (foo_->IsExtensionNumber(39));
1491
 
  EXPECT_FALSE(foo_->IsExtensionNumber(40));
1492
 
}
1493
 
 
1494
 
TEST_F(ExtensionDescriptorTest, FindExtensionByName) {
1495
 
  // Note that FileDescriptor::FindExtensionByName() is tested by
1496
 
  // FileDescriptorTest.
1497
 
  ASSERT_EQ(2, bar_->extension_count());
1498
 
 
1499
 
  EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message"));
1500
 
  EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group"  ));
1501
 
 
1502
 
  EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL);
1503
 
  EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL);
1504
 
  EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL);
1505
 
}
1506
 
 
1507
 
TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
1508
 
  vector<const FieldDescriptor*> extensions;
1509
 
  pool_.FindAllExtensions(foo_, &extensions);
1510
 
  ASSERT_EQ(4, extensions.size());
1511
 
  EXPECT_EQ(10, extensions[0]->number());
1512
 
  EXPECT_EQ(19, extensions[1]->number());
1513
 
  EXPECT_EQ(30, extensions[2]->number());
1514
 
  EXPECT_EQ(39, extensions[3]->number());
1515
 
}
1516
 
 
1517
 
// ===================================================================
1518
 
 
1519
 
class MiscTest : public testing::Test {
1520
 
 protected:
1521
 
  // Function which makes a field of the given type just to find out what its
1522
 
  // cpp_type is.
1523
 
  FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
1524
 
    FileDescriptorProto file_proto;
1525
 
    file_proto.set_name("foo.proto");
1526
 
    AddEmptyEnum(&file_proto, "DummyEnum");
1527
 
 
1528
 
    DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
1529
 
    FieldDescriptorProto* field =
1530
 
      AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
1531
 
               static_cast<FieldDescriptorProto::Type>(static_cast<int>(type)));
1532
 
 
1533
 
    if (type == FieldDescriptor::TYPE_MESSAGE ||
1534
 
        type == FieldDescriptor::TYPE_GROUP) {
1535
 
      field->set_type_name("TestMessage");
1536
 
    } else if (type == FieldDescriptor::TYPE_ENUM) {
1537
 
      field->set_type_name("DummyEnum");
1538
 
    }
1539
 
 
1540
 
    // Build the descriptors and get the pointers.
1541
 
    DescriptorPool pool;
1542
 
    const FileDescriptor* file = pool.BuildFile(file_proto);
1543
 
 
1544
 
    if (file != NULL &&
1545
 
        file->message_type_count() == 1 &&
1546
 
        file->message_type(0)->field_count() == 1) {
1547
 
      return file->message_type(0)->field(0)->cpp_type();
1548
 
    } else {
1549
 
      return static_cast<FieldDescriptor::CppType>(0);
1550
 
    }
1551
 
  }
1552
 
};
1553
 
 
1554
 
TEST_F(MiscTest, CppTypes) {
1555
 
  // Test that CPP types are assigned correctly.
1556
 
 
1557
 
  typedef FieldDescriptor FD;  // avoid ugly line wrapping
1558
 
 
1559
 
  EXPECT_EQ(FD::CPPTYPE_DOUBLE , GetCppTypeForFieldType(FD::TYPE_DOUBLE  ));
1560
 
  EXPECT_EQ(FD::CPPTYPE_FLOAT  , GetCppTypeForFieldType(FD::TYPE_FLOAT   ));
1561
 
  EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_INT64   ));
1562
 
  EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_UINT64  ));
1563
 
  EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_INT32   ));
1564
 
  EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_FIXED64 ));
1565
 
  EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_FIXED32 ));
1566
 
  EXPECT_EQ(FD::CPPTYPE_BOOL   , GetCppTypeForFieldType(FD::TYPE_BOOL    ));
1567
 
  EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_STRING  ));
1568
 
  EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP   ));
1569
 
  EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE ));
1570
 
  EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_BYTES   ));
1571
 
  EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_UINT32  ));
1572
 
  EXPECT_EQ(FD::CPPTYPE_ENUM   , GetCppTypeForFieldType(FD::TYPE_ENUM    ));
1573
 
  EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_SFIXED32));
1574
 
  EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_SFIXED64));
1575
 
  EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_SINT32  ));
1576
 
  EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_SINT64  ));
1577
 
}
1578
 
 
1579
 
TEST_F(MiscTest, DefaultValues) {
1580
 
  // Test that setting default values works.
1581
 
  FileDescriptorProto file_proto;
1582
 
  file_proto.set_name("foo.proto");
1583
 
 
1584
 
  EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum");
1585
 
  AddEnumValue(enum_type_proto, "A", 1);
1586
 
  AddEnumValue(enum_type_proto, "B", 2);
1587
 
 
1588
 
  DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
1589
 
 
1590
 
  typedef FieldDescriptorProto FD;  // avoid ugly line wrapping
1591
 
  const FD::Label label = FD::LABEL_OPTIONAL;
1592
 
 
1593
 
  // Create fields of every CPP type with default values.
1594
 
  AddField(message_proto, "int32" , 1, label, FD::TYPE_INT32 )
1595
 
    ->set_default_value("-1");
1596
 
  AddField(message_proto, "int64" , 2, label, FD::TYPE_INT64 )
1597
 
    ->set_default_value("-1000000000000");
1598
 
  AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32)
1599
 
    ->set_default_value("42");
1600
 
  AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64)
1601
 
    ->set_default_value("2000000000000");
1602
 
  AddField(message_proto, "float" , 5, label, FD::TYPE_FLOAT )
1603
 
    ->set_default_value("4.5");
1604
 
  AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE)
1605
 
    ->set_default_value("10e100");
1606
 
  AddField(message_proto, "bool"  , 7, label, FD::TYPE_BOOL  )
1607
 
    ->set_default_value("true");
1608
 
  AddField(message_proto, "string", 8, label, FD::TYPE_STRING)
1609
 
    ->set_default_value("hello");
1610
 
  AddField(message_proto, "data"  , 9, label, FD::TYPE_BYTES )
1611
 
    ->set_default_value("\\001\\002\\003");
1612
 
 
1613
 
  FieldDescriptorProto* enum_field =
1614
 
    AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM);
1615
 
  enum_field->set_type_name("DummyEnum");
1616
 
  enum_field->set_default_value("B");
1617
 
 
1618
 
  // Strings are allowed to have empty defaults.  (At one point, due to
1619
 
  // a bug, empty defaults for strings were rejected.  Oops.)
1620
 
  AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING)
1621
 
    ->set_default_value("");
1622
 
 
1623
 
  // Add a second set of fields with implicit defalut values.
1624
 
  AddField(message_proto, "implicit_int32" , 21, label, FD::TYPE_INT32 );
1625
 
  AddField(message_proto, "implicit_int64" , 22, label, FD::TYPE_INT64 );
1626
 
  AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32);
1627
 
  AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64);
1628
 
  AddField(message_proto, "implicit_float" , 25, label, FD::TYPE_FLOAT );
1629
 
  AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE);
1630
 
  AddField(message_proto, "implicit_bool"  , 27, label, FD::TYPE_BOOL  );
1631
 
  AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING);
1632
 
  AddField(message_proto, "implicit_data"  , 29, label, FD::TYPE_BYTES );
1633
 
  AddField(message_proto, "implicit_enum"  , 30, label, FD::TYPE_ENUM)
1634
 
    ->set_type_name("DummyEnum");
1635
 
 
1636
 
  // Build it.
1637
 
  DescriptorPool pool;
1638
 
  const FileDescriptor* file = pool.BuildFile(file_proto);
1639
 
  ASSERT_TRUE(file != NULL);
1640
 
 
1641
 
  ASSERT_EQ(1, file->enum_type_count());
1642
 
  const EnumDescriptor* enum_type = file->enum_type(0);
1643
 
  ASSERT_EQ(2, enum_type->value_count());
1644
 
  const EnumValueDescriptor* enum_value_a = enum_type->value(0);
1645
 
  const EnumValueDescriptor* enum_value_b = enum_type->value(1);
1646
 
 
1647
 
  ASSERT_EQ(1, file->message_type_count());
1648
 
  const Descriptor* message = file->message_type(0);
1649
 
 
1650
 
  ASSERT_EQ(21, message->field_count());
1651
 
 
1652
 
  // Check the default values.
1653
 
  ASSERT_TRUE(message->field(0)->has_default_value());
1654
 
  ASSERT_TRUE(message->field(1)->has_default_value());
1655
 
  ASSERT_TRUE(message->field(2)->has_default_value());
1656
 
  ASSERT_TRUE(message->field(3)->has_default_value());
1657
 
  ASSERT_TRUE(message->field(4)->has_default_value());
1658
 
  ASSERT_TRUE(message->field(5)->has_default_value());
1659
 
  ASSERT_TRUE(message->field(6)->has_default_value());
1660
 
  ASSERT_TRUE(message->field(7)->has_default_value());
1661
 
  ASSERT_TRUE(message->field(8)->has_default_value());
1662
 
  ASSERT_TRUE(message->field(9)->has_default_value());
1663
 
  ASSERT_TRUE(message->field(10)->has_default_value());
1664
 
 
1665
 
  EXPECT_EQ(-1              , message->field(0)->default_value_int32 ());
1666
 
  EXPECT_EQ(-GOOGLE_ULONGLONG(1000000000000),
1667
 
            message->field(1)->default_value_int64 ());
1668
 
  EXPECT_EQ(42              , message->field(2)->default_value_uint32());
1669
 
  EXPECT_EQ(GOOGLE_ULONGLONG(2000000000000),
1670
 
            message->field(3)->default_value_uint64());
1671
 
  EXPECT_EQ(4.5             , message->field(4)->default_value_float ());
1672
 
  EXPECT_EQ(10e100          , message->field(5)->default_value_double());
1673
 
  EXPECT_EQ(true            , message->field(6)->default_value_bool  ());
1674
 
  EXPECT_EQ("hello"         , message->field(7)->default_value_string());
1675
 
  EXPECT_EQ("\001\002\003"  , message->field(8)->default_value_string());
1676
 
  EXPECT_EQ(enum_value_b    , message->field(9)->default_value_enum  ());
1677
 
  EXPECT_EQ(""              , message->field(10)->default_value_string());
1678
 
 
1679
 
  ASSERT_FALSE(message->field(11)->has_default_value());
1680
 
  ASSERT_FALSE(message->field(12)->has_default_value());
1681
 
  ASSERT_FALSE(message->field(13)->has_default_value());
1682
 
  ASSERT_FALSE(message->field(14)->has_default_value());
1683
 
  ASSERT_FALSE(message->field(15)->has_default_value());
1684
 
  ASSERT_FALSE(message->field(16)->has_default_value());
1685
 
  ASSERT_FALSE(message->field(17)->has_default_value());
1686
 
  ASSERT_FALSE(message->field(18)->has_default_value());
1687
 
  ASSERT_FALSE(message->field(19)->has_default_value());
1688
 
  ASSERT_FALSE(message->field(20)->has_default_value());
1689
 
 
1690
 
  EXPECT_EQ(0    , message->field(11)->default_value_int32 ());
1691
 
  EXPECT_EQ(0    , message->field(12)->default_value_int64 ());
1692
 
  EXPECT_EQ(0    , message->field(13)->default_value_uint32());
1693
 
  EXPECT_EQ(0    , message->field(14)->default_value_uint64());
1694
 
  EXPECT_EQ(0.0f , message->field(15)->default_value_float ());
1695
 
  EXPECT_EQ(0.0  , message->field(16)->default_value_double());
1696
 
  EXPECT_EQ(false, message->field(17)->default_value_bool  ());
1697
 
  EXPECT_EQ(""   , message->field(18)->default_value_string());
1698
 
  EXPECT_EQ(""   , message->field(19)->default_value_string());
1699
 
  EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
1700
 
}
1701
 
 
1702
 
TEST_F(MiscTest, FieldOptions) {
1703
 
  // Try setting field options.
1704
 
 
1705
 
  FileDescriptorProto file_proto;
1706
 
  file_proto.set_name("foo.proto");
1707
 
 
1708
 
  DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
1709
 
  AddField(message_proto, "foo", 1,
1710
 
           FieldDescriptorProto::LABEL_OPTIONAL,
1711
 
           FieldDescriptorProto::TYPE_INT32);
1712
 
  FieldDescriptorProto* bar_proto =
1713
 
    AddField(message_proto, "bar", 2,
1714
 
             FieldDescriptorProto::LABEL_OPTIONAL,
1715
 
             FieldDescriptorProto::TYPE_INT32);
1716
 
 
1717
 
  FieldOptions* options = bar_proto->mutable_options();
1718
 
  options->set_ctype(FieldOptions::CORD);
1719
 
 
1720
 
  // Build the descriptors and get the pointers.
1721
 
  DescriptorPool pool;
1722
 
  const FileDescriptor* file = pool.BuildFile(file_proto);
1723
 
  ASSERT_TRUE(file != NULL);
1724
 
 
1725
 
  ASSERT_EQ(1, file->message_type_count());
1726
 
  const Descriptor* message = file->message_type(0);
1727
 
 
1728
 
  ASSERT_EQ(2, message->field_count());
1729
 
  const FieldDescriptor* foo = message->field(0);
1730
 
  const FieldDescriptor* bar = message->field(1);
1731
 
 
1732
 
  // "foo" had no options set, so it should return the default options.
1733
 
  EXPECT_EQ(&FieldOptions::default_instance(), &foo->options());
1734
 
 
1735
 
  // "bar" had options set.
1736
 
  EXPECT_NE(&FieldOptions::default_instance(), options);
1737
 
  EXPECT_TRUE(bar->options().has_ctype());
1738
 
  EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
1739
 
}
1740
 
 
1741
 
// ===================================================================
1742
 
 
1743
 
class AllowUnknownDependenciesTest : public testing::Test {
1744
 
 protected:
1745
 
  virtual void SetUp() {
1746
 
    FileDescriptorProto foo_proto, bar_proto;
1747
 
 
1748
 
    pool_.AllowUnknownDependencies();
1749
 
 
1750
 
    ASSERT_TRUE(TextFormat::ParseFromString(
1751
 
      "name: 'foo.proto'"
1752
 
      "dependency: 'bar.proto'"
1753
 
      "dependency: 'baz.proto'"
1754
 
      "message_type {"
1755
 
      "  name: 'Foo'"
1756
 
      "  field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
1757
 
      "  field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
1758
 
      "  field { name:'qux' number:3 label:LABEL_OPTIONAL"
1759
 
      "    type_name: '.corge.Qux'"
1760
 
      "    type: TYPE_ENUM"
1761
 
      "    options {"
1762
 
      "      uninterpreted_option {"
1763
 
      "        name {"
1764
 
      "          name_part: 'grault'"
1765
 
      "          is_extension: true"
1766
 
      "        }"
1767
 
      "        positive_int_value: 1234"
1768
 
      "      }"
1769
 
      "    }"
1770
 
      "  }"
1771
 
      "}",
1772
 
      &foo_proto));
1773
 
    ASSERT_TRUE(TextFormat::ParseFromString(
1774
 
      "name: 'bar.proto'"
1775
 
      "message_type { name: 'Bar' }",
1776
 
      &bar_proto));
1777
 
 
1778
 
    // Collect pointers to stuff.
1779
 
    bar_file_ = pool_.BuildFile(bar_proto);
1780
 
    ASSERT_TRUE(bar_file_ != NULL);
1781
 
 
1782
 
    ASSERT_EQ(1, bar_file_->message_type_count());
1783
 
    bar_type_ = bar_file_->message_type(0);
1784
 
 
1785
 
    foo_file_ = pool_.BuildFile(foo_proto);
1786
 
    ASSERT_TRUE(foo_file_ != NULL);
1787
 
 
1788
 
    ASSERT_EQ(1, foo_file_->message_type_count());
1789
 
    foo_type_ = foo_file_->message_type(0);
1790
 
 
1791
 
    ASSERT_EQ(3, foo_type_->field_count());
1792
 
    bar_field_ = foo_type_->field(0);
1793
 
    baz_field_ = foo_type_->field(1);
1794
 
    qux_field_ = foo_type_->field(2);
1795
 
  }
1796
 
 
1797
 
  const FileDescriptor* bar_file_;
1798
 
  const Descriptor* bar_type_;
1799
 
  const FileDescriptor* foo_file_;
1800
 
  const Descriptor* foo_type_;
1801
 
  const FieldDescriptor* bar_field_;
1802
 
  const FieldDescriptor* baz_field_;
1803
 
  const FieldDescriptor* qux_field_;
1804
 
 
1805
 
  DescriptorPool pool_;
1806
 
};
1807
 
 
1808
 
TEST_F(AllowUnknownDependenciesTest, PlaceholderFile) {
1809
 
  ASSERT_EQ(2, foo_file_->dependency_count());
1810
 
  EXPECT_EQ(bar_file_, foo_file_->dependency(0));
1811
 
 
1812
 
  const FileDescriptor* baz_file = foo_file_->dependency(1);
1813
 
  EXPECT_EQ("baz.proto", baz_file->name());
1814
 
  EXPECT_EQ(0, baz_file->message_type_count());
1815
 
 
1816
 
  // Placeholder files should not be findable.
1817
 
  EXPECT_EQ(bar_file_, pool_.FindFileByName(bar_file_->name()));
1818
 
  EXPECT_TRUE(pool_.FindFileByName(baz_file->name()) == NULL);
1819
 
}
1820
 
 
1821
 
TEST_F(AllowUnknownDependenciesTest, PlaceholderTypes) {
1822
 
  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
1823
 
  EXPECT_EQ(bar_type_, bar_field_->message_type());
1824
 
 
1825
 
  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
1826
 
  const Descriptor* baz_type = baz_field_->message_type();
1827
 
  EXPECT_EQ("Baz", baz_type->name());
1828
 
  EXPECT_EQ("Baz", baz_type->full_name());
1829
 
  EXPECT_EQ("Baz.placeholder.proto", baz_type->file()->name());
1830
 
  EXPECT_EQ(0, baz_type->extension_range_count());
1831
 
 
1832
 
  ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
1833
 
  const EnumDescriptor* qux_type = qux_field_->enum_type();
1834
 
  EXPECT_EQ("Qux", qux_type->name());
1835
 
  EXPECT_EQ("corge.Qux", qux_type->full_name());
1836
 
  EXPECT_EQ("corge.Qux.placeholder.proto", qux_type->file()->name());
1837
 
 
1838
 
  // Placeholder types should not be findable.
1839
 
  EXPECT_EQ(bar_type_, pool_.FindMessageTypeByName(bar_type_->full_name()));
1840
 
  EXPECT_TRUE(pool_.FindMessageTypeByName(baz_type->full_name()) == NULL);
1841
 
  EXPECT_TRUE(pool_.FindEnumTypeByName(qux_type->full_name()) == NULL);
1842
 
}
1843
 
 
1844
 
TEST_F(AllowUnknownDependenciesTest, CopyTo) {
1845
 
  // FieldDescriptor::CopyTo() should write non-fully-qualified type names
1846
 
  // for placeholder types which were not originally fully-qualified.
1847
 
  FieldDescriptorProto proto;
1848
 
 
1849
 
  // Bar is not a placeholder, so it is fully-qualified.
1850
 
  bar_field_->CopyTo(&proto);
1851
 
  EXPECT_EQ(".Bar", proto.type_name());
1852
 
  EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type());
1853
 
 
1854
 
  // Baz is an unqualified placeholder.
1855
 
  proto.Clear();
1856
 
  baz_field_->CopyTo(&proto);
1857
 
  EXPECT_EQ("Baz", proto.type_name());
1858
 
  EXPECT_FALSE(proto.has_type());
1859
 
 
1860
 
  // Qux is a fully-qualified placeholder.
1861
 
  proto.Clear();
1862
 
  qux_field_->CopyTo(&proto);
1863
 
  EXPECT_EQ(".corge.Qux", proto.type_name());
1864
 
  EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
1865
 
}
1866
 
 
1867
 
TEST_F(AllowUnknownDependenciesTest, CustomOptions) {
1868
 
  // Qux should still have the uninterpreted option attached.
1869
 
  ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
1870
 
  const UninterpretedOption& option =
1871
 
    qux_field_->options().uninterpreted_option(0);
1872
 
  ASSERT_EQ(1, option.name_size());
1873
 
  EXPECT_EQ("grault", option.name(0).name_part());
1874
 
}
1875
 
 
1876
 
TEST_F(AllowUnknownDependenciesTest, UnknownExtendee) {
1877
 
  // Test that we can extend an unknown type.  This is slightly tricky because
1878
 
  // it means that the placeholder type must have an extension range.
1879
 
 
1880
 
  FileDescriptorProto extension_proto;
1881
 
 
1882
 
  ASSERT_TRUE(TextFormat::ParseFromString(
1883
 
    "name: 'extension.proto'"
1884
 
    "extension { extendee: 'UnknownType' name:'some_extension' number:123"
1885
 
    "            label:LABEL_OPTIONAL type:TYPE_INT32 }",
1886
 
    &extension_proto));
1887
 
  const FileDescriptor* file = pool_.BuildFile(extension_proto);
1888
 
 
1889
 
  ASSERT_TRUE(file != NULL);
1890
 
 
1891
 
  ASSERT_EQ(1, file->extension_count());
1892
 
  const Descriptor* extendee = file->extension(0)->containing_type();
1893
 
  EXPECT_EQ("UnknownType", extendee->name());
1894
 
  ASSERT_EQ(1, extendee->extension_range_count());
1895
 
  EXPECT_EQ(1, extendee->extension_range(0)->start);
1896
 
  EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
1897
 
}
1898
 
 
1899
 
TEST_F(AllowUnknownDependenciesTest, CustomOption) {
1900
 
  // Test that we can use a custom option without having parsed
1901
 
  // descriptor.proto.
1902
 
 
1903
 
  FileDescriptorProto option_proto;
1904
 
 
1905
 
  ASSERT_TRUE(TextFormat::ParseFromString(
1906
 
    "name: \"unknown_custom_options.proto\" "
1907
 
    "dependency: \"google/protobuf/descriptor.proto\" "
1908
 
    "extension { "
1909
 
    "  extendee: \"google.protobuf.FileOptions\" "
1910
 
    "  name: \"some_option\" "
1911
 
    "  number: 123456 "
1912
 
    "  label: LABEL_OPTIONAL "
1913
 
    "  type: TYPE_INT32 "
1914
 
    "} "
1915
 
    "options { "
1916
 
    "  uninterpreted_option { "
1917
 
    "    name { "
1918
 
    "      name_part: \"some_option\" "
1919
 
    "      is_extension: true "
1920
 
    "    } "
1921
 
    "    positive_int_value: 1234 "
1922
 
    "  } "
1923
 
    "  uninterpreted_option { "
1924
 
    "    name { "
1925
 
    "      name_part: \"unknown_option\" "
1926
 
    "      is_extension: true "
1927
 
    "    } "
1928
 
    "    positive_int_value: 1234 "
1929
 
    "  } "
1930
 
    "  uninterpreted_option { "
1931
 
    "    name { "
1932
 
    "      name_part: \"optimize_for\" "
1933
 
    "      is_extension: false "
1934
 
    "    } "
1935
 
    "    identifier_value: \"SPEED\" "
1936
 
    "  } "
1937
 
    "}",
1938
 
    &option_proto));
1939
 
 
1940
 
  const FileDescriptor* file = pool_.BuildFile(option_proto);
1941
 
  ASSERT_TRUE(file != NULL);
1942
 
 
1943
 
  // Verify that no extension options were set, but they were left as
1944
 
  // uninterpreted_options.
1945
 
  vector<const FieldDescriptor*> fields;
1946
 
  file->options().GetReflection()->ListFields(file->options(), &fields);
1947
 
  ASSERT_EQ(2, fields.size());
1948
 
  EXPECT_TRUE(file->options().has_optimize_for());
1949
 
  EXPECT_EQ(2, file->options().uninterpreted_option_size());
1950
 
}
1951
 
 
1952
 
// ===================================================================
1953
 
 
1954
 
TEST(CustomOptions, OptionLocations) {
1955
 
  const Descriptor* message =
1956
 
      protobuf_unittest::TestMessageWithCustomOptions::descriptor();
1957
 
  const FileDescriptor* file = message->file();
1958
 
  const FieldDescriptor* field = message->FindFieldByName("field1");
1959
 
  const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
1960
 
  // TODO(benjy): Support EnumValue options, once the compiler does.
1961
 
  const ServiceDescriptor* service =
1962
 
      file->FindServiceByName("TestServiceWithCustomOptions");
1963
 
  const MethodDescriptor* method = service->FindMethodByName("Foo");
1964
 
 
1965
 
  EXPECT_EQ(GOOGLE_LONGLONG(9876543210),
1966
 
            file->options().GetExtension(protobuf_unittest::file_opt1));
1967
 
  EXPECT_EQ(-56,
1968
 
            message->options().GetExtension(protobuf_unittest::message_opt1));
1969
 
  EXPECT_EQ(GOOGLE_LONGLONG(8765432109),
1970
 
            field->options().GetExtension(protobuf_unittest::field_opt1));
1971
 
  EXPECT_EQ(42,  // Check that we get the default for an option we don't set.
1972
 
            field->options().GetExtension(protobuf_unittest::field_opt2));
1973
 
  EXPECT_EQ(-789,
1974
 
            enm->options().GetExtension(protobuf_unittest::enum_opt1));
1975
 
  EXPECT_EQ(123,
1976
 
            enm->value(1)->options().GetExtension(
1977
 
              protobuf_unittest::enum_value_opt1));
1978
 
  EXPECT_EQ(GOOGLE_LONGLONG(-9876543210),
1979
 
            service->options().GetExtension(protobuf_unittest::service_opt1));
1980
 
  EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
1981
 
            method->options().GetExtension(protobuf_unittest::method_opt1));
1982
 
 
1983
 
  // See that the regular options went through unscathed.
1984
 
  EXPECT_TRUE(message->options().has_message_set_wire_format());
1985
 
  EXPECT_EQ(FieldOptions::CORD, field->options().ctype());
1986
 
}
1987
 
 
1988
 
TEST(CustomOptions, OptionTypes) {
1989
 
  const MessageOptions* options = NULL;
1990
 
 
1991
 
  options =
1992
 
      &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options();
1993
 
  EXPECT_EQ(false    , options->GetExtension(protobuf_unittest::bool_opt));
1994
 
  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
1995
 
  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
1996
 
  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint32_opt));
1997
 
  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint64_opt));
1998
 
  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt));
1999
 
  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt));
2000
 
  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed32_opt));
2001
 
  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed64_opt));
2002
 
  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt));
2003
 
  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt));
2004
 
 
2005
 
  options =
2006
 
      &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options();
2007
 
  EXPECT_EQ(true      , options->GetExtension(protobuf_unittest::bool_opt));
2008
 
  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::int32_opt));
2009
 
  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::int64_opt));
2010
 
  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
2011
 
  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt));
2012
 
  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sint32_opt));
2013
 
  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sint64_opt));
2014
 
  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt));
2015
 
  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt));
2016
 
  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sfixed32_opt));
2017
 
  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sfixed64_opt));
2018
 
 
2019
 
  options =
2020
 
      &protobuf_unittest::CustomOptionOtherValues::descriptor()->options();
2021
 
  EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt));
2022
 
  EXPECT_FLOAT_EQ(12.3456789,
2023
 
                  options->GetExtension(protobuf_unittest::float_opt));
2024
 
  EXPECT_DOUBLE_EQ(1.234567890123456789,
2025
 
                   options->GetExtension(protobuf_unittest::double_opt));
2026
 
  EXPECT_EQ("Hello, \"World\"",
2027
 
            options->GetExtension(protobuf_unittest::string_opt));
2028
 
 
2029
 
  EXPECT_EQ(string("Hello\0World", 11),
2030
 
            options->GetExtension(protobuf_unittest::bytes_opt));
2031
 
 
2032
 
  EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
2033
 
            options->GetExtension(protobuf_unittest::enum_opt));
2034
 
 
2035
 
  options =
2036
 
      &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options();
2037
 
  EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt));
2038
 
  EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt));
2039
 
 
2040
 
  options =
2041
 
      &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options();
2042
 
  EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt));
2043
 
  EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt));
2044
 
}
2045
 
 
2046
 
TEST(CustomOptions, ComplexExtensionOptions) {
2047
 
  const MessageOptions* options =
2048
 
      &protobuf_unittest::VariousComplexOptions::descriptor()->options();
2049
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
2050
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
2051
 
            GetExtension(protobuf_unittest::quux), 324);
2052
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
2053
 
            GetExtension(protobuf_unittest::corge).qux(), 876);
2054
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
2055
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
2056
 
            GetExtension(protobuf_unittest::grault), 654);
2057
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
2058
 
            743);
2059
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
2060
 
            GetExtension(protobuf_unittest::quux), 1999);
2061
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
2062
 
            GetExtension(protobuf_unittest::corge).qux(), 2008);
2063
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
2064
 
            GetExtension(protobuf_unittest::garply).foo(), 741);
2065
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
2066
 
            GetExtension(protobuf_unittest::garply).
2067
 
            GetExtension(protobuf_unittest::quux), 1998);
2068
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
2069
 
            GetExtension(protobuf_unittest::garply).
2070
 
            GetExtension(protobuf_unittest::corge).qux(), 2121);
2071
 
  EXPECT_EQ(options->GetExtension(
2072
 
      protobuf_unittest::ComplexOptionType2::ComplexOptionType4::complex_opt4).
2073
 
            waldo(), 1971);
2074
 
  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
2075
 
            fred().waldo(), 321);
2076
 
  EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux());
2077
 
  EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3).
2078
 
                complexoptiontype5().plugh());
2079
 
  EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
2080
 
}
2081
 
 
2082
 
TEST(CustomOptions, OptionsFromOtherFile) {
2083
 
  // Test that to use a custom option, we only need to import the file
2084
 
  // defining the option; we do not also have to import descriptor.proto.
2085
 
  DescriptorPool pool;
2086
 
 
2087
 
  FileDescriptorProto file_proto;
2088
 
  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
2089
 
  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
2090
 
 
2091
 
  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
2092
 
    ->file()->CopyTo(&file_proto);
2093
 
  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
2094
 
 
2095
 
  ASSERT_TRUE(TextFormat::ParseFromString(
2096
 
    "name: \"custom_options_import.proto\" "
2097
 
    "package: \"protobuf_unittest\" "
2098
 
    "dependency: \"google/protobuf/unittest_custom_options.proto\" "
2099
 
    "options { "
2100
 
    "  uninterpreted_option { "
2101
 
    "    name { "
2102
 
    "      name_part: \"file_opt1\" "
2103
 
    "      is_extension: true "
2104
 
    "    } "
2105
 
    "    positive_int_value: 1234 "
2106
 
    "  } "
2107
 
    // Test a non-extension option too.  (At one point this failed due to a
2108
 
    // bug.)
2109
 
    "  uninterpreted_option { "
2110
 
    "    name { "
2111
 
    "      name_part: \"java_package\" "
2112
 
    "      is_extension: false "
2113
 
    "    } "
2114
 
    "    string_value: \"foo\" "
2115
 
    "  } "
2116
 
    // Test that enum-typed options still work too.  (At one point this also
2117
 
    // failed due to a bug.)
2118
 
    "  uninterpreted_option { "
2119
 
    "    name { "
2120
 
    "      name_part: \"optimize_for\" "
2121
 
    "      is_extension: false "
2122
 
    "    } "
2123
 
    "    identifier_value: \"SPEED\" "
2124
 
    "  } "
2125
 
    "}"
2126
 
    ,
2127
 
    &file_proto));
2128
 
 
2129
 
  const FileDescriptor* file = pool.BuildFile(file_proto);
2130
 
  ASSERT_TRUE(file != NULL);
2131
 
  EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1));
2132
 
  EXPECT_TRUE(file->options().has_java_package());
2133
 
  EXPECT_EQ("foo", file->options().java_package());
2134
 
  EXPECT_TRUE(file->options().has_optimize_for());
2135
 
  EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for());
2136
 
}
2137
 
 
2138
 
TEST(CustomOptions, MessageOptionThreeFieldsSet) {
2139
 
  // This tests a bug which previously existed in custom options parsing.  The
2140
 
  // bug occurred when you defined a custom option with message type and then
2141
 
  // set three fields of that option on a single definition (see the example
2142
 
  // below).  The bug is a bit hard to explain, so check the change history if
2143
 
  // you want to know more.
2144
 
  DescriptorPool pool;
2145
 
 
2146
 
  FileDescriptorProto file_proto;
2147
 
  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
2148
 
  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
2149
 
 
2150
 
  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
2151
 
    ->file()->CopyTo(&file_proto);
2152
 
  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
2153
 
 
2154
 
  // The following represents the definition:
2155
 
  //
2156
 
  //   import "google/protobuf/unittest_custom_options.proto"
2157
 
  //   package protobuf_unittest;
2158
 
  //   message Foo {
2159
 
  //     option (complex_opt1).foo  = 1234;
2160
 
  //     option (complex_opt1).foo2 = 1234;
2161
 
  //     option (complex_opt1).foo3 = 1234;
2162
 
  //   }
2163
 
  ASSERT_TRUE(TextFormat::ParseFromString(
2164
 
    "name: \"custom_options_import.proto\" "
2165
 
    "package: \"protobuf_unittest\" "
2166
 
    "dependency: \"google/protobuf/unittest_custom_options.proto\" "
2167
 
    "message_type { "
2168
 
    "  name: \"Foo\" "
2169
 
    "  options { "
2170
 
    "    uninterpreted_option { "
2171
 
    "      name { "
2172
 
    "        name_part: \"complex_opt1\" "
2173
 
    "        is_extension: true "
2174
 
    "      } "
2175
 
    "      name { "
2176
 
    "        name_part: \"foo\" "
2177
 
    "        is_extension: false "
2178
 
    "      } "
2179
 
    "      positive_int_value: 1234 "
2180
 
    "    } "
2181
 
    "    uninterpreted_option { "
2182
 
    "      name { "
2183
 
    "        name_part: \"complex_opt1\" "
2184
 
    "        is_extension: true "
2185
 
    "      } "
2186
 
    "      name { "
2187
 
    "        name_part: \"foo2\" "
2188
 
    "        is_extension: false "
2189
 
    "      } "
2190
 
    "      positive_int_value: 1234 "
2191
 
    "    } "
2192
 
    "    uninterpreted_option { "
2193
 
    "      name { "
2194
 
    "        name_part: \"complex_opt1\" "
2195
 
    "        is_extension: true "
2196
 
    "      } "
2197
 
    "      name { "
2198
 
    "        name_part: \"foo3\" "
2199
 
    "        is_extension: false "
2200
 
    "      } "
2201
 
    "      positive_int_value: 1234 "
2202
 
    "    } "
2203
 
    "  } "
2204
 
    "}",
2205
 
    &file_proto));
2206
 
 
2207
 
  const FileDescriptor* file = pool.BuildFile(file_proto);
2208
 
  ASSERT_TRUE(file != NULL);
2209
 
  ASSERT_EQ(1, file->message_type_count());
2210
 
 
2211
 
  const MessageOptions& options = file->message_type(0)->options();
2212
 
  EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
2213
 
}
2214
 
 
2215
 
 
2216
 
// ===================================================================
2217
 
 
2218
 
// The tests below trigger every unique call to AddError() in descriptor.cc,
2219
 
// in the order in which they appear in that file.  I'm using TextFormat here
2220
 
// to specify the input descriptors because building them using code would
2221
 
// be too bulky.
2222
 
 
2223
 
class MockErrorCollector : public DescriptorPool::ErrorCollector {
2224
 
 public:
2225
 
  MockErrorCollector() {}
2226
 
  ~MockErrorCollector() {}
2227
 
 
2228
 
  string text_;
2229
 
 
2230
 
  // implements ErrorCollector ---------------------------------------
2231
 
  void AddError(const string& filename,
2232
 
                const string& element_name, const Message* descriptor,
2233
 
                ErrorLocation location, const string& message) {
2234
 
    const char* location_name = NULL;
2235
 
    switch (location) {
2236
 
      case NAME         : location_name = "NAME"         ; break;
2237
 
      case NUMBER       : location_name = "NUMBER"       ; break;
2238
 
      case TYPE         : location_name = "TYPE"         ; break;
2239
 
      case EXTENDEE     : location_name = "EXTENDEE"     ; break;
2240
 
      case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
2241
 
      case OPTION_NAME  : location_name = "OPTION_NAME"  ; break;
2242
 
      case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
2243
 
      case INPUT_TYPE   : location_name = "INPUT_TYPE"   ; break;
2244
 
      case OUTPUT_TYPE  : location_name = "OUTPUT_TYPE"  ; break;
2245
 
      case OTHER        : location_name = "OTHER"        ; break;
2246
 
    }
2247
 
 
2248
 
    strings::SubstituteAndAppend(
2249
 
      &text_, "$0: $1: $2: $3\n",
2250
 
      filename, element_name, location_name, message);
2251
 
  }
2252
 
};
2253
 
 
2254
 
class ValidationErrorTest : public testing::Test {
2255
 
 protected:
2256
 
  // Parse file_text as a FileDescriptorProto in text format and add it
2257
 
  // to the DescriptorPool.  Expect no errors.
2258
 
  void BuildFile(const string& file_text) {
2259
 
    FileDescriptorProto file_proto;
2260
 
    ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
2261
 
    ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
2262
 
  }
2263
 
 
2264
 
  // Parse file_text as a FileDescriptorProto in text format and add it
2265
 
  // to the DescriptorPool.  Expect errors to be produced which match the
2266
 
  // given error text.
2267
 
  void BuildFileWithErrors(const string& file_text,
2268
 
                           const string& expected_errors) {
2269
 
    FileDescriptorProto file_proto;
2270
 
    ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
2271
 
 
2272
 
    MockErrorCollector error_collector;
2273
 
    EXPECT_TRUE(
2274
 
      pool_.BuildFileCollectingErrors(file_proto, &error_collector) == NULL);
2275
 
    EXPECT_EQ(expected_errors, error_collector.text_);
2276
 
  }
2277
 
 
2278
 
  // Builds some already-parsed file in our test pool.
2279
 
  void BuildFileInTestPool(const FileDescriptor* file) {
2280
 
    FileDescriptorProto file_proto;
2281
 
    file->CopyTo(&file_proto);
2282
 
    ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
2283
 
  }
2284
 
 
2285
 
  // Build descriptor.proto in our test pool. This allows us to extend it in
2286
 
  // the test pool, so we can test custom options.
2287
 
  void BuildDescriptorMessagesInTestPool() {
2288
 
    BuildFileInTestPool(DescriptorProto::descriptor()->file());
2289
 
  }
2290
 
 
2291
 
  DescriptorPool pool_;
2292
 
};
2293
 
 
2294
 
TEST_F(ValidationErrorTest, AlreadyDefined) {
2295
 
  BuildFileWithErrors(
2296
 
    "name: \"foo.proto\" "
2297
 
    "message_type { name: \"Foo\" }"
2298
 
    "message_type { name: \"Foo\" }",
2299
 
 
2300
 
    "foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
2301
 
}
2302
 
 
2303
 
TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
2304
 
  BuildFileWithErrors(
2305
 
    "name: \"foo.proto\" "
2306
 
    "package: \"foo.bar\" "
2307
 
    "message_type { name: \"Foo\" }"
2308
 
    "message_type { name: \"Foo\" }",
2309
 
 
2310
 
    "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
2311
 
      "\"foo.bar\".\n");
2312
 
}
2313
 
 
2314
 
TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
2315
 
  BuildFile(
2316
 
    "name: \"foo.proto\" "
2317
 
    "message_type { name: \"Foo\" }");
2318
 
 
2319
 
  BuildFileWithErrors(
2320
 
    "name: \"bar.proto\" "
2321
 
    "message_type { name: \"Foo\" }",
2322
 
 
2323
 
    "bar.proto: Foo: NAME: \"Foo\" is already defined in file "
2324
 
      "\"foo.proto\".\n");
2325
 
}
2326
 
 
2327
 
TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
2328
 
  BuildFile(
2329
 
    "name: \"foo.proto\" "
2330
 
    "message_type { name: \"foo\" }");
2331
 
  BuildFileWithErrors(
2332
 
    "name: \"bar.proto\" "
2333
 
    "package: \"foo.bar\"",
2334
 
 
2335
 
    "bar.proto: foo: NAME: \"foo\" is already defined (as something other "
2336
 
      "than a package) in file \"foo.proto\".\n");
2337
 
}
2338
 
 
2339
 
TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) {
2340
 
  BuildFileWithErrors(
2341
 
    "name: \"foo.proto\" "
2342
 
    "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
2343
 
    "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
2344
 
 
2345
 
    "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
2346
 
    "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
2347
 
      "meaning that enum values are siblings of their type, not children of "
2348
 
      "it.  Therefore, \"FOO\" must be unique within the global scope, not "
2349
 
      "just within \"Bar\".\n");
2350
 
}
2351
 
 
2352
 
TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
2353
 
  BuildFileWithErrors(
2354
 
    "name: \"foo.proto\" "
2355
 
    "package: \"pkg\" "
2356
 
    "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
2357
 
    "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
2358
 
 
2359
 
    "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
2360
 
    "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
2361
 
      "meaning that enum values are siblings of their type, not children of "
2362
 
      "it.  Therefore, \"FOO\" must be unique within \"pkg\", not just within "
2363
 
      "\"Bar\".\n");
2364
 
}
2365
 
 
2366
 
TEST_F(ValidationErrorTest, MissingName) {
2367
 
  BuildFileWithErrors(
2368
 
    "name: \"foo.proto\" "
2369
 
    "message_type { }",
2370
 
 
2371
 
    "foo.proto: : NAME: Missing name.\n");
2372
 
}
2373
 
 
2374
 
TEST_F(ValidationErrorTest, InvalidName) {
2375
 
  BuildFileWithErrors(
2376
 
    "name: \"foo.proto\" "
2377
 
    "message_type { name: \"$\" }",
2378
 
 
2379
 
    "foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
2380
 
}
2381
 
 
2382
 
TEST_F(ValidationErrorTest, InvalidPackageName) {
2383
 
  BuildFileWithErrors(
2384
 
    "name: \"foo.proto\" "
2385
 
    "package: \"foo.$\"",
2386
 
 
2387
 
    "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
2388
 
}
2389
 
 
2390
 
TEST_F(ValidationErrorTest, MissingFileName) {
2391
 
  BuildFileWithErrors(
2392
 
    "",
2393
 
 
2394
 
    ": : OTHER: Missing field: FileDescriptorProto.name.\n");
2395
 
}
2396
 
 
2397
 
TEST_F(ValidationErrorTest, DupeDependency) {
2398
 
  BuildFile("name: \"foo.proto\"");
2399
 
  BuildFileWithErrors(
2400
 
    "name: \"bar.proto\" "
2401
 
    "dependency: \"foo.proto\" "
2402
 
    "dependency: \"foo.proto\" ",
2403
 
 
2404
 
    "bar.proto: bar.proto: OTHER: Import \"foo.proto\" was listed twice.\n");
2405
 
}
2406
 
 
2407
 
TEST_F(ValidationErrorTest, UnknownDependency) {
2408
 
  BuildFileWithErrors(
2409
 
    "name: \"bar.proto\" "
2410
 
    "dependency: \"foo.proto\" ",
2411
 
 
2412
 
    "bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n");
2413
 
}
2414
 
 
2415
 
TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
2416
 
  // Used to crash:  If we depend on a non-existent file and then refer to a
2417
 
  // package defined in a file that we didn't import, and that package is
2418
 
  // nested within a parent package which this file is also in, and we don't
2419
 
  // include that parent package in the name (i.e. we do a relative lookup)...
2420
 
  // Yes, really.
2421
 
  BuildFile(
2422
 
    "name: 'foo.proto' "
2423
 
    "package: 'outer.foo' ");
2424
 
  BuildFileWithErrors(
2425
 
    "name: 'bar.proto' "
2426
 
    "dependency: 'baz.proto' "
2427
 
    "package: 'outer.bar' "
2428
 
    "message_type { "
2429
 
    "  name: 'Bar' "
2430
 
    "  field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }"
2431
 
    "}",
2432
 
 
2433
 
    "bar.proto: bar.proto: OTHER: Import \"baz.proto\" has not been loaded.\n"
2434
 
    "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined in "
2435
 
      "\"foo.proto\", which is not imported by \"bar.proto\".  To use it here, "
2436
 
      "please add the necessary import.\n");
2437
 
}
2438
 
 
2439
 
TEST_F(ValidationErrorTest, DupeFile) {
2440
 
  BuildFile(
2441
 
    "name: \"foo.proto\" "
2442
 
    "message_type { name: \"Foo\" }");
2443
 
  // Note:  We should *not* get redundant errors about "Foo" already being
2444
 
  //   defined.
2445
 
  BuildFileWithErrors(
2446
 
    "name: \"foo.proto\" "
2447
 
    "message_type { name: \"Foo\" } "
2448
 
    // Add another type so that the files aren't identical (in which case there
2449
 
    // would be no error).
2450
 
    "enum_type { name: \"Bar\" }",
2451
 
 
2452
 
    "foo.proto: foo.proto: OTHER: A file with this name is already in the "
2453
 
      "pool.\n");
2454
 
}
2455
 
 
2456
 
TEST_F(ValidationErrorTest, FieldInExtensionRange) {
2457
 
  BuildFileWithErrors(
2458
 
    "name: \"foo.proto\" "
2459
 
    "message_type {"
2460
 
    "  name: \"Foo\""
2461
 
    "  field { name: \"foo\" number:  9 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2462
 
    "  field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2463
 
    "  field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2464
 
    "  field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2465
 
    "  extension_range { start: 10 end: 20 }"
2466
 
    "}",
2467
 
 
2468
 
    "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
2469
 
      "\"bar\" (10).\n"
2470
 
    "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
2471
 
      "\"baz\" (19).\n");
2472
 
}
2473
 
 
2474
 
TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
2475
 
  BuildFileWithErrors(
2476
 
    "name: \"foo.proto\" "
2477
 
    "message_type {"
2478
 
    "  name: \"Foo\""
2479
 
    "  extension_range { start: 10 end: 20 }"
2480
 
    "  extension_range { start: 20 end: 30 }"
2481
 
    "  extension_range { start: 19 end: 21 }"
2482
 
    "}",
2483
 
 
2484
 
    "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
2485
 
      "already-defined range 10 to 19.\n"
2486
 
    "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
2487
 
      "already-defined range 20 to 29.\n");
2488
 
}
2489
 
 
2490
 
TEST_F(ValidationErrorTest, InvalidDefaults) {
2491
 
  BuildFileWithErrors(
2492
 
    "name: \"foo.proto\" "
2493
 
    "message_type {"
2494
 
    "  name: \"Foo\""
2495
 
 
2496
 
    // Invalid number.
2497
 
    "  field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
2498
 
    "          default_value: \"abc\" }"
2499
 
 
2500
 
    // Empty default value.
2501
 
    "  field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
2502
 
    "          default_value: \"\" }"
2503
 
 
2504
 
    // Invalid boolean.
2505
 
    "  field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
2506
 
    "          default_value: \"abc\" }"
2507
 
 
2508
 
    // Messages can't have defaults.
2509
 
    "  field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: TYPE_MESSAGE"
2510
 
    "          default_value: \"abc\" type_name: \"Foo\" }"
2511
 
 
2512
 
    // Same thing, but we don't know that this field has message type until
2513
 
    // we look up the type name.
2514
 
    "  field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
2515
 
    "          default_value: \"abc\" type_name: \"Foo\" }"
2516
 
 
2517
 
    // Repeateds can't have defaults.
2518
 
    "  field { name: \"corge\" number: 6 label: LABEL_REPEATED type: TYPE_INT32"
2519
 
    "          default_value: \"1\" }"
2520
 
    "}",
2521
 
 
2522
 
    "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n"
2523
 
    "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value.\n"
2524
 
    "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
2525
 
      "false.\n"
2526
 
    "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
2527
 
    "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default "
2528
 
      "values.\n"
2529
 
    // This ends up being reported later because the error is detected at
2530
 
    // cross-linking time.
2531
 
    "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
2532
 
      "values.\n");
2533
 
}
2534
 
 
2535
 
TEST_F(ValidationErrorTest, NegativeFieldNumber) {
2536
 
  BuildFileWithErrors(
2537
 
    "name: \"foo.proto\" "
2538
 
    "message_type {"
2539
 
    "  name: \"Foo\""
2540
 
    "  field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2541
 
    "}",
2542
 
 
2543
 
    "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
2544
 
}
2545
 
 
2546
 
TEST_F(ValidationErrorTest, HugeFieldNumber) {
2547
 
  BuildFileWithErrors(
2548
 
    "name: \"foo.proto\" "
2549
 
    "message_type {"
2550
 
    "  name: \"Foo\""
2551
 
    "  field { name: \"foo\" number: 0x70000000 "
2552
 
    "          label:LABEL_OPTIONAL type:TYPE_INT32 }"
2553
 
    "}",
2554
 
 
2555
 
    "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
2556
 
      "536870911.\n");
2557
 
}
2558
 
 
2559
 
TEST_F(ValidationErrorTest, ReservedFieldNumber) {
2560
 
  BuildFileWithErrors(
2561
 
    "name: \"foo.proto\" "
2562
 
    "message_type {"
2563
 
    "  name: \"Foo\""
2564
 
    "  field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2565
 
    "  field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2566
 
    "  field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2567
 
    "  field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2568
 
    "}",
2569
 
 
2570
 
    "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
2571
 
      "reserved for the protocol buffer library implementation.\n"
2572
 
    "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
2573
 
      "reserved for the protocol buffer library implementation.\n");
2574
 
}
2575
 
 
2576
 
TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
2577
 
  BuildFileWithErrors(
2578
 
    "name: \"foo.proto\" "
2579
 
    "message_type {"
2580
 
    "  name: \"Foo\""
2581
 
    "  extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
2582
 
    "              type_name: \"Foo\" }"
2583
 
    "}",
2584
 
 
2585
 
    "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
2586
 
      "extension field.\n");
2587
 
}
2588
 
 
2589
 
TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
2590
 
  BuildFileWithErrors(
2591
 
    "name: \"foo.proto\" "
2592
 
    "message_type {"
2593
 
    "  name: \"Bar\""
2594
 
    "  extension_range { start: 1 end: 2 }"
2595
 
    "}"
2596
 
    "message_type {"
2597
 
    "  name: \"Foo\""
2598
 
    "  field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
2599
 
    "          type_name: \"Foo\" extendee: \"Bar\" }"
2600
 
    "}",
2601
 
 
2602
 
    "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
2603
 
      "non-extension field.\n");
2604
 
}
2605
 
 
2606
 
TEST_F(ValidationErrorTest, FieldNumberConflict) {
2607
 
  BuildFileWithErrors(
2608
 
    "name: \"foo.proto\" "
2609
 
    "message_type {"
2610
 
    "  name: \"Foo\""
2611
 
    "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2612
 
    "  field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2613
 
    "}",
2614
 
 
2615
 
    "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
2616
 
      "\"Foo\" by field \"foo\".\n");
2617
 
}
2618
 
 
2619
 
TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
2620
 
  BuildFileWithErrors(
2621
 
    "name: \"foo.proto\" "
2622
 
    "message_type {"
2623
 
    "  name: \"MessageSet\""
2624
 
    "  options { message_set_wire_format: true }"
2625
 
    "  extension_range { start: 4 end: 5 }"
2626
 
    "}"
2627
 
    "message_type {"
2628
 
    "  name: \"Foo\""
2629
 
    "  extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
2630
 
    "              extendee: \"MessageSet\" }"
2631
 
    "}",
2632
 
 
2633
 
    "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
2634
 
      "messages.\n");
2635
 
}
2636
 
 
2637
 
TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
2638
 
  BuildFileWithErrors(
2639
 
    "name: \"foo.proto\" "
2640
 
    "message_type {"
2641
 
    "  name: \"MessageSet\""
2642
 
    "  options { message_set_wire_format: true }"
2643
 
    "  extension_range { start: 4 end: 5 }"
2644
 
    "}"
2645
 
    "message_type {"
2646
 
    "  name: \"Foo\""
2647
 
    "  extension { name:\"foo\" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE"
2648
 
    "              type_name: \"Foo\" extendee: \"MessageSet\" }"
2649
 
    "}",
2650
 
 
2651
 
    "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
2652
 
      "messages.\n");
2653
 
}
2654
 
 
2655
 
TEST_F(ValidationErrorTest, FieldInMessageSet) {
2656
 
  BuildFileWithErrors(
2657
 
    "name: \"foo.proto\" "
2658
 
    "message_type {"
2659
 
    "  name: \"Foo\""
2660
 
    "  options { message_set_wire_format: true }"
2661
 
    "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2662
 
    "}",
2663
 
 
2664
 
    "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
2665
 
      "extensions.\n");
2666
 
}
2667
 
 
2668
 
TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
2669
 
  BuildFileWithErrors(
2670
 
    "name: \"foo.proto\" "
2671
 
    "message_type {"
2672
 
    "  name: \"Foo\""
2673
 
    "  extension_range { start: -10 end: -1 }"
2674
 
    "}",
2675
 
 
2676
 
    "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
2677
 
}
2678
 
 
2679
 
TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
2680
 
  BuildFileWithErrors(
2681
 
    "name: \"foo.proto\" "
2682
 
    "message_type {"
2683
 
    "  name: \"Foo\""
2684
 
    "  extension_range { start: 1 end: 0x70000000 }"
2685
 
    "}",
2686
 
 
2687
 
    "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
2688
 
      "536870911.\n");
2689
 
}
2690
 
 
2691
 
TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
2692
 
  BuildFileWithErrors(
2693
 
    "name: \"foo.proto\" "
2694
 
    "message_type {"
2695
 
    "  name: \"Foo\""
2696
 
    "  extension_range { start: 10 end: 10 }"
2697
 
    "  extension_range { start: 10 end: 5 }"
2698
 
    "}",
2699
 
 
2700
 
    "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
2701
 
      "start number.\n"
2702
 
    "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
2703
 
      "start number.\n");
2704
 
}
2705
 
 
2706
 
TEST_F(ValidationErrorTest, EmptyEnum) {
2707
 
  BuildFileWithErrors(
2708
 
    "name: \"foo.proto\" "
2709
 
    "enum_type { name: \"Foo\" }"
2710
 
    // Also use the empty enum in a message to make sure there are no crashes
2711
 
    // during validation (possible if the code attempts to derive a default
2712
 
    // value for the field).
2713
 
    "message_type {"
2714
 
    "  name: \"Bar\""
2715
 
    "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type_name:\"Foo\" }"
2716
 
    "  field { name: \"bar\" number: 2 label:LABEL_OPTIONAL type_name:\"Foo\" "
2717
 
    "          default_value: \"NO_SUCH_VALUE\" }"
2718
 
    "}",
2719
 
 
2720
 
    "foo.proto: Foo: NAME: Enums must contain at least one value.\n"
2721
 
    "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
2722
 
      "\"NO_SUCH_VALUE\".\n");
2723
 
}
2724
 
 
2725
 
TEST_F(ValidationErrorTest, UndefinedExtendee) {
2726
 
  BuildFileWithErrors(
2727
 
    "name: \"foo.proto\" "
2728
 
    "message_type {"
2729
 
    "  name: \"Foo\""
2730
 
    "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
2731
 
    "              extendee: \"Bar\" }"
2732
 
    "}",
2733
 
 
2734
 
    "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
2735
 
}
2736
 
 
2737
 
TEST_F(ValidationErrorTest, NonMessageExtendee) {
2738
 
  BuildFileWithErrors(
2739
 
    "name: \"foo.proto\" "
2740
 
    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
2741
 
    "message_type {"
2742
 
    "  name: \"Foo\""
2743
 
    "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
2744
 
    "              extendee: \"Bar\" }"
2745
 
    "}",
2746
 
 
2747
 
    "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
2748
 
}
2749
 
 
2750
 
TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
2751
 
  BuildFileWithErrors(
2752
 
    "name: \"foo.proto\" "
2753
 
    "message_type {"
2754
 
    "  name: \"Bar\""
2755
 
    "}"
2756
 
    "message_type {"
2757
 
    "  name: \"Foo\""
2758
 
    "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
2759
 
    "              extendee: \"Bar\" }"
2760
 
    "}",
2761
 
 
2762
 
    "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
2763
 
      "number.\n");
2764
 
}
2765
 
 
2766
 
TEST_F(ValidationErrorTest, UndefinedFieldType) {
2767
 
  BuildFileWithErrors(
2768
 
    "name: \"foo.proto\" "
2769
 
    "message_type {"
2770
 
    "  name: \"Foo\""
2771
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
2772
 
    "}",
2773
 
 
2774
 
    "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
2775
 
}
2776
 
 
2777
 
TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
2778
 
  BuildFile(
2779
 
    "name: \"bar.proto\" "
2780
 
    "message_type { name: \"Bar\" } ");
2781
 
 
2782
 
  BuildFileWithErrors(
2783
 
    "name: \"foo.proto\" "
2784
 
    "message_type {"
2785
 
    "  name: \"Foo\""
2786
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
2787
 
    "}",
2788
 
    "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
2789
 
      "which is not imported by \"foo.proto\".  To use it here, please add the "
2790
 
      "necessary import.\n");
2791
 
}
2792
 
 
2793
 
TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
2794
 
  // The following should produce an error that Bar.Baz is not defined:
2795
 
  //   message Bar { message Baz {} }
2796
 
  //   message Foo {
2797
 
  //     message Bar {
2798
 
  //       // Placing "message Baz{}" here, or removing Foo.Bar altogether,
2799
 
  //       // would fix the error.
2800
 
  //     }
2801
 
  //     optional Bar.Baz baz = 1;
2802
 
  //   }
2803
 
  // An one point the lookup code incorrectly did not produce an error in this
2804
 
  // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first,
2805
 
  // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually
2806
 
  // refer to the inner Bar, not the outer one.
2807
 
  BuildFileWithErrors(
2808
 
    "name: \"foo.proto\" "
2809
 
    "message_type {"
2810
 
    "  name: \"Bar\""
2811
 
    "  nested_type { name: \"Baz\" }"
2812
 
    "}"
2813
 
    "message_type {"
2814
 
    "  name: \"Foo\""
2815
 
    "  nested_type { name: \"Bar\" }"
2816
 
    "  field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
2817
 
    "          type_name:\"Bar.Baz\" }"
2818
 
    "}",
2819
 
 
2820
 
    "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n");
2821
 
}
2822
 
 
2823
 
TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
2824
 
  // This test would find the most local "Bar" first, and does, but
2825
 
  // proceeds to find the outer one because the inner one's not an
2826
 
  // aggregate.
2827
 
  BuildFile(
2828
 
    "name: \"foo.proto\" "
2829
 
    "message_type {"
2830
 
    "  name: \"Bar\""
2831
 
    "  nested_type { name: \"Baz\" }"
2832
 
    "}"
2833
 
    "message_type {"
2834
 
    "  name: \"Foo\""
2835
 
    "  field { name: \"Bar\" number:1 type:TYPE_BYTES } "
2836
 
    "  field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
2837
 
    "          type_name:\"Bar.Baz\" }"
2838
 
    "}");
2839
 
}
2840
 
 
2841
 
TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
2842
 
  // Imagine we have the following:
2843
 
  //
2844
 
  // foo.proto:
2845
 
  //   package foo.bar;
2846
 
  // bar.proto:
2847
 
  //   package foo.bar;
2848
 
  //   import "foo.proto";
2849
 
  //   message Bar {}
2850
 
  // baz.proto:
2851
 
  //   package foo;
2852
 
  //   import "bar.proto"
2853
 
  //   message Baz { optional bar.Bar qux = 1; }
2854
 
  //
2855
 
  // When validating baz.proto, we will look up "bar.Bar".  As part of this
2856
 
  // lookup, we first lookup "bar" then try to find "Bar" within it.  "bar"
2857
 
  // should resolve to "foo.bar".  Note, though, that "foo.bar" was originally
2858
 
  // defined in foo.proto, which is not a direct dependency of baz.proto.  The
2859
 
  // implementation of FindSymbol() normally only returns symbols in direct
2860
 
  // dependencies, not indirect ones.  This test insures that this does not
2861
 
  // prevent it from finding "foo.bar".
2862
 
 
2863
 
  BuildFile(
2864
 
    "name: \"foo.proto\" "
2865
 
    "package: \"foo.bar\" ");
2866
 
  BuildFile(
2867
 
    "name: \"bar.proto\" "
2868
 
    "package: \"foo.bar\" "
2869
 
    "dependency: \"foo.proto\" "
2870
 
    "message_type { name: \"Bar\" }");
2871
 
  BuildFile(
2872
 
    "name: \"baz.proto\" "
2873
 
    "package: \"foo\" "
2874
 
    "dependency: \"bar.proto\" "
2875
 
    "message_type { "
2876
 
    "  name: \"Baz\" "
2877
 
    "  field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
2878
 
    "          type_name:\"bar.Bar\" }"
2879
 
    "}");
2880
 
}
2881
 
 
2882
 
TEST_F(ValidationErrorTest, FieldTypeNotAType) {
2883
 
  BuildFileWithErrors(
2884
 
    "name: \"foo.proto\" "
2885
 
    "message_type {"
2886
 
    "  name: \"Foo\""
2887
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
2888
 
    "          type_name:\".Foo.bar\" }"
2889
 
    "  field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2890
 
    "}",
2891
 
 
2892
 
    "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
2893
 
}
2894
 
 
2895
 
TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
2896
 
  BuildFileWithErrors(
2897
 
    "name: \"foo.proto\" "
2898
 
    "message_type {"
2899
 
    "  nested_type {"
2900
 
    "    name: \"Bar\""
2901
 
    "    field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2902
 
    "  }"
2903
 
    "  name: \"Foo\""
2904
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
2905
 
    "          type_name:\"Bar.Baz\" }"
2906
 
    "}",
2907
 
    "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
2908
 
}
2909
 
 
2910
 
TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
2911
 
  BuildFile(
2912
 
    "name: \"foo.proto\" "
2913
 
    "message_type {"
2914
 
    "  name: \"Bar\""
2915
 
    "}"
2916
 
    "message_type {"
2917
 
    "  name: \"Foo\""
2918
 
    "  field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
2919
 
    "}");
2920
 
}
2921
 
 
2922
 
TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
2923
 
  BuildFileWithErrors(
2924
 
    "name: \"foo.proto\" "
2925
 
    "message_type { name: \"Bar\" } "
2926
 
    "message_type {"
2927
 
    "  name: \"Foo\""
2928
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
2929
 
    "          type_name:\"Bar\" }"
2930
 
    "}",
2931
 
 
2932
 
    "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
2933
 
}
2934
 
 
2935
 
TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
2936
 
  BuildFileWithErrors(
2937
 
    "name: \"foo.proto\" "
2938
 
    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
2939
 
    "message_type {"
2940
 
    "  name: \"Foo\""
2941
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
2942
 
    "          type_name:\"Bar\" }"
2943
 
    "}",
2944
 
 
2945
 
    "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
2946
 
}
2947
 
 
2948
 
TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
2949
 
  BuildFileWithErrors(
2950
 
    "name: \"foo.proto\" "
2951
 
    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
2952
 
    "message_type {"
2953
 
    "  name: \"Foo\""
2954
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
2955
 
    "          default_value:\"NO_SUCH_VALUE\" }"
2956
 
    "}",
2957
 
 
2958
 
    "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
2959
 
      "\"NO_SUCH_VALUE\".\n");
2960
 
}
2961
 
 
2962
 
TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
2963
 
  BuildFileWithErrors(
2964
 
    "name: \"foo.proto\" "
2965
 
    "message_type {"
2966
 
    "  name: \"Foo\""
2967
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
2968
 
    "          type_name:\"Foo\" }"
2969
 
    "}",
2970
 
 
2971
 
    "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
2972
 
}
2973
 
 
2974
 
TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
2975
 
  BuildFileWithErrors(
2976
 
    "name: \"foo.proto\" "
2977
 
    "message_type {"
2978
 
    "  name: \"Foo\""
2979
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
2980
 
    "}",
2981
 
 
2982
 
    "foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
2983
 
      "type_name.\n");
2984
 
}
2985
 
 
2986
 
TEST_F(ValidationErrorTest, InputTypeNotDefined) {
2987
 
  BuildFileWithErrors(
2988
 
    "name: \"foo.proto\" "
2989
 
    "message_type { name: \"Foo\" } "
2990
 
    "service {"
2991
 
    "  name: \"TestService\""
2992
 
    "  method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
2993
 
    "}",
2994
 
 
2995
 
    "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n");
2996
 
}
2997
 
 
2998
 
TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
2999
 
  BuildFileWithErrors(
3000
 
    "name: \"foo.proto\" "
3001
 
    "message_type { name: \"Foo\" } "
3002
 
    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
3003
 
    "service {"
3004
 
    "  name: \"TestService\""
3005
 
    "  method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
3006
 
    "}",
3007
 
 
3008
 
    "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n");
3009
 
}
3010
 
 
3011
 
TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
3012
 
  BuildFileWithErrors(
3013
 
    "name: \"foo.proto\" "
3014
 
    "message_type { name: \"Foo\" } "
3015
 
    "service {"
3016
 
    "  name: \"TestService\""
3017
 
    "  method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
3018
 
    "}",
3019
 
 
3020
 
    "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n");
3021
 
}
3022
 
 
3023
 
TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
3024
 
  BuildFileWithErrors(
3025
 
    "name: \"foo.proto\" "
3026
 
    "message_type { name: \"Foo\" } "
3027
 
    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
3028
 
    "service {"
3029
 
    "  name: \"TestService\""
3030
 
    "  method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
3031
 
    "}",
3032
 
 
3033
 
    "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n");
3034
 
}
3035
 
 
3036
 
TEST_F(ValidationErrorTest, IllegalPackedField) {
3037
 
  BuildFileWithErrors(
3038
 
    "name: \"foo.proto\" "
3039
 
    "message_type {\n"
3040
 
    "  name: \"Foo\""
3041
 
    "  field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
3042
 
    "          type:TYPE_STRING "
3043
 
    "          options { uninterpreted_option {"
3044
 
    "            name { name_part: \"packed\" is_extension: false }"
3045
 
    "            identifier_value: \"true\" }}}\n"
3046
 
    "  field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
3047
 
    "          type_name: \"Foo\""
3048
 
    "          options { uninterpreted_option {"
3049
 
    "            name { name_part: \"packed\" is_extension: false }"
3050
 
    "            identifier_value: \"true\" }}}\n"
3051
 
    "  field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
3052
 
    "          type:TYPE_INT32 "
3053
 
    "          options { uninterpreted_option {"
3054
 
    "            name { name_part: \"packed\" is_extension: false }"
3055
 
    "            identifier_value: \"true\" }}}\n"
3056
 
    "}",
3057
 
 
3058
 
    "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
3059
 
        "specified for repeated primitive fields.\n"
3060
 
    "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
3061
 
        "specified for repeated primitive fields.\n"
3062
 
    "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
3063
 
        "specified for repeated primitive fields.\n"
3064
 
        );
3065
 
}
3066
 
 
3067
 
TEST_F(ValidationErrorTest, OptionWrongType) {
3068
 
  BuildFileWithErrors(
3069
 
    "name: \"foo.proto\" "
3070
 
    "message_type { "
3071
 
    "  name: \"TestMessage\" "
3072
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
3073
 
    "          options { uninterpreted_option { name { name_part: \"ctype\" "
3074
 
    "                                                  is_extension: false }"
3075
 
    "                                           positive_int_value: 1 }"
3076
 
    "          }"
3077
 
    "  }"
3078
 
    "}\n",
3079
 
 
3080
 
    "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
3081
 
    "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
3082
 
}
3083
 
 
3084
 
TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
3085
 
  BuildFileWithErrors(
3086
 
    "name: \"foo.proto\" "
3087
 
    "message_type { "
3088
 
    "  name: \"TestMessage\" "
3089
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
3090
 
    "          options { uninterpreted_option { name { name_part: \"ctype\" "
3091
 
    "                                                  is_extension: false }"
3092
 
    "                                           name { name_part: \"foo\" "
3093
 
    "                                                  is_extension: true }"
3094
 
    "                                           positive_int_value: 1 }"
3095
 
    "          }"
3096
 
    "  }"
3097
 
    "}\n",
3098
 
 
3099
 
    "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
3100
 
    "atomic type, not a message.\n");
3101
 
}
3102
 
 
3103
 
TEST_F(ValidationErrorTest, DupOption) {
3104
 
  BuildFileWithErrors(
3105
 
    "name: \"foo.proto\" "
3106
 
    "message_type { "
3107
 
    "  name: \"TestMessage\" "
3108
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
3109
 
    "          options { uninterpreted_option { name { name_part: \"ctype\" "
3110
 
    "                                                  is_extension: false }"
3111
 
    "                                           identifier_value: \"CORD\" }"
3112
 
    "                    uninterpreted_option { name { name_part: \"ctype\" "
3113
 
    "                                                  is_extension: false }"
3114
 
    "                                           identifier_value: \"CORD\" }"
3115
 
    "          }"
3116
 
    "  }"
3117
 
    "}\n",
3118
 
 
3119
 
    "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
3120
 
    "already set.\n");
3121
 
}
3122
 
 
3123
 
TEST_F(ValidationErrorTest, InvalidOptionName) {
3124
 
  BuildFileWithErrors(
3125
 
    "name: \"foo.proto\" "
3126
 
    "message_type { "
3127
 
    "  name: \"TestMessage\" "
3128
 
    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
3129
 
    "          options { uninterpreted_option { "
3130
 
    "                      name { name_part: \"uninterpreted_option\" "
3131
 
    "                             is_extension: false }"
3132
 
    "                      positive_int_value: 1 "
3133
 
    "                    }"
3134
 
    "          }"
3135
 
    "  }"
3136
 
    "}\n",
3137
 
 
3138
 
    "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
3139
 
    "reserved name \"uninterpreted_option\".\n");
3140
 
}
3141
 
 
3142
 
TEST_F(ValidationErrorTest, RepeatedOption) {
3143
 
  BuildDescriptorMessagesInTestPool();
3144
 
 
3145
 
  BuildFileWithErrors(
3146
 
    "name: \"foo.proto\" "
3147
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3148
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_REPEATED "
3149
 
    "            type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
3150
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3151
 
    "                                        is_extension: true } "
3152
 
    "                                 double_value: 1.2 } }",
3153
 
 
3154
 
    "foo.proto: foo.proto: OPTION_NAME: Option field \"(foo)\" is repeated. "
3155
 
    "Repeated options are not supported.\n");
3156
 
}
3157
 
 
3158
 
TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
3159
 
  BuildDescriptorMessagesInTestPool();
3160
 
 
3161
 
  BuildFileWithErrors(
3162
 
    "name: \"foo.proto\" "
3163
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3164
 
    "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
3165
 
    "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
3166
 
    "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
3167
 
    "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
3168
 
 
3169
 
    "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
3170
 
    "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
3171
 
}
3172
 
 
3173
 
TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
3174
 
  BuildDescriptorMessagesInTestPool();
3175
 
 
3176
 
  BuildFileWithErrors(
3177
 
    "name: \"foo.proto\" "
3178
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3179
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3180
 
    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
3181
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3182
 
    "                                        is_extension: true } "
3183
 
    "                                 positive_int_value: 0x80000000 } "
3184
 
    "}",
3185
 
 
3186
 
    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
3187
 
    "for int32 option \"foo\".\n");
3188
 
}
3189
 
 
3190
 
TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
3191
 
  BuildDescriptorMessagesInTestPool();
3192
 
 
3193
 
  BuildFileWithErrors(
3194
 
    "name: \"foo.proto\" "
3195
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3196
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3197
 
    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
3198
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3199
 
    "                                        is_extension: true } "
3200
 
    "                                 negative_int_value: -0x80000001 } "
3201
 
    "}",
3202
 
 
3203
 
    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
3204
 
    "for int32 option \"foo\".\n");
3205
 
}
3206
 
 
3207
 
TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
3208
 
  BuildDescriptorMessagesInTestPool();
3209
 
 
3210
 
  BuildFileWithErrors(
3211
 
    "name: \"foo.proto\" "
3212
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3213
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3214
 
    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
3215
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3216
 
    "                                        is_extension: true } "
3217
 
    "                                 string_value: \"5\" } }",
3218
 
 
3219
 
    "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
3220
 
    "for int32 option \"foo\".\n");
3221
 
}
3222
 
 
3223
 
TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
3224
 
  BuildDescriptorMessagesInTestPool();
3225
 
 
3226
 
  BuildFileWithErrors(
3227
 
    "name: \"foo.proto\" "
3228
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3229
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3230
 
    "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
3231
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3232
 
    "                                        is_extension: true } "
3233
 
    "                                 positive_int_value: 0x8000000000000000 } "
3234
 
    "}",
3235
 
 
3236
 
    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
3237
 
    "for int64 option \"foo\".\n");
3238
 
}
3239
 
 
3240
 
TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
3241
 
  BuildDescriptorMessagesInTestPool();
3242
 
 
3243
 
  BuildFileWithErrors(
3244
 
    "name: \"foo.proto\" "
3245
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3246
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3247
 
    "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
3248
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3249
 
    "                                        is_extension: true } "
3250
 
    "                                 identifier_value: \"5\" } }",
3251
 
 
3252
 
    "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
3253
 
    "for int64 option \"foo\".\n");
3254
 
}
3255
 
 
3256
 
TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
3257
 
  BuildDescriptorMessagesInTestPool();
3258
 
 
3259
 
  BuildFileWithErrors(
3260
 
    "name: \"foo.proto\" "
3261
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3262
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3263
 
    "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
3264
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3265
 
    "                                        is_extension: true } "
3266
 
    "                                 positive_int_value: 0x100000000 } }",
3267
 
 
3268
 
    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
3269
 
    "for uint32 option \"foo\".\n");
3270
 
}
3271
 
 
3272
 
TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
3273
 
  BuildDescriptorMessagesInTestPool();
3274
 
 
3275
 
  BuildFileWithErrors(
3276
 
    "name: \"foo.proto\" "
3277
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3278
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3279
 
    "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
3280
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3281
 
    "                                        is_extension: true } "
3282
 
    "                                 double_value: -5.6 } }",
3283
 
 
3284
 
    "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
3285
 
    "for uint32 option \"foo\".\n");
3286
 
}
3287
 
 
3288
 
TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
3289
 
  BuildDescriptorMessagesInTestPool();
3290
 
 
3291
 
  BuildFileWithErrors(
3292
 
    "name: \"foo.proto\" "
3293
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3294
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3295
 
    "            type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
3296
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3297
 
    "                                        is_extension: true } "
3298
 
    "                                 negative_int_value: -5 } }",
3299
 
 
3300
 
    "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
3301
 
    "for uint64 option \"foo\".\n");
3302
 
}
3303
 
 
3304
 
TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
3305
 
  BuildDescriptorMessagesInTestPool();
3306
 
 
3307
 
  BuildFileWithErrors(
3308
 
    "name: \"foo.proto\" "
3309
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3310
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3311
 
    "            type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
3312
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3313
 
    "                                        is_extension: true } "
3314
 
    "                                 string_value: \"bar\" } }",
3315
 
 
3316
 
    "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
3317
 
    "for float option \"foo\".\n");
3318
 
}
3319
 
 
3320
 
TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
3321
 
  BuildDescriptorMessagesInTestPool();
3322
 
 
3323
 
  BuildFileWithErrors(
3324
 
    "name: \"foo.proto\" "
3325
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3326
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3327
 
    "            type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
3328
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3329
 
    "                                        is_extension: true } "
3330
 
    "                                 string_value: \"bar\" } }",
3331
 
 
3332
 
    "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
3333
 
    "for double option \"foo\".\n");
3334
 
}
3335
 
 
3336
 
TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
3337
 
  BuildDescriptorMessagesInTestPool();
3338
 
 
3339
 
  BuildFileWithErrors(
3340
 
    "name: \"foo.proto\" "
3341
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3342
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3343
 
    "            type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
3344
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3345
 
    "                                        is_extension: true } "
3346
 
    "                                 identifier_value: \"bar\" } }",
3347
 
 
3348
 
    "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
3349
 
    "for boolean option \"foo\".\n");
3350
 
}
3351
 
 
3352
 
TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
3353
 
  BuildDescriptorMessagesInTestPool();
3354
 
 
3355
 
  BuildFileWithErrors(
3356
 
    "name: \"foo.proto\" "
3357
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3358
 
    "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
3359
 
    "                              value { name: \"BAZ\" number: 2 } }"
3360
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3361
 
    "            type: TYPE_ENUM type_name: \"FooEnum\" "
3362
 
    "            extendee: \"google.protobuf.FileOptions\" }"
3363
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3364
 
    "                                        is_extension: true } "
3365
 
    "                                 string_value: \"QUUX\" } }",
3366
 
 
3367
 
    "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
3368
 
    "enum-valued option \"foo\".\n");
3369
 
}
3370
 
 
3371
 
TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
3372
 
  BuildDescriptorMessagesInTestPool();
3373
 
 
3374
 
  BuildFileWithErrors(
3375
 
    "name: \"foo.proto\" "
3376
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3377
 
    "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
3378
 
    "                              value { name: \"BAZ\" number: 2 } }"
3379
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3380
 
    "            type: TYPE_ENUM type_name: \"FooEnum\" "
3381
 
    "            extendee: \"google.protobuf.FileOptions\" }"
3382
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3383
 
    "                                        is_extension: true } "
3384
 
    "                                 identifier_value: \"QUUX\" } }",
3385
 
 
3386
 
    "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
3387
 
    "named \"QUUX\" for option \"foo\".\n");
3388
 
}
3389
 
 
3390
 
TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
3391
 
  BuildDescriptorMessagesInTestPool();
3392
 
 
3393
 
  BuildFileWithErrors(
3394
 
    "name: \"foo.proto\" "
3395
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3396
 
    "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
3397
 
    "                               value { name: \"BAZ\" number: 2 } }"
3398
 
    "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
3399
 
    "                               value { name: \"QUUX\" number: 2 } }"
3400
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3401
 
    "            type: TYPE_ENUM type_name: \"FooEnum1\" "
3402
 
    "            extendee: \"google.protobuf.FileOptions\" }"
3403
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3404
 
    "                                        is_extension: true } "
3405
 
    "                                 identifier_value: \"QUUX\" } }",
3406
 
 
3407
 
    "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
3408
 
    "named \"QUUX\" for option \"foo\". This appears to be a value from a "
3409
 
    "sibling type.\n");
3410
 
}
3411
 
 
3412
 
TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
3413
 
  BuildDescriptorMessagesInTestPool();
3414
 
 
3415
 
  BuildFileWithErrors(
3416
 
    "name: \"foo.proto\" "
3417
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3418
 
    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
3419
 
    "            type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
3420
 
    "options { uninterpreted_option { name { name_part: \"foo\" "
3421
 
    "                                        is_extension: true } "
3422
 
    "                                 identifier_value: \"QUUX\" } }",
3423
 
 
3424
 
    "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string for "
3425
 
    "string option \"foo\".\n");
3426
 
}
3427
 
 
3428
 
TEST_F(ValidationErrorTest, TryingToSetMessageValuedOption) {
3429
 
  BuildDescriptorMessagesInTestPool();
3430
 
 
3431
 
  BuildFileWithErrors(
3432
 
    "name: \"foo.proto\" "
3433
 
    "dependency: \"google/protobuf/descriptor.proto\" "
3434
 
    "message_type { "
3435
 
    "  name: \"TestMessage\" "
3436
 
    "  field { name:\"baz\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING }"
3437
 
    "}"
3438
 
    "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
3439
 
    "            type: TYPE_MESSAGE type_name: \"TestMessage\" "
3440
 
    "            extendee: \"google.protobuf.FileOptions\" }"
3441
 
    "options { uninterpreted_option { name { name_part: \"bar\" "
3442
 
    "                                        is_extension: true } "
3443
 
    "                                 identifier_value: \"QUUX\" } }",
3444
 
 
3445
 
    "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" cannot be of "
3446
 
    "message type.\n");
3447
 
}
3448
 
 
3449
 
TEST_F(ValidationErrorTest, NotLiteImportsLite) {
3450
 
  BuildFile(
3451
 
    "name: \"bar.proto\" "
3452
 
    "options { optimize_for: LITE_RUNTIME } ");
3453
 
 
3454
 
  BuildFileWithErrors(
3455
 
    "name: \"foo.proto\" "
3456
 
    "dependency: \"bar.proto\" ",
3457
 
 
3458
 
    "foo.proto: foo.proto: OTHER: Files that do not use optimize_for = "
3459
 
      "LITE_RUNTIME cannot import files which do use this option.  This file "
3460
 
      "is not lite, but it imports \"bar.proto\" which is.\n");
3461
 
}
3462
 
 
3463
 
TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
3464
 
  BuildFile(
3465
 
    "name: \"bar.proto\" "
3466
 
    "message_type: {"
3467
 
    "  name: \"Bar\""
3468
 
    "  extension_range { start: 1 end: 1000 }"
3469
 
    "}");
3470
 
 
3471
 
  BuildFileWithErrors(
3472
 
    "name: \"foo.proto\" "
3473
 
    "dependency: \"bar.proto\" "
3474
 
    "options { optimize_for: LITE_RUNTIME } "
3475
 
    "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL "
3476
 
    "            type: TYPE_INT32 extendee: \"Bar\" }",
3477
 
 
3478
 
    "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be "
3479
 
      "declared in non-lite files.  Note that you cannot extend a non-lite "
3480
 
      "type to contain a lite type, but the reverse is allowed.\n");
3481
 
}
3482
 
 
3483
 
TEST_F(ValidationErrorTest, NoLiteServices) {
3484
 
  BuildFileWithErrors(
3485
 
    "name: \"foo.proto\" "
3486
 
    "options { optimize_for: LITE_RUNTIME } "
3487
 
    "service { name: \"Foo\" }",
3488
 
 
3489
 
    "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
3490
 
    "define services unless you set both options cc_generic_services and "
3491
 
    "java_generic_sevices to false.\n");
3492
 
 
3493
 
  BuildFile(
3494
 
    "name: \"bar.proto\" "
3495
 
    "options {"
3496
 
    "  optimize_for: LITE_RUNTIME"
3497
 
    "  cc_generic_services: false"
3498
 
    "  java_generic_services: false"
3499
 
    "} "
3500
 
    "service { name: \"Foo\" }");
3501
 
}
3502
 
 
3503
 
TEST_F(ValidationErrorTest, RollbackAfterError) {
3504
 
  // Build a file which contains every kind of construct but references an
3505
 
  // undefined type.  All these constructs will be added to the symbol table
3506
 
  // before the undefined type error is noticed.  The DescriptorPool will then
3507
 
  // have to roll everything back.
3508
 
  BuildFileWithErrors(
3509
 
    "name: \"foo.proto\" "
3510
 
    "message_type {"
3511
 
    "  name: \"TestMessage\""
3512
 
    "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
3513
 
    "} "
3514
 
    "enum_type {"
3515
 
    "  name: \"TestEnum\""
3516
 
    "  value { name:\"BAR\" number:1 }"
3517
 
    "} "
3518
 
    "service {"
3519
 
    "  name: \"TestService\""
3520
 
    "  method {"
3521
 
    "    name: \"Baz\""
3522
 
    "    input_type: \"NoSuchType\""    // error
3523
 
    "    output_type: \"TestMessage\""
3524
 
    "  }"
3525
 
    "}",
3526
 
 
3527
 
    "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n");
3528
 
 
3529
 
  // Make sure that if we build the same file again with the error fixed,
3530
 
  // it works.  If the above rollback was incomplete, then some symbols will
3531
 
  // be left defined, and this second attempt will fail since it tries to
3532
 
  // re-define the same symbols.
3533
 
  BuildFile(
3534
 
    "name: \"foo.proto\" "
3535
 
    "message_type {"
3536
 
    "  name: \"TestMessage\""
3537
 
    "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
3538
 
    "} "
3539
 
    "enum_type {"
3540
 
    "  name: \"TestEnum\""
3541
 
    "  value { name:\"BAR\" number:1 }"
3542
 
    "} "
3543
 
    "service {"
3544
 
    "  name: \"TestService\""
3545
 
    "  method { name:\"Baz\""
3546
 
    "           input_type:\"TestMessage\""
3547
 
    "           output_type:\"TestMessage\" }"
3548
 
    "}");
3549
 
}
3550
 
 
3551
 
TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
3552
 
  // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is
3553
 
  // provided.
3554
 
 
3555
 
  FileDescriptorProto file_proto;
3556
 
  ASSERT_TRUE(TextFormat::ParseFromString(
3557
 
    "name: \"foo.proto\" "
3558
 
    "message_type { name: \"Foo\" } "
3559
 
    "message_type { name: \"Foo\" } ",
3560
 
    &file_proto));
3561
 
 
3562
 
  vector<string> errors;
3563
 
 
3564
 
  {
3565
 
    ScopedMemoryLog log;
3566
 
    EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL);
3567
 
    errors = log.GetMessages(ERROR);
3568
 
  }
3569
 
 
3570
 
  ASSERT_EQ(2, errors.size());
3571
 
 
3572
 
  EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]);
3573
 
  EXPECT_EQ("  Foo: \"Foo\" is already defined.", errors[1]);
3574
 
}
3575
 
 
3576
 
// ===================================================================
3577
 
// DescriptorDatabase
3578
 
 
3579
 
static void AddToDatabase(SimpleDescriptorDatabase* database,
3580
 
                          const char* file_text) {
3581
 
  FileDescriptorProto file_proto;
3582
 
  EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
3583
 
  database->Add(file_proto);
3584
 
}
3585
 
 
3586
 
class DatabaseBackedPoolTest : public testing::Test {
3587
 
 protected:
3588
 
  DatabaseBackedPoolTest() {}
3589
 
 
3590
 
  SimpleDescriptorDatabase database_;
3591
 
 
3592
 
  virtual void SetUp() {
3593
 
    AddToDatabase(&database_,
3594
 
      "name: \"foo.proto\" "
3595
 
      "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
3596
 
      "enum_type { name:\"TestEnum\" value { name:\"DUMMY\" number:0 } } "
3597
 
      "service { name:\"TestService\" } ");
3598
 
    AddToDatabase(&database_,
3599
 
      "name: \"bar.proto\" "
3600
 
      "dependency: \"foo.proto\" "
3601
 
      "message_type { name:\"Bar\" } "
3602
 
      "extension { name:\"foo_ext\" extendee: \".Foo\" number:5 "
3603
 
      "            label:LABEL_OPTIONAL type:TYPE_INT32 } ");
3604
 
  }
3605
 
 
3606
 
  // We can't inject a file containing errors into a DescriptorPool, so we
3607
 
  // need an actual mock DescriptorDatabase to test errors.
3608
 
  class ErrorDescriptorDatabase : public DescriptorDatabase {
3609
 
   public:
3610
 
    ErrorDescriptorDatabase() {}
3611
 
    ~ErrorDescriptorDatabase() {}
3612
 
 
3613
 
    // implements DescriptorDatabase ---------------------------------
3614
 
    bool FindFileByName(const string& filename,
3615
 
                        FileDescriptorProto* output) {
3616
 
      // error.proto and error2.proto cyclically import each other.
3617
 
      if (filename == "error.proto") {
3618
 
        output->Clear();
3619
 
        output->set_name("error.proto");
3620
 
        output->add_dependency("error2.proto");
3621
 
        return true;
3622
 
      } else if (filename == "error2.proto") {
3623
 
        output->Clear();
3624
 
        output->set_name("error2.proto");
3625
 
        output->add_dependency("error.proto");
3626
 
        return true;
3627
 
      } else {
3628
 
        return false;
3629
 
      }
3630
 
    }
3631
 
    bool FindFileContainingSymbol(const string& symbol_name,
3632
 
                                  FileDescriptorProto* output) {
3633
 
      return false;
3634
 
    }
3635
 
    bool FindFileContainingExtension(const string& containing_type,
3636
 
                                     int field_number,
3637
 
                                     FileDescriptorProto* output) {
3638
 
      return false;
3639
 
    }
3640
 
  };
3641
 
 
3642
 
  // A DescriptorDatabase that counts how many times each method has been
3643
 
  // called and forwards to some other DescriptorDatabase.
3644
 
  class CallCountingDatabase : public DescriptorDatabase {
3645
 
   public:
3646
 
    CallCountingDatabase(DescriptorDatabase* wrapped_db)
3647
 
      : wrapped_db_(wrapped_db) {
3648
 
      Clear();
3649
 
    }
3650
 
    ~CallCountingDatabase() {}
3651
 
 
3652
 
    DescriptorDatabase* wrapped_db_;
3653
 
 
3654
 
    int call_count_;
3655
 
 
3656
 
    void Clear() {
3657
 
      call_count_ = 0;
3658
 
    }
3659
 
 
3660
 
    // implements DescriptorDatabase ---------------------------------
3661
 
    bool FindFileByName(const string& filename,
3662
 
                        FileDescriptorProto* output) {
3663
 
      ++call_count_;
3664
 
      return wrapped_db_->FindFileByName(filename, output);
3665
 
    }
3666
 
    bool FindFileContainingSymbol(const string& symbol_name,
3667
 
                                  FileDescriptorProto* output) {
3668
 
      ++call_count_;
3669
 
      return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
3670
 
    }
3671
 
    bool FindFileContainingExtension(const string& containing_type,
3672
 
                                     int field_number,
3673
 
                                     FileDescriptorProto* output) {
3674
 
      ++call_count_;
3675
 
      return wrapped_db_->FindFileContainingExtension(
3676
 
        containing_type, field_number, output);
3677
 
    }
3678
 
  };
3679
 
 
3680
 
  // A DescriptorDatabase which falsely always returns foo.proto when searching
3681
 
  // for any symbol or extension number.  This shouldn't cause the
3682
 
  // DescriptorPool to reload foo.proto if it is already loaded.
3683
 
  class FalsePositiveDatabase : public DescriptorDatabase {
3684
 
   public:
3685
 
    FalsePositiveDatabase(DescriptorDatabase* wrapped_db)
3686
 
      : wrapped_db_(wrapped_db) {}
3687
 
    ~FalsePositiveDatabase() {}
3688
 
 
3689
 
    DescriptorDatabase* wrapped_db_;
3690
 
 
3691
 
    // implements DescriptorDatabase ---------------------------------
3692
 
    bool FindFileByName(const string& filename,
3693
 
                        FileDescriptorProto* output) {
3694
 
      return wrapped_db_->FindFileByName(filename, output);
3695
 
    }
3696
 
    bool FindFileContainingSymbol(const string& symbol_name,
3697
 
                                  FileDescriptorProto* output) {
3698
 
      return FindFileByName("foo.proto", output);
3699
 
    }
3700
 
    bool FindFileContainingExtension(const string& containing_type,
3701
 
                                     int field_number,
3702
 
                                     FileDescriptorProto* output) {
3703
 
      return FindFileByName("foo.proto", output);
3704
 
    }
3705
 
  };
3706
 
};
3707
 
 
3708
 
TEST_F(DatabaseBackedPoolTest, FindFileByName) {
3709
 
  DescriptorPool pool(&database_);
3710
 
 
3711
 
  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
3712
 
  ASSERT_TRUE(foo != NULL);
3713
 
  EXPECT_EQ("foo.proto", foo->name());
3714
 
  ASSERT_EQ(1, foo->message_type_count());
3715
 
  EXPECT_EQ("Foo", foo->message_type(0)->name());
3716
 
 
3717
 
  EXPECT_EQ(foo, pool.FindFileByName("foo.proto"));
3718
 
 
3719
 
  EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == NULL);
3720
 
}
3721
 
 
3722
 
TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
3723
 
  DescriptorPool pool(&database_);
3724
 
 
3725
 
  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
3726
 
  ASSERT_TRUE(foo != NULL);
3727
 
  EXPECT_EQ("foo.proto", foo->name());
3728
 
  ASSERT_EQ(1, foo->message_type_count());
3729
 
  EXPECT_EQ("Foo", foo->message_type(0)->name());
3730
 
 
3731
 
  const FileDescriptor* bar = pool.FindFileByName("bar.proto");
3732
 
  ASSERT_TRUE(bar != NULL);
3733
 
  EXPECT_EQ("bar.proto", bar->name());
3734
 
  ASSERT_EQ(1, bar->message_type_count());
3735
 
  EXPECT_EQ("Bar", bar->message_type(0)->name());
3736
 
 
3737
 
  ASSERT_EQ(1, bar->dependency_count());
3738
 
  EXPECT_EQ(foo, bar->dependency(0));
3739
 
}
3740
 
 
3741
 
TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
3742
 
  DescriptorPool pool(&database_);
3743
 
 
3744
 
  const FileDescriptor* bar = pool.FindFileByName("bar.proto");
3745
 
  ASSERT_TRUE(bar != NULL);
3746
 
  EXPECT_EQ("bar.proto", bar->name());
3747
 
  ASSERT_EQ(1, bar->message_type_count());
3748
 
  ASSERT_EQ("Bar", bar->message_type(0)->name());
3749
 
 
3750
 
  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
3751
 
  ASSERT_TRUE(foo != NULL);
3752
 
  EXPECT_EQ("foo.proto", foo->name());
3753
 
  ASSERT_EQ(1, foo->message_type_count());
3754
 
  ASSERT_EQ("Foo", foo->message_type(0)->name());
3755
 
 
3756
 
  ASSERT_EQ(1, bar->dependency_count());
3757
 
  EXPECT_EQ(foo, bar->dependency(0));
3758
 
}
3759
 
 
3760
 
TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) {
3761
 
  DescriptorPool pool(&database_);
3762
 
 
3763
 
  const FileDescriptor* file = pool.FindFileContainingSymbol("Foo");
3764
 
  ASSERT_TRUE(file != NULL);
3765
 
  EXPECT_EQ("foo.proto", file->name());
3766
 
  EXPECT_EQ(file, pool.FindFileByName("foo.proto"));
3767
 
 
3768
 
  EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == NULL);
3769
 
}
3770
 
 
3771
 
TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
3772
 
  DescriptorPool pool(&database_);
3773
 
 
3774
 
  const Descriptor* type = pool.FindMessageTypeByName("Foo");
3775
 
  ASSERT_TRUE(type != NULL);
3776
 
  EXPECT_EQ("Foo", type->name());
3777
 
  EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto"));
3778
 
 
3779
 
  EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == NULL);
3780
 
}
3781
 
 
3782
 
TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) {
3783
 
  DescriptorPool pool(&database_);
3784
 
 
3785
 
  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
3786
 
  ASSERT_TRUE(foo != NULL);
3787
 
 
3788
 
  const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5);
3789
 
  ASSERT_TRUE(extension != NULL);
3790
 
  EXPECT_EQ("foo_ext", extension->name());
3791
 
  EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto"));
3792
 
 
3793
 
  EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL);
3794
 
}
3795
 
 
3796
 
TEST_F(DatabaseBackedPoolTest, FindAllExtensions) {
3797
 
  DescriptorPool pool(&database_);
3798
 
 
3799
 
  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
3800
 
 
3801
 
  for (int i = 0; i < 2; ++i) {
3802
 
    // Repeat the lookup twice, to check that we get consistent
3803
 
    // results despite the fallback database lookup mutating the pool.
3804
 
    vector<const FieldDescriptor*> extensions;
3805
 
    pool.FindAllExtensions(foo, &extensions);
3806
 
    ASSERT_EQ(1, extensions.size());
3807
 
    EXPECT_EQ(5, extensions[0]->number());
3808
 
  }
3809
 
}
3810
 
 
3811
 
TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
3812
 
  ErrorDescriptorDatabase error_database;
3813
 
  DescriptorPool pool(&error_database);
3814
 
 
3815
 
  vector<string> errors;
3816
 
 
3817
 
  {
3818
 
    ScopedMemoryLog log;
3819
 
    EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
3820
 
    errors = log.GetMessages(ERROR);
3821
 
  }
3822
 
 
3823
 
  EXPECT_FALSE(errors.empty());
3824
 
}
3825
 
 
3826
 
TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
3827
 
  ErrorDescriptorDatabase error_database;
3828
 
  MockErrorCollector error_collector;
3829
 
  DescriptorPool pool(&error_database, &error_collector);
3830
 
 
3831
 
  EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
3832
 
  EXPECT_EQ(
3833
 
    "error.proto: error.proto: OTHER: File recursively imports itself: "
3834
 
      "error.proto -> error2.proto -> error.proto\n"
3835
 
    "error2.proto: error2.proto: OTHER: Import \"error.proto\" was not "
3836
 
      "found or had errors.\n"
3837
 
    "error.proto: error.proto: OTHER: Import \"error2.proto\" was not "
3838
 
      "found or had errors.\n",
3839
 
    error_collector.text_);
3840
 
}
3841
 
 
3842
 
TEST_F(DatabaseBackedPoolTest, UnittestProto) {
3843
 
  // Try to load all of unittest.proto from a DescriptorDatabase.  This should
3844
 
  // thoroughly test all paths through DescriptorBuilder to insure that there
3845
 
  // are no deadlocking problems when pool_->mutex_ is non-NULL.
3846
 
  const FileDescriptor* original_file =
3847
 
    protobuf_unittest::TestAllTypes::descriptor()->file();
3848
 
 
3849
 
  DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
3850
 
  DescriptorPool pool(&database);
3851
 
  const FileDescriptor* file_from_database =
3852
 
    pool.FindFileByName(original_file->name());
3853
 
 
3854
 
  ASSERT_TRUE(file_from_database != NULL);
3855
 
 
3856
 
  FileDescriptorProto original_file_proto;
3857
 
  original_file->CopyTo(&original_file_proto);
3858
 
 
3859
 
  FileDescriptorProto file_from_database_proto;
3860
 
  file_from_database->CopyTo(&file_from_database_proto);
3861
 
 
3862
 
  EXPECT_EQ(original_file_proto.DebugString(),
3863
 
            file_from_database_proto.DebugString());
3864
 
}
3865
 
 
3866
 
TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
3867
 
  // Searching for a child of an existing descriptor should never fall back
3868
 
  // to the DescriptorDatabase even if it isn't found, because we know all
3869
 
  // children are already loaded.
3870
 
  CallCountingDatabase call_counter(&database_);
3871
 
  DescriptorPool pool(&call_counter);
3872
 
 
3873
 
  const FileDescriptor* file = pool.FindFileByName("foo.proto");
3874
 
  ASSERT_TRUE(file != NULL);
3875
 
  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
3876
 
  ASSERT_TRUE(foo != NULL);
3877
 
  const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
3878
 
  ASSERT_TRUE(test_enum != NULL);
3879
 
  const ServiceDescriptor* test_service = pool.FindServiceByName("TestService");
3880
 
  ASSERT_TRUE(test_service != NULL);
3881
 
 
3882
 
  EXPECT_NE(0, call_counter.call_count_);
3883
 
  call_counter.Clear();
3884
 
 
3885
 
  EXPECT_TRUE(foo->FindFieldByName("no_such_field") == NULL);
3886
 
  EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == NULL);
3887
 
  EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == NULL);
3888
 
  EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == NULL);
3889
 
  EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
3890
 
  EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == NULL);
3891
 
  EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == NULL);
3892
 
 
3893
 
  EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == NULL);
3894
 
  EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == NULL);
3895
 
  EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
3896
 
  EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL);
3897
 
  EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL);
3898
 
  EXPECT_EQ(0, call_counter.call_count_);
3899
 
}
3900
 
 
3901
 
TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
3902
 
  // If FindFileContainingSymbol() or FindFileContainingExtension() return a
3903
 
  // file that is already in the DescriptorPool, it should not attempt to
3904
 
  // reload the file.
3905
 
  FalsePositiveDatabase false_positive_database(&database_);
3906
 
  MockErrorCollector error_collector;
3907
 
  DescriptorPool pool(&false_positive_database, &error_collector);
3908
 
 
3909
 
  // First make sure foo.proto is loaded.
3910
 
  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
3911
 
  ASSERT_TRUE(foo != NULL);
3912
 
 
3913
 
  // Try inducing false positives.
3914
 
  EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == NULL);
3915
 
  EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == NULL);
3916
 
 
3917
 
  // No errors should have been reported.  (If foo.proto was incorrectly
3918
 
  // loaded multiple times, errors would have been reported.)
3919
 
  EXPECT_EQ("", error_collector.text_);
3920
 
}
3921
 
 
3922
 
TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
3923
 
  ErrorDescriptorDatabase error_database;
3924
 
  MockErrorCollector error_collector;
3925
 
  DescriptorPool pool(&error_database, &error_collector);
3926
 
 
3927
 
  EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
3928
 
  error_collector.text_.clear();
3929
 
  EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
3930
 
  EXPECT_EQ("", error_collector.text_);
3931
 
}
3932
 
 
3933
 
TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
3934
 
  // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
3935
 
  // to FindFieldByName()), we should fail fast, without checking the fallback
3936
 
  // database.
3937
 
  CallCountingDatabase call_counter(&database_);
3938
 
  DescriptorPool pool(&call_counter);
3939
 
 
3940
 
  const FileDescriptor* file = pool.FindFileByName("foo.proto");
3941
 
  ASSERT_TRUE(file != NULL);
3942
 
  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
3943
 
  ASSERT_TRUE(foo != NULL);
3944
 
  const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
3945
 
  ASSERT_TRUE(test_enum != NULL);
3946
 
 
3947
 
  EXPECT_NE(0, call_counter.call_count_);
3948
 
  call_counter.Clear();
3949
 
 
3950
 
  EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == NULL);
3951
 
  EXPECT_TRUE(pool.FindFieldByName("Foo") == NULL);
3952
 
  EXPECT_TRUE(pool.FindExtensionByName("Foo") == NULL);
3953
 
  EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == NULL);
3954
 
  EXPECT_TRUE(pool.FindEnumValueByName("Foo") == NULL);
3955
 
  EXPECT_TRUE(pool.FindServiceByName("Foo") == NULL);
3956
 
  EXPECT_TRUE(pool.FindMethodByName("Foo") == NULL);
3957
 
 
3958
 
  EXPECT_EQ(0, call_counter.call_count_);
3959
 
}
3960
 
 
3961
 
// ===================================================================
3962
 
 
3963
 
 
3964
 
}  // namespace descriptor_unittest
3965
 
}  // namespace protobuf
3966
 
}  // namespace google