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.Descriptors.Descriptor; 34 import com.google.protobuf.Descriptors.FieldDescriptor; 35 36 import java.io.InputStream; 37 import java.io.IOException; 38 import java.util.ArrayList; 39 import java.util.List; 40 import java.util.Map; 41 42 /** 43 * A partial implementation of the {@link Message} interface which implements 44 * as many methods of that interface as possible in terms of other methods. 45 * 46 * @author kenton@google.com Kenton Varda 47 */ 48 public abstract class AbstractMessage extends AbstractMessageLite 49 implements Message { 50 @SuppressWarnings("unchecked") isInitialized()51 public boolean isInitialized() { 52 // Check that all required fields are present. 53 for (final FieldDescriptor field : getDescriptorForType().getFields()) { 54 if (field.isRequired()) { 55 if (!hasField(field)) { 56 return false; 57 } 58 } 59 } 60 61 // Check that embedded messages are initialized. 62 for (final Map.Entry<FieldDescriptor, Object> entry : 63 getAllFields().entrySet()) { 64 final FieldDescriptor field = entry.getKey(); 65 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 66 if (field.isRepeated()) { 67 for (final Message element : (List<Message>) entry.getValue()) { 68 if (!element.isInitialized()) { 69 return false; 70 } 71 } 72 } else { 73 if (!((Message) entry.getValue()).isInitialized()) { 74 return false; 75 } 76 } 77 } 78 } 79 80 return true; 81 } 82 83 @Override toString()84 public final String toString() { 85 return TextFormat.printToString(this); 86 } 87 writeTo(final CodedOutputStream output)88 public void writeTo(final CodedOutputStream output) throws IOException { 89 final boolean isMessageSet = 90 getDescriptorForType().getOptions().getMessageSetWireFormat(); 91 92 for (final Map.Entry<FieldDescriptor, Object> entry : 93 getAllFields().entrySet()) { 94 final FieldDescriptor field = entry.getKey(); 95 final Object value = entry.getValue(); 96 if (isMessageSet && field.isExtension() && 97 field.getType() == FieldDescriptor.Type.MESSAGE && 98 !field.isRepeated()) { 99 output.writeMessageSetExtension(field.getNumber(), (Message) value); 100 } else { 101 FieldSet.writeField(field, value, output); 102 } 103 } 104 105 final UnknownFieldSet unknownFields = getUnknownFields(); 106 if (isMessageSet) { 107 unknownFields.writeAsMessageSetTo(output); 108 } else { 109 unknownFields.writeTo(output); 110 } 111 } 112 113 private int memoizedSize = -1; 114 getSerializedSize()115 public int getSerializedSize() { 116 int size = memoizedSize; 117 if (size != -1) { 118 return size; 119 } 120 121 size = 0; 122 final boolean isMessageSet = 123 getDescriptorForType().getOptions().getMessageSetWireFormat(); 124 125 for (final Map.Entry<FieldDescriptor, Object> entry : 126 getAllFields().entrySet()) { 127 final FieldDescriptor field = entry.getKey(); 128 final Object value = entry.getValue(); 129 if (isMessageSet && field.isExtension() && 130 field.getType() == FieldDescriptor.Type.MESSAGE && 131 !field.isRepeated()) { 132 size += CodedOutputStream.computeMessageSetExtensionSize( 133 field.getNumber(), (Message) value); 134 } else { 135 size += FieldSet.computeFieldSize(field, value); 136 } 137 } 138 139 final UnknownFieldSet unknownFields = getUnknownFields(); 140 if (isMessageSet) { 141 size += unknownFields.getSerializedSizeAsMessageSet(); 142 } else { 143 size += unknownFields.getSerializedSize(); 144 } 145 146 memoizedSize = size; 147 return size; 148 } 149 150 @Override equals(final Object other)151 public boolean equals(final Object other) { 152 if (other == this) { 153 return true; 154 } 155 if (!(other instanceof Message)) { 156 return false; 157 } 158 final Message otherMessage = (Message) other; 159 if (getDescriptorForType() != otherMessage.getDescriptorForType()) { 160 return false; 161 } 162 return getAllFields().equals(otherMessage.getAllFields()) && 163 getUnknownFields().equals(otherMessage.getUnknownFields()); 164 } 165 166 @Override hashCode()167 public int hashCode() { 168 int hash = 41; 169 hash = (19 * hash) + getDescriptorForType().hashCode(); 170 hash = (53 * hash) + getAllFields().hashCode(); 171 hash = (29 * hash) + getUnknownFields().hashCode(); 172 return hash; 173 } 174 175 // ================================================================= 176 177 /** 178 * A partial implementation of the {@link Message.Builder} interface which 179 * implements as many methods of that interface as possible in terms of 180 * other methods. 181 */ 182 @SuppressWarnings("unchecked") 183 public static abstract class Builder<BuilderType extends Builder> 184 extends AbstractMessageLite.Builder<BuilderType> 185 implements Message.Builder { 186 // The compiler produces an error if this is not declared explicitly. 187 @Override clone()188 public abstract BuilderType clone(); 189 clear()190 public BuilderType clear() { 191 for (final Map.Entry<FieldDescriptor, Object> entry : 192 getAllFields().entrySet()) { 193 clearField(entry.getKey()); 194 } 195 return (BuilderType) this; 196 } 197 mergeFrom(final Message other)198 public BuilderType mergeFrom(final Message other) { 199 if (other.getDescriptorForType() != getDescriptorForType()) { 200 throw new IllegalArgumentException( 201 "mergeFrom(Message) can only merge messages of the same type."); 202 } 203 204 // Note: We don't attempt to verify that other's fields have valid 205 // types. Doing so would be a losing battle. We'd have to verify 206 // all sub-messages as well, and we'd have to make copies of all of 207 // them to insure that they don't change after verification (since 208 // the Message interface itself cannot enforce immutability of 209 // implementations). 210 // TODO(kenton): Provide a function somewhere called makeDeepCopy() 211 // which allows people to make secure deep copies of messages. 212 213 for (final Map.Entry<FieldDescriptor, Object> entry : 214 other.getAllFields().entrySet()) { 215 final FieldDescriptor field = entry.getKey(); 216 if (field.isRepeated()) { 217 for (final Object element : (List)entry.getValue()) { 218 addRepeatedField(field, element); 219 } 220 } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 221 final Message existingValue = (Message)getField(field); 222 if (existingValue == existingValue.getDefaultInstanceForType()) { 223 setField(field, entry.getValue()); 224 } else { 225 setField(field, 226 existingValue.newBuilderForType() 227 .mergeFrom(existingValue) 228 .mergeFrom((Message)entry.getValue()) 229 .build()); 230 } 231 } else { 232 setField(field, entry.getValue()); 233 } 234 } 235 236 mergeUnknownFields(other.getUnknownFields()); 237 238 return (BuilderType) this; 239 } 240 241 @Override mergeFrom(final CodedInputStream input)242 public BuilderType mergeFrom(final CodedInputStream input) 243 throws IOException { 244 return mergeFrom(input, ExtensionRegistry.getEmptyRegistry()); 245 } 246 247 @Override mergeFrom( final CodedInputStream input, final ExtensionRegistryLite extensionRegistry)248 public BuilderType mergeFrom( 249 final CodedInputStream input, 250 final ExtensionRegistryLite extensionRegistry) 251 throws IOException { 252 final UnknownFieldSet.Builder unknownFields = 253 UnknownFieldSet.newBuilder(getUnknownFields()); 254 while (true) { 255 final int tag = input.readTag(); 256 if (tag == 0) { 257 break; 258 } 259 260 if (!mergeFieldFrom(input, unknownFields, extensionRegistry, 261 this, tag)) { 262 // end group tag 263 break; 264 } 265 } 266 setUnknownFields(unknownFields.build()); 267 return (BuilderType) this; 268 } 269 270 /** 271 * Like {@link #mergeFrom(CodedInputStream, UnknownFieldSet.Builder, 272 * ExtensionRegistryLite, Message.Builder)}, but parses a single field. 273 * Package-private because it is used by GeneratedMessage.ExtendableMessage. 274 * @param tag The tag, which should have already been read. 275 * @return {@code true} unless the tag is an end-group tag. 276 */ 277 @SuppressWarnings("unchecked") mergeFieldFrom( final CodedInputStream input, final UnknownFieldSet.Builder unknownFields, final ExtensionRegistryLite extensionRegistry, final Message.Builder builder, final int tag)278 static boolean mergeFieldFrom( 279 final CodedInputStream input, 280 final UnknownFieldSet.Builder unknownFields, 281 final ExtensionRegistryLite extensionRegistry, 282 final Message.Builder builder, 283 final int tag) throws IOException { 284 final Descriptor type = builder.getDescriptorForType(); 285 286 if (type.getOptions().getMessageSetWireFormat() && 287 tag == WireFormat.MESSAGE_SET_ITEM_TAG) { 288 mergeMessageSetExtensionFromCodedStream( 289 input, unknownFields, extensionRegistry, builder); 290 return true; 291 } 292 293 final int wireType = WireFormat.getTagWireType(tag); 294 final int fieldNumber = WireFormat.getTagFieldNumber(tag); 295 296 final FieldDescriptor field; 297 Message defaultInstance = null; 298 299 if (type.isExtensionNumber(fieldNumber)) { 300 // extensionRegistry may be either ExtensionRegistry or 301 // ExtensionRegistryLite. Since the type we are parsing is a full 302 // message, only a full ExtensionRegistry could possibly contain 303 // extensions of it. Otherwise we will treat the registry as if it 304 // were empty. 305 if (extensionRegistry instanceof ExtensionRegistry) { 306 final ExtensionRegistry.ExtensionInfo extension = 307 ((ExtensionRegistry) extensionRegistry) 308 .findExtensionByNumber(type, fieldNumber); 309 if (extension == null) { 310 field = null; 311 } else { 312 field = extension.descriptor; 313 defaultInstance = extension.defaultInstance; 314 if (defaultInstance == null && 315 field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 316 throw new IllegalStateException( 317 "Message-typed extension lacked default instance: " + 318 field.getFullName()); 319 } 320 } 321 } else { 322 field = null; 323 } 324 } else { 325 field = type.findFieldByNumber(fieldNumber); 326 } 327 328 boolean unknown = false; 329 boolean packed = false; 330 if (field == null) { 331 unknown = true; // Unknown field. 332 } else if (wireType == FieldSet.getWireFormatForFieldType( 333 field.getLiteType(), 334 false /* isPacked */)) { 335 packed = false; 336 } else if (field.isPackable() && 337 wireType == FieldSet.getWireFormatForFieldType( 338 field.getLiteType(), 339 true /* isPacked */)) { 340 packed = true; 341 } else { 342 unknown = true; // Unknown wire type. 343 } 344 345 if (unknown) { // Unknown field or wrong wire type. Skip. 346 return unknownFields.mergeFieldFrom(tag, input); 347 } 348 349 if (packed) { 350 final int length = input.readRawVarint32(); 351 final int limit = input.pushLimit(length); 352 if (field.getLiteType() == WireFormat.FieldType.ENUM) { 353 while (input.getBytesUntilLimit() > 0) { 354 final int rawValue = input.readEnum(); 355 final Object value = field.getEnumType().findValueByNumber(rawValue); 356 if (value == null) { 357 // If the number isn't recognized as a valid value for this 358 // enum, drop it (don't even add it to unknownFields). 359 return true; 360 } 361 builder.addRepeatedField(field, value); 362 } 363 } else { 364 while (input.getBytesUntilLimit() > 0) { 365 final Object value = 366 FieldSet.readPrimitiveField(input, field.getLiteType()); 367 builder.addRepeatedField(field, value); 368 } 369 } 370 input.popLimit(limit); 371 } else { 372 final Object value; 373 switch (field.getType()) { 374 case GROUP: { 375 final Message.Builder subBuilder; 376 if (defaultInstance != null) { 377 subBuilder = defaultInstance.newBuilderForType(); 378 } else { 379 subBuilder = builder.newBuilderForField(field); 380 } 381 if (!field.isRepeated()) { 382 subBuilder.mergeFrom((Message) builder.getField(field)); 383 } 384 input.readGroup(field.getNumber(), subBuilder, extensionRegistry); 385 value = subBuilder.build(); 386 break; 387 } 388 case MESSAGE: { 389 final Message.Builder subBuilder; 390 if (defaultInstance != null) { 391 subBuilder = defaultInstance.newBuilderForType(); 392 } else { 393 subBuilder = builder.newBuilderForField(field); 394 } 395 if (!field.isRepeated()) { 396 subBuilder.mergeFrom((Message) builder.getField(field)); 397 } 398 input.readMessage(subBuilder, extensionRegistry); 399 value = subBuilder.build(); 400 break; 401 } 402 case ENUM: 403 final int rawValue = input.readEnum(); 404 value = field.getEnumType().findValueByNumber(rawValue); 405 // If the number isn't recognized as a valid value for this enum, 406 // drop it. 407 if (value == null) { 408 unknownFields.mergeVarintField(fieldNumber, rawValue); 409 return true; 410 } 411 break; 412 default: 413 value = FieldSet.readPrimitiveField(input, field.getLiteType()); 414 break; 415 } 416 417 if (field.isRepeated()) { 418 builder.addRepeatedField(field, value); 419 } else { 420 builder.setField(field, value); 421 } 422 } 423 424 return true; 425 } 426 427 /** Called by {@code #mergeFieldFrom()} to parse a MessageSet extension. */ mergeMessageSetExtensionFromCodedStream( final CodedInputStream input, final UnknownFieldSet.Builder unknownFields, final ExtensionRegistryLite extensionRegistry, final Message.Builder builder)428 private static void mergeMessageSetExtensionFromCodedStream( 429 final CodedInputStream input, 430 final UnknownFieldSet.Builder unknownFields, 431 final ExtensionRegistryLite extensionRegistry, 432 final Message.Builder builder) throws IOException { 433 final Descriptor type = builder.getDescriptorForType(); 434 435 // The wire format for MessageSet is: 436 // message MessageSet { 437 // repeated group Item = 1 { 438 // required int32 typeId = 2; 439 // required bytes message = 3; 440 // } 441 // } 442 // "typeId" is the extension's field number. The extension can only be 443 // a message type, where "message" contains the encoded bytes of that 444 // message. 445 // 446 // In practice, we will probably never see a MessageSet item in which 447 // the message appears before the type ID, or where either field does not 448 // appear exactly once. However, in theory such cases are valid, so we 449 // should be prepared to accept them. 450 451 int typeId = 0; 452 ByteString rawBytes = null; // If we encounter "message" before "typeId" 453 Message.Builder subBuilder = null; 454 FieldDescriptor field = null; 455 456 while (true) { 457 final int tag = input.readTag(); 458 if (tag == 0) { 459 break; 460 } 461 462 if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) { 463 typeId = input.readUInt32(); 464 // Zero is not a valid type ID. 465 if (typeId != 0) { 466 final ExtensionRegistry.ExtensionInfo extension; 467 468 // extensionRegistry may be either ExtensionRegistry or 469 // ExtensionRegistryLite. Since the type we are parsing is a full 470 // message, only a full ExtensionRegistry could possibly contain 471 // extensions of it. Otherwise we will treat the registry as if it 472 // were empty. 473 if (extensionRegistry instanceof ExtensionRegistry) { 474 extension = ((ExtensionRegistry) extensionRegistry) 475 .findExtensionByNumber(type, typeId); 476 } else { 477 extension = null; 478 } 479 480 if (extension != null) { 481 field = extension.descriptor; 482 subBuilder = extension.defaultInstance.newBuilderForType(); 483 final Message originalMessage = (Message)builder.getField(field); 484 if (originalMessage != null) { 485 subBuilder.mergeFrom(originalMessage); 486 } 487 if (rawBytes != null) { 488 // We already encountered the message. Parse it now. 489 subBuilder.mergeFrom( 490 CodedInputStream.newInstance(rawBytes.newInput())); 491 rawBytes = null; 492 } 493 } else { 494 // Unknown extension number. If we already saw data, put it 495 // in rawBytes. 496 if (rawBytes != null) { 497 unknownFields.mergeField(typeId, 498 UnknownFieldSet.Field.newBuilder() 499 .addLengthDelimited(rawBytes) 500 .build()); 501 rawBytes = null; 502 } 503 } 504 } 505 } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) { 506 if (typeId == 0) { 507 // We haven't seen a type ID yet, so we have to store the raw bytes 508 // for now. 509 rawBytes = input.readBytes(); 510 } else if (subBuilder == null) { 511 // We don't know how to parse this. Ignore it. 512 unknownFields.mergeField(typeId, 513 UnknownFieldSet.Field.newBuilder() 514 .addLengthDelimited(input.readBytes()) 515 .build()); 516 } else { 517 // We already know the type, so we can parse directly from the input 518 // with no copying. Hooray! 519 input.readMessage(subBuilder, extensionRegistry); 520 } 521 } else { 522 // Unknown tag. Skip it. 523 if (!input.skipField(tag)) { 524 break; // end of group 525 } 526 } 527 } 528 529 input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG); 530 531 if (subBuilder != null) { 532 builder.setField(field, subBuilder.build()); 533 } 534 } 535 mergeUnknownFields(final UnknownFieldSet unknownFields)536 public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) { 537 setUnknownFields( 538 UnknownFieldSet.newBuilder(getUnknownFields()) 539 .mergeFrom(unknownFields) 540 .build()); 541 return (BuilderType) this; 542 } 543 544 /** 545 * Construct an UninitializedMessageException reporting missing fields in 546 * the given message. 547 */ 548 protected static UninitializedMessageException newUninitializedMessageException(Message message)549 newUninitializedMessageException(Message message) { 550 return new UninitializedMessageException(findMissingFields(message)); 551 } 552 553 /** 554 * Populates {@code this.missingFields} with the full "path" of each 555 * missing required field in the given message. 556 */ findMissingFields(final Message message)557 private static List<String> findMissingFields(final Message message) { 558 final List<String> results = new ArrayList<String>(); 559 findMissingFields(message, "", results); 560 return results; 561 } 562 563 /** Recursive helper implementing {@link #findMissingFields(Message)}. */ findMissingFields(final Message message, final String prefix, final List<String> results)564 private static void findMissingFields(final Message message, 565 final String prefix, 566 final List<String> results) { 567 for (final FieldDescriptor field : 568 message.getDescriptorForType().getFields()) { 569 if (field.isRequired() && !message.hasField(field)) { 570 results.add(prefix + field.getName()); 571 } 572 } 573 574 for (final Map.Entry<FieldDescriptor, Object> entry : 575 message.getAllFields().entrySet()) { 576 final FieldDescriptor field = entry.getKey(); 577 final Object value = entry.getValue(); 578 579 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 580 if (field.isRepeated()) { 581 int i = 0; 582 for (final Object element : (List) value) { 583 findMissingFields((Message) element, 584 subMessagePrefix(prefix, field, i++), 585 results); 586 } 587 } else { 588 if (message.hasField(field)) { 589 findMissingFields((Message) value, 590 subMessagePrefix(prefix, field, -1), 591 results); 592 } 593 } 594 } 595 } 596 } 597 subMessagePrefix(final String prefix, final FieldDescriptor field, final int index)598 private static String subMessagePrefix(final String prefix, 599 final FieldDescriptor field, 600 final int index) { 601 final StringBuilder result = new StringBuilder(prefix); 602 if (field.isExtension()) { 603 result.append('(') 604 .append(field.getFullName()) 605 .append(')'); 606 } else { 607 result.append(field.getName()); 608 } 609 if (index != -1) { 610 result.append('[') 611 .append(index) 612 .append(']'); 613 } 614 result.append('.'); 615 return result.toString(); 616 } 617 618 // =============================================================== 619 // The following definitions seem to be required in order to make javac 620 // not produce weird errors like: 621 // 622 // java/com/google/protobuf/DynamicMessage.java:203: types 623 // com.google.protobuf.AbstractMessage.Builder< 624 // com.google.protobuf.DynamicMessage.Builder> and 625 // com.google.protobuf.AbstractMessage.Builder< 626 // com.google.protobuf.DynamicMessage.Builder> are incompatible; both 627 // define mergeFrom(com.google.protobuf.ByteString), but with unrelated 628 // return types. 629 // 630 // Strangely, these lines are only needed if javac is invoked separately 631 // on AbstractMessage.java and AbstractMessageLite.java. If javac is 632 // invoked on both simultaneously, it works. (Or maybe the important 633 // point is whether or not DynamicMessage.java is compiled together with 634 // AbstractMessageLite.java -- not sure.) I suspect this is a compiler 635 // bug. 636 637 @Override mergeFrom(final ByteString data)638 public BuilderType mergeFrom(final ByteString data) 639 throws InvalidProtocolBufferException { 640 return super.mergeFrom(data); 641 } 642 643 @Override mergeFrom( final ByteString data, final ExtensionRegistryLite extensionRegistry)644 public BuilderType mergeFrom( 645 final ByteString data, 646 final ExtensionRegistryLite extensionRegistry) 647 throws InvalidProtocolBufferException { 648 return super.mergeFrom(data, extensionRegistry); 649 } 650 651 @Override mergeFrom(final byte[] data)652 public BuilderType mergeFrom(final byte[] data) 653 throws InvalidProtocolBufferException { 654 return super.mergeFrom(data); 655 } 656 657 @Override mergeFrom( final byte[] data, final int off, final int len)658 public BuilderType mergeFrom( 659 final byte[] data, final int off, final int len) 660 throws InvalidProtocolBufferException { 661 return super.mergeFrom(data, off, len); 662 } 663 664 @Override mergeFrom( final byte[] data, final ExtensionRegistryLite extensionRegistry)665 public BuilderType mergeFrom( 666 final byte[] data, 667 final ExtensionRegistryLite extensionRegistry) 668 throws InvalidProtocolBufferException { 669 return super.mergeFrom(data, extensionRegistry); 670 } 671 672 @Override mergeFrom( final byte[] data, final int off, final int len, final ExtensionRegistryLite extensionRegistry)673 public BuilderType mergeFrom( 674 final byte[] data, final int off, final int len, 675 final ExtensionRegistryLite extensionRegistry) 676 throws InvalidProtocolBufferException { 677 return super.mergeFrom(data, off, len, extensionRegistry); 678 } 679 680 @Override mergeFrom(final InputStream input)681 public BuilderType mergeFrom(final InputStream input) 682 throws IOException { 683 return super.mergeFrom(input); 684 } 685 686 @Override mergeFrom( final InputStream input, final ExtensionRegistryLite extensionRegistry)687 public BuilderType mergeFrom( 688 final InputStream input, 689 final ExtensionRegistryLite extensionRegistry) 690 throws IOException { 691 return super.mergeFrom(input, extensionRegistry); 692 } 693 694 @Override mergeDelimitedFrom(final InputStream input)695 public boolean mergeDelimitedFrom(final InputStream input) 696 throws IOException { 697 return super.mergeDelimitedFrom(input); 698 } 699 700 @Override mergeDelimitedFrom( final InputStream input, final ExtensionRegistryLite extensionRegistry)701 public boolean mergeDelimitedFrom( 702 final InputStream input, 703 final ExtensionRegistryLite extensionRegistry) 704 throws IOException { 705 return super.mergeDelimitedFrom(input, extensionRegistry); 706 } 707 708 } 709 } 710