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.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@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 newUninitializedMessageException(MessageType message)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 */ checkMessageInitialized(MessageType message)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 parsePartialFrom(CodedInputStream input)81 public MessageType parsePartialFrom(CodedInputStream input) 82 throws InvalidProtocolBufferException { 83 return parsePartialFrom(input, EMPTY_REGISTRY); 84 } 85 parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)86 public MessageType parseFrom(CodedInputStream input, 87 ExtensionRegistryLite extensionRegistry) 88 throws InvalidProtocolBufferException { 89 return checkMessageInitialized( 90 parsePartialFrom(input, extensionRegistry)); 91 } 92 parseFrom(CodedInputStream input)93 public MessageType parseFrom(CodedInputStream input) 94 throws InvalidProtocolBufferException { 95 return parseFrom(input, EMPTY_REGISTRY); 96 } 97 parsePartialFrom(ByteString data, ExtensionRegistryLite extensionRegistry)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 } catch (IOException e) { 114 throw new RuntimeException( 115 "Reading from a ByteString threw an IOException (should " + 116 "never happen).", e); 117 } 118 } 119 parsePartialFrom(ByteString data)120 public MessageType parsePartialFrom(ByteString data) 121 throws InvalidProtocolBufferException { 122 return parsePartialFrom(data, EMPTY_REGISTRY); 123 } 124 parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry)125 public MessageType parseFrom(ByteString data, 126 ExtensionRegistryLite extensionRegistry) 127 throws InvalidProtocolBufferException { 128 return checkMessageInitialized(parsePartialFrom(data, extensionRegistry)); 129 } 130 parseFrom(ByteString data)131 public MessageType parseFrom(ByteString data) 132 throws InvalidProtocolBufferException { 133 return parseFrom(data, EMPTY_REGISTRY); 134 } 135 parsePartialFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)136 public MessageType parsePartialFrom(byte[] data, int off, int len, 137 ExtensionRegistryLite extensionRegistry) 138 throws InvalidProtocolBufferException { 139 try { 140 CodedInputStream input = CodedInputStream.newInstance(data, off, len); 141 MessageType message = parsePartialFrom(input, extensionRegistry); 142 try { 143 input.checkLastTagWas(0); 144 } catch (InvalidProtocolBufferException e) { 145 throw e.setUnfinishedMessage(message); 146 } 147 return message; 148 } catch (InvalidProtocolBufferException e) { 149 throw e; 150 } catch (IOException e) { 151 throw new RuntimeException( 152 "Reading from a byte array threw an IOException (should " + 153 "never happen).", e); 154 } 155 } 156 parsePartialFrom(byte[] data, int off, int len)157 public MessageType parsePartialFrom(byte[] data, int off, int len) 158 throws InvalidProtocolBufferException { 159 return parsePartialFrom(data, off, len, EMPTY_REGISTRY); 160 } 161 parsePartialFrom(byte[] data, ExtensionRegistryLite extensionRegistry)162 public MessageType parsePartialFrom(byte[] data, 163 ExtensionRegistryLite extensionRegistry) 164 throws InvalidProtocolBufferException { 165 return parsePartialFrom(data, 0, data.length, extensionRegistry); 166 } 167 parsePartialFrom(byte[] data)168 public MessageType parsePartialFrom(byte[] data) 169 throws InvalidProtocolBufferException { 170 return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY); 171 } 172 parseFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)173 public MessageType parseFrom(byte[] data, int off, int len, 174 ExtensionRegistryLite extensionRegistry) 175 throws InvalidProtocolBufferException { 176 return checkMessageInitialized( 177 parsePartialFrom(data, off, len, extensionRegistry)); 178 } 179 parseFrom(byte[] data, int off, int len)180 public MessageType parseFrom(byte[] data, int off, int len) 181 throws InvalidProtocolBufferException { 182 return parseFrom(data, off, len, EMPTY_REGISTRY); 183 } 184 parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry)185 public MessageType parseFrom(byte[] data, 186 ExtensionRegistryLite extensionRegistry) 187 throws InvalidProtocolBufferException { 188 return parseFrom(data, 0, data.length, extensionRegistry); 189 } 190 parseFrom(byte[] data)191 public MessageType parseFrom(byte[] data) 192 throws InvalidProtocolBufferException { 193 return parseFrom(data, EMPTY_REGISTRY); 194 } 195 parsePartialFrom(InputStream input, ExtensionRegistryLite extensionRegistry)196 public MessageType parsePartialFrom(InputStream input, 197 ExtensionRegistryLite extensionRegistry) 198 throws InvalidProtocolBufferException { 199 CodedInputStream codedInput = CodedInputStream.newInstance(input); 200 MessageType message = parsePartialFrom(codedInput, extensionRegistry); 201 try { 202 codedInput.checkLastTagWas(0); 203 } catch (InvalidProtocolBufferException e) { 204 throw e.setUnfinishedMessage(message); 205 } 206 return message; 207 } 208 parsePartialFrom(InputStream input)209 public MessageType parsePartialFrom(InputStream input) 210 throws InvalidProtocolBufferException { 211 return parsePartialFrom(input, EMPTY_REGISTRY); 212 } 213 parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry)214 public MessageType parseFrom(InputStream input, 215 ExtensionRegistryLite extensionRegistry) 216 throws InvalidProtocolBufferException { 217 return checkMessageInitialized( 218 parsePartialFrom(input, extensionRegistry)); 219 } 220 parseFrom(InputStream input)221 public MessageType parseFrom(InputStream input) 222 throws InvalidProtocolBufferException { 223 return parseFrom(input, EMPTY_REGISTRY); 224 } 225 parsePartialDelimitedFrom( InputStream input, ExtensionRegistryLite extensionRegistry)226 public MessageType parsePartialDelimitedFrom( 227 InputStream input, 228 ExtensionRegistryLite extensionRegistry) 229 throws InvalidProtocolBufferException { 230 int size; 231 try { 232 int firstByte = input.read(); 233 if (firstByte == -1) { 234 return null; 235 } 236 size = CodedInputStream.readRawVarint32(firstByte, input); 237 } catch (IOException e) { 238 throw new InvalidProtocolBufferException(e.getMessage()); 239 } 240 InputStream limitedInput = new LimitedInputStream(input, size); 241 return parsePartialFrom(limitedInput, extensionRegistry); 242 } 243 parsePartialDelimitedFrom(InputStream input)244 public MessageType parsePartialDelimitedFrom(InputStream input) 245 throws InvalidProtocolBufferException { 246 return parsePartialDelimitedFrom(input, EMPTY_REGISTRY); 247 } 248 parseDelimitedFrom( InputStream input, ExtensionRegistryLite extensionRegistry)249 public MessageType parseDelimitedFrom( 250 InputStream input, 251 ExtensionRegistryLite extensionRegistry) 252 throws InvalidProtocolBufferException { 253 return checkMessageInitialized( 254 parsePartialDelimitedFrom(input, extensionRegistry)); 255 } 256 parseDelimitedFrom(InputStream input)257 public MessageType parseDelimitedFrom(InputStream input) 258 throws InvalidProtocolBufferException { 259 return parseDelimitedFrom(input, EMPTY_REGISTRY); 260 } 261 } 262