1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // http://code.google.com/p/protobuf/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 package com.google.protobuf; 32 33 import com.google.protobuf.DescriptorProtos.DescriptorProto; 34 import com.google.protobuf.DescriptorProtos.EnumDescriptorProto; 35 import com.google.protobuf.DescriptorProtos.EnumValueDescriptorProto; 36 import com.google.protobuf.DescriptorProtos.FieldDescriptorProto; 37 import com.google.protobuf.DescriptorProtos.FileDescriptorProto; 38 import com.google.protobuf.Descriptors.DescriptorValidationException; 39 import com.google.protobuf.Descriptors.FileDescriptor; 40 import com.google.protobuf.Descriptors.Descriptor; 41 import com.google.protobuf.Descriptors.FieldDescriptor; 42 import com.google.protobuf.Descriptors.EnumDescriptor; 43 import com.google.protobuf.Descriptors.EnumValueDescriptor; 44 import com.google.protobuf.Descriptors.ServiceDescriptor; 45 import com.google.protobuf.Descriptors.MethodDescriptor; 46 47 import com.google.protobuf.test.UnittestImport; 48 import com.google.protobuf.test.UnittestImport.ImportEnum; 49 import com.google.protobuf.test.UnittestImport.ImportMessage; 50 import protobuf_unittest.UnittestProto; 51 import protobuf_unittest.UnittestProto.ForeignEnum; 52 import protobuf_unittest.UnittestProto.ForeignMessage; 53 import protobuf_unittest.UnittestProto.TestAllTypes; 54 import protobuf_unittest.UnittestProto.TestAllExtensions; 55 import protobuf_unittest.UnittestProto.TestExtremeDefaultValues; 56 import protobuf_unittest.UnittestProto.TestRequired; 57 import protobuf_unittest.UnittestProto.TestService; 58 import protobuf_unittest.UnittestCustomOptions; 59 60 61 import junit.framework.TestCase; 62 63 import java.util.Arrays; 64 import java.util.Collections; 65 import java.util.List; 66 67 /** 68 * Unit test for {@link Descriptors}. 69 * 70 * @author kenton@google.com Kenton Varda 71 */ 72 public class DescriptorsTest extends TestCase { 73 74 // Regression test for bug where referencing a FieldDescriptor.Type value 75 // before a FieldDescriptorProto.Type value would yield a 76 // ExceptionInInitializerError. 77 @SuppressWarnings("unused") 78 private static final Object STATIC_INIT_TEST = FieldDescriptor.Type.BOOL; 79 testFieldTypeEnumMapping()80 public void testFieldTypeEnumMapping() throws Exception { 81 assertEquals(FieldDescriptor.Type.values().length, 82 FieldDescriptorProto.Type.values().length); 83 for (FieldDescriptor.Type type : FieldDescriptor.Type.values()) { 84 FieldDescriptorProto.Type protoType = type.toProto(); 85 assertEquals("TYPE_" + type.name(), protoType.name()); 86 assertEquals(type, FieldDescriptor.Type.valueOf(protoType)); 87 } 88 } 89 testFileDescriptor()90 public void testFileDescriptor() throws Exception { 91 FileDescriptor file = UnittestProto.getDescriptor(); 92 93 assertEquals("google/protobuf/unittest.proto", file.getName()); 94 assertEquals("protobuf_unittest", file.getPackage()); 95 96 assertEquals("UnittestProto", file.getOptions().getJavaOuterClassname()); 97 assertEquals("google/protobuf/unittest.proto", 98 file.toProto().getName()); 99 100 assertEquals(Arrays.asList(UnittestImport.getDescriptor()), 101 file.getDependencies()); 102 103 Descriptor messageType = TestAllTypes.getDescriptor(); 104 assertEquals(messageType, file.getMessageTypes().get(0)); 105 assertEquals(messageType, file.findMessageTypeByName("TestAllTypes")); 106 assertNull(file.findMessageTypeByName("NoSuchType")); 107 assertNull(file.findMessageTypeByName("protobuf_unittest.TestAllTypes")); 108 for (int i = 0; i < file.getMessageTypes().size(); i++) { 109 assertEquals(i, file.getMessageTypes().get(i).getIndex()); 110 } 111 112 EnumDescriptor enumType = ForeignEnum.getDescriptor(); 113 assertEquals(enumType, file.getEnumTypes().get(0)); 114 assertEquals(enumType, file.findEnumTypeByName("ForeignEnum")); 115 assertNull(file.findEnumTypeByName("NoSuchType")); 116 assertNull(file.findEnumTypeByName("protobuf_unittest.ForeignEnum")); 117 assertEquals(Arrays.asList(ImportEnum.getDescriptor()), 118 UnittestImport.getDescriptor().getEnumTypes()); 119 for (int i = 0; i < file.getEnumTypes().size(); i++) { 120 assertEquals(i, file.getEnumTypes().get(i).getIndex()); 121 } 122 123 ServiceDescriptor service = TestService.getDescriptor(); 124 assertEquals(service, file.getServices().get(0)); 125 assertEquals(service, file.findServiceByName("TestService")); 126 assertNull(file.findServiceByName("NoSuchType")); 127 assertNull(file.findServiceByName("protobuf_unittest.TestService")); 128 assertEquals(Collections.emptyList(), 129 UnittestImport.getDescriptor().getServices()); 130 for (int i = 0; i < file.getServices().size(); i++) { 131 assertEquals(i, file.getServices().get(i).getIndex()); 132 } 133 134 FieldDescriptor extension = 135 UnittestProto.optionalInt32Extension.getDescriptor(); 136 assertEquals(extension, file.getExtensions().get(0)); 137 assertEquals(extension, 138 file.findExtensionByName("optional_int32_extension")); 139 assertNull(file.findExtensionByName("no_such_ext")); 140 assertNull(file.findExtensionByName( 141 "protobuf_unittest.optional_int32_extension")); 142 assertEquals(Collections.emptyList(), 143 UnittestImport.getDescriptor().getExtensions()); 144 for (int i = 0; i < file.getExtensions().size(); i++) { 145 assertEquals(i, file.getExtensions().get(i).getIndex()); 146 } 147 } 148 testDescriptor()149 public void testDescriptor() throws Exception { 150 Descriptor messageType = TestAllTypes.getDescriptor(); 151 Descriptor nestedType = TestAllTypes.NestedMessage.getDescriptor(); 152 153 assertEquals("TestAllTypes", messageType.getName()); 154 assertEquals("protobuf_unittest.TestAllTypes", messageType.getFullName()); 155 assertEquals(UnittestProto.getDescriptor(), messageType.getFile()); 156 assertNull(messageType.getContainingType()); 157 assertEquals(DescriptorProtos.MessageOptions.getDefaultInstance(), 158 messageType.getOptions()); 159 assertEquals("TestAllTypes", messageType.toProto().getName()); 160 161 assertEquals("NestedMessage", nestedType.getName()); 162 assertEquals("protobuf_unittest.TestAllTypes.NestedMessage", 163 nestedType.getFullName()); 164 assertEquals(UnittestProto.getDescriptor(), nestedType.getFile()); 165 assertEquals(messageType, nestedType.getContainingType()); 166 167 FieldDescriptor field = messageType.getFields().get(0); 168 assertEquals("optional_int32", field.getName()); 169 assertEquals(field, messageType.findFieldByName("optional_int32")); 170 assertNull(messageType.findFieldByName("no_such_field")); 171 assertEquals(field, messageType.findFieldByNumber(1)); 172 assertNull(messageType.findFieldByNumber(571283)); 173 for (int i = 0; i < messageType.getFields().size(); i++) { 174 assertEquals(i, messageType.getFields().get(i).getIndex()); 175 } 176 177 assertEquals(nestedType, messageType.getNestedTypes().get(0)); 178 assertEquals(nestedType, messageType.findNestedTypeByName("NestedMessage")); 179 assertNull(messageType.findNestedTypeByName("NoSuchType")); 180 for (int i = 0; i < messageType.getNestedTypes().size(); i++) { 181 assertEquals(i, messageType.getNestedTypes().get(i).getIndex()); 182 } 183 184 EnumDescriptor enumType = TestAllTypes.NestedEnum.getDescriptor(); 185 assertEquals(enumType, messageType.getEnumTypes().get(0)); 186 assertEquals(enumType, messageType.findEnumTypeByName("NestedEnum")); 187 assertNull(messageType.findEnumTypeByName("NoSuchType")); 188 for (int i = 0; i < messageType.getEnumTypes().size(); i++) { 189 assertEquals(i, messageType.getEnumTypes().get(i).getIndex()); 190 } 191 } 192 testFieldDescriptor()193 public void testFieldDescriptor() throws Exception { 194 Descriptor messageType = TestAllTypes.getDescriptor(); 195 FieldDescriptor primitiveField = 196 messageType.findFieldByName("optional_int32"); 197 FieldDescriptor enumField = 198 messageType.findFieldByName("optional_nested_enum"); 199 FieldDescriptor messageField = 200 messageType.findFieldByName("optional_foreign_message"); 201 FieldDescriptor cordField = 202 messageType.findFieldByName("optional_cord"); 203 FieldDescriptor extension = 204 UnittestProto.optionalInt32Extension.getDescriptor(); 205 FieldDescriptor nestedExtension = TestRequired.single.getDescriptor(); 206 207 assertEquals("optional_int32", primitiveField.getName()); 208 assertEquals("protobuf_unittest.TestAllTypes.optional_int32", 209 primitiveField.getFullName()); 210 assertEquals(1, primitiveField.getNumber()); 211 assertEquals(messageType, primitiveField.getContainingType()); 212 assertEquals(UnittestProto.getDescriptor(), primitiveField.getFile()); 213 assertEquals(FieldDescriptor.Type.INT32, primitiveField.getType()); 214 assertEquals(FieldDescriptor.JavaType.INT, primitiveField.getJavaType()); 215 assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(), 216 primitiveField.getOptions()); 217 assertFalse(primitiveField.isExtension()); 218 assertEquals("optional_int32", primitiveField.toProto().getName()); 219 220 assertEquals("optional_nested_enum", enumField.getName()); 221 assertEquals(FieldDescriptor.Type.ENUM, enumField.getType()); 222 assertEquals(FieldDescriptor.JavaType.ENUM, enumField.getJavaType()); 223 assertEquals(TestAllTypes.NestedEnum.getDescriptor(), 224 enumField.getEnumType()); 225 226 assertEquals("optional_foreign_message", messageField.getName()); 227 assertEquals(FieldDescriptor.Type.MESSAGE, messageField.getType()); 228 assertEquals(FieldDescriptor.JavaType.MESSAGE, messageField.getJavaType()); 229 assertEquals(ForeignMessage.getDescriptor(), messageField.getMessageType()); 230 231 assertEquals("optional_cord", cordField.getName()); 232 assertEquals(FieldDescriptor.Type.STRING, cordField.getType()); 233 assertEquals(FieldDescriptor.JavaType.STRING, cordField.getJavaType()); 234 assertEquals(DescriptorProtos.FieldOptions.CType.CORD, 235 cordField.getOptions().getCtype()); 236 237 assertEquals("optional_int32_extension", extension.getName()); 238 assertEquals("protobuf_unittest.optional_int32_extension", 239 extension.getFullName()); 240 assertEquals(1, extension.getNumber()); 241 assertEquals(TestAllExtensions.getDescriptor(), 242 extension.getContainingType()); 243 assertEquals(UnittestProto.getDescriptor(), extension.getFile()); 244 assertEquals(FieldDescriptor.Type.INT32, extension.getType()); 245 assertEquals(FieldDescriptor.JavaType.INT, extension.getJavaType()); 246 assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(), 247 extension.getOptions()); 248 assertTrue(extension.isExtension()); 249 assertEquals(null, extension.getExtensionScope()); 250 assertEquals("optional_int32_extension", extension.toProto().getName()); 251 252 assertEquals("single", nestedExtension.getName()); 253 assertEquals("protobuf_unittest.TestRequired.single", 254 nestedExtension.getFullName()); 255 assertEquals(TestRequired.getDescriptor(), 256 nestedExtension.getExtensionScope()); 257 } 258 testFieldDescriptorLabel()259 public void testFieldDescriptorLabel() throws Exception { 260 FieldDescriptor requiredField = 261 TestRequired.getDescriptor().findFieldByName("a"); 262 FieldDescriptor optionalField = 263 TestAllTypes.getDescriptor().findFieldByName("optional_int32"); 264 FieldDescriptor repeatedField = 265 TestAllTypes.getDescriptor().findFieldByName("repeated_int32"); 266 267 assertTrue(requiredField.isRequired()); 268 assertFalse(requiredField.isRepeated()); 269 assertFalse(optionalField.isRequired()); 270 assertFalse(optionalField.isRepeated()); 271 assertFalse(repeatedField.isRequired()); 272 assertTrue(repeatedField.isRepeated()); 273 } 274 testFieldDescriptorDefault()275 public void testFieldDescriptorDefault() throws Exception { 276 Descriptor d = TestAllTypes.getDescriptor(); 277 assertFalse(d.findFieldByName("optional_int32").hasDefaultValue()); 278 assertEquals(0, d.findFieldByName("optional_int32").getDefaultValue()); 279 assertTrue(d.findFieldByName("default_int32").hasDefaultValue()); 280 assertEquals(41, d.findFieldByName("default_int32").getDefaultValue()); 281 282 d = TestExtremeDefaultValues.getDescriptor(); 283 assertEquals( 284 ByteString.copyFrom( 285 "\0\001\007\b\f\n\r\t\013\\\'\"\u00fe".getBytes("ISO-8859-1")), 286 d.findFieldByName("escaped_bytes").getDefaultValue()); 287 assertEquals(-1, d.findFieldByName("large_uint32").getDefaultValue()); 288 assertEquals(-1L, d.findFieldByName("large_uint64").getDefaultValue()); 289 } 290 testEnumDescriptor()291 public void testEnumDescriptor() throws Exception { 292 EnumDescriptor enumType = ForeignEnum.getDescriptor(); 293 EnumDescriptor nestedType = TestAllTypes.NestedEnum.getDescriptor(); 294 295 assertEquals("ForeignEnum", enumType.getName()); 296 assertEquals("protobuf_unittest.ForeignEnum", enumType.getFullName()); 297 assertEquals(UnittestProto.getDescriptor(), enumType.getFile()); 298 assertNull(enumType.getContainingType()); 299 assertEquals(DescriptorProtos.EnumOptions.getDefaultInstance(), 300 enumType.getOptions()); 301 302 assertEquals("NestedEnum", nestedType.getName()); 303 assertEquals("protobuf_unittest.TestAllTypes.NestedEnum", 304 nestedType.getFullName()); 305 assertEquals(UnittestProto.getDescriptor(), nestedType.getFile()); 306 assertEquals(TestAllTypes.getDescriptor(), nestedType.getContainingType()); 307 308 EnumValueDescriptor value = ForeignEnum.FOREIGN_FOO.getValueDescriptor(); 309 assertEquals(value, enumType.getValues().get(0)); 310 assertEquals("FOREIGN_FOO", value.getName()); 311 assertEquals(4, value.getNumber()); 312 assertEquals(value, enumType.findValueByName("FOREIGN_FOO")); 313 assertEquals(value, enumType.findValueByNumber(4)); 314 assertNull(enumType.findValueByName("NO_SUCH_VALUE")); 315 for (int i = 0; i < enumType.getValues().size(); i++) { 316 assertEquals(i, enumType.getValues().get(i).getIndex()); 317 } 318 } 319 testServiceDescriptor()320 public void testServiceDescriptor() throws Exception { 321 ServiceDescriptor service = TestService.getDescriptor(); 322 323 assertEquals("TestService", service.getName()); 324 assertEquals("protobuf_unittest.TestService", service.getFullName()); 325 assertEquals(UnittestProto.getDescriptor(), service.getFile()); 326 327 assertEquals(2, service.getMethods().size()); 328 329 MethodDescriptor fooMethod = service.getMethods().get(0); 330 assertEquals("Foo", fooMethod.getName()); 331 assertEquals(UnittestProto.FooRequest.getDescriptor(), 332 fooMethod.getInputType()); 333 assertEquals(UnittestProto.FooResponse.getDescriptor(), 334 fooMethod.getOutputType()); 335 assertEquals(fooMethod, service.findMethodByName("Foo")); 336 337 MethodDescriptor barMethod = service.getMethods().get(1); 338 assertEquals("Bar", barMethod.getName()); 339 assertEquals(UnittestProto.BarRequest.getDescriptor(), 340 barMethod.getInputType()); 341 assertEquals(UnittestProto.BarResponse.getDescriptor(), 342 barMethod.getOutputType()); 343 assertEquals(barMethod, service.findMethodByName("Bar")); 344 345 assertNull(service.findMethodByName("NoSuchMethod")); 346 347 for (int i = 0; i < service.getMethods().size(); i++) { 348 assertEquals(i, service.getMethods().get(i).getIndex()); 349 } 350 } 351 352 testCustomOptions()353 public void testCustomOptions() throws Exception { 354 Descriptor descriptor = 355 UnittestCustomOptions.TestMessageWithCustomOptions.getDescriptor(); 356 357 assertTrue( 358 descriptor.getOptions().hasExtension(UnittestCustomOptions.messageOpt1)); 359 assertEquals(Integer.valueOf(-56), 360 descriptor.getOptions().getExtension(UnittestCustomOptions.messageOpt1)); 361 362 FieldDescriptor field = descriptor.findFieldByName("field1"); 363 assertNotNull(field); 364 365 assertTrue( 366 field.getOptions().hasExtension(UnittestCustomOptions.fieldOpt1)); 367 assertEquals(Long.valueOf(8765432109L), 368 field.getOptions().getExtension(UnittestCustomOptions.fieldOpt1)); 369 370 EnumDescriptor enumType = 371 UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor(); 372 373 assertTrue( 374 enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1)); 375 assertEquals(Integer.valueOf(-789), 376 enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1)); 377 378 ServiceDescriptor service = 379 UnittestCustomOptions.TestServiceWithCustomOptions.getDescriptor(); 380 381 assertTrue( 382 service.getOptions().hasExtension(UnittestCustomOptions.serviceOpt1)); 383 assertEquals(Long.valueOf(-9876543210L), 384 service.getOptions().getExtension(UnittestCustomOptions.serviceOpt1)); 385 386 MethodDescriptor method = service.findMethodByName("Foo"); 387 assertNotNull(method); 388 389 assertTrue( 390 method.getOptions().hasExtension(UnittestCustomOptions.methodOpt1)); 391 assertEquals(UnittestCustomOptions.MethodOpt1.METHODOPT1_VAL2, 392 method.getOptions().getExtension(UnittestCustomOptions.methodOpt1)); 393 } 394 395 /** 396 * Test that the FieldDescriptor.Type enum is the same as the 397 * WireFormat.FieldType enum. 398 */ testFieldTypeTablesMatch()399 public void testFieldTypeTablesMatch() throws Exception { 400 FieldDescriptor.Type[] values1 = FieldDescriptor.Type.values(); 401 WireFormat.FieldType[] values2 = WireFormat.FieldType.values(); 402 403 assertEquals(values1.length, values2.length); 404 405 for (int i = 0; i < values1.length; i++) { 406 assertEquals(values1[i].toString(), values2[i].toString()); 407 } 408 } 409 410 /** 411 * Test that the FieldDescriptor.JavaType enum is the same as the 412 * WireFormat.JavaType enum. 413 */ testJavaTypeTablesMatch()414 public void testJavaTypeTablesMatch() throws Exception { 415 FieldDescriptor.JavaType[] values1 = FieldDescriptor.JavaType.values(); 416 WireFormat.JavaType[] values2 = WireFormat.JavaType.values(); 417 418 assertEquals(values1.length, values2.length); 419 420 for (int i = 0; i < values1.length; i++) { 421 assertEquals(values1[i].toString(), values2[i].toString()); 422 } 423 } 424 testEnormousDescriptor()425 public void testEnormousDescriptor() throws Exception { 426 // The descriptor for this file is larger than 64k, yet it did not cause 427 // a compiler error due to an over-long string literal. 428 assertTrue( 429 UnittestEnormousDescriptor.getDescriptor() 430 .toProto().getSerializedSize() > 65536); 431 } 432 433 /** 434 * Tests that the DescriptorValidationException works as intended. 435 */ testDescriptorValidatorException()436 public void testDescriptorValidatorException() throws Exception { 437 FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder() 438 .setName("foo.proto") 439 .addMessageType(DescriptorProto.newBuilder() 440 .setName("Foo") 441 .addField(FieldDescriptorProto.newBuilder() 442 .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) 443 .setType(FieldDescriptorProto.Type.TYPE_INT32) 444 .setName("foo") 445 .setNumber(1) 446 .setDefaultValue("invalid") 447 .build()) 448 .build()) 449 .build(); 450 try { 451 Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, 452 new FileDescriptor[0]); 453 fail("DescriptorValidationException expected"); 454 } catch (DescriptorValidationException e) { 455 // Expected; check that the error message contains some useful hints 456 assertTrue(e.getMessage().indexOf("foo") != -1); 457 assertTrue(e.getMessage().indexOf("Foo") != -1); 458 assertTrue(e.getMessage().indexOf("invalid") != -1); 459 assertTrue(e.getCause() instanceof NumberFormatException); 460 assertTrue(e.getCause().getMessage().indexOf("invalid") != -1); 461 } 462 } 463 464 /** 465 * Tests the translate/crosslink for an example where a message field's name 466 * and type name are the same. 467 */ testDescriptorComplexCrosslink()468 public void testDescriptorComplexCrosslink() throws Exception { 469 FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder() 470 .setName("foo.proto") 471 .addMessageType(DescriptorProto.newBuilder() 472 .setName("Foo") 473 .addField(FieldDescriptorProto.newBuilder() 474 .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) 475 .setType(FieldDescriptorProto.Type.TYPE_INT32) 476 .setName("foo") 477 .setNumber(1) 478 .build()) 479 .build()) 480 .addMessageType(DescriptorProto.newBuilder() 481 .setName("Bar") 482 .addField(FieldDescriptorProto.newBuilder() 483 .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) 484 .setTypeName("Foo") 485 .setName("Foo") 486 .setNumber(1) 487 .build()) 488 .build()) 489 .build(); 490 // translate and crosslink 491 FileDescriptor file = 492 Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, 493 new FileDescriptor[0]); 494 // verify resulting descriptors 495 assertNotNull(file); 496 List<Descriptor> msglist = file.getMessageTypes(); 497 assertNotNull(msglist); 498 assertTrue(msglist.size() == 2); 499 boolean barFound = false; 500 for (Descriptor desc : msglist) { 501 if (desc.getName().equals("Bar")) { 502 barFound = true; 503 assertNotNull(desc.getFields()); 504 List<FieldDescriptor> fieldlist = desc.getFields(); 505 assertNotNull(fieldlist); 506 assertTrue(fieldlist.size() == 1); 507 assertTrue(fieldlist.get(0).getType() == FieldDescriptor.Type.MESSAGE); 508 assertTrue(fieldlist.get(0).getMessageType().getName().equals("Foo")); 509 } 510 } 511 assertTrue(barFound); 512 } 513 testInvalidPublicDependency()514 public void testInvalidPublicDependency() throws Exception { 515 FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() 516 .setName("foo.proto") .build(); 517 FileDescriptorProto barProto = FileDescriptorProto.newBuilder() 518 .setName("boo.proto") 519 .addDependency("foo.proto") 520 .addPublicDependency(1) // Error, should be 0. 521 .build(); 522 FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom(fooProto, 523 new FileDescriptor[0]); 524 try { 525 Descriptors.FileDescriptor.buildFrom(barProto, 526 new FileDescriptor[] {fooFile}); 527 fail("DescriptorValidationException expected"); 528 } catch (DescriptorValidationException e) { 529 assertTrue( 530 e.getMessage().indexOf("Invalid public dependency index.") != -1); 531 } 532 } 533 testHiddenDependency()534 public void testHiddenDependency() throws Exception { 535 FileDescriptorProto barProto = FileDescriptorProto.newBuilder() 536 .setName("bar.proto") 537 .addMessageType(DescriptorProto.newBuilder().setName("Bar")) 538 .build(); 539 FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder() 540 .setName("forward.proto") 541 .addDependency("bar.proto") 542 .build(); 543 FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() 544 .setName("foo.proto") 545 .addDependency("forward.proto") 546 .addMessageType(DescriptorProto.newBuilder() 547 .setName("Foo") 548 .addField(FieldDescriptorProto.newBuilder() 549 .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) 550 .setTypeName("Bar") 551 .setName("bar") 552 .setNumber(1))) 553 .build(); 554 FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom( 555 barProto, new FileDescriptor[0]); 556 FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom( 557 forwardProto, new FileDescriptor[] {barFile}); 558 559 try { 560 Descriptors.FileDescriptor.buildFrom( 561 fooProto, new FileDescriptor[] {forwardFile}); 562 fail("DescriptorValidationException expected"); 563 } catch (DescriptorValidationException e) { 564 assertTrue(e.getMessage().indexOf("Bar") != -1); 565 assertTrue(e.getMessage().indexOf("is not defined") != -1); 566 } 567 } 568 testPublicDependency()569 public void testPublicDependency() throws Exception { 570 FileDescriptorProto barProto = FileDescriptorProto.newBuilder() 571 .setName("bar.proto") 572 .addMessageType(DescriptorProto.newBuilder().setName("Bar")) 573 .build(); 574 FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder() 575 .setName("forward.proto") 576 .addDependency("bar.proto") 577 .addPublicDependency(0) 578 .build(); 579 FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() 580 .setName("foo.proto") 581 .addDependency("forward.proto") 582 .addMessageType(DescriptorProto.newBuilder() 583 .setName("Foo") 584 .addField(FieldDescriptorProto.newBuilder() 585 .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) 586 .setTypeName("Bar") 587 .setName("bar") 588 .setNumber(1))) 589 .build(); 590 FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom( 591 barProto, new FileDescriptor[0]); 592 FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom( 593 forwardProto, new FileDescriptor[]{barFile}); 594 Descriptors.FileDescriptor.buildFrom( 595 fooProto, new FileDescriptor[] {forwardFile}); 596 } 597 598 /** 599 * Tests the translate/crosslink for an example with a more complex namespace 600 * referencing. 601 */ testComplexNamespacePublicDependency()602 public void testComplexNamespacePublicDependency() throws Exception { 603 FileDescriptorProto fooProto = FileDescriptorProto.newBuilder() 604 .setName("bar.proto") 605 .setPackage("a.b.c.d.bar.shared") 606 .addEnumType(EnumDescriptorProto.newBuilder() 607 .setName("MyEnum") 608 .addValue(EnumValueDescriptorProto.newBuilder() 609 .setName("BLAH") 610 .setNumber(1))) 611 .build(); 612 FileDescriptorProto barProto = FileDescriptorProto.newBuilder() 613 .setName("foo.proto") 614 .addDependency("bar.proto") 615 .setPackage("a.b.c.d.foo.shared") 616 .addMessageType(DescriptorProto.newBuilder() 617 .setName("MyMessage") 618 .addField(FieldDescriptorProto.newBuilder() 619 .setLabel(FieldDescriptorProto.Label.LABEL_REPEATED) 620 .setTypeName("bar.shared.MyEnum") 621 .setName("MyField") 622 .setNumber(1))) 623 .build(); 624 // translate and crosslink 625 FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom( 626 fooProto, new FileDescriptor[0]); 627 FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom( 628 barProto, new FileDescriptor[]{fooFile}); 629 // verify resulting descriptors 630 assertNotNull(barFile); 631 List<Descriptor> msglist = barFile.getMessageTypes(); 632 assertNotNull(msglist); 633 assertTrue(msglist.size() == 1); 634 Descriptor desc = msglist.get(0); 635 if (desc.getName().equals("MyMessage")) { 636 assertNotNull(desc.getFields()); 637 List<FieldDescriptor> fieldlist = desc.getFields(); 638 assertNotNull(fieldlist); 639 assertTrue(fieldlist.size() == 1); 640 FieldDescriptor field = fieldlist.get(0); 641 assertTrue(field.getType() == FieldDescriptor.Type.ENUM); 642 assertTrue(field.getEnumType().getName().equals("MyEnum")); 643 assertTrue(field.getEnumType().getFile().getName().equals("bar.proto")); 644 assertTrue(field.getEnumType().getFile().getPackage().equals( 645 "a.b.c.d.bar.shared")); 646 } 647 } 648 } 649