1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.
3
// http://code.google.com/p/protobuf/
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
9
// http://www.apache.org/licenses/LICENSE-2.0
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
17
// Author: kenton@google.com (Kenton Varda)
18
// Based on original Protocol Buffers design by
19
// Sanjay Ghemawat, Jeff Dean, and others.
21
// This file makes extensive use of RFC 3092. :)
25
#include <google/protobuf/descriptor.h>
26
#include <google/protobuf/descriptor_database.h>
27
#include <google/protobuf/descriptor.pb.h>
28
#include <google/protobuf/text_format.h>
29
#include <google/protobuf/unittest.pb.h>
30
#include <google/protobuf/stubs/strutil.h>
31
#include <google/protobuf/stubs/substitute.h>
33
#include <google/protobuf/stubs/common.h>
34
#include <google/protobuf/testing/googletest.h>
35
#include <gtest/gtest.h>
42
// Some helpers to make assembling descriptors faster.
43
DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) {
44
DescriptorProto* result = file->add_message_type();
45
result->set_name(name);
49
DescriptorProto* AddNestedMessage(DescriptorProto* parent, const string& name) {
50
DescriptorProto* result = parent->add_nested_type();
51
result->set_name(name);
55
EnumDescriptorProto* AddEnum(FileDescriptorProto* file, const string& name) {
56
EnumDescriptorProto* result = file->add_enum_type();
57
result->set_name(name);
61
EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent,
63
EnumDescriptorProto* result = parent->add_enum_type();
64
result->set_name(name);
68
ServiceDescriptorProto* AddService(FileDescriptorProto* file,
70
ServiceDescriptorProto* result = file->add_service();
71
result->set_name(name);
75
FieldDescriptorProto* AddField(DescriptorProto* parent,
76
const string& name, int number,
77
FieldDescriptorProto::Label label,
78
FieldDescriptorProto::Type type) {
79
FieldDescriptorProto* result = parent->add_field();
80
result->set_name(name);
81
result->set_number(number);
82
result->set_label(label);
83
result->set_type(type);
87
FieldDescriptorProto* AddExtension(FileDescriptorProto* file,
88
const string& extendee,
89
const string& name, int number,
90
FieldDescriptorProto::Label label,
91
FieldDescriptorProto::Type type) {
92
FieldDescriptorProto* result = file->add_extension();
93
result->set_name(name);
94
result->set_number(number);
95
result->set_label(label);
96
result->set_type(type);
97
result->set_extendee(extendee);
101
FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent,
102
const string& extendee,
103
const string& name, int number,
104
FieldDescriptorProto::Label label,
105
FieldDescriptorProto::Type type) {
106
FieldDescriptorProto* result = parent->add_extension();
107
result->set_name(name);
108
result->set_number(number);
109
result->set_label(label);
110
result->set_type(type);
111
result->set_extendee(extendee);
115
DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent,
116
int start, int end) {
117
DescriptorProto::ExtensionRange* result = parent->add_extension_range();
118
result->set_start(start);
119
result->set_end(end);
123
EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto,
124
const string& name, int number) {
125
EnumValueDescriptorProto* result = enum_proto->add_value();
126
result->set_name(name);
127
result->set_number(number);
131
MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service,
133
const string& input_type,
134
const string& output_type) {
135
MethodDescriptorProto* result = service->add_method();
136
result->set_name(name);
137
result->set_input_type(input_type);
138
result->set_output_type(output_type);
142
// Empty enums technically aren't allowed. We need to insert a dummy value
144
void AddEmptyEnum(FileDescriptorProto* file, const string& name) {
145
AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
148
// ===================================================================
150
// Test simple files.
151
class FileDescriptorTest : public testing::Test {
153
virtual void SetUp() {
154
// Build descriptors for the following definitions:
157
// message FooMessage { extensions 1; }
158
// enum FooEnum {FOO_ENUM_VALUE = 1;}
159
// service FooService {}
160
// extend FooMessage { optional int32 foo_extension = 1; }
163
// package bar_package;
164
// message BarMessage { extensions 1; }
165
// enum BarEnum {BAR_ENUM_VALUE = 1;}
166
// service BarService {}
167
// extend BarMessage { optional int32 bar_extension = 1; }
169
// Also, we have an empty file "baz.proto". This file's purpose is to
170
// make sure that even though it has the same package as foo.proto,
171
// searching it for members of foo.proto won't work.
173
FileDescriptorProto foo_file;
174
foo_file.set_name("foo.proto");
175
AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2);
176
AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1);
177
AddService(&foo_file, "FooService");
178
AddExtension(&foo_file, "FooMessage", "foo_extension", 1,
179
FieldDescriptorProto::LABEL_OPTIONAL,
180
FieldDescriptorProto::TYPE_INT32);
182
FileDescriptorProto bar_file;
183
bar_file.set_name("bar.proto");
184
bar_file.set_package("bar_package");
185
bar_file.add_dependency("foo.proto");
186
AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2);
187
AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1);
188
AddService(&bar_file, "BarService");
189
AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1,
190
FieldDescriptorProto::LABEL_OPTIONAL,
191
FieldDescriptorProto::TYPE_INT32);
193
FileDescriptorProto baz_file;
194
baz_file.set_name("baz.proto");
196
// Build the descriptors and get the pointers.
197
foo_file_ = pool_.BuildFile(foo_file);
198
ASSERT_TRUE(foo_file_ != NULL);
200
bar_file_ = pool_.BuildFile(bar_file);
201
ASSERT_TRUE(bar_file_ != NULL);
203
baz_file_ = pool_.BuildFile(baz_file);
204
ASSERT_TRUE(baz_file_ != NULL);
206
ASSERT_EQ(1, foo_file_->message_type_count());
207
foo_message_ = foo_file_->message_type(0);
208
ASSERT_EQ(1, foo_file_->enum_type_count());
209
foo_enum_ = foo_file_->enum_type(0);
210
ASSERT_EQ(1, foo_enum_->value_count());
211
foo_enum_value_ = foo_enum_->value(0);
212
ASSERT_EQ(1, foo_file_->service_count());
213
foo_service_ = foo_file_->service(0);
214
ASSERT_EQ(1, foo_file_->extension_count());
215
foo_extension_ = foo_file_->extension(0);
217
ASSERT_EQ(1, bar_file_->message_type_count());
218
bar_message_ = bar_file_->message_type(0);
219
ASSERT_EQ(1, bar_file_->enum_type_count());
220
bar_enum_ = bar_file_->enum_type(0);
221
ASSERT_EQ(1, bar_enum_->value_count());
222
bar_enum_value_ = bar_enum_->value(0);
223
ASSERT_EQ(1, bar_file_->service_count());
224
bar_service_ = bar_file_->service(0);
225
ASSERT_EQ(1, bar_file_->extension_count());
226
bar_extension_ = bar_file_->extension(0);
229
DescriptorPool pool_;
231
const FileDescriptor* foo_file_;
232
const FileDescriptor* bar_file_;
233
const FileDescriptor* baz_file_;
235
const Descriptor* foo_message_;
236
const EnumDescriptor* foo_enum_;
237
const EnumValueDescriptor* foo_enum_value_;
238
const ServiceDescriptor* foo_service_;
239
const FieldDescriptor* foo_extension_;
241
const Descriptor* bar_message_;
242
const EnumDescriptor* bar_enum_;
243
const EnumValueDescriptor* bar_enum_value_;
244
const ServiceDescriptor* bar_service_;
245
const FieldDescriptor* bar_extension_;
248
TEST_F(FileDescriptorTest, Name) {
249
EXPECT_EQ("foo.proto", foo_file_->name());
250
EXPECT_EQ("bar.proto", bar_file_->name());
251
EXPECT_EQ("baz.proto", baz_file_->name());
254
TEST_F(FileDescriptorTest, Package) {
255
EXPECT_EQ("", foo_file_->package());
256
EXPECT_EQ("bar_package", bar_file_->package());
259
TEST_F(FileDescriptorTest, Dependencies) {
260
EXPECT_EQ(0, foo_file_->dependency_count());
261
EXPECT_EQ(1, bar_file_->dependency_count());
262
EXPECT_EQ(foo_file_, bar_file_->dependency(0));
265
TEST_F(FileDescriptorTest, FindMessageTypeByName) {
266
EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage"));
267
EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage"));
269
EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == NULL);
270
EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == NULL);
271
EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == NULL);
273
EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == NULL);
274
EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == NULL);
277
TEST_F(FileDescriptorTest, FindEnumTypeByName) {
278
EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum"));
279
EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum"));
281
EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == NULL);
282
EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == NULL);
283
EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == NULL);
285
EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == NULL);
286
EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == NULL);
289
TEST_F(FileDescriptorTest, FindEnumValueByName) {
290
EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE"));
291
EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE"));
293
EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == NULL);
294
EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
295
EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
297
EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
298
EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == NULL);
301
TEST_F(FileDescriptorTest, FindServiceByName) {
302
EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService"));
303
EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService"));
305
EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == NULL);
306
EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == NULL);
307
EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == NULL);
309
EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == NULL);
310
EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == NULL);
313
TEST_F(FileDescriptorTest, FindExtensionByName) {
314
EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension"));
315
EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension"));
317
EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == NULL);
318
EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == NULL);
319
EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == NULL);
321
EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == NULL);
322
EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == NULL);
325
TEST_F(FileDescriptorTest, FindExtensionByNumber) {
326
EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1));
327
EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1));
329
EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL);
332
// ===================================================================
334
// Test simple flat messages and fields.
335
class DescriptorTest : public testing::Test {
337
virtual void SetUp() {
338
// Build descriptors for the following definitions:
341
// message TestForeign {}
344
// message TestMessage {
345
// required string foo = 1;
346
// optional TestEnum bar = 6;
347
// repeated TestForeign baz = 500000000;
348
// optional group qux = 15 {}
352
// package corge.grault;
353
// message TestMessage2 {
354
// required string foo = 1;
355
// required string bar = 2;
356
// required string quux = 6;
359
// We cheat and use TestForeign as the type for qux rather than create
360
// an actual nested type.
362
// Since all primitive types (including string) use the same building
363
// code, there's no need to test each one individually.
365
// TestMessage2 is primarily here to test FindFieldByName and friends.
366
// All messages created from the same DescriptorPool share the same lookup
367
// table, so we need to insure that they don't interfere.
369
FileDescriptorProto foo_file;
370
foo_file.set_name("foo.proto");
371
AddMessage(&foo_file, "TestForeign");
372
AddEmptyEnum(&foo_file, "TestEnum");
374
DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
375
AddField(message, "foo", 1,
376
FieldDescriptorProto::LABEL_REQUIRED,
377
FieldDescriptorProto::TYPE_STRING);
378
AddField(message, "bar", 6,
379
FieldDescriptorProto::LABEL_OPTIONAL,
380
FieldDescriptorProto::TYPE_ENUM)
381
->set_type_name("TestEnum");
382
AddField(message, "baz", 500000000,
383
FieldDescriptorProto::LABEL_REPEATED,
384
FieldDescriptorProto::TYPE_MESSAGE)
385
->set_type_name("TestForeign");
386
AddField(message, "qux", 15,
387
FieldDescriptorProto::LABEL_OPTIONAL,
388
FieldDescriptorProto::TYPE_GROUP)
389
->set_type_name("TestForeign");
391
FileDescriptorProto bar_file;
392
bar_file.set_name("bar.proto");
393
bar_file.set_package("corge.grault");
395
DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
396
AddField(message2, "foo", 1,
397
FieldDescriptorProto::LABEL_REQUIRED,
398
FieldDescriptorProto::TYPE_STRING);
399
AddField(message2, "bar", 2,
400
FieldDescriptorProto::LABEL_REQUIRED,
401
FieldDescriptorProto::TYPE_STRING);
402
AddField(message2, "quux", 6,
403
FieldDescriptorProto::LABEL_REQUIRED,
404
FieldDescriptorProto::TYPE_STRING);
406
// Build the descriptors and get the pointers.
407
foo_file_ = pool_.BuildFile(foo_file);
408
ASSERT_TRUE(foo_file_ != NULL);
410
bar_file_ = pool_.BuildFile(bar_file);
411
ASSERT_TRUE(bar_file_ != NULL);
413
ASSERT_EQ(1, foo_file_->enum_type_count());
414
enum_ = foo_file_->enum_type(0);
416
ASSERT_EQ(2, foo_file_->message_type_count());
417
foreign_ = foo_file_->message_type(0);
418
message_ = foo_file_->message_type(1);
420
ASSERT_EQ(4, message_->field_count());
421
foo_ = message_->field(0);
422
bar_ = message_->field(1);
423
baz_ = message_->field(2);
424
qux_ = message_->field(3);
426
ASSERT_EQ(1, bar_file_->message_type_count());
427
message2_ = bar_file_->message_type(0);
429
ASSERT_EQ(3, message2_->field_count());
430
foo2_ = message2_->field(0);
431
bar2_ = message2_->field(1);
432
quux2_ = message2_->field(2);
435
DescriptorPool pool_;
437
const FileDescriptor* foo_file_;
438
const FileDescriptor* bar_file_;
440
const Descriptor* message_;
441
const Descriptor* message2_;
442
const Descriptor* foreign_;
443
const EnumDescriptor* enum_;
445
const FieldDescriptor* foo_;
446
const FieldDescriptor* bar_;
447
const FieldDescriptor* baz_;
448
const FieldDescriptor* qux_;
450
const FieldDescriptor* foo2_;
451
const FieldDescriptor* bar2_;
452
const FieldDescriptor* quux2_;
455
TEST_F(DescriptorTest, Name) {
456
EXPECT_EQ("TestMessage", message_->name());
457
EXPECT_EQ("TestMessage", message_->full_name());
458
EXPECT_EQ(foo_file_, message_->file());
460
EXPECT_EQ("TestMessage2", message2_->name());
461
EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name());
462
EXPECT_EQ(bar_file_, message2_->file());
465
TEST_F(DescriptorTest, ContainingType) {
466
EXPECT_TRUE(message_->containing_type() == NULL);
467
EXPECT_TRUE(message2_->containing_type() == NULL);
470
TEST_F(DescriptorTest, FieldsByIndex) {
471
ASSERT_EQ(4, message_->field_count());
472
EXPECT_EQ(foo_, message_->field(0));
473
EXPECT_EQ(bar_, message_->field(1));
474
EXPECT_EQ(baz_, message_->field(2));
475
EXPECT_EQ(qux_, message_->field(3));
478
TEST_F(DescriptorTest, FindFieldByName) {
479
// All messages in the same DescriptorPool share a single lookup table for
480
// fields. So, in addition to testing that FindFieldByName finds the fields
481
// of the message, we need to test that it does *not* find the fields of
484
EXPECT_EQ(foo_, message_->FindFieldByName("foo"));
485
EXPECT_EQ(bar_, message_->FindFieldByName("bar"));
486
EXPECT_EQ(baz_, message_->FindFieldByName("baz"));
487
EXPECT_EQ(qux_, message_->FindFieldByName("qux"));
488
EXPECT_TRUE(message_->FindFieldByName("no_such_field") == NULL);
489
EXPECT_TRUE(message_->FindFieldByName("quux") == NULL);
491
EXPECT_EQ(foo2_ , message2_->FindFieldByName("foo" ));
492
EXPECT_EQ(bar2_ , message2_->FindFieldByName("bar" ));
493
EXPECT_EQ(quux2_, message2_->FindFieldByName("quux"));
494
EXPECT_TRUE(message2_->FindFieldByName("baz") == NULL);
495
EXPECT_TRUE(message2_->FindFieldByName("qux") == NULL);
498
TEST_F(DescriptorTest, FindFieldByNumber) {
499
EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
500
EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
501
EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
502
EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
503
EXPECT_TRUE(message_->FindFieldByNumber(837592) == NULL);
504
EXPECT_TRUE(message_->FindFieldByNumber(2) == NULL);
506
EXPECT_EQ(foo2_ , message2_->FindFieldByNumber(1));
507
EXPECT_EQ(bar2_ , message2_->FindFieldByNumber(2));
508
EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
509
EXPECT_TRUE(message2_->FindFieldByNumber(15) == NULL);
510
EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == NULL);
513
TEST_F(DescriptorTest, FieldName) {
514
EXPECT_EQ("foo", foo_->name());
515
EXPECT_EQ("bar", bar_->name());
516
EXPECT_EQ("baz", baz_->name());
517
EXPECT_EQ("qux", qux_->name());
520
TEST_F(DescriptorTest, FieldFullName) {
521
EXPECT_EQ("TestMessage.foo", foo_->full_name());
522
EXPECT_EQ("TestMessage.bar", bar_->full_name());
523
EXPECT_EQ("TestMessage.baz", baz_->full_name());
524
EXPECT_EQ("TestMessage.qux", qux_->full_name());
526
EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name());
527
EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name());
528
EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name());
531
TEST_F(DescriptorTest, FieldFile) {
532
EXPECT_EQ(foo_file_, foo_->file());
533
EXPECT_EQ(foo_file_, bar_->file());
534
EXPECT_EQ(foo_file_, baz_->file());
535
EXPECT_EQ(foo_file_, qux_->file());
537
EXPECT_EQ(bar_file_, foo2_->file());
538
EXPECT_EQ(bar_file_, bar2_->file());
539
EXPECT_EQ(bar_file_, quux2_->file());
542
TEST_F(DescriptorTest, FieldIndex) {
543
EXPECT_EQ(0, foo_->index());
544
EXPECT_EQ(1, bar_->index());
545
EXPECT_EQ(2, baz_->index());
546
EXPECT_EQ(3, qux_->index());
549
TEST_F(DescriptorTest, FieldNumber) {
550
EXPECT_EQ( 1, foo_->number());
551
EXPECT_EQ( 6, bar_->number());
552
EXPECT_EQ(500000000, baz_->number());
553
EXPECT_EQ( 15, qux_->number());
556
TEST_F(DescriptorTest, FieldType) {
557
EXPECT_EQ(FieldDescriptor::TYPE_STRING , foo_->type());
558
EXPECT_EQ(FieldDescriptor::TYPE_ENUM , bar_->type());
559
EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type());
560
EXPECT_EQ(FieldDescriptor::TYPE_GROUP , qux_->type());
563
TEST_F(DescriptorTest, FieldLabel) {
564
EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label());
565
EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label());
566
EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label());
567
EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label());
569
EXPECT_TRUE (foo_->is_required());
570
EXPECT_FALSE(foo_->is_optional());
571
EXPECT_FALSE(foo_->is_repeated());
573
EXPECT_FALSE(bar_->is_required());
574
EXPECT_TRUE (bar_->is_optional());
575
EXPECT_FALSE(bar_->is_repeated());
577
EXPECT_FALSE(baz_->is_required());
578
EXPECT_FALSE(baz_->is_optional());
579
EXPECT_TRUE (baz_->is_repeated());
582
TEST_F(DescriptorTest, FieldHasDefault) {
583
EXPECT_FALSE(foo_->has_default_value());
584
EXPECT_FALSE(bar_->has_default_value());
585
EXPECT_FALSE(baz_->has_default_value());
586
EXPECT_FALSE(qux_->has_default_value());
589
TEST_F(DescriptorTest, FieldContainingType) {
590
EXPECT_EQ(message_, foo_->containing_type());
591
EXPECT_EQ(message_, bar_->containing_type());
592
EXPECT_EQ(message_, baz_->containing_type());
593
EXPECT_EQ(message_, qux_->containing_type());
595
EXPECT_EQ(message2_, foo2_ ->containing_type());
596
EXPECT_EQ(message2_, bar2_ ->containing_type());
597
EXPECT_EQ(message2_, quux2_->containing_type());
600
TEST_F(DescriptorTest, FieldMessageType) {
601
EXPECT_TRUE(foo_->message_type() == NULL);
602
EXPECT_TRUE(bar_->message_type() == NULL);
604
EXPECT_EQ(foreign_, baz_->message_type());
605
EXPECT_EQ(foreign_, qux_->message_type());
608
TEST_F(DescriptorTest, FieldEnumType) {
609
EXPECT_TRUE(foo_->enum_type() == NULL);
610
EXPECT_TRUE(baz_->enum_type() == NULL);
611
EXPECT_TRUE(qux_->enum_type() == NULL);
613
EXPECT_EQ(enum_, bar_->enum_type());
616
// ===================================================================
618
// Test enum descriptors.
619
class EnumDescriptorTest : public testing::Test {
621
virtual void SetUp() {
622
// Build descriptors for the following definitions:
631
// package corge.grault;
637
// TestEnum2 is primarily here to test FindValueByName and friends.
638
// All enums created from the same DescriptorPool share the same lookup
639
// table, so we need to insure that they don't interfere.
642
FileDescriptorProto foo_file;
643
foo_file.set_name("foo.proto");
645
EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum");
646
AddEnumValue(enum_proto, "FOO", 1);
647
AddEnumValue(enum_proto, "BAR", 2);
650
FileDescriptorProto bar_file;
651
bar_file.set_name("bar.proto");
652
bar_file.set_package("corge.grault");
654
EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2");
655
AddEnumValue(enum2_proto, "FOO", 1);
656
AddEnumValue(enum2_proto, "BAZ", 3);
658
// Build the descriptors and get the pointers.
659
foo_file_ = pool_.BuildFile(foo_file);
660
ASSERT_TRUE(foo_file_ != NULL);
662
bar_file_ = pool_.BuildFile(bar_file);
663
ASSERT_TRUE(bar_file_ != NULL);
665
ASSERT_EQ(1, foo_file_->enum_type_count());
666
enum_ = foo_file_->enum_type(0);
668
ASSERT_EQ(2, enum_->value_count());
669
foo_ = enum_->value(0);
670
bar_ = enum_->value(1);
672
ASSERT_EQ(1, bar_file_->enum_type_count());
673
enum2_ = bar_file_->enum_type(0);
675
ASSERT_EQ(2, enum2_->value_count());
676
foo2_ = enum2_->value(0);
677
baz2_ = enum2_->value(1);
680
DescriptorPool pool_;
682
const FileDescriptor* foo_file_;
683
const FileDescriptor* bar_file_;
685
const EnumDescriptor* enum_;
686
const EnumDescriptor* enum2_;
688
const EnumValueDescriptor* foo_;
689
const EnumValueDescriptor* bar_;
691
const EnumValueDescriptor* foo2_;
692
const EnumValueDescriptor* baz2_;
695
TEST_F(EnumDescriptorTest, Name) {
696
EXPECT_EQ("TestEnum", enum_->name());
697
EXPECT_EQ("TestEnum", enum_->full_name());
698
EXPECT_EQ(foo_file_, enum_->file());
700
EXPECT_EQ("TestEnum2", enum2_->name());
701
EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name());
702
EXPECT_EQ(bar_file_, enum2_->file());
705
TEST_F(EnumDescriptorTest, ContainingType) {
706
EXPECT_TRUE(enum_->containing_type() == NULL);
707
EXPECT_TRUE(enum2_->containing_type() == NULL);
710
TEST_F(EnumDescriptorTest, ValuesByIndex) {
711
ASSERT_EQ(2, enum_->value_count());
712
EXPECT_EQ(foo_, enum_->value(0));
713
EXPECT_EQ(bar_, enum_->value(1));
716
TEST_F(EnumDescriptorTest, FindValueByName) {
717
EXPECT_EQ(foo_ , enum_ ->FindValueByName("FOO"));
718
EXPECT_EQ(bar_ , enum_ ->FindValueByName("BAR"));
719
EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO"));
720
EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ"));
722
EXPECT_TRUE(enum_ ->FindValueByName("NO_SUCH_VALUE") == NULL);
723
EXPECT_TRUE(enum_ ->FindValueByName("BAZ" ) == NULL);
724
EXPECT_TRUE(enum2_->FindValueByName("BAR" ) == NULL);
727
TEST_F(EnumDescriptorTest, FindValueByNumber) {
728
EXPECT_EQ(foo_ , enum_ ->FindValueByNumber(1));
729
EXPECT_EQ(bar_ , enum_ ->FindValueByNumber(2));
730
EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
731
EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
733
EXPECT_TRUE(enum_ ->FindValueByNumber(416) == NULL);
734
EXPECT_TRUE(enum_ ->FindValueByNumber(3) == NULL);
735
EXPECT_TRUE(enum2_->FindValueByNumber(2) == NULL);
738
TEST_F(EnumDescriptorTest, ValueName) {
739
EXPECT_EQ("FOO", foo_->name());
740
EXPECT_EQ("BAR", bar_->name());
743
TEST_F(EnumDescriptorTest, ValueFullName) {
744
EXPECT_EQ("FOO", foo_->full_name());
745
EXPECT_EQ("BAR", bar_->full_name());
746
EXPECT_EQ("corge.grault.FOO", foo2_->full_name());
747
EXPECT_EQ("corge.grault.BAZ", baz2_->full_name());
750
TEST_F(EnumDescriptorTest, ValueIndex) {
751
EXPECT_EQ(0, foo_->index());
752
EXPECT_EQ(1, bar_->index());
755
TEST_F(EnumDescriptorTest, ValueNumber) {
756
EXPECT_EQ(1, foo_->number());
757
EXPECT_EQ(2, bar_->number());
760
TEST_F(EnumDescriptorTest, ValueType) {
761
EXPECT_EQ(enum_ , foo_ ->type());
762
EXPECT_EQ(enum_ , bar_ ->type());
763
EXPECT_EQ(enum2_, foo2_->type());
764
EXPECT_EQ(enum2_, baz2_->type());
767
// ===================================================================
769
// Test service descriptors.
770
class ServiceDescriptorTest : public testing::Test {
772
virtual void SetUp() {
773
// Build descriptors for the following messages and service:
775
// message FooRequest {}
776
// message FooResponse {}
777
// message BarRequest {}
778
// message BarResponse {}
779
// message BazRequest {}
780
// message BazResponse {}
782
// service TestService {
783
// rpc Foo(FooRequest) returns (FooResponse);
784
// rpc Bar(BarRequest) returns (BarResponse);
788
// package corge.grault
789
// service TestService2 {
790
// rpc Foo(FooRequest) returns (FooResponse);
791
// rpc Baz(BazRequest) returns (BazResponse);
794
FileDescriptorProto foo_file;
795
foo_file.set_name("foo.proto");
797
AddMessage(&foo_file, "FooRequest");
798
AddMessage(&foo_file, "FooResponse");
799
AddMessage(&foo_file, "BarRequest");
800
AddMessage(&foo_file, "BarResponse");
801
AddMessage(&foo_file, "BazRequest");
802
AddMessage(&foo_file, "BazResponse");
804
ServiceDescriptorProto* service = AddService(&foo_file, "TestService");
805
AddMethod(service, "Foo", "FooRequest", "FooResponse");
806
AddMethod(service, "Bar", "BarRequest", "BarResponse");
808
FileDescriptorProto bar_file;
809
bar_file.set_name("bar.proto");
810
bar_file.set_package("corge.grault");
811
bar_file.add_dependency("foo.proto");
813
ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2");
814
AddMethod(service2, "Foo", "FooRequest", "FooResponse");
815
AddMethod(service2, "Baz", "BazRequest", "BazResponse");
817
// Build the descriptors and get the pointers.
818
foo_file_ = pool_.BuildFile(foo_file);
819
ASSERT_TRUE(foo_file_ != NULL);
821
bar_file_ = pool_.BuildFile(bar_file);
822
ASSERT_TRUE(bar_file_ != NULL);
824
ASSERT_EQ(6, foo_file_->message_type_count());
825
foo_request_ = foo_file_->message_type(0);
826
foo_response_ = foo_file_->message_type(1);
827
bar_request_ = foo_file_->message_type(2);
828
bar_response_ = foo_file_->message_type(3);
829
baz_request_ = foo_file_->message_type(4);
830
baz_response_ = foo_file_->message_type(5);
832
ASSERT_EQ(1, foo_file_->service_count());
833
service_ = foo_file_->service(0);
835
ASSERT_EQ(2, service_->method_count());
836
foo_ = service_->method(0);
837
bar_ = service_->method(1);
839
ASSERT_EQ(1, bar_file_->service_count());
840
service2_ = bar_file_->service(0);
842
ASSERT_EQ(2, service2_->method_count());
843
foo2_ = service2_->method(0);
844
baz2_ = service2_->method(1);
847
DescriptorPool pool_;
849
const FileDescriptor* foo_file_;
850
const FileDescriptor* bar_file_;
852
const Descriptor* foo_request_;
853
const Descriptor* foo_response_;
854
const Descriptor* bar_request_;
855
const Descriptor* bar_response_;
856
const Descriptor* baz_request_;
857
const Descriptor* baz_response_;
859
const ServiceDescriptor* service_;
860
const ServiceDescriptor* service2_;
862
const MethodDescriptor* foo_;
863
const MethodDescriptor* bar_;
865
const MethodDescriptor* foo2_;
866
const MethodDescriptor* baz2_;
869
TEST_F(ServiceDescriptorTest, Name) {
870
EXPECT_EQ("TestService", service_->name());
871
EXPECT_EQ("TestService", service_->full_name());
872
EXPECT_EQ(foo_file_, service_->file());
874
EXPECT_EQ("TestService2", service2_->name());
875
EXPECT_EQ("corge.grault.TestService2", service2_->full_name());
876
EXPECT_EQ(bar_file_, service2_->file());
879
TEST_F(ServiceDescriptorTest, MethodsByIndex) {
880
ASSERT_EQ(2, service_->method_count());
881
EXPECT_EQ(foo_, service_->method(0));
882
EXPECT_EQ(bar_, service_->method(1));
885
TEST_F(ServiceDescriptorTest, FindMethodByName) {
886
EXPECT_EQ(foo_ , service_ ->FindMethodByName("Foo"));
887
EXPECT_EQ(bar_ , service_ ->FindMethodByName("Bar"));
888
EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo"));
889
EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz"));
891
EXPECT_TRUE(service_ ->FindMethodByName("NoSuchMethod") == NULL);
892
EXPECT_TRUE(service_ ->FindMethodByName("Baz" ) == NULL);
893
EXPECT_TRUE(service2_->FindMethodByName("Bar" ) == NULL);
896
TEST_F(ServiceDescriptorTest, MethodName) {
897
EXPECT_EQ("Foo", foo_->name());
898
EXPECT_EQ("Bar", bar_->name());
901
TEST_F(ServiceDescriptorTest, MethodFullName) {
902
EXPECT_EQ("TestService.Foo", foo_->full_name());
903
EXPECT_EQ("TestService.Bar", bar_->full_name());
904
EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name());
905
EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name());
908
TEST_F(ServiceDescriptorTest, MethodIndex) {
909
EXPECT_EQ(0, foo_->index());
910
EXPECT_EQ(1, bar_->index());
913
TEST_F(ServiceDescriptorTest, MethodParent) {
914
EXPECT_EQ(service_, foo_->service());
915
EXPECT_EQ(service_, bar_->service());
918
TEST_F(ServiceDescriptorTest, MethodInputType) {
919
EXPECT_EQ(foo_request_, foo_->input_type());
920
EXPECT_EQ(bar_request_, bar_->input_type());
923
TEST_F(ServiceDescriptorTest, MethodOutputType) {
924
EXPECT_EQ(foo_response_, foo_->output_type());
925
EXPECT_EQ(bar_response_, bar_->output_type());
928
// ===================================================================
930
// Test nested types.
931
class NestedDescriptorTest : public testing::Test {
933
virtual void SetUp() {
934
// Build descriptors for the following definitions:
937
// message TestMessage {
940
// enum Baz { A = 1; }
941
// enum Qux { B = 1; }
945
// package corge.grault;
946
// message TestMessage2 {
949
// enum Qux { A = 1; }
950
// enum Quux { C = 1; }
953
// TestMessage2 is primarily here to test FindNestedTypeByName and friends.
954
// All messages created from the same DescriptorPool share the same lookup
955
// table, so we need to insure that they don't interfere.
957
// We add enum values to the enums in order to test searching for enum
958
// values across a message's scope.
960
FileDescriptorProto foo_file;
961
foo_file.set_name("foo.proto");
963
DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
964
AddNestedMessage(message, "Foo");
965
AddNestedMessage(message, "Bar");
966
EnumDescriptorProto* baz = AddNestedEnum(message, "Baz");
967
AddEnumValue(baz, "A", 1);
968
EnumDescriptorProto* qux = AddNestedEnum(message, "Qux");
969
AddEnumValue(qux, "B", 1);
971
FileDescriptorProto bar_file;
972
bar_file.set_name("bar.proto");
973
bar_file.set_package("corge.grault");
975
DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
976
AddNestedMessage(message2, "Foo");
977
AddNestedMessage(message2, "Baz");
978
EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux");
979
AddEnumValue(qux2, "A", 1);
980
EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux");
981
AddEnumValue(quux2, "C", 1);
983
// Build the descriptors and get the pointers.
984
foo_file_ = pool_.BuildFile(foo_file);
985
ASSERT_TRUE(foo_file_ != NULL);
987
bar_file_ = pool_.BuildFile(bar_file);
988
ASSERT_TRUE(bar_file_ != NULL);
990
ASSERT_EQ(1, foo_file_->message_type_count());
991
message_ = foo_file_->message_type(0);
993
ASSERT_EQ(2, message_->nested_type_count());
994
foo_ = message_->nested_type(0);
995
bar_ = message_->nested_type(1);
997
ASSERT_EQ(2, message_->enum_type_count());
998
baz_ = message_->enum_type(0);
999
qux_ = message_->enum_type(1);
1001
ASSERT_EQ(1, baz_->value_count());
1002
a_ = baz_->value(0);
1003
ASSERT_EQ(1, qux_->value_count());
1004
b_ = qux_->value(0);
1006
ASSERT_EQ(1, bar_file_->message_type_count());
1007
message2_ = bar_file_->message_type(0);
1009
ASSERT_EQ(2, message2_->nested_type_count());
1010
foo2_ = message2_->nested_type(0);
1011
baz2_ = message2_->nested_type(1);
1013
ASSERT_EQ(2, message2_->enum_type_count());
1014
qux2_ = message2_->enum_type(0);
1015
quux2_ = message2_->enum_type(1);
1017
ASSERT_EQ(1, qux2_->value_count());
1018
a2_ = qux2_->value(0);
1019
ASSERT_EQ(1, quux2_->value_count());
1020
c2_ = quux2_->value(0);
1023
DescriptorPool pool_;
1025
const FileDescriptor* foo_file_;
1026
const FileDescriptor* bar_file_;
1028
const Descriptor* message_;
1029
const Descriptor* message2_;
1031
const Descriptor* foo_;
1032
const Descriptor* bar_;
1033
const EnumDescriptor* baz_;
1034
const EnumDescriptor* qux_;
1035
const EnumValueDescriptor* a_;
1036
const EnumValueDescriptor* b_;
1038
const Descriptor* foo2_;
1039
const Descriptor* baz2_;
1040
const EnumDescriptor* qux2_;
1041
const EnumDescriptor* quux2_;
1042
const EnumValueDescriptor* a2_;
1043
const EnumValueDescriptor* c2_;
1046
TEST_F(NestedDescriptorTest, MessageName) {
1047
EXPECT_EQ("Foo", foo_ ->name());
1048
EXPECT_EQ("Bar", bar_ ->name());
1049
EXPECT_EQ("Foo", foo2_->name());
1050
EXPECT_EQ("Baz", baz2_->name());
1052
EXPECT_EQ("TestMessage.Foo", foo_->full_name());
1053
EXPECT_EQ("TestMessage.Bar", bar_->full_name());
1054
EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name());
1055
EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name());
1058
TEST_F(NestedDescriptorTest, MessageContainingType) {
1059
EXPECT_EQ(message_ , foo_ ->containing_type());
1060
EXPECT_EQ(message_ , bar_ ->containing_type());
1061
EXPECT_EQ(message2_, foo2_->containing_type());
1062
EXPECT_EQ(message2_, baz2_->containing_type());
1065
TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
1066
ASSERT_EQ(2, message_->nested_type_count());
1067
EXPECT_EQ(foo_, message_->nested_type(0));
1068
EXPECT_EQ(bar_, message_->nested_type(1));
1071
TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
1072
EXPECT_TRUE(message_->FindFieldByName("Foo") == NULL);
1073
EXPECT_TRUE(message_->FindFieldByName("Qux") == NULL);
1074
EXPECT_TRUE(message_->FindExtensionByName("Foo") == NULL);
1075
EXPECT_TRUE(message_->FindExtensionByName("Qux") == NULL);
1078
TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
1079
EXPECT_EQ(foo_ , message_ ->FindNestedTypeByName("Foo"));
1080
EXPECT_EQ(bar_ , message_ ->FindNestedTypeByName("Bar"));
1081
EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo"));
1082
EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz"));
1084
EXPECT_TRUE(message_ ->FindNestedTypeByName("NoSuchType") == NULL);
1085
EXPECT_TRUE(message_ ->FindNestedTypeByName("Baz" ) == NULL);
1086
EXPECT_TRUE(message2_->FindNestedTypeByName("Bar" ) == NULL);
1088
EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == NULL);
1091
TEST_F(NestedDescriptorTest, EnumName) {
1092
EXPECT_EQ("Baz" , baz_ ->name());
1093
EXPECT_EQ("Qux" , qux_ ->name());
1094
EXPECT_EQ("Qux" , qux2_->name());
1095
EXPECT_EQ("Quux", quux2_->name());
1097
EXPECT_EQ("TestMessage.Baz", baz_->full_name());
1098
EXPECT_EQ("TestMessage.Qux", qux_->full_name());
1099
EXPECT_EQ("corge.grault.TestMessage2.Qux" , qux2_ ->full_name());
1100
EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name());
1103
TEST_F(NestedDescriptorTest, EnumContainingType) {
1104
EXPECT_EQ(message_ , baz_ ->containing_type());
1105
EXPECT_EQ(message_ , qux_ ->containing_type());
1106
EXPECT_EQ(message2_, qux2_ ->containing_type());
1107
EXPECT_EQ(message2_, quux2_->containing_type());
1110
TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
1111
ASSERT_EQ(2, message_->nested_type_count());
1112
EXPECT_EQ(foo_, message_->nested_type(0));
1113
EXPECT_EQ(bar_, message_->nested_type(1));
1116
TEST_F(NestedDescriptorTest, FindEnumTypeByName) {
1117
EXPECT_EQ(baz_ , message_ ->FindEnumTypeByName("Baz" ));
1118
EXPECT_EQ(qux_ , message_ ->FindEnumTypeByName("Qux" ));
1119
EXPECT_EQ(qux2_ , message2_->FindEnumTypeByName("Qux" ));
1120
EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux"));
1122
EXPECT_TRUE(message_ ->FindEnumTypeByName("NoSuchType") == NULL);
1123
EXPECT_TRUE(message_ ->FindEnumTypeByName("Quux" ) == NULL);
1124
EXPECT_TRUE(message2_->FindEnumTypeByName("Baz" ) == NULL);
1126
EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == NULL);
1129
TEST_F(NestedDescriptorTest, FindEnumValueByName) {
1130
EXPECT_EQ(a_ , message_ ->FindEnumValueByName("A"));
1131
EXPECT_EQ(b_ , message_ ->FindEnumValueByName("B"));
1132
EXPECT_EQ(a2_, message2_->FindEnumValueByName("A"));
1133
EXPECT_EQ(c2_, message2_->FindEnumValueByName("C"));
1135
EXPECT_TRUE(message_ ->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
1136
EXPECT_TRUE(message_ ->FindEnumValueByName("C" ) == NULL);
1137
EXPECT_TRUE(message2_->FindEnumValueByName("B" ) == NULL);
1139
EXPECT_TRUE(message_->FindEnumValueByName("Foo") == NULL);
1142
// ===================================================================
1145
class ExtensionDescriptorTest : public testing::Test {
1147
virtual void SetUp() {
1148
// Build descriptors for the following definitions:
1154
// extensions 10 to 19;
1155
// extensions 30 to 39;
1157
// extends Foo with optional int32 foo_int32 = 10;
1158
// extends Foo with repeated TestEnum foo_enum = 19;
1160
// extends Foo with optional Qux foo_message = 30;
1161
// // (using Qux as the group type)
1162
// extends Foo with repeated group foo_group = 39;
1165
FileDescriptorProto foo_file;
1166
foo_file.set_name("foo.proto");
1168
AddEmptyEnum(&foo_file, "Baz");
1169
AddMessage(&foo_file, "Qux");
1171
DescriptorProto* foo = AddMessage(&foo_file, "Foo");
1172
AddExtensionRange(foo, 10, 20);
1173
AddExtensionRange(foo, 30, 40);
1175
AddExtension(&foo_file, "Foo", "foo_int32", 10,
1176
FieldDescriptorProto::LABEL_OPTIONAL,
1177
FieldDescriptorProto::TYPE_INT32);
1178
AddExtension(&foo_file, "Foo", "foo_enum", 19,
1179
FieldDescriptorProto::LABEL_REPEATED,
1180
FieldDescriptorProto::TYPE_ENUM)
1181
->set_type_name("Baz");
1183
DescriptorProto* bar = AddMessage(&foo_file, "Bar");
1184
AddNestedExtension(bar, "Foo", "foo_message", 30,
1185
FieldDescriptorProto::LABEL_OPTIONAL,
1186
FieldDescriptorProto::TYPE_MESSAGE)
1187
->set_type_name("Qux");
1188
AddNestedExtension(bar, "Foo", "foo_group", 39,
1189
FieldDescriptorProto::LABEL_REPEATED,
1190
FieldDescriptorProto::TYPE_GROUP)
1191
->set_type_name("Qux");
1193
// Build the descriptors and get the pointers.
1194
foo_file_ = pool_.BuildFile(foo_file);
1195
ASSERT_TRUE(foo_file_ != NULL);
1197
ASSERT_EQ(1, foo_file_->enum_type_count());
1198
baz_ = foo_file_->enum_type(0);
1200
ASSERT_EQ(3, foo_file_->message_type_count());
1201
qux_ = foo_file_->message_type(0);
1202
foo_ = foo_file_->message_type(1);
1203
bar_ = foo_file_->message_type(2);
1206
DescriptorPool pool_;
1208
const FileDescriptor* foo_file_;
1210
const Descriptor* foo_;
1211
const Descriptor* bar_;
1212
const EnumDescriptor* baz_;
1213
const Descriptor* qux_;
1216
TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
1217
EXPECT_EQ(0, bar_->extension_range_count());
1218
ASSERT_EQ(2, foo_->extension_range_count());
1220
EXPECT_EQ(10, foo_->extension_range(0)->start);
1221
EXPECT_EQ(30, foo_->extension_range(1)->start);
1223
EXPECT_EQ(20, foo_->extension_range(0)->end);
1224
EXPECT_EQ(40, foo_->extension_range(1)->end);
1227
TEST_F(ExtensionDescriptorTest, Extensions) {
1228
EXPECT_EQ(0, foo_->extension_count());
1229
ASSERT_EQ(2, foo_file_->extension_count());
1230
ASSERT_EQ(2, bar_->extension_count());
1232
EXPECT_TRUE(foo_file_->extension(0)->is_extension());
1233
EXPECT_TRUE(foo_file_->extension(1)->is_extension());
1234
EXPECT_TRUE(bar_->extension(0)->is_extension());
1235
EXPECT_TRUE(bar_->extension(1)->is_extension());
1237
EXPECT_EQ("foo_int32" , foo_file_->extension(0)->name());
1238
EXPECT_EQ("foo_enum" , foo_file_->extension(1)->name());
1239
EXPECT_EQ("foo_message", bar_->extension(0)->name());
1240
EXPECT_EQ("foo_group" , bar_->extension(1)->name());
1242
EXPECT_EQ(10, foo_file_->extension(0)->number());
1243
EXPECT_EQ(19, foo_file_->extension(1)->number());
1244
EXPECT_EQ(30, bar_->extension(0)->number());
1245
EXPECT_EQ(39, bar_->extension(1)->number());
1247
EXPECT_EQ(FieldDescriptor::TYPE_INT32 , foo_file_->extension(0)->type());
1248
EXPECT_EQ(FieldDescriptor::TYPE_ENUM , foo_file_->extension(1)->type());
1249
EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type());
1250
EXPECT_EQ(FieldDescriptor::TYPE_GROUP , bar_->extension(1)->type());
1252
EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
1253
EXPECT_EQ(qux_, bar_->extension(0)->message_type());
1254
EXPECT_EQ(qux_, bar_->extension(1)->message_type());
1256
EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label());
1257
EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label());
1258
EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label());
1259
EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label());
1261
EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
1262
EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
1263
EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
1264
EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
1266
EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == NULL);
1267
EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == NULL);
1268
EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
1269
EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
1272
TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
1273
EXPECT_FALSE(foo_->IsExtensionNumber( 9));
1274
EXPECT_TRUE (foo_->IsExtensionNumber(10));
1275
EXPECT_TRUE (foo_->IsExtensionNumber(19));
1276
EXPECT_FALSE(foo_->IsExtensionNumber(20));
1277
EXPECT_FALSE(foo_->IsExtensionNumber(29));
1278
EXPECT_TRUE (foo_->IsExtensionNumber(30));
1279
EXPECT_TRUE (foo_->IsExtensionNumber(39));
1280
EXPECT_FALSE(foo_->IsExtensionNumber(40));
1283
TEST_F(ExtensionDescriptorTest, FindExtensionByName) {
1284
// Note that FileDescriptor::FindExtensionByName() is tested by
1285
// FileDescriptorTest.
1286
ASSERT_EQ(2, bar_->extension_count());
1288
EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message"));
1289
EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group" ));
1291
EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL);
1292
EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL);
1293
EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL);
1296
// ===================================================================
1298
class MiscTest : public testing::Test {
1300
// Function which makes a field of the given type just to find out what its
1302
FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
1303
FileDescriptorProto file_proto;
1304
file_proto.set_name("foo.proto");
1305
AddEmptyEnum(&file_proto, "DummyEnum");
1307
DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
1308
FieldDescriptorProto* field =
1309
AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
1310
static_cast<FieldDescriptorProto::Type>(type));
1312
if (type == FieldDescriptor::TYPE_MESSAGE ||
1313
type == FieldDescriptor::TYPE_GROUP) {
1314
field->set_type_name("TestMessage");
1315
} else if (type == FieldDescriptor::TYPE_ENUM) {
1316
field->set_type_name("DummyEnum");
1319
// Build the descriptors and get the pointers.
1320
DescriptorPool pool;
1321
const FileDescriptor* file = pool.BuildFile(file_proto);
1324
file->message_type_count() == 1 &&
1325
file->message_type(0)->field_count() == 1) {
1326
return file->message_type(0)->field(0)->cpp_type();
1328
return static_cast<FieldDescriptor::CppType>(0);
1333
TEST_F(MiscTest, CppTypes) {
1334
// Test that CPP types are assigned correctly.
1336
typedef FieldDescriptor FD; // avoid ugly line wrapping
1338
EXPECT_EQ(FD::CPPTYPE_DOUBLE , GetCppTypeForFieldType(FD::TYPE_DOUBLE ));
1339
EXPECT_EQ(FD::CPPTYPE_FLOAT , GetCppTypeForFieldType(FD::TYPE_FLOAT ));
1340
EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_INT64 ));
1341
EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_UINT64 ));
1342
EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_INT32 ));
1343
EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_FIXED64 ));
1344
EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_FIXED32 ));
1345
EXPECT_EQ(FD::CPPTYPE_BOOL , GetCppTypeForFieldType(FD::TYPE_BOOL ));
1346
EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_STRING ));
1347
EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP ));
1348
EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE ));
1349
EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_BYTES ));
1350
EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_UINT32 ));
1351
EXPECT_EQ(FD::CPPTYPE_ENUM , GetCppTypeForFieldType(FD::TYPE_ENUM ));
1352
EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SFIXED32));
1353
EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SFIXED64));
1354
EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SINT32 ));
1355
EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SINT64 ));
1358
TEST_F(MiscTest, DefaultValues) {
1359
// Test that setting default values works.
1360
FileDescriptorProto file_proto;
1361
file_proto.set_name("foo.proto");
1363
EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum");
1364
AddEnumValue(enum_type_proto, "A", 1);
1365
AddEnumValue(enum_type_proto, "B", 2);
1367
DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
1369
typedef FieldDescriptorProto FD; // avoid ugly line wrapping
1370
const FD::Label label = FD::LABEL_OPTIONAL;
1372
// Create fields of every CPP type with default values.
1373
AddField(message_proto, "int32" , 1, label, FD::TYPE_INT32 )
1374
->set_default_value("-1");
1375
AddField(message_proto, "int64" , 2, label, FD::TYPE_INT64 )
1376
->set_default_value("-1000000000000");
1377
AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32)
1378
->set_default_value("42");
1379
AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64)
1380
->set_default_value("2000000000000");
1381
AddField(message_proto, "float" , 5, label, FD::TYPE_FLOAT )
1382
->set_default_value("4.5");
1383
AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE)
1384
->set_default_value("10e100");
1385
AddField(message_proto, "bool" , 7, label, FD::TYPE_BOOL )
1386
->set_default_value("true");
1387
AddField(message_proto, "string", 8, label, FD::TYPE_STRING)
1388
->set_default_value("hello");
1389
AddField(message_proto, "data" , 9, label, FD::TYPE_BYTES )
1390
->set_default_value("\\001\\002\\003");
1392
FieldDescriptorProto* enum_field =
1393
AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM);
1394
enum_field->set_type_name("DummyEnum");
1395
enum_field->set_default_value("B");
1397
// Strings are allowed to have empty defaults. (At one point, due to
1398
// a bug, empty defaults for strings were rejected. Oops.)
1399
AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING)
1400
->set_default_value("");
1402
// Add a second set of fields with implicit defalut values.
1403
AddField(message_proto, "implicit_int32" , 21, label, FD::TYPE_INT32 );
1404
AddField(message_proto, "implicit_int64" , 22, label, FD::TYPE_INT64 );
1405
AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32);
1406
AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64);
1407
AddField(message_proto, "implicit_float" , 25, label, FD::TYPE_FLOAT );
1408
AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE);
1409
AddField(message_proto, "implicit_bool" , 27, label, FD::TYPE_BOOL );
1410
AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING);
1411
AddField(message_proto, "implicit_data" , 29, label, FD::TYPE_BYTES );
1412
AddField(message_proto, "implicit_enum" , 30, label, FD::TYPE_ENUM)
1413
->set_type_name("DummyEnum");
1416
DescriptorPool pool;
1417
const FileDescriptor* file = pool.BuildFile(file_proto);
1418
ASSERT_TRUE(file != NULL);
1420
ASSERT_EQ(1, file->enum_type_count());
1421
const EnumDescriptor* enum_type = file->enum_type(0);
1422
ASSERT_EQ(2, enum_type->value_count());
1423
const EnumValueDescriptor* enum_value_a = enum_type->value(0);
1424
const EnumValueDescriptor* enum_value_b = enum_type->value(1);
1426
ASSERT_EQ(1, file->message_type_count());
1427
const Descriptor* message = file->message_type(0);
1429
ASSERT_EQ(21, message->field_count());
1431
// Check the default values.
1432
ASSERT_TRUE(message->field(0)->has_default_value());
1433
ASSERT_TRUE(message->field(1)->has_default_value());
1434
ASSERT_TRUE(message->field(2)->has_default_value());
1435
ASSERT_TRUE(message->field(3)->has_default_value());
1436
ASSERT_TRUE(message->field(4)->has_default_value());
1437
ASSERT_TRUE(message->field(5)->has_default_value());
1438
ASSERT_TRUE(message->field(6)->has_default_value());
1439
ASSERT_TRUE(message->field(7)->has_default_value());
1440
ASSERT_TRUE(message->field(8)->has_default_value());
1441
ASSERT_TRUE(message->field(9)->has_default_value());
1442
ASSERT_TRUE(message->field(10)->has_default_value());
1444
EXPECT_EQ(-1 , message->field(0)->default_value_int32 ());
1445
EXPECT_EQ(-GOOGLE_ULONGLONG(1000000000000),
1446
message->field(1)->default_value_int64 ());
1447
EXPECT_EQ(42 , message->field(2)->default_value_uint32());
1448
EXPECT_EQ(GOOGLE_ULONGLONG(2000000000000),
1449
message->field(3)->default_value_uint64());
1450
EXPECT_EQ(4.5 , message->field(4)->default_value_float ());
1451
EXPECT_EQ(10e100 , message->field(5)->default_value_double());
1452
EXPECT_EQ(true , message->field(6)->default_value_bool ());
1453
EXPECT_EQ("hello" , message->field(7)->default_value_string());
1454
EXPECT_EQ("\001\002\003" , message->field(8)->default_value_string());
1455
EXPECT_EQ(enum_value_b , message->field(9)->default_value_enum ());
1456
EXPECT_EQ("" , message->field(10)->default_value_string());
1458
ASSERT_FALSE(message->field(11)->has_default_value());
1459
ASSERT_FALSE(message->field(12)->has_default_value());
1460
ASSERT_FALSE(message->field(13)->has_default_value());
1461
ASSERT_FALSE(message->field(14)->has_default_value());
1462
ASSERT_FALSE(message->field(15)->has_default_value());
1463
ASSERT_FALSE(message->field(16)->has_default_value());
1464
ASSERT_FALSE(message->field(17)->has_default_value());
1465
ASSERT_FALSE(message->field(18)->has_default_value());
1466
ASSERT_FALSE(message->field(19)->has_default_value());
1467
ASSERT_FALSE(message->field(20)->has_default_value());
1469
EXPECT_EQ(0 , message->field(11)->default_value_int32 ());
1470
EXPECT_EQ(0 , message->field(12)->default_value_int64 ());
1471
EXPECT_EQ(0 , message->field(13)->default_value_uint32());
1472
EXPECT_EQ(0 , message->field(14)->default_value_uint64());
1473
EXPECT_EQ(0.0f , message->field(15)->default_value_float ());
1474
EXPECT_EQ(0.0 , message->field(16)->default_value_double());
1475
EXPECT_EQ(false, message->field(17)->default_value_bool ());
1476
EXPECT_EQ("" , message->field(18)->default_value_string());
1477
EXPECT_EQ("" , message->field(19)->default_value_string());
1478
EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
1481
TEST_F(MiscTest, FieldOptions) {
1482
// Try setting field options.
1484
FileDescriptorProto file_proto;
1485
file_proto.set_name("foo.proto");
1487
DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
1488
AddField(message_proto, "foo", 1,
1489
FieldDescriptorProto::LABEL_OPTIONAL,
1490
FieldDescriptorProto::TYPE_INT32);
1491
FieldDescriptorProto* bar_proto =
1492
AddField(message_proto, "bar", 2,
1493
FieldDescriptorProto::LABEL_OPTIONAL,
1494
FieldDescriptorProto::TYPE_INT32);
1496
FieldOptions* options = bar_proto->mutable_options();
1497
options->set_ctype(FieldOptions::CORD);
1499
// Build the descriptors and get the pointers.
1500
DescriptorPool pool;
1501
const FileDescriptor* file = pool.BuildFile(file_proto);
1502
ASSERT_TRUE(file != NULL);
1504
ASSERT_EQ(1, file->message_type_count());
1505
const Descriptor* message = file->message_type(0);
1507
ASSERT_EQ(2, message->field_count());
1508
const FieldDescriptor* foo = message->field(0);
1509
const FieldDescriptor* bar = message->field(1);
1511
// "foo" had no options set, so it should return the default options.
1512
EXPECT_EQ(&FieldOptions::default_instance(), &foo->options());
1514
// "bar" had options set.
1515
EXPECT_NE(&FieldOptions::default_instance(), options);
1516
EXPECT_TRUE(bar->options().has_ctype());
1517
EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
1520
// ===================================================================
1522
// The tests below trigger every unique call to AddError() in descriptor.cc,
1523
// in the order in which they appear in that file. I'm using TextFormat here
1524
// to specify the input descriptors because building them using code would
1527
class MockErrorCollector : public DescriptorPool::ErrorCollector {
1529
MockErrorCollector() {}
1530
~MockErrorCollector() {}
1534
// implements ErrorCollector ---------------------------------------
1535
void AddError(const string& filename,
1536
const string& element_name, const Message* descriptor,
1537
ErrorLocation location, const string& message) {
1538
const char* location_name = NULL;
1540
case NAME : location_name = "NAME" ; break;
1541
case NUMBER : location_name = "NUMBER" ; break;
1542
case TYPE : location_name = "TYPE" ; break;
1543
case EXTENDEE : location_name = "EXTENDEE" ; break;
1544
case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
1545
case INPUT_TYPE : location_name = "INPUT_TYPE" ; break;
1546
case OUTPUT_TYPE : location_name = "OUTPUT_TYPE" ; break;
1547
case OTHER : location_name = "OTHER" ; break;
1550
strings::SubstituteAndAppend(
1551
&text_, "$0: $1: $2: $3\n",
1552
filename, element_name, location_name, message);
1556
class ValidationErrorTest : public testing::Test {
1558
// Parse file_text as a FileDescriptorProto in text format and add it
1559
// to the DescriptorPool. Expect no errors.
1560
void BuildFile(const string& file_text) {
1561
FileDescriptorProto file_proto;
1562
ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
1563
ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
1566
// Parse file_text as a FileDescriptorProto in text format and add it
1567
// to the DescriptorPool. Expect errors to be produced which match the
1568
// given error text.
1569
void BuildFileWithErrors(const string& file_text,
1570
const string& expected_errors) {
1571
FileDescriptorProto file_proto;
1572
ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
1574
MockErrorCollector error_collector;
1576
pool_.BuildFileCollectingErrors(file_proto, &error_collector) == NULL);
1577
EXPECT_EQ(expected_errors, error_collector.text_);
1580
DescriptorPool pool_;
1583
TEST_F(ValidationErrorTest, AlreadyDefined) {
1584
BuildFileWithErrors(
1585
"name: \"foo.proto\" "
1586
"message_type { name: \"Foo\" }"
1587
"message_type { name: \"Foo\" }",
1589
"foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
1592
TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
1593
BuildFileWithErrors(
1594
"name: \"foo.proto\" "
1595
"package: \"foo.bar\" "
1596
"message_type { name: \"Foo\" }"
1597
"message_type { name: \"Foo\" }",
1599
"foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
1603
TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
1605
"name: \"foo.proto\" "
1606
"message_type { name: \"Foo\" }");
1608
BuildFileWithErrors(
1609
"name: \"bar.proto\" "
1610
"message_type { name: \"Foo\" }",
1612
"bar.proto: Foo: NAME: \"Foo\" is already defined in file "
1613
"\"foo.proto\".\n");
1616
TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
1618
"name: \"foo.proto\" "
1619
"message_type { name: \"foo\" }");
1620
BuildFileWithErrors(
1621
"name: \"bar.proto\" "
1622
"package: \"foo.bar\"",
1624
"bar.proto: foo: NAME: \"foo\" is already defined (as something other "
1625
"than a package) in file \"foo.proto\".\n");
1628
TEST_F(ValidationErrorTest, MissingName) {
1629
BuildFileWithErrors(
1630
"name: \"foo.proto\" "
1633
"foo.proto: : NAME: Missing name.\n");
1636
TEST_F(ValidationErrorTest, InvalidName) {
1637
BuildFileWithErrors(
1638
"name: \"foo.proto\" "
1639
"message_type { name: \"$\" }",
1641
"foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
1644
TEST_F(ValidationErrorTest, InvalidPackageName) {
1645
BuildFileWithErrors(
1646
"name: \"foo.proto\" "
1647
"package: \"foo.$\"",
1649
"foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
1652
TEST_F(ValidationErrorTest, MissingFileName) {
1653
BuildFileWithErrors(
1656
": : OTHER: Missing field: FileDescriptorProto.name.\n");
1659
TEST_F(ValidationErrorTest, DupeDependency) {
1660
BuildFile("name: \"foo.proto\"");
1661
BuildFileWithErrors(
1662
"name: \"bar.proto\" "
1663
"dependency: \"foo.proto\" "
1664
"dependency: \"foo.proto\" ",
1666
"bar.proto: bar.proto: OTHER: Import \"foo.proto\" was listed twice.\n");
1669
TEST_F(ValidationErrorTest, UnknownDependency) {
1670
BuildFileWithErrors(
1671
"name: \"bar.proto\" "
1672
"dependency: \"foo.proto\" ",
1674
"bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n");
1677
TEST_F(ValidationErrorTest, DupeFile) {
1679
"name: \"foo.proto\" "
1680
"message_type { name: \"Foo\" }");
1681
// Note: We should *not* get redundant errors about "Foo" already being
1683
BuildFileWithErrors(
1684
"name: \"foo.proto\" "
1685
"message_type { name: \"Foo\" }",
1687
"foo.proto: foo.proto: OTHER: A file with this name is already in the "
1691
TEST_F(ValidationErrorTest, FieldInExtensionRange) {
1692
BuildFileWithErrors(
1693
"name: \"foo.proto\" "
1696
" field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1697
" field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1698
" field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1699
" field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1700
" extension_range { start: 10 end: 20 }"
1703
"foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
1705
"foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
1709
TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
1710
BuildFileWithErrors(
1711
"name: \"foo.proto\" "
1714
" extension_range { start: 10 end: 20 }"
1715
" extension_range { start: 20 end: 30 }"
1716
" extension_range { start: 19 end: 21 }"
1719
"foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
1720
"already-defined range 10 to 19.\n"
1721
"foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
1722
"already-defined range 20 to 29.\n");
1725
TEST_F(ValidationErrorTest, InvalidDefaults) {
1726
BuildFileWithErrors(
1727
"name: \"foo.proto\" "
1732
" field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
1733
" default_value: \"abc\" }"
1735
// Empty default value.
1736
" field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
1737
" default_value: \"\" }"
1740
" field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
1741
" default_value: \"abc\" }"
1743
// Messages can't have defaults.
1744
" field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: TYPE_MESSAGE"
1745
" default_value: \"abc\" type_name: \"Foo\" }"
1747
// Same thing, but we don't know that this field has message type until
1748
// we look up the type name.
1749
" field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
1750
" default_value: \"abc\" type_name: \"Foo\" }"
1753
"foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n"
1754
"foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value.\n"
1755
"foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
1757
"foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
1758
"foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
1762
TEST_F(ValidationErrorTest, NegativeFieldNumber) {
1763
BuildFileWithErrors(
1764
"name: \"foo.proto\" "
1767
" field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1770
"foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
1773
TEST_F(ValidationErrorTest, HugeFieldNumber) {
1774
BuildFileWithErrors(
1775
"name: \"foo.proto\" "
1778
" field { name: \"foo\" number: 0x70000000 "
1779
" label:LABEL_OPTIONAL type:TYPE_INT32 }"
1782
"foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
1786
TEST_F(ValidationErrorTest, ReservedFieldNumber) {
1787
BuildFileWithErrors(
1788
"name: \"foo.proto\" "
1791
" field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1792
" field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1793
" field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1794
" field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1797
"foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
1798
"reserved for the protocol buffer library implementation.\n"
1799
"foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
1800
"reserved for the protocol buffer library implementation.\n");
1803
TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
1804
BuildFileWithErrors(
1805
"name: \"foo.proto\" "
1808
" extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
1809
" type_name: \"Foo\" }"
1812
"foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
1813
"extension field.\n");
1816
TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
1817
BuildFileWithErrors(
1818
"name: \"foo.proto\" "
1821
" extension_range { start: 1 end: 2 }"
1825
" field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
1826
" type_name: \"Foo\" extendee: \"Bar\" }"
1829
"foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
1830
"non-extension field.\n");
1833
TEST_F(ValidationErrorTest, FieldNumberConflict) {
1834
BuildFileWithErrors(
1835
"name: \"foo.proto\" "
1838
" field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1839
" field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1842
"foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
1843
"\"Foo\" by field \"foo\".\n");
1846
TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
1847
BuildFileWithErrors(
1848
"name: \"foo.proto\" "
1850
" name: \"MessageSet\""
1851
" options { message_set_wire_format: true }"
1852
" extension_range { start: 4 end: 5 }"
1856
" extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
1857
" extendee: \"MessageSet\" }"
1860
"foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
1864
TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
1865
BuildFileWithErrors(
1866
"name: \"foo.proto\" "
1868
" name: \"MessageSet\""
1869
" options { message_set_wire_format: true }"
1870
" extension_range { start: 4 end: 5 }"
1874
" extension { name:\"foo\" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE"
1875
" type_name: \"Foo\" extendee: \"MessageSet\" }"
1878
"foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
1882
TEST_F(ValidationErrorTest, FieldInMessageSet) {
1883
BuildFileWithErrors(
1884
"name: \"foo.proto\" "
1887
" options { message_set_wire_format: true }"
1888
" field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
1891
"foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
1895
TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
1896
BuildFileWithErrors(
1897
"name: \"foo.proto\" "
1900
" extension_range { start: -10 end: -1 }"
1903
"foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
1906
TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
1907
BuildFileWithErrors(
1908
"name: \"foo.proto\" "
1911
" extension_range { start: 1 end: 0x70000000 }"
1914
"foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
1918
TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
1919
BuildFileWithErrors(
1920
"name: \"foo.proto\" "
1923
" extension_range { start: 10 end: 10 }"
1924
" extension_range { start: 10 end: 5 }"
1927
"foo.proto: Foo: NUMBER: Extension range end number must be greater than "
1929
"foo.proto: Foo: NUMBER: Extension range end number must be greater than "
1933
TEST_F(ValidationErrorTest, EmptyEnum) {
1934
BuildFileWithErrors(
1935
"name: \"foo.proto\" "
1936
"enum_type { name: \"Foo\" }"
1937
// Also use the empty enum in a message to make sure there are no crashes
1938
// during validation (possible if the code attempts to derive a default
1939
// value for the field).
1942
" field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type_name:\"Foo\" }"
1943
" field { name: \"bar\" number: 2 label:LABEL_OPTIONAL type_name:\"Foo\" "
1944
" default_value: \"NO_SUCH_VALUE\" }"
1947
"foo.proto: Foo: NAME: Enums must contain at least one value.\n"
1948
"foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
1949
"\"NO_SUCH_VALUE\".\n");
1952
TEST_F(ValidationErrorTest, UndefinedExtendee) {
1953
BuildFileWithErrors(
1954
"name: \"foo.proto\" "
1957
" extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
1958
" extendee: \"Bar\" }"
1961
"foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
1964
TEST_F(ValidationErrorTest, NonMessageExtendee) {
1965
BuildFileWithErrors(
1966
"name: \"foo.proto\" "
1967
"enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
1970
" extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
1971
" extendee: \"Bar\" }"
1974
"foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
1977
TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
1978
BuildFileWithErrors(
1979
"name: \"foo.proto\" "
1985
" extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
1986
" extendee: \"Bar\" }"
1989
"foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
1993
TEST_F(ValidationErrorTest, UndefinedFieldType) {
1994
BuildFileWithErrors(
1995
"name: \"foo.proto\" "
1998
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
2001
"foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
2004
TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
2006
"name: \"bar.proto\" "
2007
"message_type { name: \"Bar\" } ");
2009
BuildFileWithErrors(
2010
"name: \"foo.proto\" "
2013
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
2015
"foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
2016
"which is not imported by \"foo.proto\". To use it here, please add the "
2017
"necessary import.\n");
2020
TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
2021
// The following should produce an error that Bar.Baz is not defined:
2022
// message Bar { message Baz {} }
2025
// // Placing "message Baz{}" here, or removing Foo.Bar altogether,
2026
// // would fix the error.
2028
// optional Bar.Baz baz = 1;
2030
// An one point the lookup code incorrectly did not produce an error in this
2031
// case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first,
2032
// fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually
2033
// refer to the inner Bar, not the outer one.
2034
BuildFileWithErrors(
2035
"name: \"foo.proto\" "
2038
" nested_type { name: \"Baz\" }"
2042
" nested_type { name: \"Bar\" }"
2043
" field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
2044
" type_name:\"Bar.Baz\" }"
2047
"foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n");
2050
TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
2051
// Imagine we have the following:
2057
// import "foo.proto";
2061
// import "bar.proto"
2062
// message Baz { optional bar.Bar qux = 1; }
2064
// When validating baz.proto, we will look up "bar.Bar". As part of this
2065
// lookup, we first lookup "bar" then try to find "Bar" within it. "bar"
2066
// should resolve to "foo.bar". Note, though, that "foo.bar" was originally
2067
// defined in foo.proto, which is not a direct dependency of baz.proto. The
2068
// implementation of FindSymbol() normally only returns symbols in direct
2069
// dependencies, not indirect ones. This test insures that this does not
2070
// prevent it from finding "foo.bar".
2073
"name: \"foo.proto\" "
2074
"package: \"foo.bar\" ");
2076
"name: \"bar.proto\" "
2077
"package: \"foo.bar\" "
2078
"dependency: \"foo.proto\" "
2079
"message_type { name: \"Bar\" }");
2081
"name: \"baz.proto\" "
2083
"dependency: \"bar.proto\" "
2086
" field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
2087
" type_name:\"bar.Bar\" }"
2091
TEST_F(ValidationErrorTest, FieldTypeNotAType) {
2092
BuildFileWithErrors(
2093
"name: \"foo.proto\" "
2096
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"bar\" }"
2097
" field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
2100
"foo.proto: Foo.foo: TYPE: \"bar\" is not a type.\n");
2103
TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
2104
BuildFileWithErrors(
2105
"name: \"foo.proto\" "
2106
"message_type { name: \"Bar\" } "
2109
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
2110
" type_name:\"Bar\" }"
2113
"foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
2116
TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
2117
BuildFileWithErrors(
2118
"name: \"foo.proto\" "
2119
"enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
2122
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
2123
" type_name:\"Bar\" }"
2126
"foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
2129
TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
2130
BuildFileWithErrors(
2131
"name: \"foo.proto\" "
2132
"enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
2135
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
2136
" default_value:\"NO_SUCH_VALUE\" }"
2139
"foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
2140
"\"NO_SUCH_VALUE\".\n");
2143
TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
2144
BuildFileWithErrors(
2145
"name: \"foo.proto\" "
2148
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
2149
" type_name:\"Foo\" }"
2152
"foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
2155
TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
2156
BuildFileWithErrors(
2157
"name: \"foo.proto\" "
2160
" field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
2163
"foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
2167
TEST_F(ValidationErrorTest, InputTypeNotDefined) {
2168
BuildFileWithErrors(
2169
"name: \"foo.proto\" "
2170
"message_type { name: \"Foo\" } "
2172
" name: \"TestService\""
2173
" method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
2176
"foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n");
2179
TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
2180
BuildFileWithErrors(
2181
"name: \"foo.proto\" "
2182
"message_type { name: \"Foo\" } "
2183
"enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
2185
" name: \"TestService\""
2186
" method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
2189
"foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n");
2192
TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
2193
BuildFileWithErrors(
2194
"name: \"foo.proto\" "
2195
"message_type { name: \"Foo\" } "
2197
" name: \"TestService\""
2198
" method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
2201
"foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n");
2204
TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
2205
BuildFileWithErrors(
2206
"name: \"foo.proto\" "
2207
"message_type { name: \"Foo\" } "
2208
"enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
2210
" name: \"TestService\""
2211
" method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
2214
"foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n");
2217
TEST_F(ValidationErrorTest, RollbackAfterError) {
2218
// Build a file which contains every kind of construct but references an
2219
// undefined type. All these constructs will be added to the symbol table
2220
// before the undefined type error is noticed. The DescriptorPool will then
2221
// have to roll everything back.
2222
BuildFileWithErrors(
2223
"name: \"foo.proto\" "
2225
" name: \"TestMessage\""
2226
" field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
2229
" name: \"TestEnum\""
2230
" value { name:\"BAR\" number:1 }"
2233
" name: \"TestService\""
2236
" input_type: \"NoSuchType\"" // error
2237
" output_type: \"TestMessage\""
2241
"foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n");
2243
// Make sure that if we build the same file again with the error fixed,
2244
// it works. If the above rollback was incomplete, then some symbols will
2245
// be left defined, and this second attempt will fail since it tries to
2246
// re-define the same symbols.
2248
"name: \"foo.proto\" "
2250
" name: \"TestMessage\""
2251
" field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
2254
" name: \"TestEnum\""
2255
" value { name:\"BAR\" number:1 }"
2258
" name: \"TestService\""
2259
" method { name:\"Baz\""
2260
" input_type:\"TestMessage\""
2261
" output_type:\"TestMessage\" }"
2265
TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
2266
// Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is
2269
FileDescriptorProto file_proto;
2270
ASSERT_TRUE(TextFormat::ParseFromString(
2271
"name: \"foo.proto\" "
2272
"message_type { name: \"Foo\" } "
2273
"message_type { name: \"Foo\" } ",
2276
vector<string> errors;
2279
ScopedMemoryLog log;
2280
EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL);
2281
errors = log.GetMessages(ERROR);
2284
ASSERT_EQ(2, errors.size());
2286
EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]);
2287
EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]);
2290
// ===================================================================
2291
// DescriptorDatabase
2293
static void AddToDatabase(SimpleDescriptorDatabase* database,
2294
const char* file_text) {
2295
FileDescriptorProto file_proto;
2296
EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
2297
database->Add(file_proto);
2300
class DatabaseBackedPoolTest : public testing::Test {
2302
DatabaseBackedPoolTest() {}
2304
SimpleDescriptorDatabase database_;
2306
virtual void SetUp() {
2307
AddToDatabase(&database_,
2308
"name: \"foo.proto\" "
2309
"message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
2310
"enum_type { name:\"TestEnum\" value { name:\"DUMMY\" number:0 } } "
2311
"service { name:\"TestService\" } ");
2312
AddToDatabase(&database_,
2313
"name: \"bar.proto\" "
2314
"dependency: \"foo.proto\" "
2315
"message_type { name:\"Bar\" } "
2316
"extension { name:\"foo_ext\" extendee: \".Foo\" number:5 "
2317
" label:LABEL_OPTIONAL type:TYPE_INT32 } ");
2320
// We can't inject a file containing errors into a DescriptorPool, so we
2321
// need an actual mock DescriptorDatabase to test errors.
2322
class ErrorDescriptorDatabase : public DescriptorDatabase {
2324
ErrorDescriptorDatabase() {}
2325
~ErrorDescriptorDatabase() {}
2327
// implements DescriptorDatabase ---------------------------------
2328
bool FindFileByName(const string& filename,
2329
FileDescriptorProto* output) {
2330
// error.proto and error2.proto cyclically import each other.
2331
if (filename == "error.proto") {
2333
output->set_name("error.proto");
2334
output->add_dependency("error2.proto");
2336
} else if (filename == "error2.proto") {
2338
output->set_name("error2.proto");
2339
output->add_dependency("error.proto");
2345
bool FindFileContainingSymbol(const string& symbol_name,
2346
FileDescriptorProto* output) {
2349
bool FindFileContainingExtension(const string& containing_type,
2351
FileDescriptorProto* output) {
2356
// A DescriptorDatabase that counts how many times each method has been
2357
// called and forwards to some other DescriptorDatabase.
2358
class CallCountingDatabase : public DescriptorDatabase {
2360
CallCountingDatabase(DescriptorDatabase* wrapped_db)
2361
: wrapped_db_(wrapped_db) {
2364
~CallCountingDatabase() {}
2366
DescriptorDatabase* wrapped_db_;
2374
// implements DescriptorDatabase ---------------------------------
2375
bool FindFileByName(const string& filename,
2376
FileDescriptorProto* output) {
2378
return wrapped_db_->FindFileByName(filename, output);
2380
bool FindFileContainingSymbol(const string& symbol_name,
2381
FileDescriptorProto* output) {
2383
return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
2385
bool FindFileContainingExtension(const string& containing_type,
2387
FileDescriptorProto* output) {
2389
return wrapped_db_->FindFileContainingExtension(
2390
containing_type, field_number, output);
2394
// A DescriptorDatabase which falsely always returns foo.proto when searching
2395
// for any symbol or extension number. This shouldn't cause the
2396
// DescriptorPool to reload foo.proto if it is already loaded.
2397
class FalsePositiveDatabase : public DescriptorDatabase {
2399
FalsePositiveDatabase(DescriptorDatabase* wrapped_db)
2400
: wrapped_db_(wrapped_db) {}
2401
~FalsePositiveDatabase() {}
2403
DescriptorDatabase* wrapped_db_;
2405
// implements DescriptorDatabase ---------------------------------
2406
bool FindFileByName(const string& filename,
2407
FileDescriptorProto* output) {
2408
return wrapped_db_->FindFileByName(filename, output);
2410
bool FindFileContainingSymbol(const string& symbol_name,
2411
FileDescriptorProto* output) {
2412
return FindFileByName("foo.proto", output);
2414
bool FindFileContainingExtension(const string& containing_type,
2416
FileDescriptorProto* output) {
2417
return FindFileByName("foo.proto", output);
2422
TEST_F(DatabaseBackedPoolTest, FindFileByName) {
2423
DescriptorPool pool(&database_);
2425
const FileDescriptor* foo = pool.FindFileByName("foo.proto");
2426
ASSERT_TRUE(foo != NULL);
2427
EXPECT_EQ("foo.proto", foo->name());
2428
ASSERT_EQ(1, foo->message_type_count());
2429
EXPECT_EQ("Foo", foo->message_type(0)->name());
2431
EXPECT_EQ(foo, pool.FindFileByName("foo.proto"));
2433
EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == NULL);
2436
TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
2437
DescriptorPool pool(&database_);
2439
const FileDescriptor* foo = pool.FindFileByName("foo.proto");
2440
ASSERT_TRUE(foo != NULL);
2441
EXPECT_EQ("foo.proto", foo->name());
2442
ASSERT_EQ(1, foo->message_type_count());
2443
EXPECT_EQ("Foo", foo->message_type(0)->name());
2445
const FileDescriptor* bar = pool.FindFileByName("bar.proto");
2446
ASSERT_TRUE(bar != NULL);
2447
EXPECT_EQ("bar.proto", bar->name());
2448
ASSERT_EQ(1, bar->message_type_count());
2449
EXPECT_EQ("Bar", bar->message_type(0)->name());
2451
ASSERT_EQ(1, bar->dependency_count());
2452
EXPECT_EQ(foo, bar->dependency(0));
2455
TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
2456
DescriptorPool pool(&database_);
2458
const FileDescriptor* bar = pool.FindFileByName("bar.proto");
2459
ASSERT_TRUE(bar != NULL);
2460
EXPECT_EQ("bar.proto", bar->name());
2461
ASSERT_EQ(1, bar->message_type_count());
2462
ASSERT_EQ("Bar", bar->message_type(0)->name());
2464
const FileDescriptor* foo = pool.FindFileByName("foo.proto");
2465
ASSERT_TRUE(foo != NULL);
2466
EXPECT_EQ("foo.proto", foo->name());
2467
ASSERT_EQ(1, foo->message_type_count());
2468
ASSERT_EQ("Foo", foo->message_type(0)->name());
2470
ASSERT_EQ(1, bar->dependency_count());
2471
EXPECT_EQ(foo, bar->dependency(0));
2474
TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) {
2475
DescriptorPool pool(&database_);
2477
const FileDescriptor* file = pool.FindFileContainingSymbol("Foo");
2478
ASSERT_TRUE(file != NULL);
2479
EXPECT_EQ("foo.proto", file->name());
2480
EXPECT_EQ(file, pool.FindFileByName("foo.proto"));
2482
EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == NULL);
2485
TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
2486
DescriptorPool pool(&database_);
2488
const Descriptor* type = pool.FindMessageTypeByName("Foo");
2489
ASSERT_TRUE(type != NULL);
2490
EXPECT_EQ("Foo", type->name());
2491
EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto"));
2493
EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == NULL);
2496
TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) {
2497
DescriptorPool pool(&database_);
2499
const Descriptor* foo = pool.FindMessageTypeByName("Foo");
2500
ASSERT_TRUE(foo != NULL);
2502
const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5);
2503
ASSERT_TRUE(extension != NULL);
2504
EXPECT_EQ("foo_ext", extension->name());
2505
EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto"));
2507
EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL);
2510
TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
2511
ErrorDescriptorDatabase error_database;
2512
DescriptorPool pool(&error_database);
2514
vector<string> errors;
2517
ScopedMemoryLog log;
2518
EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
2519
errors = log.GetMessages(ERROR);
2522
EXPECT_FALSE(errors.empty());
2525
TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
2526
ErrorDescriptorDatabase error_database;
2527
MockErrorCollector error_collector;
2528
DescriptorPool pool(&error_database, &error_collector);
2530
EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
2532
"error.proto: error.proto: OTHER: File recursively imports itself: "
2533
"error.proto -> error2.proto -> error.proto\n"
2534
"error2.proto: error2.proto: OTHER: Import \"error.proto\" was not "
2535
"found or had errors.\n"
2536
"error.proto: error.proto: OTHER: Import \"error2.proto\" was not "
2537
"found or had errors.\n",
2538
error_collector.text_);
2541
TEST_F(DatabaseBackedPoolTest, UnittestProto) {
2542
// Try to load all of unittest.proto from a DescriptorDatabase. This should
2543
// thoroughly test all paths through DescriptorBuilder to insure that there
2544
// are no deadlocking problems when pool_->mutex_ is non-NULL.
2545
const FileDescriptor* original_file =
2546
protobuf_unittest::TestAllTypes::descriptor()->file();
2548
DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
2549
DescriptorPool pool(&database);
2550
const FileDescriptor* file_from_database =
2551
pool.FindFileByName(original_file->name());
2553
ASSERT_TRUE(file_from_database != NULL);
2555
FileDescriptorProto original_file_proto;
2556
original_file->CopyTo(&original_file_proto);
2558
FileDescriptorProto file_from_database_proto;
2559
file_from_database->CopyTo(&file_from_database_proto);
2561
EXPECT_EQ(original_file_proto.DebugString(),
2562
file_from_database_proto.DebugString());
2565
TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
2566
// Searching for a child of an existing descriptor should never fall back
2567
// to the DescriptorDatabase even if it isn't found, because we know all
2568
// children are already loaded.
2569
CallCountingDatabase call_counter(&database_);
2570
DescriptorPool pool(&call_counter);
2572
const FileDescriptor* file = pool.FindFileByName("foo.proto");
2573
ASSERT_TRUE(file != NULL);
2574
const Descriptor* foo = pool.FindMessageTypeByName("Foo");
2575
ASSERT_TRUE(foo != NULL);
2576
const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
2577
ASSERT_TRUE(test_enum != NULL);
2578
const ServiceDescriptor* test_service = pool.FindServiceByName("TestService");
2579
ASSERT_TRUE(test_service != NULL);
2581
EXPECT_NE(0, call_counter.call_count_);
2582
call_counter.Clear();
2584
EXPECT_TRUE(foo->FindFieldByName("no_such_field") == NULL);
2585
EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == NULL);
2586
EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == NULL);
2587
EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == NULL);
2588
EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
2589
EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == NULL);
2590
EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == NULL);
2592
EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == NULL);
2593
EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == NULL);
2594
EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
2595
EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL);
2596
EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL);
2597
EXPECT_EQ(0, call_counter.call_count_);
2600
TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
2601
// If FindFileContainingSymbol() or FindFileContainingExtension() return a
2602
// file that is already in the DescriptorPool, it should not attempt to
2604
FalsePositiveDatabase false_positive_database(&database_);
2605
MockErrorCollector error_collector;
2606
DescriptorPool pool(&false_positive_database, &error_collector);
2608
// First make sure foo.proto is loaded.
2609
const Descriptor* foo = pool.FindMessageTypeByName("Foo");
2610
ASSERT_TRUE(foo != NULL);
2612
// Try inducing false positives.
2613
EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == NULL);
2614
EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == NULL);
2616
// No errors should have been reported. (If foo.proto was incorrectly
2617
// loaded multiple times, errors would have been reported.)
2618
EXPECT_EQ("", error_collector.text_);
2621
TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
2622
ErrorDescriptorDatabase error_database;
2623
MockErrorCollector error_collector;
2624
DescriptorPool pool(&error_database, &error_collector);
2626
EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
2627
error_collector.text_.clear();
2628
EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
2629
EXPECT_EQ("", error_collector.text_);
2632
} // anonymous namespace
2633
} // namespace protobuf
2634
} // namespace google