15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Based on original Protocol Buffers design by
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Sanjay Ghemawat, Jeff Dean, and others.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file makes extensive use of RFC 3092.  :)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/compiler/importer.h>
40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/unittest.pb.h>
41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/unittest_custom_options.pb.h>
42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/io/zero_copy_stream_impl.h>
43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/descriptor.pb.h>
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor_database.h>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/dynamic_message.h>
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/text_format.h>
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h>
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/substitute.h>
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h>
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/googletest.h>
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtest/gtest.h>
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace descriptor_unittest {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some helpers to make assembling descriptors faster.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorProto* result = file->add_message_type();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorProto* AddNestedMessage(DescriptorProto* parent, const string& name) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorProto* result = parent->add_nested_type();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EnumDescriptorProto* AddEnum(FileDescriptorProto* file, const string& name) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnumDescriptorProto* result = file->add_enum_type();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const string& name) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnumDescriptorProto* result = parent->add_enum_type();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServiceDescriptorProto* AddService(FileDescriptorProto* file,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const string& name) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceDescriptorProto* result = file->add_service();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FieldDescriptorProto* AddField(DescriptorProto* parent,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const string& name, int number,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               FieldDescriptorProto::Label label,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               FieldDescriptorProto::Type type) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldDescriptorProto* result = parent->add_field();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_number(number);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_label(label);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_type(type);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FieldDescriptorProto* AddExtension(FileDescriptorProto* file,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const string& extendee,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const string& name, int number,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   FieldDescriptorProto::Label label,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   FieldDescriptorProto::Type type) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldDescriptorProto* result = file->add_extension();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_number(number);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_label(label);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_type(type);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_extendee(extendee);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const string& extendee,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const string& name, int number,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         FieldDescriptorProto::Label label,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         FieldDescriptorProto::Type type) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldDescriptorProto* result = parent->add_extension();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_number(number);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_label(label);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_type(type);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_extendee(extendee);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   int start, int end) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorProto::ExtensionRange* result = parent->add_extension_range();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_start(start);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_end(end);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const string& name, int number) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnumValueDescriptorProto* result = enum_proto->add_value();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_number(number);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const string& name,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const string& input_type,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const string& output_type) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MethodDescriptorProto* result = service->add_method();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_name(name);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_input_type(input_type);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result->set_output_type(output_type);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Empty enums technically aren't allowed.  We need to insert a dummy value
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// into them.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddEmptyEnum(FileDescriptorProto* file, const string& name) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test simple files.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FileDescriptorTest : public testing::Test {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build descriptors for the following definitions:
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   // in "foo.proto"
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message FooMessage { extensions 1; }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   enum FooEnum {FOO_ENUM_VALUE = 1;}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   service FooService {}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   extend FooMessage { optional int32 foo_extension = 1; }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   // in "bar.proto"
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   package bar_package;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message BarMessage { extensions 1; }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   enum BarEnum {BAR_ENUM_VALUE = 1;}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   service BarService {}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   extend BarMessage { optional int32 bar_extension = 1; }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Also, we have an empty file "baz.proto".  This file's purpose is to
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // make sure that even though it has the same package as foo.proto,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // searching it for members of foo.proto won't work.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto foo_file;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file.set_name("foo.proto");
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddService(&foo_file, "FooService");
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtension(&foo_file, "FooMessage", "foo_extension", 1,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::LABEL_OPTIONAL,
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::TYPE_INT32);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto bar_file;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_name("bar.proto");
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_package("bar_package");
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.add_dependency("foo.proto");
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddService(&bar_file, "BarService");
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::LABEL_OPTIONAL,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::TYPE_INT32);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto baz_file;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz_file.set_name("baz.proto");
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build the descriptors and get the pointers.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file_ = pool_.BuildFile(foo_file);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(foo_file_ != NULL);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file_ = pool_.BuildFile(bar_file);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(bar_file_ != NULL);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz_file_ = pool_.BuildFile(baz_file);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(baz_file_ != NULL);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->message_type_count());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_message_ = foo_file_->message_type(0);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->enum_type_count());
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_enum_ = foo_file_->enum_type(0);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_enum_->value_count());
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_enum_value_ = foo_enum_->value(0);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->service_count());
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_service_ = foo_file_->service(0);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->extension_count());
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_extension_ = foo_file_->extension(0);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_file_->message_type_count());
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_message_ = bar_file_->message_type(0);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_file_->enum_type_count());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_enum_ = bar_file_->enum_type(0);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_enum_->value_count());
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_enum_value_ = bar_enum_->value(0);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_file_->service_count());
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_service_ = bar_file_->service(0);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_file_->extension_count());
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_extension_ = bar_file_->extension(0);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool_;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo_file_;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* bar_file_;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* baz_file_;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor*          foo_message_;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor*      foo_enum_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* foo_enum_value_;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ServiceDescriptor*   foo_service_;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor*     foo_extension_;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor*          bar_message_;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor*      bar_enum_;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* bar_enum_value_;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ServiceDescriptor*   bar_service_;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor*     bar_extension_;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, Name) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo.proto", foo_file_->name());
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bar.proto", bar_file_->name());
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("baz.proto", baz_file_->name());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, Package) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", foo_file_->package());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bar_package", bar_file_->package());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, Dependencies) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, foo_file_->dependency_count());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, bar_file_->dependency_count());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_file_, bar_file_->dependency(0));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, FindMessageTypeByName) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage"));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage"));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == NULL);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == NULL);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == NULL);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == NULL);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == NULL);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, FindEnumTypeByName) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum"));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum"));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == NULL);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == NULL);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == NULL);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == NULL);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == NULL);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, FindEnumValueByName) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE"));
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE"));
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == NULL);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == NULL);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, FindServiceByName) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService"));
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService"));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == NULL);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == NULL);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == NULL);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == NULL);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == NULL);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, FindExtensionByName) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension"));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension"));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == NULL);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == NULL);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == NULL);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == NULL);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == NULL);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, FindExtensionByNumber) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1));
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1));
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileDescriptorTest, BuildAgain) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that if te call BuildFile again on the same input we get the same
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FileDescriptor back.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto file;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  foo_file_->CopyTo(&file);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_file_, pool_.BuildFile(file));
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But if we change the file then it won't work.
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file.set_package("some.other.package");
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool_.BuildFile(file) == NULL);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test simple flat messages and fields.
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DescriptorTest : public testing::Test {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build descriptors for the following definitions:
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   // in "foo.proto"
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message TestForeign {}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   enum TestEnum {}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message TestMessage {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     required string      foo = 1;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     optional TestEnum    bar = 6;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     repeated TestForeign baz = 500000000;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     optional group       qux = 15 {}
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   // in "bar.proto"
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   package corge.grault;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message TestMessage2 {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     required string foo = 1;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     required string bar = 2;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     required string quux = 6;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We cheat and use TestForeign as the type for qux rather than create
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // an actual nested type.
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Since all primitive types (including string) use the same building
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // code, there's no need to test each one individually.
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TestMessage2 is primarily here to test FindFieldByName and friends.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // All messages created from the same DescriptorPool share the same lookup
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // table, so we need to insure that they don't interfere.
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto foo_file;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file.set_name("foo.proto");
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMessage(&foo_file, "TestForeign");
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEmptyEnum(&foo_file, "TestEnum");
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message, "foo", 1,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_REQUIRED,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_STRING);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message, "bar", 6,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_OPTIONAL,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_ENUM)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ->set_type_name("TestEnum");
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message, "baz", 500000000,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_REPEATED,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_MESSAGE)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ->set_type_name("TestForeign");
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message, "qux", 15,
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_OPTIONAL,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_GROUP)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ->set_type_name("TestForeign");
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto bar_file;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_name("bar.proto");
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_package("corge.grault");
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message2, "foo", 1,
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_REQUIRED,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_STRING);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message2, "bar", 2,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_REQUIRED,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_STRING);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message2, "quux", 6,
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_REQUIRED,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_STRING);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build the descriptors and get the pointers.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file_ = pool_.BuildFile(foo_file);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(foo_file_ != NULL);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file_ = pool_.BuildFile(bar_file);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(bar_file_ != NULL);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->enum_type_count());
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum_ = foo_file_->enum_type(0);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, foo_file_->message_type_count());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foreign_ = foo_file_->message_type(0);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_ = foo_file_->message_type(1);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(4, message_->field_count());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_ = message_->field(0);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_ = message_->field(1);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz_ = message_->field(2);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    qux_ = message_->field(3);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_file_->message_type_count());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message2_ = bar_file_->message_type(0);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(3, message2_->field_count());
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo2_  = message2_->field(0);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar2_  = message2_->field(1);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    quux2_ = message2_->field(2);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool_;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo_file_;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* bar_file_;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* message_;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* message2_;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foreign_;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* enum_;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* foo_;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* bar_;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* baz_;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* qux_;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* foo2_;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* bar2_;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* quux2_;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, Name) {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage", message_->name());
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage", message_->full_name());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_file_, message_->file());
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage2", message2_->name());
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name());
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_file_, message2_->file());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, ContainingType) {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->containing_type() == NULL);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message2_->containing_type() == NULL);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldsByIndex) {
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4, message_->field_count());
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, message_->field(0));
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_, message_->field(1));
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(baz_, message_->field(2));
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(qux_, message_->field(3));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FindFieldByName) {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All messages in the same DescriptorPool share a single lookup table for
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fields.  So, in addition to testing that FindFieldByName finds the fields
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the message, we need to test that it does *not* find the fields of
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // *other* messages.
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, message_->FindFieldByName("foo"));
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_, message_->FindFieldByName("bar"));
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(baz_, message_->FindFieldByName("baz"));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(qux_, message_->FindFieldByName("qux"));
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByName("no_such_field") == NULL);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByName("quux") == NULL);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo2_ , message2_->FindFieldByName("foo" ));
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar2_ , message2_->FindFieldByName("bar" ));
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quux2_, message2_->FindFieldByName("quux"));
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message2_->FindFieldByName("baz") == NULL);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message2_->FindFieldByName("qux") == NULL);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FindFieldByNumber) {
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByNumber(837592) == NULL);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByNumber(2) == NULL);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo2_ , message2_->FindFieldByNumber(1));
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar2_ , message2_->FindFieldByNumber(2));
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message2_->FindFieldByNumber(15) == NULL);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == NULL);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldName) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo", foo_->name());
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bar", bar_->name());
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("baz", baz_->name());
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("qux", qux_->name());
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldFullName) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage.foo", foo_->full_name());
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage.bar", bar_->full_name());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage.baz", baz_->full_name());
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage.qux", qux_->full_name());
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name());
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name());
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name());
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldFile) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_file_, foo_->file());
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_file_, bar_->file());
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_file_, baz_->file());
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_file_, qux_->file());
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_file_, foo2_->file());
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_file_, bar2_->file());
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_file_, quux2_->file());
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldIndex) {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, foo_->index());
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, bar_->index());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, baz_->index());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, qux_->index());
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldNumber) {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(        1, foo_->number());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(        6, bar_->number());
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(500000000, baz_->number());
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(       15, qux_->number());
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldType) {
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::TYPE_STRING , foo_->type());
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::TYPE_ENUM   , bar_->type());
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type());
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::TYPE_GROUP  , qux_->type());
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldLabel) {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label());
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label());
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label());
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label());
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE (foo_->is_required());
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(foo_->is_optional());
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(foo_->is_repeated());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bar_->is_required());
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE (bar_->is_optional());
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bar_->is_repeated());
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(baz_->is_required());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(baz_->is_optional());
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE (baz_->is_repeated());
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldHasDefault) {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(foo_->has_default_value());
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(bar_->has_default_value());
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(baz_->has_default_value());
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(qux_->has_default_value());
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldContainingType) {
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_, foo_->containing_type());
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_, bar_->containing_type());
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_, baz_->containing_type());
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_, qux_->containing_type());
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message2_, foo2_ ->containing_type());
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message2_, bar2_ ->containing_type());
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message2_, quux2_->containing_type());
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldMessageType) {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_->message_type() == NULL);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar_->message_type() == NULL);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foreign_, baz_->message_type());
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foreign_, qux_->message_type());
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DescriptorTest, FieldEnumType) {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_->enum_type() == NULL);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(baz_->enum_type() == NULL);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(qux_->enum_type() == NULL);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(enum_, bar_->enum_type());
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class StylizedFieldNamesTest : public testing::Test {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetUp() {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto file;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file.set_name("foo.proto");
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorProto* message = AddMessage(&file, "TestMessage");
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message, "foo_foo", 1,
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_OPTIONAL,
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_INT32);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message, "FooBar", 2,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_OPTIONAL,
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_INT32);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message, "fooBaz", 3,
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_OPTIONAL,
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_INT32);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message, "fooFoo", 4,  // Camel-case conflict with foo_foo.
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_OPTIONAL,
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_INT32);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message, "foobar", 5,  // Lower-case conflict with FooBar.
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_OPTIONAL,
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_INT32);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::LABEL_OPTIONAL,
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::TYPE_INT32);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::LABEL_OPTIONAL,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::TYPE_INT32);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::LABEL_OPTIONAL,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::TYPE_INT32);
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedExtension(message, "ExtendableMessage", "barFoo", 4,  // Conflict
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::LABEL_OPTIONAL,
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::TYPE_INT32);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedExtension(message, "ExtendableMessage", "barbar", 5,  // Conflict
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::LABEL_OPTIONAL,
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::TYPE_INT32);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::LABEL_OPTIONAL,
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::TYPE_INT32);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtension(&file, "ExtendableMessage", "BazBar", 12,
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::LABEL_OPTIONAL,
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::TYPE_INT32);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::LABEL_OPTIONAL,
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::TYPE_INT32);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtension(&file, "ExtendableMessage", "bazFoo", 14,  // Conflict
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::LABEL_OPTIONAL,
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::TYPE_INT32);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtension(&file, "ExtendableMessage", "bazbar", 15,  // Conflict
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::LABEL_OPTIONAL,
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::TYPE_INT32);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_ = pool_.BuildFile(file);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(file_ != NULL);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, file_->message_type_count());
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_ = file_->message_type(1);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ("TestMessage", message_->name());
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(5, message_->field_count());
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(5, message_->extension_count());
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(5, file_->extension_count());
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool_;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file_;
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* message_;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(StylizedFieldNamesTest, LowercaseName) {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foobar" , message_->field(1)->lowercase_name());
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foobaz" , message_->field(2)->lowercase_name());
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foofoo" , message_->field(3)->lowercase_name());
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foobar" , message_->field(4)->lowercase_name());
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("barbar" , message_->extension(1)->lowercase_name());
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("barbaz" , message_->extension(2)->lowercase_name());
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("barfoo" , message_->extension(3)->lowercase_name());
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("barbar" , message_->extension(4)->lowercase_name());
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bazbar" , file_->extension(1)->lowercase_name());
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bazbaz" , file_->extension(2)->lowercase_name());
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bazfoo" , file_->extension(3)->lowercase_name());
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bazbar" , file_->extension(4)->lowercase_name());
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(StylizedFieldNamesTest, CamelcaseName) {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->field(0),
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindFieldByLowercaseName("foo_foo"));
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->field(1),
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindFieldByLowercaseName("foobar"));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->field(2),
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindFieldByLowercaseName("foobaz"));
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == NULL);
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == NULL);
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == NULL);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == NULL);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->extension(0),
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindExtensionByLowercaseName("bar_foo"));
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->extension(1),
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindExtensionByLowercaseName("barbar"));
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->extension(2),
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindExtensionByLowercaseName("barbaz"));
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == NULL);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == NULL);
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == NULL);
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == NULL);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(file_->extension(0),
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_->FindExtensionByLowercaseName("baz_foo"));
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(file_->extension(1),
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_->FindExtensionByLowercaseName("bazbar"));
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(file_->extension(2),
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_->FindExtensionByLowercaseName("bazbaz"));
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == NULL);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == NULL);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == NULL);
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->field(0),
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindFieldByCamelcaseName("fooFoo"));
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->field(1),
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindFieldByCamelcaseName("fooBar"));
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->field(2),
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindFieldByCamelcaseName("fooBaz"));
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == NULL);
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == NULL);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == NULL);
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == NULL);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->extension(0),
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindExtensionByCamelcaseName("barFoo"));
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->extension(1),
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindExtensionByCamelcaseName("barBar"));
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_->extension(2),
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message_->FindExtensionByCamelcaseName("barBaz"));
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == NULL);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == NULL);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == NULL);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(file_->extension(0),
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_->FindExtensionByCamelcaseName("bazFoo"));
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(file_->extension(1),
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_->FindExtensionByCamelcaseName("bazBar"));
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(file_->extension(2),
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_->FindExtensionByCamelcaseName("bazBaz"));
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == NULL);
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == NULL);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test enum descriptors.
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EnumDescriptorTest : public testing::Test {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build descriptors for the following definitions:
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   // in "foo.proto"
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   enum TestEnum {
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     FOO = 1;
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     BAR = 2;
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   }
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   // in "bar.proto"
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   package corge.grault;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   enum TestEnum2 {
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     FOO = 1;
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     BAZ = 3;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   }
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TestEnum2 is primarily here to test FindValueByName and friends.
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // All enums created from the same DescriptorPool share the same lookup
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // table, so we need to insure that they don't interfere.
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TestEnum
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto foo_file;
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file.set_name("foo.proto");
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum");
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(enum_proto, "FOO", 1);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(enum_proto, "BAR", 2);
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TestEnum2
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto bar_file;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_name("bar.proto");
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_package("corge.grault");
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2");
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(enum2_proto, "FOO", 1);
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(enum2_proto, "BAZ", 3);
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build the descriptors and get the pointers.
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file_ = pool_.BuildFile(foo_file);
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(foo_file_ != NULL);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file_ = pool_.BuildFile(bar_file);
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(bar_file_ != NULL);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->enum_type_count());
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum_ = foo_file_->enum_type(0);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, enum_->value_count());
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_ = enum_->value(0);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_ = enum_->value(1);
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_file_->enum_type_count());
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum2_ = bar_file_->enum_type(0);
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, enum2_->value_count());
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo2_ = enum2_->value(0);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz2_ = enum2_->value(1);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool_;
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo_file_;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* bar_file_;
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* enum_;
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* enum2_;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* foo_;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* bar_;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* foo2_;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* baz2_;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, Name) {
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestEnum", enum_->name());
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestEnum", enum_->full_name());
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_file_, enum_->file());
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestEnum2", enum2_->name());
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name());
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_file_, enum2_->file());
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, ContainingType) {
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(enum_->containing_type() == NULL);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(enum2_->containing_type() == NULL);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, ValuesByIndex) {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, enum_->value_count());
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, enum_->value(0));
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_, enum_->value(1));
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, FindValueByName) {
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_ , enum_ ->FindValueByName("FOO"));
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_ , enum_ ->FindValueByName("BAR"));
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO"));
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ"));
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(enum_ ->FindValueByName("NO_SUCH_VALUE") == NULL);
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(enum_ ->FindValueByName("BAZ"          ) == NULL);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(enum2_->FindValueByName("BAR"          ) == NULL);
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, FindValueByNumber) {
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_ , enum_ ->FindValueByNumber(1));
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_ , enum_ ->FindValueByNumber(2));
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(enum_ ->FindValueByNumber(416) == NULL);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(enum_ ->FindValueByNumber(3) == NULL);
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(enum2_->FindValueByNumber(2) == NULL);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, ValueName) {
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("FOO", foo_->name());
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("BAR", bar_->name());
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, ValueFullName) {
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("FOO", foo_->full_name());
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("BAR", bar_->full_name());
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.FOO", foo2_->full_name());
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.BAZ", baz2_->full_name());
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, ValueIndex) {
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, foo_->index());
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, bar_->index());
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, ValueNumber) {
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, foo_->number());
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, bar_->number());
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(EnumDescriptorTest, ValueType) {
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(enum_ , foo_ ->type());
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(enum_ , bar_ ->type());
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(enum2_, foo2_->type());
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(enum2_, baz2_->type());
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test service descriptors.
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ServiceDescriptorTest : public testing::Test {
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build descriptors for the following messages and service:
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    // in "foo.proto"
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    message FooRequest  {}
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    message FooResponse {}
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    message BarRequest  {}
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    message BarResponse {}
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    message BazRequest  {}
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    message BazResponse {}
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    service TestService {
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //      rpc Foo(FooRequest) returns (FooResponse);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //      rpc Bar(BarRequest) returns (BarResponse);
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    }
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    // in "bar.proto"
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    package corge.grault
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    service TestService2 {
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //      rpc Foo(FooRequest) returns (FooResponse);
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //      rpc Baz(BazRequest) returns (BazResponse);
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //    }
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto foo_file;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file.set_name("foo.proto");
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMessage(&foo_file, "FooRequest");
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMessage(&foo_file, "FooResponse");
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMessage(&foo_file, "BarRequest");
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMessage(&foo_file, "BarResponse");
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMessage(&foo_file, "BazRequest");
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMessage(&foo_file, "BazResponse");
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServiceDescriptorProto* service = AddService(&foo_file, "TestService");
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMethod(service, "Foo", "FooRequest", "FooResponse");
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMethod(service, "Bar", "BarRequest", "BarResponse");
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto bar_file;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_name("bar.proto");
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_package("corge.grault");
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.add_dependency("foo.proto");
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2");
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMethod(service2, "Foo", "FooRequest", "FooResponse");
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMethod(service2, "Baz", "BazRequest", "BazResponse");
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build the descriptors and get the pointers.
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file_ = pool_.BuildFile(foo_file);
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(foo_file_ != NULL);
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file_ = pool_.BuildFile(bar_file);
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(bar_file_ != NULL);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(6, foo_file_->message_type_count());
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_request_  = foo_file_->message_type(0);
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_response_ = foo_file_->message_type(1);
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_request_  = foo_file_->message_type(2);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_response_ = foo_file_->message_type(3);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz_request_  = foo_file_->message_type(4);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz_response_ = foo_file_->message_type(5);
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->service_count());
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_ = foo_file_->service(0);
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, service_->method_count());
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_ = service_->method(0);
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_ = service_->method(1);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_file_->service_count());
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service2_ = bar_file_->service(0);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, service2_->method_count());
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo2_ = service2_->method(0);
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz2_ = service2_->method(1);
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool_;
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo_file_;
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* bar_file_;
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo_request_;
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo_response_;
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* bar_request_;
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* bar_response_;
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* baz_request_;
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* baz_response_;
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ServiceDescriptor* service_;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ServiceDescriptor* service2_;
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MethodDescriptor* foo_;
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MethodDescriptor* bar_;
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MethodDescriptor* foo2_;
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MethodDescriptor* baz2_;
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceDescriptorTest, Name) {
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestService", service_->name());
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestService", service_->full_name());
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_file_, service_->file());
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestService2", service2_->name());
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestService2", service2_->full_name());
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_file_, service2_->file());
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceDescriptorTest, MethodsByIndex) {
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, service_->method_count());
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, service_->method(0));
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_, service_->method(1));
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceDescriptorTest, FindMethodByName) {
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_ , service_ ->FindMethodByName("Foo"));
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_ , service_ ->FindMethodByName("Bar"));
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo"));
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz"));
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(service_ ->FindMethodByName("NoSuchMethod") == NULL);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(service_ ->FindMethodByName("Baz"         ) == NULL);
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(service2_->FindMethodByName("Bar"         ) == NULL);
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceDescriptorTest, MethodName) {
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Foo", foo_->name());
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Bar", bar_->name());
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceDescriptorTest, MethodFullName) {
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestService.Foo", foo_->full_name());
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestService.Bar", bar_->full_name());
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name());
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name());
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceDescriptorTest, MethodIndex) {
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, foo_->index());
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, bar_->index());
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceDescriptorTest, MethodParent) {
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(service_, foo_->service());
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(service_, bar_->service());
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceDescriptorTest, MethodInputType) {
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_request_, foo_->input_type());
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_request_, bar_->input_type());
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceDescriptorTest, MethodOutputType) {
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_response_, foo_->output_type());
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_response_, bar_->output_type());
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test nested types.
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NestedDescriptorTest : public testing::Test {
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build descriptors for the following definitions:
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   // in "foo.proto"
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message TestMessage {
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     message Foo {}
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     message Bar {}
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     enum Baz { A = 1; }
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     enum Qux { B = 1; }
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   }
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   // in "bar.proto"
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   package corge.grault;
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message TestMessage2 {
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     message Foo {}
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     message Baz {}
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     enum Qux  { A = 1; }
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     enum Quux { C = 1; }
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   }
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TestMessage2 is primarily here to test FindNestedTypeByName and friends.
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // All messages created from the same DescriptorPool share the same lookup
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // table, so we need to insure that they don't interfere.
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We add enum values to the enums in order to test searching for enum
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // values across a message's scope.
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto foo_file;
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file.set_name("foo.proto");
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedMessage(message, "Foo");
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedMessage(message, "Bar");
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EnumDescriptorProto* baz = AddNestedEnum(message, "Baz");
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(baz, "A", 1);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EnumDescriptorProto* qux = AddNestedEnum(message, "Qux");
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(qux, "B", 1);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto bar_file;
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_name("bar.proto");
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file.set_package("corge.grault");
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedMessage(message2, "Foo");
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedMessage(message2, "Baz");
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux");
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(qux2, "A", 1);
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux");
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEnumValue(quux2, "C", 1);
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build the descriptors and get the pointers.
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file_ = pool_.BuildFile(foo_file);
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(foo_file_ != NULL);
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_file_ = pool_.BuildFile(bar_file);
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(bar_file_ != NULL);
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->message_type_count());
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_ = foo_file_->message_type(0);
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, message_->nested_type_count());
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_ = message_->nested_type(0);
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_ = message_->nested_type(1);
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, message_->enum_type_count());
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz_ = message_->enum_type(0);
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    qux_ = message_->enum_type(1);
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, baz_->value_count());
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    a_ = baz_->value(0);
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, qux_->value_count());
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    b_ = qux_->value(0);
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_file_->message_type_count());
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message2_ = bar_file_->message_type(0);
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, message2_->nested_type_count());
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo2_ = message2_->nested_type(0);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz2_ = message2_->nested_type(1);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(2, message2_->enum_type_count());
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    qux2_ = message2_->enum_type(0);
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    quux2_ = message2_->enum_type(1);
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, qux2_->value_count());
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    a2_ = qux2_->value(0);
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, quux2_->value_count());
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c2_ = quux2_->value(0);
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool_;
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo_file_;
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* bar_file_;
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* message_;
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* message2_;
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo_;
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* bar_;
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* baz_;
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* qux_;
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* a_;
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* b_;
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo2_;
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* baz2_;
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* qux2_;
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* quux2_;
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* a2_;
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* c2_;
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, MessageName) {
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Foo", foo_ ->name());
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Bar", bar_ ->name());
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Foo", foo2_->name());
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Baz", baz2_->name());
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage.Foo", foo_->full_name());
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage.Bar", bar_->full_name());
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name());
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name());
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, MessageContainingType) {
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_ , foo_ ->containing_type());
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_ , bar_ ->containing_type());
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message2_, foo2_->containing_type());
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message2_, baz2_->containing_type());
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, message_->nested_type_count());
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, message_->nested_type(0));
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_, message_->nested_type(1));
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByName("Foo") == NULL);
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindFieldByName("Qux") == NULL);
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByName("Foo") == NULL);
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindExtensionByName("Qux") == NULL);
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_ , message_ ->FindNestedTypeByName("Foo"));
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_ , message_ ->FindNestedTypeByName("Bar"));
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo"));
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz"));
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_ ->FindNestedTypeByName("NoSuchType") == NULL);
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_ ->FindNestedTypeByName("Baz"       ) == NULL);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message2_->FindNestedTypeByName("Bar"       ) == NULL);
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == NULL);
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, EnumName) {
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Baz" , baz_ ->name());
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Qux" , qux_ ->name());
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Qux" , qux2_->name());
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Quux", quux2_->name());
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage.Baz", baz_->full_name());
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("TestMessage.Qux", qux_->full_name());
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestMessage2.Qux" , qux2_ ->full_name());
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name());
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, EnumContainingType) {
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_ , baz_  ->containing_type());
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message_ , qux_  ->containing_type());
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message2_, qux2_ ->containing_type());
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(message2_, quux2_->containing_type());
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, message_->nested_type_count());
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, message_->nested_type(0));
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_, message_->nested_type(1));
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, FindEnumTypeByName) {
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(baz_  , message_ ->FindEnumTypeByName("Baz" ));
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(qux_  , message_ ->FindEnumTypeByName("Qux" ));
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(qux2_ , message2_->FindEnumTypeByName("Qux" ));
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux"));
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_ ->FindEnumTypeByName("NoSuchType") == NULL);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_ ->FindEnumTypeByName("Quux"      ) == NULL);
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message2_->FindEnumTypeByName("Baz"       ) == NULL);
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == NULL);
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NestedDescriptorTest, FindEnumValueByName) {
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(a_ , message_ ->FindEnumValueByName("A"));
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(b_ , message_ ->FindEnumValueByName("B"));
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(a2_, message2_->FindEnumValueByName("A"));
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(c2_, message2_->FindEnumValueByName("C"));
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_ ->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_ ->FindEnumValueByName("C"            ) == NULL);
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message2_->FindEnumValueByName("B"            ) == NULL);
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message_->FindEnumValueByName("Foo") == NULL);
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test extensions.
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionDescriptorTest : public testing::Test {
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build descriptors for the following definitions:
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   enum Baz {}
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message Qux {}
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message Foo {
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     extensions 10 to 19;
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     extensions 30 to 39;
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   }
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   extends Foo with optional int32 foo_int32 = 10;
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   extends Foo with repeated TestEnum foo_enum = 19;
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   message Bar {
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     extends Foo with optional Qux foo_message = 30;
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     // (using Qux as the group type)
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //     extends Foo with repeated group foo_group = 39;
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   }
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto foo_file;
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file.set_name("foo.proto");
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEmptyEnum(&foo_file, "Baz");
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddMessage(&foo_file, "Qux");
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorProto* foo = AddMessage(&foo_file, "Foo");
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtensionRange(foo, 10, 20);
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtensionRange(foo, 30, 40);
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtension(&foo_file, "Foo", "foo_int32", 10,
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::LABEL_OPTIONAL,
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::TYPE_INT32);
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddExtension(&foo_file, "Foo", "foo_enum", 19,
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::LABEL_REPEATED,
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FieldDescriptorProto::TYPE_ENUM)
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ->set_type_name("Baz");
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorProto* bar = AddMessage(&foo_file, "Bar");
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedExtension(bar, "Foo", "foo_message", 30,
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::LABEL_OPTIONAL,
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::TYPE_MESSAGE)
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ->set_type_name("Qux");
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddNestedExtension(bar, "Foo", "foo_group", 39,
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::LABEL_REPEATED,
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       FieldDescriptorProto::TYPE_GROUP)
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ->set_type_name("Qux");
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build the descriptors and get the pointers.
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_file_ = pool_.BuildFile(foo_file);
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(foo_file_ != NULL);
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->enum_type_count());
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz_ = foo_file_->enum_type(0);
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(3, foo_file_->message_type_count());
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    qux_ = foo_file_->message_type(0);
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_ = foo_file_->message_type(1);
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_ = foo_file_->message_type(2);
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool_;
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo_file_;
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo_;
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* bar_;
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* baz_;
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* qux_;
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, bar_->extension_range_count());
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, foo_->extension_range_count());
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, foo_->extension_range(0)->start);
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(30, foo_->extension_range(1)->start);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(20, foo_->extension_range(0)->end);
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(40, foo_->extension_range(1)->end);
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionDescriptorTest, Extensions) {
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, foo_->extension_count());
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, foo_file_->extension_count());
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, bar_->extension_count());
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->extension(0)->is_extension());
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->extension(1)->is_extension());
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar_->extension(0)->is_extension());
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar_->extension(1)->is_extension());
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo_int32"  , foo_file_->extension(0)->name());
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo_enum"   , foo_file_->extension(1)->name());
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo_message", bar_->extension(0)->name());
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo_group"  , bar_->extension(1)->name());
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, foo_file_->extension(0)->number());
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(19, foo_file_->extension(1)->number());
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(30, bar_->extension(0)->number());
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(39, bar_->extension(1)->number());
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::TYPE_INT32  , foo_file_->extension(0)->type());
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::TYPE_ENUM   , foo_file_->extension(1)->type());
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type());
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::TYPE_GROUP  , bar_->extension(1)->type());
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(qux_, bar_->extension(0)->message_type());
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(qux_, bar_->extension(1)->message_type());
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label());
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label());
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label());
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label());
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == NULL);
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == NULL);
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(foo_->IsExtensionNumber( 9));
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE (foo_->IsExtensionNumber(10));
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE (foo_->IsExtensionNumber(19));
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(foo_->IsExtensionNumber(20));
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(foo_->IsExtensionNumber(29));
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE (foo_->IsExtensionNumber(30));
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE (foo_->IsExtensionNumber(39));
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(foo_->IsExtensionNumber(40));
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionDescriptorTest, FindExtensionByName) {
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that FileDescriptor::FindExtensionByName() is tested by
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FileDescriptorTest.
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, bar_->extension_count());
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message"));
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group"  ));
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL);
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL);
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL);
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<const FieldDescriptor*> extensions;
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_.FindAllExtensions(foo_, &extensions);
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4, extensions.size());
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, extensions[0]->number());
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(19, extensions[1]->number());
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(30, extensions[2]->number());
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(39, extensions[3]->number());
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MiscTest : public testing::Test {
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1523ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Function which makes a field descriptor of the given type.
1524ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FieldDescriptor* GetFieldDescriptorOfType(FieldDescriptor::Type type) {
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto file_proto;
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_proto.set_name("foo.proto");
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddEmptyEnum(&file_proto, "DummyEnum");
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FieldDescriptorProto* field =
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               static_cast<FieldDescriptorProto::Type>(static_cast<int>(type)));
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type == FieldDescriptor::TYPE_MESSAGE ||
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        type == FieldDescriptor::TYPE_GROUP) {
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      field->set_type_name("TestMessage");
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (type == FieldDescriptor::TYPE_ENUM) {
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      field->set_type_name("DummyEnum");
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build the descriptors and get the pointers.
1542ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    pool_.reset(new DescriptorPool());
1543ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const FileDescriptor* file = pool_->BuildFile(file_proto);
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (file != NULL &&
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file->message_type_count() == 1 &&
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file->message_type(0)->field_count() == 1) {
1548ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return file->message_type(0)->field(0);
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1550ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return NULL;
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1553ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1554ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const char* GetTypeNameForFieldType(FieldDescriptor::Type type) {
1555ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const FieldDescriptor* field = GetFieldDescriptorOfType(type);
1556ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return field != NULL ? field->type_name() : "";
1557ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1558ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1559ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
1560ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const FieldDescriptor* field = GetFieldDescriptorOfType(type);
1561ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return field != NULL ? field->cpp_type() :
1562ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        static_cast<FieldDescriptor::CppType>(0);
1563ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1564ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1565ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const char* GetCppTypeNameForFieldType(FieldDescriptor::Type type) {
1566ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    const FieldDescriptor* field = GetFieldDescriptorOfType(type);
1567ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return field != NULL ? field->cpp_type_name() : "";
1568ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1569ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1570ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  scoped_ptr<DescriptorPool> pool_;
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1573ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(MiscTest, TypeNames) {
1574ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Test that correct type names are returned.
1575ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1576ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  typedef FieldDescriptor FD;  // avoid ugly line wrapping
1577ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1578ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("double"  , GetTypeNameForFieldType(FD::TYPE_DOUBLE  ));
1579ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("float"   , GetTypeNameForFieldType(FD::TYPE_FLOAT   ));
1580ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("int64"   , GetTypeNameForFieldType(FD::TYPE_INT64   ));
1581ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("uint64"  , GetTypeNameForFieldType(FD::TYPE_UINT64  ));
1582ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("int32"   , GetTypeNameForFieldType(FD::TYPE_INT32   ));
1583ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("fixed64" , GetTypeNameForFieldType(FD::TYPE_FIXED64 ));
1584ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("fixed32" , GetTypeNameForFieldType(FD::TYPE_FIXED32 ));
1585ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("bool"    , GetTypeNameForFieldType(FD::TYPE_BOOL    ));
1586ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("string"  , GetTypeNameForFieldType(FD::TYPE_STRING  ));
1587ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("group"   , GetTypeNameForFieldType(FD::TYPE_GROUP   ));
1588ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("message" , GetTypeNameForFieldType(FD::TYPE_MESSAGE ));
1589ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("bytes"   , GetTypeNameForFieldType(FD::TYPE_BYTES   ));
1590ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("uint32"  , GetTypeNameForFieldType(FD::TYPE_UINT32  ));
1591ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("enum"    , GetTypeNameForFieldType(FD::TYPE_ENUM    ));
1592ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32));
1593ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64));
1594ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("sint32"  , GetTypeNameForFieldType(FD::TYPE_SINT32  ));
1595ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("sint64"  , GetTypeNameForFieldType(FD::TYPE_SINT64  ));
1596ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
1597ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(MiscTest, CppTypes) {
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that CPP types are assigned correctly.
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef FieldDescriptor FD;  // avoid ugly line wrapping
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_DOUBLE , GetCppTypeForFieldType(FD::TYPE_DOUBLE  ));
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_FLOAT  , GetCppTypeForFieldType(FD::TYPE_FLOAT   ));
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_INT64   ));
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_UINT64  ));
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_INT32   ));
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_FIXED64 ));
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_FIXED32 ));
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_BOOL   , GetCppTypeForFieldType(FD::TYPE_BOOL    ));
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_STRING  ));
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP   ));
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE ));
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_BYTES   ));
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_UINT32  ));
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_ENUM   , GetCppTypeForFieldType(FD::TYPE_ENUM    ));
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_SFIXED32));
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_SFIXED64));
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_INT32  , GetCppTypeForFieldType(FD::TYPE_SINT32  ));
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FD::CPPTYPE_INT64  , GetCppTypeForFieldType(FD::TYPE_SINT64  ));
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1623ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(MiscTest, CppTypeNames) {
1624ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Test that correct CPP type names are returned.
1625ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1626ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  typedef FieldDescriptor FD;  // avoid ugly line wrapping
1627ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1628ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("double" , GetCppTypeNameForFieldType(FD::TYPE_DOUBLE  ));
1629ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("float"  , GetCppTypeNameForFieldType(FD::TYPE_FLOAT   ));
1630ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("int64"  , GetCppTypeNameForFieldType(FD::TYPE_INT64   ));
1631ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_UINT64  ));
1632ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("int32"  , GetCppTypeNameForFieldType(FD::TYPE_INT32   ));
1633ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_FIXED64 ));
1634ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_FIXED32 ));
1635ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("bool"   , GetCppTypeNameForFieldType(FD::TYPE_BOOL    ));
1636ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_STRING  ));
1637ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_GROUP   ));
1638ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE ));
1639ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_BYTES   ));
1640ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_UINT32  ));
1641ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("enum"   , GetCppTypeNameForFieldType(FD::TYPE_ENUM    ));
1642ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("int32"  , GetCppTypeNameForFieldType(FD::TYPE_SFIXED32));
1643ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("int64"  , GetCppTypeNameForFieldType(FD::TYPE_SFIXED64));
1644ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("int32"  , GetCppTypeNameForFieldType(FD::TYPE_SINT32  ));
1645ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_STREQ("int64"  , GetCppTypeNameForFieldType(FD::TYPE_SINT64  ));
1646ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
1647ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(MiscTest, DefaultValues) {
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that setting default values works.
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto file_proto;
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_proto.set_name("foo.proto");
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum");
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddEnumValue(enum_type_proto, "A", 1);
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddEnumValue(enum_type_proto, "B", 2);
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef FieldDescriptorProto FD;  // avoid ugly line wrapping
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FD::Label label = FD::LABEL_OPTIONAL;
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create fields of every CPP type with default values.
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "int32" , 1, label, FD::TYPE_INT32 )
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("-1");
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "int64" , 2, label, FD::TYPE_INT64 )
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("-1000000000000");
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32)
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("42");
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64)
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("2000000000000");
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "float" , 5, label, FD::TYPE_FLOAT )
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("4.5");
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("10e100");
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "bool"  , 7, label, FD::TYPE_BOOL  )
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("true");
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "string", 8, label, FD::TYPE_STRING)
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("hello");
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "data"  , 9, label, FD::TYPE_BYTES )
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("\\001\\002\\003");
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldDescriptorProto* enum_field =
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM);
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum_field->set_type_name("DummyEnum");
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum_field->set_default_value("B");
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Strings are allowed to have empty defaults.  (At one point, due to
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a bug, empty defaults for strings were rejected.  Oops.)
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING)
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_default_value("");
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a second set of fields with implicit defalut values.
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_int32" , 21, label, FD::TYPE_INT32 );
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_int64" , 22, label, FD::TYPE_INT64 );
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32);
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64);
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_float" , 25, label, FD::TYPE_FLOAT );
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE);
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_bool"  , 27, label, FD::TYPE_BOOL  );
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING);
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_data"  , 29, label, FD::TYPE_BYTES );
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "implicit_enum"  , 30, label, FD::TYPE_ENUM)
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->set_type_name("DummyEnum");
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build it.
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool;
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file = pool.BuildFile(file_proto);
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file != NULL);
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, file->enum_type_count());
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* enum_type = file->enum_type(0);
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, enum_type->value_count());
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* enum_value_a = enum_type->value(0);
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* enum_value_b = enum_type->value(1);
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, file->message_type_count());
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* message = file->message_type(0);
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(21, message->field_count());
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the default values.
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(0)->has_default_value());
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(1)->has_default_value());
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(2)->has_default_value());
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(3)->has_default_value());
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(4)->has_default_value());
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(5)->has_default_value());
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(6)->has_default_value());
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(7)->has_default_value());
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(8)->has_default_value());
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(9)->has_default_value());
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message->field(10)->has_default_value());
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1              , message->field(0)->default_value_int32 ());
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-GOOGLE_ULONGLONG(1000000000000),
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message->field(1)->default_value_int64 ());
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(42              , message->field(2)->default_value_uint32());
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GOOGLE_ULONGLONG(2000000000000),
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message->field(3)->default_value_uint64());
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4.5             , message->field(4)->default_value_float ());
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10e100          , message->field(5)->default_value_double());
17423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(                message->field(6)->default_value_bool  ());
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello"         , message->field(7)->default_value_string());
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("\001\002\003"  , message->field(8)->default_value_string());
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(enum_value_b    , message->field(9)->default_value_enum  ());
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(""              , message->field(10)->default_value_string());
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(11)->has_default_value());
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(12)->has_default_value());
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(13)->has_default_value());
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(14)->has_default_value());
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(15)->has_default_value());
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(16)->has_default_value());
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(17)->has_default_value());
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(18)->has_default_value());
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(19)->has_default_value());
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(message->field(20)->has_default_value());
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0    , message->field(11)->default_value_int32 ());
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0    , message->field(12)->default_value_int64 ());
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0    , message->field(13)->default_value_uint32());
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0    , message->field(14)->default_value_uint64());
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0.0f , message->field(15)->default_value_float ());
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0.0  , message->field(16)->default_value_double());
17653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(    message->field(17)->default_value_bool  ());
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(""   , message->field(18)->default_value_string());
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(""   , message->field(19)->default_value_string());
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(MiscTest, FieldOptions) {
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try setting field options.
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto file_proto;
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_proto.set_name("foo.proto");
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddField(message_proto, "foo", 1,
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           FieldDescriptorProto::LABEL_OPTIONAL,
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           FieldDescriptorProto::TYPE_INT32);
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldDescriptorProto* bar_proto =
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddField(message_proto, "bar", 2,
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::LABEL_OPTIONAL,
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             FieldDescriptorProto::TYPE_INT32);
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldOptions* options = bar_proto->mutable_options();
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options->set_ctype(FieldOptions::CORD);
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build the descriptors and get the pointers.
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool;
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file = pool.BuildFile(file_proto);
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file != NULL);
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, file->message_type_count());
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* message = file->message_type(0);
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, message->field_count());
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* foo = message->field(0);
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* bar = message->field(1);
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "foo" had no options set, so it should return the default options.
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&FieldOptions::default_instance(), &foo->options());
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "bar" had options set.
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(&FieldOptions::default_instance(), options);
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(bar->options().has_ctype());
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
1811ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochenum DescriptorPoolMode {
1812ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  NO_DATABASE,
1813ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  FALLBACK_DATABASE
1814ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch};
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1816ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass AllowUnknownDependenciesTest
1817ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    : public testing::TestWithParam<DescriptorPoolMode> {
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1819ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DescriptorPoolMode mode() {
1820ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return GetParam();
1821ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch   }
1822ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto foo_proto, bar_proto;
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1826ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    switch (mode()) {
1827ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      case NO_DATABASE:
1828ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        pool_.reset(new DescriptorPool);
1829ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        break;
1830ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      case FALLBACK_DATABASE:
1831ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        pool_.reset(new DescriptorPool(&db_));
1832ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        break;
1833ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
1834ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1835ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    pool_->AllowUnknownDependencies();
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(TextFormat::ParseFromString(
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "name: 'foo.proto'"
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "dependency: 'bar.proto'"
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "dependency: 'baz.proto'"
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "message_type {"
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  name: 'Foo'"
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  field { name:'qux' number:3 label:LABEL_OPTIONAL"
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "    type_name: '.corge.Qux'"
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "    type: TYPE_ENUM"
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "    options {"
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "      uninterpreted_option {"
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "        name {"
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "          name_part: 'grault'"
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "          is_extension: true"
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "        }"
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "        positive_int_value: 1234"
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "      }"
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "    }"
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  }"
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "}",
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &foo_proto));
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(TextFormat::ParseFromString(
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "name: 'bar.proto'"
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "message_type { name: 'Bar' }",
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &bar_proto));
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Collect pointers to stuff.
1866ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    bar_file_ = BuildFile(bar_proto);
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(bar_file_ != NULL);
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, bar_file_->message_type_count());
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_type_ = bar_file_->message_type(0);
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1872ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    foo_file_ = BuildFile(foo_proto);
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(foo_file_ != NULL);
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, foo_file_->message_type_count());
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    foo_type_ = foo_file_->message_type(0);
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(3, foo_type_->field_count());
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bar_field_ = foo_type_->field(0);
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    baz_field_ = foo_type_->field(1);
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    qux_field_ = foo_type_->field(2);
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1884ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor* BuildFile(const FileDescriptorProto& proto) {
1885ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    switch (mode()) {
1886ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      case NO_DATABASE:
1887ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        return pool_->BuildFile(proto);
1888ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        break;
1889ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      case FALLBACK_DATABASE: {
1890ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        EXPECT_TRUE(db_.Add(proto));
1891ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        return pool_->FindFileByName(proto.name());
1892ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      }
1893ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
1894ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    GOOGLE_LOG(FATAL) << "Can't get here.";
1895ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return NULL;
1896ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1897ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* bar_file_;
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* bar_type_;
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo_file_;
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo_type_;
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* bar_field_;
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* baz_field_;
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* qux_field_;
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1906ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SimpleDescriptorDatabase db_;        // used if in FALLBACK_DATABASE mode.
1907ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  scoped_ptr<DescriptorPool> pool_;
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1910ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_P(AllowUnknownDependenciesTest, PlaceholderFile) {
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, foo_file_->dependency_count());
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_file_, foo_file_->dependency(0));
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* baz_file = foo_file_->dependency(1);
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("baz.proto", baz_file->name());
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, baz_file->message_type_count());
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Placeholder files should not be findable.
1919ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(bar_file_, pool_->FindFileByName(bar_file_->name()));
1920ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool_->FindFileByName(baz_file->name()) == NULL);
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1923ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) {
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bar_type_, bar_field_->message_type());
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* baz_type = baz_field_->message_type();
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Baz", baz_type->name());
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Baz", baz_type->full_name());
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Baz.placeholder.proto", baz_type->file()->name());
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, baz_type->extension_range_count());
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* qux_type = qux_field_->enum_type();
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Qux", qux_type->name());
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.Qux", qux_type->full_name());
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("corge.Qux.placeholder.proto", qux_type->file()->name());
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Placeholder types should not be findable.
1941ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name()));
1942ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool_->FindMessageTypeByName(baz_type->full_name()) == NULL);
1943ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool_->FindEnumTypeByName(qux_type->full_name()) == NULL);
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1946ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_P(AllowUnknownDependenciesTest, CopyTo) {
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FieldDescriptor::CopyTo() should write non-fully-qualified type names
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for placeholder types which were not originally fully-qualified.
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldDescriptorProto proto;
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Bar is not a placeholder, so it is fully-qualified.
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bar_field_->CopyTo(&proto);
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(".Bar", proto.type_name());
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type());
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Baz is an unqualified placeholder.
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto.Clear();
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  baz_field_->CopyTo(&proto);
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Baz", proto.type_name());
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(proto.has_type());
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Qux is a fully-qualified placeholder.
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proto.Clear();
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  qux_field_->CopyTo(&proto);
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(".corge.Qux", proto.type_name());
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1969ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_P(AllowUnknownDependenciesTest, CustomOptions) {
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Qux should still have the uninterpreted option attached.
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const UninterpretedOption& option =
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    qux_field_->options().uninterpreted_option(0);
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, option.name_size());
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("grault", option.name(0).name_part());
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1978ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_P(AllowUnknownDependenciesTest, UnknownExtendee) {
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we can extend an unknown type.  This is slightly tricky because
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it means that the placeholder type must have an extension range.
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto extension_proto;
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(TextFormat::ParseFromString(
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: 'extension.proto'"
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { extendee: 'UnknownType' name:'some_extension' number:123"
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            label:LABEL_OPTIONAL type:TYPE_INT32 }",
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    &extension_proto));
1989ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor* file = BuildFile(extension_proto);
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file != NULL);
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, file->extension_count());
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* extendee = file->extension(0)->containing_type();
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("UnknownType", extendee->name());
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, extendee->extension_range_count());
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, extendee->extension_range(0)->start);
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2001ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_P(AllowUnknownDependenciesTest, CustomOption) {
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that we can use a custom option without having parsed
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // descriptor.proto.
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto option_proto;
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(TextFormat::ParseFromString(
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"unknown_custom_options.proto\" "
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { "
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extendee: \"google.protobuf.FileOptions\" "
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"some_option\" "
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  number: 123456 "
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  label: LABEL_OPTIONAL "
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  type: TYPE_INT32 "
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "} "
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { "
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  uninterpreted_option { "
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    name { "
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name_part: \"some_option\" "
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      is_extension: true "
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    } "
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    positive_int_value: 1234 "
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  } "
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  uninterpreted_option { "
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    name { "
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name_part: \"unknown_option\" "
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      is_extension: true "
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    } "
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    positive_int_value: 1234 "
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  } "
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  uninterpreted_option { "
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    name { "
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name_part: \"optimize_for\" "
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      is_extension: false "
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    } "
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    identifier_value: \"SPEED\" "
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  } "
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    &option_proto));
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2042ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor* file = BuildFile(option_proto);
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file != NULL);
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that no extension options were set, but they were left as
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // uninterpreted_options.
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<const FieldDescriptor*> fields;
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file->options().GetReflection()->ListFields(file->options(), &fields);
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, fields.size());
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file->options().has_optimize_for());
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, file->options().uninterpreted_option_size());
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2054ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_P(AllowUnknownDependenciesTest,
2055ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       UndeclaredDependencyTriggersBuildOfDependency) {
2056ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Crazy case: suppose foo.proto refers to a symbol without declaring the
2057ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // dependency that finds it. In the event that the pool is backed by a
2058ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // DescriptorDatabase, the pool will attempt to find the symbol in the
2059ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // database. If successful, it will build the undeclared dependency to verify
2060ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // that the file does indeed contain the symbol. If that file fails to build,
2061ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // then its descriptors must be rolled back. However, we still want foo.proto
2062ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // to build successfully, since we are allowing unknown dependencies.
2063ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2064ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  FileDescriptorProto undeclared_dep_proto;
2065ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // We make this file fail to build by giving it two fields with tag 1.
2066ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_TRUE(TextFormat::ParseFromString(
2067ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"invalid_file_as_undeclared_dep.proto\" "
2068ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "package: \"undeclared\" "
2069ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type: {  "
2070ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  name: \"Quux\"  "
2071ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  field { "
2072ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "    name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 "
2073ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  }"
2074ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  field { "
2075ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "    name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 "
2076ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  }"
2077ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "}",
2078ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    &undeclared_dep_proto));
2079ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // We can't use the BuildFile() helper because we don't actually want to build
2080ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // it into the descriptor pool in the fallback database case: it just needs to
2081ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // be sitting in the database so that it gets built during the building of
2082ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // test.proto below.
2083ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  switch (mode()) {
2084ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case NO_DATABASE: {
2085ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ASSERT_TRUE(pool_->BuildFile(undeclared_dep_proto) == NULL);
2086ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      break;
2087ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
2088ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    case FALLBACK_DATABASE: {
2089ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ASSERT_TRUE(db_.Add(undeclared_dep_proto));
2090ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
2091ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
2092ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2093ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  FileDescriptorProto test_proto;
2094ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_TRUE(TextFormat::ParseFromString(
2095ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"test.proto\" "
2096ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type: { "
2097ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  name: \"Corge\" "
2098ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  field { "
2099ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "    name:'quux' number:1 label: LABEL_OPTIONAL "
2100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "    type_name:'undeclared.Quux' type: TYPE_MESSAGE "
2101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  }"
2102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "}",
2103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    &test_proto));
2104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor* file = BuildFile(test_proto);
2106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_TRUE(file != NULL);
2107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GOOGLE_LOG(INFO) << file->DebugString();
2108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(0, file->dependency_count());
2110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ(1, file->message_type_count());
2111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const Descriptor* corge_desc = file->message_type(0);
2112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ("Corge", corge_desc->name());
2113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ(1, corge_desc->field_count());
2114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FieldDescriptor* quux_field = corge_desc->field(0);
2116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, quux_field->type());
2117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ("Quux", quux_field->message_type()->name());
2118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ("undeclared.Quux", quux_field->message_type()->full_name());
2119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("undeclared.Quux.placeholder.proto",
2120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            quux_field->message_type()->file()->name());
2121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // The place holder type should not be findable.
2122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == NULL);
2123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
2124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochINSTANTIATE_TEST_CASE_P(DatabaseSource,
2126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                        AllowUnknownDependenciesTest,
2127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                        testing::Values(NO_DATABASE, FALLBACK_DATABASE));
2128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CustomOptions, OptionLocations) {
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* message =
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      protobuf_unittest::TestMessageWithCustomOptions::descriptor();
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file = message->file();
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* field = message->FindFieldByName("field1");
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(benjy): Support EnumValue options, once the compiler does.
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ServiceDescriptor* service =
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file->FindServiceByName("TestServiceWithCustomOptions");
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MethodDescriptor* method = service->FindMethodByName("Foo");
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GOOGLE_LONGLONG(9876543210),
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file->options().GetExtension(protobuf_unittest::file_opt1));
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-56,
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            message->options().GetExtension(protobuf_unittest::message_opt1));
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GOOGLE_LONGLONG(8765432109),
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field->options().GetExtension(protobuf_unittest::field_opt1));
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(42,  // Check that we get the default for an option we don't set.
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field->options().GetExtension(protobuf_unittest::field_opt2));
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-789,
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            enm->options().GetExtension(protobuf_unittest::enum_opt1));
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(123,
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            enm->value(1)->options().GetExtension(
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              protobuf_unittest::enum_value_opt1));
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GOOGLE_LONGLONG(-9876543210),
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            service->options().GetExtension(protobuf_unittest::service_opt1));
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            method->options().GetExtension(protobuf_unittest::method_opt1));
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See that the regular options went through unscathed.
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message->options().has_message_set_wire_format());
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FieldOptions::CORD, field->options().ctype());
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CustomOptions, OptionTypes) {
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MessageOptions* options = NULL;
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options =
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options();
21703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(        options->GetExtension(protobuf_unittest::bool_opt));
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint32_opt));
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint64_opt));
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt));
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt));
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed32_opt));
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed64_opt));
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt));
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt));
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options =
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options();
21843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(          options->GetExtension(protobuf_unittest::bool_opt));
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::int32_opt));
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::int64_opt));
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt));
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sint32_opt));
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sint64_opt));
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt));
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt));
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sfixed32_opt));
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sfixed64_opt));
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options =
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &protobuf_unittest::CustomOptionOtherValues::descriptor()->options();
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt));
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FLOAT_EQ(12.3456789,
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  options->GetExtension(protobuf_unittest::float_opt));
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(1.234567890123456789,
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   options->GetExtension(protobuf_unittest::double_opt));
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello, \"World\"",
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            options->GetExtension(protobuf_unittest::string_opt));
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(string("Hello\0World", 11),
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            options->GetExtension(protobuf_unittest::bytes_opt));
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            options->GetExtension(protobuf_unittest::enum_opt));
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options =
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options();
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt));
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt));
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  options =
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options();
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt));
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt));
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CustomOptions, ComplexExtensionOptions) {
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MessageOptions* options =
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &protobuf_unittest::VariousComplexOptions::descriptor()->options();
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::quux), 324);
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::corge).qux(), 876);
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::grault), 654);
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            743);
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::quux), 1999);
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::corge).qux(), 2008);
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::garply).foo(), 741);
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::garply).
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::quux), 1998);
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::garply).
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetExtension(protobuf_unittest::corge).qux(), 2121);
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      protobuf_unittest::ComplexOptionType2::ComplexOptionType4::complex_opt4).
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            waldo(), 1971);
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fred().waldo(), 321);
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux());
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3).
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                complexoptiontype5().plugh());
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CustomOptions, OptionsFromOtherFile) {
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that to use a custom option, we only need to import the file
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // defining the option; we do not also have to import descriptor.proto.
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool;
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto file_proto;
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->file()->CopyTo(&file_proto);
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(TextFormat::ParseFromString(
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"custom_options_import.proto\" "
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: \"protobuf_unittest\" "
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/unittest_custom_options.proto\" "
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { "
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  uninterpreted_option { "
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    name { "
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name_part: \"file_opt1\" "
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      is_extension: true "
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    } "
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    positive_int_value: 1234 "
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  } "
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test a non-extension option too.  (At one point this failed due to a
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // bug.)
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  uninterpreted_option { "
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    name { "
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name_part: \"java_package\" "
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      is_extension: false "
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    } "
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    string_value: \"foo\" "
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  } "
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test that enum-typed options still work too.  (At one point this also
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // failed due to a bug.)
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  uninterpreted_option { "
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    name { "
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name_part: \"optimize_for\" "
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      is_extension: false "
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    } "
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    identifier_value: \"SPEED\" "
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  } "
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}"
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ,
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    &file_proto));
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file = pool.BuildFile(file_proto);
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file != NULL);
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1));
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file->options().has_java_package());
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo", file->options().java_package());
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file->options().has_optimize_for());
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for());
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CustomOptions, MessageOptionThreeFieldsSet) {
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This tests a bug which previously existed in custom options parsing.  The
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bug occurred when you defined a custom option with message type and then
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // set three fields of that option on a single definition (see the example
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // below).  The bug is a bit hard to explain, so check the change history if
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // you want to know more.
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool;
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto file_proto;
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ->file()->CopyTo(&file_proto);
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following represents the definition:
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   import "google/protobuf/unittest_custom_options.proto"
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   package protobuf_unittest;
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   message Foo {
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     option (complex_opt1).foo  = 1234;
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     option (complex_opt1).foo2 = 1234;
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     option (complex_opt1).foo3 = 1234;
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   }
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(TextFormat::ParseFromString(
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"custom_options_import.proto\" "
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: \"protobuf_unittest\" "
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/unittest_custom_options.proto\" "
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { "
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\" "
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  options { "
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    uninterpreted_option { "
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name { "
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        name_part: \"complex_opt1\" "
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        is_extension: true "
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      } "
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name { "
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        name_part: \"foo\" "
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        is_extension: false "
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      } "
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      positive_int_value: 1234 "
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    } "
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    uninterpreted_option { "
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name { "
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        name_part: \"complex_opt1\" "
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        is_extension: true "
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      } "
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name { "
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        name_part: \"foo2\" "
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        is_extension: false "
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      } "
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      positive_int_value: 1234 "
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    } "
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    uninterpreted_option { "
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name { "
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        name_part: \"complex_opt1\" "
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        is_extension: true "
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      } "
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      name { "
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        name_part: \"foo3\" "
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "        is_extension: false "
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      } "
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "      positive_int_value: 1234 "
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    } "
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  } "
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    &file_proto));
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file = pool.BuildFile(file_proto);
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file != NULL);
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, file->message_type_count());
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MessageOptions& options = file->message_type(0)->options();
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that aggregate options were parsed and saved correctly in
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the appropriate descriptors.
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(CustomOptions, AggregateOptions) {
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor();
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file = msg->file();
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* field = msg->FindFieldByName("fieldname");
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ServiceDescriptor* service = file->FindServiceByName(
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "AggregateService");
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MethodDescriptor* method = service->FindMethodByName("Method");
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests for the different types of data embedded in fileopt
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const protobuf_unittest::Aggregate& file_options =
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file->options().GetExtension(protobuf_unittest::fileopt);
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, file_options.i());
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("FileAnnotation", file_options.s());
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("FileExtensionAnnotation",
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_options.file().GetExtension(protobuf_unittest::fileopt).s());
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("EmbeddedMessageSetElement",
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_options.mset().GetExtension(
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                protobuf_unittest::AggregateMessageSetElement
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ::message_set_extension).s());
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simple tests for all the other types of annotations
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MessageAnnotation",
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            msg->options().GetExtension(protobuf_unittest::msgopt).s());
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("FieldAnnotation",
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            field->options().GetExtension(protobuf_unittest::fieldopt).s());
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("EnumAnnotation",
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            enumd->options().GetExtension(protobuf_unittest::enumopt).s());
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("EnumValueAnnotation",
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("ServiceAnnotation",
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            service->options().GetExtension(protobuf_unittest::serviceopt).s());
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MethodAnnotation",
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            method->options().GetExtension(protobuf_unittest::methodopt).s());
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The tests below trigger every unique call to AddError() in descriptor.cc,
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the order in which they appear in that file.  I'm using TextFormat here
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to specify the input descriptors because building them using code would
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be too bulky.
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockErrorCollector : public DescriptorPool::ErrorCollector {
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockErrorCollector() {}
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~MockErrorCollector() {}
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string text_;
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // implements ErrorCollector ---------------------------------------
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddError(const string& filename,
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                const string& element_name, const Message* descriptor,
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ErrorLocation location, const string& message) {
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* location_name = NULL;
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (location) {
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case NAME         : location_name = "NAME"         ; break;
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case NUMBER       : location_name = "NUMBER"       ; break;
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case TYPE         : location_name = "TYPE"         ; break;
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case EXTENDEE     : location_name = "EXTENDEE"     ; break;
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case OPTION_NAME  : location_name = "OPTION_NAME"  ; break;
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case INPUT_TYPE   : location_name = "INPUT_TYPE"   ; break;
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case OUTPUT_TYPE  : location_name = "OUTPUT_TYPE"  ; break;
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case OTHER        : location_name = "OTHER"        ; break;
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strings::SubstituteAndAppend(
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &text_, "$0: $1: $2: $3\n",
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      filename, element_name, location_name, message);
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ValidationErrorTest : public testing::Test {
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse file_text as a FileDescriptorProto in text format and add it
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the DescriptorPool.  Expect no errors.
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BuildFile(const string& file_text) {
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto file_proto;
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse file_text as a FileDescriptorProto in text format and add it
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the DescriptorPool.  Expect errors to be produced which match the
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // given error text.
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BuildFileWithErrors(const string& file_text,
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const string& expected_errors) {
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto file_proto;
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockErrorCollector error_collector;
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pool_.BuildFileCollectingErrors(file_proto, &error_collector) == NULL);
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_errors, error_collector.text_);
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Builds some already-parsed file in our test pool.
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BuildFileInTestPool(const FileDescriptor* file) {
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto file_proto;
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file->CopyTo(&file_proto);
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build descriptor.proto in our test pool. This allows us to extend it in
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the test pool, so we can test custom options.
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BuildDescriptorMessagesInTestPool() {
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BuildFileInTestPool(DescriptorProto::descriptor()->file());
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool_;
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, AlreadyDefined) {
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" }"
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" }",
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: \"foo.bar\" "
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" }"
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" }",
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"foo.bar\".\n");
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" }");
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"bar.proto\" "
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" }",
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "bar.proto: Foo: NAME: \"Foo\" is already defined in file "
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"foo.proto\".\n");
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"foo\" }");
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"bar.proto\" "
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: \"foo.bar\"",
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "bar.proto: foo: NAME: \"foo\" is already defined (as something other "
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "than a package) in file \"foo.proto\".\n");
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) {
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "meaning that enum values are siblings of their type, not children of "
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "it.  Therefore, \"FOO\" must be unique within the global scope, not "
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "just within \"Bar\".\n");
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: \"pkg\" "
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "meaning that enum values are siblings of their type, not children of "
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "it.  Therefore, \"FOO\" must be unique within \"pkg\", not just within "
25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"Bar\".\n");
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, MissingName) {
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { }",
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: : NAME: Missing name.\n");
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, InvalidName) {
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"$\" }",
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, InvalidPackageName) {
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: \"foo.$\"",
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, MissingFileName) {
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "",
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ": : OTHER: Missing field: FileDescriptorProto.name.\n");
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, DupeDependency) {
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile("name: \"foo.proto\"");
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"bar.proto\" "
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"foo.proto\" "
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"foo.proto\" ",
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "bar.proto: bar.proto: OTHER: Import \"foo.proto\" was listed twice.\n");
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, UnknownDependency) {
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"bar.proto\" "
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"foo.proto\" ",
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n");
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2631ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) {
2632ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile("name: \"foo.proto\"");
2633ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFileWithErrors(
2634ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"bar.proto\" "
2635ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"foo.proto\" "
2636ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "public_dependency: 1",
2637ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n");
2638ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
2639ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to crash:  If we depend on a non-existent file and then refer to a
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // package defined in a file that we didn't import, and that package is
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // nested within a parent package which this file is also in, and we don't
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // include that parent package in the name (i.e. we do a relative lookup)...
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Yes, really.
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: 'foo.proto' "
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: 'outer.foo' ");
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: 'bar.proto' "
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: 'baz.proto' "
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: 'outer.bar' "
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { "
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: 'Bar' "
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }"
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "bar.proto: bar.proto: OTHER: Import \"baz.proto\" has not been loaded.\n"
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined in "
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"foo.proto\", which is not imported by \"bar.proto\".  To use it here, "
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "please add the necessary import.\n");
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, DupeFile) {
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" }");
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note:  We should *not* get redundant errors about "Foo" already being
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   defined.
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" } "
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Add another type so that the files aren't identical (in which case there
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // would be no error).
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Bar\" }",
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OTHER: A file with this name is already in the "
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "pool.\n");
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, FieldInExtensionRange) {
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"foo\" number:  9 label:LABEL_OPTIONAL type:TYPE_INT32 }"
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 }"
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 }"
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 }"
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 10 end: 20 }"
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"bar\" (10).\n"
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"baz\" (19).\n");
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 10 end: 20 }"
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 20 end: 30 }"
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 19 end: 21 }"
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "already-defined range 10 to 19.\n"
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "already-defined range 20 to 29.\n");
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, InvalidDefaults) {
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Invalid number.
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          default_value: \"abc\" }"
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Empty default value.
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          default_value: \"\" }"
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Invalid boolean.
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          default_value: \"abc\" }"
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Messages can't have defaults.
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: TYPE_MESSAGE"
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          default_value: \"abc\" type_name: \"Foo\" }"
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Same thing, but we don't know that this field has message type until
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we look up the type name.
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          default_value: \"abc\" type_name: \"Foo\" }"
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Repeateds can't have defaults.
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"corge\" number: 6 label: LABEL_REPEATED type: TYPE_INT32"
27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          default_value: \"1\" }"
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n"
27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value.\n"
27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "false.\n"
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default "
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "values.\n"
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This ends up being reported later because the error is detected at
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cross-linking time.
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "values.\n");
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, NegativeFieldNumber) {
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, HugeFieldNumber) {
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"foo\" number: 0x70000000 "
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          label:LABEL_OPTIONAL type:TYPE_INT32 }"
27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "536870911.\n");
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, ReservedFieldNumber) {
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "reserved for the protocol buffer library implementation.\n"
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "reserved for the protocol buffer library implementation.\n");
27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "              type_name: \"Foo\" }"
28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "extension field.\n");
28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Bar\""
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 1 end: 2 }"
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}"
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name: \"Foo\" extendee: \"Bar\" }"
28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "non-extension field.\n");
28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, FieldNumberConflict) {
28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"Foo\" by field \"foo\".\n");
28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"MessageSet\""
28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  options { message_set_wire_format: true }"
28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 4 end: 5 }"
28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}"
28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "              extendee: \"MessageSet\" }"
28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "messages.\n");
28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"MessageSet\""
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  options { message_set_wire_format: true }"
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 4 end: 5 }"
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}"
28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension { name:\"foo\" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE"
28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "              type_name: \"Foo\" extendee: \"MessageSet\" }"
28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "messages.\n");
28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, FieldInMessageSet) {
28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  options { message_set_wire_format: true }"
28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "extensions.\n");
28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: -10 end: -1 }"
28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 1 end: 0x70000000 }"
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "536870911.\n");
29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 10 end: 10 }"
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 10 end: 5 }"
29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "start number.\n"
29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "start number.\n");
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, EmptyEnum) {
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Foo\" }"
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Also use the empty enum in a message to make sure there are no crashes
29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // during validation (possible if the code attempts to derive a default
29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // value for the field).
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Bar\""
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type_name:\"Foo\" }"
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"bar\" number: 2 label:LABEL_OPTIONAL type_name:\"Foo\" "
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          default_value: \"NO_SUCH_VALUE\" }"
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo: NAME: Enums must contain at least one value.\n"
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"NO_SUCH_VALUE\".\n");
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, UndefinedExtendee) {
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "              extendee: \"Bar\" }"
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, NonMessageExtendee) {
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "              extendee: \"Bar\" }"
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Bar\""
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}"
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "              extendee: \"Bar\" }"
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "number.\n");
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, UndefinedFieldType) {
29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"bar.proto\" "
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Bar\" } ");
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "which is not imported by \"foo.proto\".  To use it here, please add the "
30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "necessary import.\n");
30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3018ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) {
3019ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Test for hidden dependencies.
3020ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3021ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // bar.proto
3022ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // message Bar{}
3023ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3024ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // forward.proto
3025ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import "bar.proto"
3026ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3027ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // foo.proto
3028ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import "forward.proto"
3029ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // message Foo {
3030ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //   optional Bar foo = 1;  // Error, needs to import bar.proto explicitly.
3031ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // }
3032ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3033ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3034ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"bar.proto\" "
3035ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type { name: \"Bar\" }");
3036ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3037ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3038ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"forward.proto\""
3039ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"bar.proto\"");
3040ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3041ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFileWithErrors(
3042ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"foo.proto\" "
3043ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"forward.proto\" "
3044ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type {"
3045ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  name: \"Foo\""
3046ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
3047ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "}",
3048ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
3049ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "which is not imported by \"foo.proto\".  To use it here, please add the "
3050ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "necessary import.\n");
3051ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
3052ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3053ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) {
3054ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Test for public dependencies.
3055ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3056ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // bar.proto
3057ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // message Bar{}
3058ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3059ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // forward.proto
3060ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import public "bar.proto"
3061ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3062ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // foo.proto
3063ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import "forward.proto"
3064ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // message Foo {
3065ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //   optional Bar foo = 1;  // Correct. "bar.proto" is public imported into
3066ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //                          // forward.proto, so when "foo.proto" imports
3067ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //                          // "forward.proto", it imports "bar.proto" too.
3068ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // }
3069ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3070ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3071ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"bar.proto\" "
3072ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type { name: \"Bar\" }");
3073ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3074ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3075ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"forward.proto\""
3076ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"bar.proto\" "
3077ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "public_dependency: 0");
3078ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3079ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3080ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"foo.proto\" "
3081ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"forward.proto\" "
3082ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type {"
3083ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  name: \"Foo\""
3084ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
3085ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "}");
3086ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
3087ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3088ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) {
3089ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Test for public dependencies.
3090ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3091ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // bar.proto
3092ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // message Bar{}
3093ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3094ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // forward.proto
3095ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import public "bar.proto"
3096ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3097ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // forward2.proto
3098ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import public "forward.proto"
3099ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // foo.proto
3101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import "forward2.proto"
3102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // message Foo {
3103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //   optional Bar foo = 1;  // Correct, public imports are transitive.
3104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // }
3105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"bar.proto\" "
3108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type { name: \"Bar\" }");
3109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"forward.proto\""
3112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"bar.proto\" "
3113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "public_dependency: 0");
3114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"forward2.proto\""
3117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"forward.proto\" "
3118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "public_dependency: 0");
3119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"foo.proto\" "
3122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"forward2.proto\" "
3123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type {"
3124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  name: \"Foo\""
3125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
3126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "}");
3127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
3128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(ValidationErrorTest,
3130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       FieldTypeDefinedInPrivateDependencyOfPublicDependency) {
3131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Test for public dependencies.
3132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // bar.proto
3134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // message Bar{}
3135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // forward.proto
3137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import "bar.proto"
3138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // forward2.proto
3140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import public "forward.proto"
3141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // // foo.proto
3143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // import "forward2.proto"
3144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // message Foo {
3145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //   optional Bar foo = 1;  // Error, the "bar.proto" is not public imported
3146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //                          // into "forward.proto", so will not be imported
3147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //                          // into either "forward2.proto" or "foo.proto".
3148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // }
3149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  //
3150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"bar.proto\" "
3152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type { name: \"Bar\" }");
3153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"forward.proto\""
3156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"bar.proto\"");
3157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFile(
3159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"forward2.proto\""
3160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"forward.proto\" "
3161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "public_dependency: 0");
3162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFileWithErrors(
3164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"foo.proto\" "
3165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dependency: \"forward2.proto\" "
3166ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "message_type {"
3167ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  name: \"Foo\""
3168ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
3169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "}",
3170ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
3171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "which is not imported by \"foo.proto\".  To use it here, please add the "
3172ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "necessary import.\n");
3173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
3174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following should produce an error that Bar.Baz is not defined:
31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   message Bar { message Baz {} }
31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   message Foo {
31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     message Bar {
31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       // Placing "message Baz{}" here, or removing Foo.Bar altogether,
31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       // would fix the error.
31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     }
31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     optional Bar.Baz baz = 1;
31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   }
31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An one point the lookup code incorrectly did not produce an error in this
31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first,
31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually
31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // refer to the inner Bar, not the outer one.
31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Bar\""
31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  nested_type { name: \"Baz\" }"
31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}"
31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  nested_type { name: \"Bar\" }"
31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name:\"Bar.Baz\" }"
32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n");
32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test would find the most local "Bar" first, and does, but
32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proceeds to find the outer one because the inner one's not an
32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // aggregate.
32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Bar\""
32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  nested_type { name: \"Baz\" }"
32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}"
32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name: \"Bar\" number:1 type:TYPE_BYTES } "
32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name:\"Bar.Baz\" }"
32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}");
32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Imagine we have the following:
32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // foo.proto:
32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   package foo.bar;
32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bar.proto:
32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   package foo.bar;
32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   import "foo.proto";
32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   message Bar {}
32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // baz.proto:
32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   package foo;
32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   import "bar.proto"
32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   message Baz { optional bar.Bar qux = 1; }
32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When validating baz.proto, we will look up "bar.Bar".  As part of this
32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // lookup, we first lookup "bar" then try to find "Bar" within it.  "bar"
32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should resolve to "foo.bar".  Note, though, that "foo.bar" was originally
32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // defined in foo.proto, which is not a direct dependency of baz.proto.  The
32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // implementation of FindSymbol() normally only returns symbols in direct
32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dependencies, not indirect ones.  This test insures that this does not
32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // prevent it from finding "foo.bar".
32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: \"foo.bar\" ");
32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"bar.proto\" "
32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: \"foo.bar\" "
32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"foo.proto\" "
32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Bar\" }");
32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"baz.proto\" "
32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "package: \"foo\" "
32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"bar.proto\" "
32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { "
32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Baz\" "
32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name:\"bar.Bar\" }"
32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}");
32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, FieldTypeNotAType) {
32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name:\".Foo.bar\" }"
32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  nested_type {"
32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    name: \"Bar\""
32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  }"
32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name:\"Bar.Baz\" }"
32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Bar\""
32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}"
32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}");
33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Bar\" } "
33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name:\"Bar\" }"
33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name:\"Bar\" }"
33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          default_value:\"NO_SUCH_VALUE\" }"
33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"NO_SUCH_VALUE\".\n");
33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name:\"Foo\" }"
33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "type_name.\n");
33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, InputTypeNotDefined) {
33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" } "
33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "service {"
33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestService\""
33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3378ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"
3379ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    );
33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" } "
33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "service {"
33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestService\""
33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3392ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"
3393ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    );
33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" } "
34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "service {"
34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestService\""
34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"
3406ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    );
34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" } "
34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "service {"
34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestService\""
34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3419ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"
3420ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    );
34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3423ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, IllegalPackedField) {
34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {\n"
34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Foo\""
34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type:TYPE_STRING "
34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          options { uninterpreted_option {"
34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            name { name_part: \"packed\" is_extension: false }"
34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            identifier_value: \"true\" }}}\n"
34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type_name: \"Foo\""
34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          options { uninterpreted_option {"
34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            name { name_part: \"packed\" is_extension: false }"
34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            identifier_value: \"true\" }}}\n"
34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          type:TYPE_INT32 "
34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          options { uninterpreted_option {"
34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            name { name_part: \"packed\" is_extension: false }"
34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            identifier_value: \"true\" }}}\n"
34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "specified for repeated primitive fields.\n"
34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "specified for repeated primitive fields.\n"
34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "specified for repeated primitive fields.\n"
34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        );
34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, OptionWrongType) {
34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { "
34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestMessage\" "
34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          options { uninterpreted_option { name { name_part: \"ctype\" "
34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                                  is_extension: false }"
34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                           positive_int_value: 1 }"
34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          }"
34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  }"
34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}\n",
34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { "
34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestMessage\" "
34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          options { uninterpreted_option { name { name_part: \"ctype\" "
34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                                  is_extension: false }"
34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                           name { name_part: \"foo\" "
34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                                  is_extension: true }"
34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                           positive_int_value: 1 }"
34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          }"
34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  }"
34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}\n",
34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "atomic type, not a message.\n");
34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, DupOption) {
34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { "
34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestMessage\" "
34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          options { uninterpreted_option { name { name_part: \"ctype\" "
34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                                  is_extension: false }"
34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                           identifier_value: \"CORD\" }"
35005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                    uninterpreted_option { name { name_part: \"ctype\" "
35015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                                  is_extension: false }"
35025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                           identifier_value: \"CORD\" }"
35035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          }"
35045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  }"
35055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}\n",
35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "already set.\n");
35095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, InvalidOptionName) {
35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { "
35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestMessage\" "
35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          options { uninterpreted_option { "
35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                      name { name_part: \"uninterpreted_option\" "
35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                             is_extension: false }"
35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                      positive_int_value: 1 "
35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                    }"
35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "          }"
35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  }"
35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}\n",
35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "reserved name \"uninterpreted_option\".\n");
35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, RepeatedOption) {
35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_REPEATED "
35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 double_value: 1.2 } }",
35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_NAME: Option field \"(foo)\" is repeated. "
35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Repeated options are not supported.\n");
35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
35585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
35595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
35625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
35635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
35655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
35695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 positive_int_value: 0x80000000 } "
35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for int32 option \"foo\".\n");
35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 negative_int_value: -0x80000001 } "
35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for int32 option \"foo\".\n");
35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 string_value: \"5\" } }",
36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for int32 option \"foo\".\n");
36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 positive_int_value: 0x8000000000000000 } "
36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for int64 option \"foo\".\n");
36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 identifier_value: \"5\" } }",
36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for int64 option \"foo\".\n");
36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 positive_int_value: 0x100000000 } }",
36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for uint32 option \"foo\".\n");
36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 double_value: -5.6 } }",
36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for uint32 option \"foo\".\n");
36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 negative_int_value: -5 } }",
36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for uint64 option \"foo\".\n");
36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 string_value: \"bar\" } }",
37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for float option \"foo\".\n");
37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 string_value: \"bar\" } }",
37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for double option \"foo\".\n");
37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 identifier_value: \"bar\" } }",
37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "for boolean option \"foo\".\n");
37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                              value { name: \"BAZ\" number: 2 } }"
37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_ENUM type_name: \"FooEnum\" "
37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            extendee: \"google.protobuf.FileOptions\" }"
37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 string_value: \"QUUX\" } }",
37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum-valued option \"foo\".\n");
37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                              value { name: \"BAZ\" number: 2 } }"
37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_ENUM type_name: \"FooEnum\" "
37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            extendee: \"google.protobuf.FileOptions\" }"
37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 identifier_value: \"QUUX\" } }",
37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "named \"QUUX\" for option \"foo\".\n");
37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
37855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                               value { name: \"BAZ\" number: 2 } }"
37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                               value { name: \"QUUX\" number: 2 } }"
37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
37895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_ENUM type_name: \"FooEnum1\" "
37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            extendee: \"google.protobuf.FileOptions\" }"
37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
37935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 identifier_value: \"QUUX\" } }",
37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "named \"QUUX\" for option \"foo\". This appears to be a value from a "
37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "sibling type.\n");
37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
38015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"google/protobuf/descriptor.proto\" "
38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { uninterpreted_option { name { name_part: \"foo\" "
38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                        is_extension: true } "
38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                                 identifier_value: \"QUUX\" } }",
38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string for "
38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "string option \"foo\".\n");
38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper function for tests that check for aggregate value parsing
38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// errors.  The "value" argument is embedded inside the
38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "uninterpreted_option" portion of the result.
38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static string EmbedAggregateValue(const char* value) {
38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return strings::Substitute(
38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "name: \"foo.proto\" "
38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "dependency: \"google/protobuf/descriptor.proto\" "
38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "message_type { name: \"Foo\" } "
38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "            type: TYPE_MESSAGE type_name: \"Foo\" "
38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "            extendee: \"google.protobuf.FileOptions\" }"
38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "options { uninterpreted_option { name { name_part: \"foo\" "
38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "                                        is_extension: true } "
38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "                                 $0 } }",
38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      value);
38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, AggregateValueNotFound) {
38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EmbedAggregateValue("string_value: \"\""),
38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "To set the entire message, use syntax like "
38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\"foo = { <proto text format> }\". To set fields within it, use "
38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "syntax like \"foo.foo = value\".\n");
38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, AggregateValueParseError) {
38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EmbedAggregateValue("aggregate_value: \"1+2\""),
38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "value for \"foo\": Expected identifier.\n");
38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildDescriptorMessagesInTestPool();
38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EmbedAggregateValue("aggregate_value: \"x:100\""),
38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, NotLiteImportsLite) {
38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"bar.proto\" "
38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { optimize_for: LITE_RUNTIME } ");
38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"bar.proto\" ",
38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: foo.proto: OTHER: Files that do not use optimize_for = "
38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "LITE_RUNTIME cannot import files which do use this option.  This file "
38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "is not lite, but it imports \"bar.proto\" which is.\n");
38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"bar.proto\" "
38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type: {"
38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"Bar\""
38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  extension_range { start: 1 end: 1000 }"
38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}");
38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "dependency: \"bar.proto\" "
38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options { optimize_for: LITE_RUNTIME } "
38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL "
38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "            type: TYPE_INT32 extendee: \"Bar\" }",
38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be "
38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "declared in non-lite files.  Note that you cannot extend a non-lite "
38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "type to contain a lite type, but the reverse is allowed.\n");
38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, NoLiteServices) {
38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options {"
39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  optimize_for: LITE_RUNTIME"
39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  cc_generic_services: true"
39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  java_generic_services: true"
39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "} "
39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "service { name: \"Foo\" }",
39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "define services unless you set both options cc_generic_services and "
39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "java_generic_sevices to false.\n");
39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"bar.proto\" "
39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "options {"
39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  optimize_for: LITE_RUNTIME"
39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  cc_generic_services: false"
39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  java_generic_services: false"
39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "} "
39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "service { name: \"Bar\" }");
39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, RollbackAfterError) {
39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build a file which contains every kind of construct but references an
39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // undefined type.  All these constructs will be added to the symbol table
39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // before the undefined type error is noticed.  The DescriptorPool will then
39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have to roll everything back.
39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFileWithErrors(
39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestMessage\""
39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "} "
39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type {"
39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestEnum\""
39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  value { name:\"BAR\" number:1 }"
39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "} "
39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "service {"
39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestService\""
39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  method {"
39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    name: \"Baz\""
39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    input_type: \"NoSuchType\""    // error
39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    output_type: \"TestMessage\""
39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  }"
39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}",
39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3944ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"
3945ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    );
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that if we build the same file again with the error fixed,
39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it works.  If the above rollback was incomplete, then some symbols will
39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be left defined, and this second attempt will fail since it tries to
39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // re-define the same symbols.
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BuildFile(
39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type {"
39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestMessage\""
39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "} "
39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "enum_type {"
39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestEnum\""
39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  value { name:\"BAR\" number:1 }"
39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "} "
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "service {"
39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  name: \"TestService\""
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  method { name:\"Baz\""
39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "           input_type:\"TestMessage\""
39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "           output_type:\"TestMessage\" }"
39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}");
39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is
39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // provided.
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto file_proto;
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(TextFormat::ParseFromString(
39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "name: \"foo.proto\" "
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" } "
39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "message_type { name: \"Foo\" } ",
39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    &file_proto));
39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL);
39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, errors.size());
39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]);
39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("  Foo: \"Foo\" is already defined.", errors[1]);
39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3994ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(ValidationErrorTest, DisallowEnumAlias) {
3995ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  BuildFileWithErrors(
3996ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "name: \"foo.proto\" "
3997ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "enum_type {"
3998ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  name: \"Bar\""
3999ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  value { name:\"ENUM_A\" number:0 }"
4000ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  value { name:\"ENUM_B\" number:0 }"
4001ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  options { allow_alias: false }"
4002ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "}",
4003ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "foo.proto: Bar: NUMBER: "
40043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "\"ENUM_B\" uses the same enum value as \"ENUM_A\". "
40053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "If this is intended, set 'option allow_alias = true;' to the enum "
40063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "definition.\n");
4007ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
4008ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DescriptorDatabase
40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void AddToDatabase(SimpleDescriptorDatabase* database,
40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const char* file_text) {
40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto file_proto;
40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  database->Add(file_proto);
40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DatabaseBackedPoolTest : public testing::Test {
40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DatabaseBackedPoolTest() {}
40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleDescriptorDatabase database_;
40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddToDatabase(&database_,
4027ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "name: 'foo.proto' "
4028ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "message_type { name:'Foo' extension_range { start: 1 end: 100 } } "
4029ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } "
4030ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "service { name:'TestService' } ");
40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddToDatabase(&database_,
4032ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "name: 'bar.proto' "
4033ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "dependency: 'foo.proto' "
4034ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "message_type { name:'Bar' } "
4035ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "extension { name:'foo_ext' extendee: '.Foo' number:5 "
40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "            label:LABEL_OPTIONAL type:TYPE_INT32 } ");
4037ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Baz has an undeclared dependency on Foo.
4038ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    AddToDatabase(&database_,
4039ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "name: 'baz.proto' "
4040ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "message_type { "
4041ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "  name:'Baz' "
4042ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "  field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } "
4043ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "}");
40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We can't inject a file containing errors into a DescriptorPool, so we
40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // need an actual mock DescriptorDatabase to test errors.
40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class ErrorDescriptorDatabase : public DescriptorDatabase {
40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ErrorDescriptorDatabase() {}
40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~ErrorDescriptorDatabase() {}
40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // implements DescriptorDatabase ---------------------------------
40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool FindFileByName(const string& filename,
40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        FileDescriptorProto* output) {
40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // error.proto and error2.proto cyclically import each other.
40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (filename == "error.proto") {
40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output->Clear();
40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output->set_name("error.proto");
40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output->add_dependency("error2.proto");
40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (filename == "error2.proto") {
40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output->Clear();
40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output->set_name("error2.proto");
40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output->add_dependency("error.proto");
40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool FindFileContainingSymbol(const string& symbol_name,
40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  FileDescriptorProto* output) {
40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool FindFileContainingExtension(const string& containing_type,
40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int field_number,
40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     FileDescriptorProto* output) {
40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A DescriptorDatabase that counts how many times each method has been
40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called and forwards to some other DescriptorDatabase.
40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class CallCountingDatabase : public DescriptorDatabase {
40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CallCountingDatabase(DescriptorDatabase* wrapped_db)
40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : wrapped_db_(wrapped_db) {
40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Clear();
40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~CallCountingDatabase() {}
40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorDatabase* wrapped_db_;
40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int call_count_;
40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Clear() {
40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      call_count_ = 0;
40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // implements DescriptorDatabase ---------------------------------
41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool FindFileByName(const string& filename,
41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        FileDescriptorProto* output) {
41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++call_count_;
41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return wrapped_db_->FindFileByName(filename, output);
41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool FindFileContainingSymbol(const string& symbol_name,
41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  FileDescriptorProto* output) {
41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++call_count_;
41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool FindFileContainingExtension(const string& containing_type,
41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int field_number,
41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     FileDescriptorProto* output) {
41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++call_count_;
41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return wrapped_db_->FindFileContainingExtension(
41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        containing_type, field_number, output);
41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A DescriptorDatabase which falsely always returns foo.proto when searching
41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for any symbol or extension number.  This shouldn't cause the
41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DescriptorPool to reload foo.proto if it is already loaded.
41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class FalsePositiveDatabase : public DescriptorDatabase {
41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FalsePositiveDatabase(DescriptorDatabase* wrapped_db)
41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : wrapped_db_(wrapped_db) {}
41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~FalsePositiveDatabase() {}
41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DescriptorDatabase* wrapped_db_;
41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // implements DescriptorDatabase ---------------------------------
41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool FindFileByName(const string& filename,
41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        FileDescriptorProto* output) {
41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return wrapped_db_->FindFileByName(filename, output);
41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool FindFileContainingSymbol(const string& symbol_name,
41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  FileDescriptorProto* output) {
41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FindFileByName("foo.proto", output);
41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool FindFileContainingExtension(const string& containing_type,
41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int field_number,
41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     FileDescriptorProto* output) {
41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FindFileByName("foo.proto", output);
41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, FindFileByName) {
41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&database_);
41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(foo != NULL);
41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo.proto", foo->name());
41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, foo->message_type_count());
41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Foo", foo->message_type(0)->name());
41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo, pool.FindFileByName("foo.proto"));
41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == NULL);
41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&database_);
41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(foo != NULL);
41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo.proto", foo->name());
41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, foo->message_type_count());
41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Foo", foo->message_type(0)->name());
41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* bar = pool.FindFileByName("bar.proto");
41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(bar != NULL);
41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bar.proto", bar->name());
41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, bar->message_type_count());
41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Bar", bar->message_type(0)->name());
41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, bar->dependency_count());
41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo, bar->dependency(0));
41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&database_);
41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* bar = pool.FindFileByName("bar.proto");
41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(bar != NULL);
41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("bar.proto", bar->name());
41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, bar->message_type_count());
41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ("Bar", bar->message_type(0)->name());
41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* foo = pool.FindFileByName("foo.proto");
41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(foo != NULL);
41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo.proto", foo->name());
41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, foo->message_type_count());
41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ("Foo", foo->message_type(0)->name());
41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, bar->dependency_count());
41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(foo, bar->dependency(0));
41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) {
42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&database_);
42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file = pool.FindFileContainingSymbol("Foo");
42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file != NULL);
42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo.proto", file->name());
42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(file, pool.FindFileByName("foo.proto"));
42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == NULL);
42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&database_);
42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* type = pool.FindMessageTypeByName("Foo");
42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(type != NULL);
42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Foo", type->name());
42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto"));
42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == NULL);
42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) {
42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&database_);
42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(foo != NULL);
42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5);
42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(extension != NULL);
42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("foo_ext", extension->name());
42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto"));
42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL);
42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, FindAllExtensions) {
42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&database_);
42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Repeat the lookup twice, to check that we get consistent
42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // results despite the fallback database lookup mutating the pool.
42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vector<const FieldDescriptor*> extensions;
42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pool.FindAllExtensions(foo, &extensions);
42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(1, extensions.size());
42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(5, extensions[0]->number());
42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ErrorDescriptorDatabase error_database;
42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&error_database);
42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog log;
42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = log.GetMessages(ERROR);
42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(errors.empty());
42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ErrorDescriptorDatabase error_database;
42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockErrorCollector error_collector;
42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&error_database, &error_collector);
42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(
42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "error.proto: error.proto: OTHER: File recursively imports itself: "
42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "error.proto -> error2.proto -> error.proto\n"
42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "error2.proto: error2.proto: OTHER: Import \"error.proto\" was not "
42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "found or had errors.\n"
42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "error.proto: error.proto: OTHER: Import \"error2.proto\" was not "
42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "found or had errors.\n",
42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_collector.text_);
42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4282ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(DatabaseBackedPoolTest, UndeclaredDependencyOnUnbuiltType) {
4283ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Check that we find and report undeclared dependencies on types that exist
4284ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // in the descriptor database but that have not not been built yet.
4285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  MockErrorCollector error_collector;
4286ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DescriptorPool pool(&database_, &error_collector);
4287ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
4288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(
4289ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", "
4290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "which is not imported by \"baz.proto\".  To use it here, please add "
4291ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "the necessary import.\n",
4292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    error_collector.text_);
4293ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
4294ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4295ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(DatabaseBackedPoolTest, RollbackAfterError) {
4296ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Make sure that all traces of bad types are removed from the pool. This used
4297ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // to be b/4529436, due to the fact that a symbol resolution failure could
4298ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // potentially cause another file to be recursively built, which would trigger
4299ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // a checkpoint _past_ possibly invalid symbols.
4300ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Baz is defined in the database, but the file is invalid because it is
4301ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // missing a necessary import.
4302ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DescriptorPool pool(&database_);
4303ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
4304ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Make sure that searching again for the file or the type fails.
4305ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindFileByName("baz.proto") == NULL);
4306ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
4307ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
4308ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, UnittestProto) {
43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try to load all of unittest.proto from a DescriptorDatabase.  This should
43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thoroughly test all paths through DescriptorBuilder to insure that there
43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are no deadlocking problems when pool_->mutex_ is non-NULL.
43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* original_file =
43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protobuf_unittest::TestAllTypes::descriptor()->file();
43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&database);
43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file_from_database =
43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pool.FindFileByName(original_file->name());
43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file_from_database != NULL);
43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto original_file_proto;
43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  original_file->CopyTo(&original_file_proto);
43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileDescriptorProto file_from_database_proto;
43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_from_database->CopyTo(&file_from_database_proto);
43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_file_proto.DebugString(),
43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            file_from_database_proto.DebugString());
43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Searching for a child of an existing descriptor should never fall back
43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the DescriptorDatabase even if it isn't found, because we know all
43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // children are already loaded.
43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallCountingDatabase call_counter(&database_);
43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&call_counter);
43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file = pool.FindFileByName("foo.proto");
43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file != NULL);
43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(foo != NULL);
43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_enum != NULL);
43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ServiceDescriptor* test_service = pool.FindServiceByName("TestService");
43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_service != NULL);
43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0, call_counter.call_count_);
43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  call_counter.Clear();
43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo->FindFieldByName("no_such_field") == NULL);
43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == NULL);
43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == NULL);
43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == NULL);
43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == NULL);
43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == NULL);
43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == NULL);
43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == NULL);
43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL);
43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL);
4365ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4366ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no.such.field") == NULL);
4367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no_such_field") == NULL);
4368ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindMessageTypeByName("Foo.NoSuchMessageType") == NULL);
4369ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindFieldByName("Foo.no_such_field") == NULL);
4370ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindExtensionByName("Foo.no_such_extension") == NULL);
4371ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindEnumTypeByName("Foo.NoSuchEnumType") == NULL);
4372ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindEnumValueByName("Foo.NO_SUCH_VALUE") == NULL);
4373ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pool.FindMethodByName("TestService.NoSuchMethod") == NULL);
4374ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, call_counter.call_count_);
43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If FindFileContainingSymbol() or FindFileContainingExtension() return a
43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file that is already in the DescriptorPool, it should not attempt to
43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reload the file.
43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FalsePositiveDatabase false_positive_database(&database_);
43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockErrorCollector error_collector;
43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&false_positive_database, &error_collector);
43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First make sure foo.proto is loaded.
43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(foo != NULL);
43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try inducing false positives.
43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == NULL);
43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == NULL);
43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No errors should have been reported.  (If foo.proto was incorrectly
43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // loaded multiple times, errors would have been reported.)
43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error_collector.text_);
43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ErrorDescriptorDatabase error_database;
44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockErrorCollector error_collector;
44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&error_database, &error_collector);
44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error_collector.text_.clear();
44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", error_collector.text_);
44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to FindFieldByName()), we should fail fast, without checking the fallback
44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // database.
44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallCountingDatabase call_counter(&database_);
44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DescriptorPool pool(&call_counter);
44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FileDescriptor* file = pool.FindFileByName("foo.proto");
44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(file != NULL);
44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(foo != NULL);
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_enum != NULL);
44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(0, call_counter.call_count_);
44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  call_counter.Clear();
44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == NULL);
44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindFieldByName("Foo") == NULL);
44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindExtensionByName("Foo") == NULL);
44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == NULL);
44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindEnumValueByName("Foo") == NULL);
44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindServiceByName("Foo") == NULL);
44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(pool.FindMethodByName("Foo") == NULL);
44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, call_counter.call_count_);
44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4440ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass AbortingErrorCollector : public DescriptorPool::ErrorCollector {
4441ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public:
4442ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  AbortingErrorCollector() {}
4443ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4444ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void AddError(
4445ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      const string &filename,
4446ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      const string &element_name,
4447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      const Message *message,
4448ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ErrorLocation location,
4449ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      const string &error_message) {
4450ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << ": "
4451ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch               << error_message;
4452ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
4453ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private:
4454ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AbortingErrorCollector);
4455ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch};
4456ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4457ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// A source tree containing only one file.
4458ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass SingletonSourceTree : public compiler::SourceTree {
4459ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public:
4460ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SingletonSourceTree(const string& filename, const string& contents)
4461ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      : filename_(filename), contents_(contents) {}
4462ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4463ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual io::ZeroCopyInputStream* Open(const string& filename) {
4464ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return filename == filename_ ?
4465ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        new io::ArrayInputStream(contents_.data(), contents_.size()) : NULL;
4466ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
4467ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4468ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private:
4469ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const string filename_;
4470ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const string contents_;
4471ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4472ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree);
4473ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch};
4474ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4475ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst char *const kSourceLocationTestInput =
4476ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "syntax = \"proto2\";\n"
4477ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "message A {\n"
4478ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "  optional int32 a = 1;\n"
4479ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "  message B {\n"
4480ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "    required double b = 1;\n"
4481ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "  }\n"
4482ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "}\n"
4483ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "enum Indecision {\n"
4484ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "  YES   = 1;\n"
4485ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "  NO    = 2;\n"
4486ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "  MAYBE = 3;\n"
4487ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "}\n"
4488ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "service S {\n"
4489ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "  rpc Method(A) returns (A.B);\n"
4490ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Put an empty line here to make the source location range match.
4491ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "\n"
4492ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "}\n";
4493ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4494ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass SourceLocationTest : public testing::Test {
4495ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public:
4496ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SourceLocationTest()
4497ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      : source_tree_("/test/test.proto", kSourceLocationTestInput),
4498ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        db_(&source_tree_),
4499ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        pool_(&db_, &collector_) {}
4500ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4501ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  static string PrintSourceLocation(const SourceLocation &loc) {
4502ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return strings::Substitute("$0:$1-$2:$3",
4503ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                               1 + loc.start_line,
4504ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                               1 + loc.start_column,
4505ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                               1 + loc.end_line,
4506ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                               1 + loc.end_column);
4507ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
4508ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4509ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private:
4510ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  AbortingErrorCollector collector_;
4511ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SingletonSourceTree source_tree_;
4512ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  compiler::SourceTreeDescriptorDatabase db_;
4513ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4514ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch protected:
4515ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DescriptorPool pool_;
4516ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch};
4517ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4518ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// TODO(adonovan): implement support for option fields and for
4519ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// subparts of declarations.
4520ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4521ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(SourceLocationTest, GetSourceLocation) {
4522ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SourceLocation loc;
4523ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4524ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor *file_desc =
4525ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
4526ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4527ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const Descriptor *a_desc = file_desc->FindMessageTypeByName("A");
4528ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(a_desc->GetSourceLocation(&loc));
4529ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("2:1-7:2", PrintSourceLocation(loc));
4530ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4531ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const Descriptor *a_b_desc = a_desc->FindNestedTypeByName("B");
4532ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc));
4533ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("4:3-6:4", PrintSourceLocation(loc));
4534ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4535ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const EnumDescriptor *e_desc = file_desc->FindEnumTypeByName("Indecision");
4536ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(e_desc->GetSourceLocation(&loc));
4537ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("8:1-12:2", PrintSourceLocation(loc));
4538ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4539ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const EnumValueDescriptor *yes_desc = e_desc->FindValueByName("YES");
4540ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(yes_desc->GetSourceLocation(&loc));
4541ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("9:3-9:13", PrintSourceLocation(loc));
4542ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4543ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const ServiceDescriptor *s_desc = file_desc->FindServiceByName("S");
4544ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(s_desc->GetSourceLocation(&loc));
4545ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("13:1-16:2", PrintSourceLocation(loc));
4546ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4547ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const MethodDescriptor *m_desc = s_desc->FindMethodByName("Method");
4548ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(m_desc->GetSourceLocation(&loc));
4549ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ("14:3-14:31", PrintSourceLocation(loc));
4550ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4551ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
4552ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4553ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Missing SourceCodeInfo doesn't cause crash:
4554ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
4555ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SourceLocation loc;
4556ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4557ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor *file_desc =
4558ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
4559ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4560ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  FileDescriptorProto proto;
4561ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  file_desc->CopyTo(&proto);  // Note, this discards the SourceCodeInfo.
4562ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(proto.has_source_code_info());
4563ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4564ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DescriptorPool bad1_pool(&pool_);
4565ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor* bad1_file_desc =
4566ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      GOOGLE_CHECK_NOTNULL(bad1_pool.BuildFile(proto));
4567ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const Descriptor *bad1_a_desc = bad1_file_desc->FindMessageTypeByName("A");
4568ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(bad1_a_desc->GetSourceLocation(&loc));
4569ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
4570ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4571ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Corrupt SourceCodeInfo doesn't cause crash:
4572ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
4573ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SourceLocation loc;
4574ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4575ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor *file_desc =
4576ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
4577ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4578ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  FileDescriptorProto proto;
4579ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  file_desc->CopyTo(&proto);  // Note, this discards the SourceCodeInfo.
4580ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(proto.has_source_code_info());
4581ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SourceCodeInfo_Location *loc_msg =
4582ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      proto.mutable_source_code_info()->add_location();
4583ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  loc_msg->add_path(1);
4584ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  loc_msg->add_path(2);
4585ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  loc_msg->add_path(3);
4586ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  loc_msg->add_span(4);
4587ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  loc_msg->add_span(5);
4588ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  loc_msg->add_span(6);
4589ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4590ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DescriptorPool bad2_pool(&pool_);
4591ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor* bad2_file_desc =
4592ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      GOOGLE_CHECK_NOTNULL(bad2_pool.BuildFile(proto));
4593ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const Descriptor *bad2_a_desc = bad2_file_desc->FindMessageTypeByName("A");
4594ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(bad2_a_desc->GetSourceLocation(&loc));
4595ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
4596ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4597ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// ===================================================================
4598ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4599ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst char* const kCopySourceCodeInfoToTestInput =
4600ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "syntax = \"proto2\";\n"
4601ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  "message Foo {}\n";
4602ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4603ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Required since source code information is not preserved by
4604ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// FileDescriptorTest.
4605ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass CopySourceCodeInfoToTest : public testing::Test {
4606ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public:
4607ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  CopySourceCodeInfoToTest()
4608ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      : source_tree_("/test/test.proto", kCopySourceCodeInfoToTestInput),
4609ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        db_(&source_tree_),
4610ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        pool_(&db_, &collector_) {}
4611ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4612ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private:
4613ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  AbortingErrorCollector collector_;
4614ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SingletonSourceTree source_tree_;
4615ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  compiler::SourceTreeDescriptorDatabase db_;
4616ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4617ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch protected:
4618ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DescriptorPool pool_;
4619ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch};
4620ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4621ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) {
4622ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor* file_desc =
4623ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
4624ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  FileDescriptorProto file_desc_proto;
4625ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_FALSE(file_desc_proto.has_source_code_info());
4626ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4627ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  file_desc->CopyTo(&file_desc_proto);
4628ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(file_desc_proto.has_source_code_info());
4629ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
4630ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4631ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) {
4632ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const FileDescriptor* file_desc =
4633ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
4634ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  FileDescriptorProto file_desc_proto;
4635ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_FALSE(file_desc_proto.has_source_code_info());
4636ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4637ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  file_desc->CopySourceCodeInfoTo(&file_desc_proto);
4638ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const SourceCodeInfo& info = file_desc_proto.source_code_info();
4639ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ(3, info.location_size());
4640ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Get the Foo message location
4641ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const SourceCodeInfo_Location& foo_location = info.location(1);
4642ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ(2, foo_location.path_size());
4643ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(FileDescriptorProto::kMessageTypeFieldNumber, foo_location.path(0));
4644ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(0, foo_location.path(1));      // Foo is the first message defined
4645ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ(3, foo_location.span_size());  // Foo spans one line
4646ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(1, foo_location.span(0));      // Foo is declared on line 1
4647ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(0, foo_location.span(1));      // Foo starts at column 0
4648ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(14, foo_location.span(2));     // Foo ends on column 14
4649ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
4650ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
4651ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// ===================================================================
4652ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace descriptor_unittest
46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
4657