Home | History | Annotate | Download | only in protobuf
      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 (at) google.com Kenton Varda
     47  */
     48 public abstract class AbstractMessage extends AbstractMessageLite
     49                                       implements Message {
     50   @SuppressWarnings("unchecked")
     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
     84   public final String toString() {
     85     return TextFormat.printToString(this);
     86   }
     87 
     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 
    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
    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
    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
    188     public abstract BuilderType clone();
    189 
    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 
    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
    242     public BuilderType mergeFrom(final CodedInputStream input)
    243                                  throws IOException {
    244       return mergeFrom(input, ExtensionRegistry.getEmptyRegistry());
    245     }
    246 
    247     @Override
    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")
    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. */
    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 
    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
    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      */
    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)}. */
    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 
    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
    638     public BuilderType mergeFrom(final ByteString data)
    639         throws InvalidProtocolBufferException {
    640       return super.mergeFrom(data);
    641     }
    642 
    643     @Override
    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
    652     public BuilderType mergeFrom(final byte[] data)
    653         throws InvalidProtocolBufferException {
    654       return super.mergeFrom(data);
    655     }
    656 
    657     @Override
    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
    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
    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
    681     public BuilderType mergeFrom(final InputStream input)
    682         throws IOException {
    683       return super.mergeFrom(input);
    684     }
    685 
    686     @Override
    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
    695     public boolean mergeDelimitedFrom(final InputStream input)
    696         throws IOException {
    697       return super.mergeDelimitedFrom(input);
    698     }
    699 
    700     @Override
    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