Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      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.AbstractMessageLite.Builder.LimitedInputStream;
     34 
     35 import java.io.IOException;
     36 import java.io.InputStream;
     37 
     38 /**
     39  * A partial implementation of the {@link Parser} interface which implements
     40  * as many methods of that interface as possible in terms of other methods.
     41  *
     42  * Note: This class implements all the convenience methods in the
     43  * {@link Parser} interface. See {@link Parser} for related javadocs.
     44  * Subclasses need to implement
     45  * {@link Parser#parsePartialFrom(CodedInputStream, ExtensionRegistryLite)}
     46  *
     47  * @author liujisi (at) google.com (Pherl Liu)
     48  */
     49 public abstract class AbstractParser<MessageType extends MessageLite>
     50     implements Parser<MessageType> {
     51   /**
     52    * Creates an UninitializedMessageException for MessageType.
     53    */
     54   private UninitializedMessageException
     55       newUninitializedMessageException(MessageType message) {
     56     if (message instanceof AbstractMessageLite) {
     57       return ((AbstractMessageLite) message).newUninitializedMessageException();
     58     }
     59     return new UninitializedMessageException(message);
     60   }
     61 
     62   /**
     63    * Helper method to check if message is initialized.
     64    *
     65    * @throws InvalidProtocolBufferException if it is not initialized.
     66    * @return The message to check.
     67    */
     68   private MessageType checkMessageInitialized(MessageType message)
     69       throws InvalidProtocolBufferException {
     70     if (message != null && !message.isInitialized()) {
     71       throw newUninitializedMessageException(message)
     72           .asInvalidProtocolBufferException()
     73           .setUnfinishedMessage(message);
     74     }
     75     return message;
     76   }
     77 
     78   private static final ExtensionRegistryLite EMPTY_REGISTRY
     79       = ExtensionRegistryLite.getEmptyRegistry();
     80 
     81   public MessageType parsePartialFrom(CodedInputStream input)
     82       throws InvalidProtocolBufferException {
     83     return parsePartialFrom(input, EMPTY_REGISTRY);
     84   }
     85 
     86   public MessageType parseFrom(CodedInputStream input,
     87                                ExtensionRegistryLite extensionRegistry)
     88       throws InvalidProtocolBufferException {
     89     return checkMessageInitialized(
     90         parsePartialFrom(input, extensionRegistry));
     91   }
     92 
     93   public MessageType parseFrom(CodedInputStream input)
     94       throws InvalidProtocolBufferException {
     95     return parseFrom(input, EMPTY_REGISTRY);
     96   }
     97 
     98   public MessageType parsePartialFrom(ByteString data,
     99                                       ExtensionRegistryLite extensionRegistry)
    100     throws InvalidProtocolBufferException {
    101     MessageType message;
    102     try {
    103       CodedInputStream input = data.newCodedInput();
    104       message = parsePartialFrom(input, extensionRegistry);
    105       try {
    106         input.checkLastTagWas(0);
    107       } catch (InvalidProtocolBufferException e) {
    108         throw e.setUnfinishedMessage(message);
    109       }
    110       return message;
    111     } catch (InvalidProtocolBufferException e) {
    112       throw e;
    113     }
    114   }
    115 
    116   public MessageType parsePartialFrom(ByteString data)
    117       throws InvalidProtocolBufferException {
    118     return parsePartialFrom(data, EMPTY_REGISTRY);
    119   }
    120 
    121   public MessageType parseFrom(ByteString data,
    122                                ExtensionRegistryLite extensionRegistry)
    123       throws InvalidProtocolBufferException {
    124     return checkMessageInitialized(parsePartialFrom(data, extensionRegistry));
    125   }
    126 
    127   public MessageType parseFrom(ByteString data)
    128       throws InvalidProtocolBufferException {
    129     return parseFrom(data, EMPTY_REGISTRY);
    130   }
    131 
    132   public MessageType parsePartialFrom(byte[] data, int off, int len,
    133                                       ExtensionRegistryLite extensionRegistry)
    134       throws InvalidProtocolBufferException {
    135     try {
    136       CodedInputStream input = CodedInputStream.newInstance(data, off, len);
    137       MessageType message = parsePartialFrom(input, extensionRegistry);
    138       try {
    139         input.checkLastTagWas(0);
    140       } catch (InvalidProtocolBufferException e) {
    141         throw e.setUnfinishedMessage(message);
    142       }
    143       return message;
    144     } catch (InvalidProtocolBufferException e) {
    145       throw e;
    146     }
    147   }
    148 
    149   public MessageType parsePartialFrom(byte[] data, int off, int len)
    150       throws InvalidProtocolBufferException {
    151     return parsePartialFrom(data, off, len, EMPTY_REGISTRY);
    152   }
    153 
    154   public MessageType parsePartialFrom(byte[] data,
    155                                       ExtensionRegistryLite extensionRegistry)
    156       throws InvalidProtocolBufferException {
    157     return parsePartialFrom(data, 0, data.length, extensionRegistry);
    158   }
    159 
    160   public MessageType parsePartialFrom(byte[] data)
    161       throws InvalidProtocolBufferException {
    162     return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY);
    163   }
    164 
    165   public MessageType parseFrom(byte[] data, int off, int len,
    166                                ExtensionRegistryLite extensionRegistry)
    167       throws InvalidProtocolBufferException {
    168     return checkMessageInitialized(
    169         parsePartialFrom(data, off, len, extensionRegistry));
    170   }
    171 
    172   public MessageType parseFrom(byte[] data, int off, int len)
    173       throws InvalidProtocolBufferException {
    174     return parseFrom(data, off, len, EMPTY_REGISTRY);
    175   }
    176 
    177   public MessageType parseFrom(byte[] data,
    178                                ExtensionRegistryLite extensionRegistry)
    179       throws InvalidProtocolBufferException {
    180     return parseFrom(data, 0, data.length, extensionRegistry);
    181   }
    182 
    183   public MessageType parseFrom(byte[] data)
    184       throws InvalidProtocolBufferException {
    185     return parseFrom(data, EMPTY_REGISTRY);
    186   }
    187 
    188   public MessageType parsePartialFrom(InputStream input,
    189                                       ExtensionRegistryLite extensionRegistry)
    190       throws InvalidProtocolBufferException {
    191     CodedInputStream codedInput = CodedInputStream.newInstance(input);
    192     MessageType message = parsePartialFrom(codedInput, extensionRegistry);
    193     try {
    194       codedInput.checkLastTagWas(0);
    195     } catch (InvalidProtocolBufferException e) {
    196       throw e.setUnfinishedMessage(message);
    197     }
    198     return message;
    199   }
    200 
    201   public MessageType parsePartialFrom(InputStream input)
    202       throws InvalidProtocolBufferException {
    203     return parsePartialFrom(input, EMPTY_REGISTRY);
    204   }
    205 
    206   public MessageType parseFrom(InputStream input,
    207                                ExtensionRegistryLite extensionRegistry)
    208       throws InvalidProtocolBufferException {
    209     return checkMessageInitialized(
    210         parsePartialFrom(input, extensionRegistry));
    211   }
    212 
    213   public MessageType parseFrom(InputStream input)
    214       throws InvalidProtocolBufferException {
    215     return parseFrom(input, EMPTY_REGISTRY);
    216   }
    217 
    218   public MessageType parsePartialDelimitedFrom(
    219       InputStream input,
    220       ExtensionRegistryLite extensionRegistry)
    221       throws InvalidProtocolBufferException {
    222     int size;
    223     try {
    224       int firstByte = input.read();
    225       if (firstByte == -1) {
    226         return null;
    227       }
    228       size = CodedInputStream.readRawVarint32(firstByte, input);
    229     } catch (IOException e) {
    230       throw new InvalidProtocolBufferException(e.getMessage());
    231     }
    232     InputStream limitedInput = new LimitedInputStream(input, size);
    233     return parsePartialFrom(limitedInput, extensionRegistry);
    234   }
    235 
    236   public MessageType parsePartialDelimitedFrom(InputStream input)
    237       throws InvalidProtocolBufferException {
    238     return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
    239   }
    240 
    241   public MessageType parseDelimitedFrom(
    242       InputStream input,
    243       ExtensionRegistryLite extensionRegistry)
    244       throws InvalidProtocolBufferException {
    245     return checkMessageInitialized(
    246         parsePartialDelimitedFrom(input, extensionRegistry));
    247   }
    248 
    249   public MessageType parseDelimitedFrom(InputStream input)
    250       throws InvalidProtocolBufferException {
    251     return parseDelimitedFrom(input, EMPTY_REGISTRY);
    252   }
    253 }
    254