1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 package com.google.protobuf;
33 import java.io.FilterInputStream;
34 import java.io.InputStream;
35 import java.io.IOException;
36 import java.io.OutputStream;
37 import java.util.Collection;
40 * A partial implementation of the {@link MessageLite} interface which
41 * implements as many methods of that interface as possible in terms of other
44 * @author kenton@google.com Kenton Varda
46 public abstract class AbstractMessageLite implements MessageLite {
47 public ByteString toByteString() {
49 final ByteString.CodedBuilder out =
50 ByteString.newCodedBuilder(getSerializedSize());
51 writeTo(out.getCodedOutput());
53 } catch (IOException e) {
54 throw new RuntimeException(
55 "Serializing to a ByteString threw an IOException (should " +
60 public byte[] toByteArray() {
62 final byte[] result = new byte[getSerializedSize()];
63 final CodedOutputStream output = CodedOutputStream.newInstance(result);
65 output.checkNoSpaceLeft();
67 } catch (IOException e) {
68 throw new RuntimeException(
69 "Serializing to a byte array threw an IOException " +
70 "(should never happen).", e);
74 public void writeTo(final OutputStream output) throws IOException {
75 final int bufferSize =
76 CodedOutputStream.computePreferredBufferSize(getSerializedSize());
77 final CodedOutputStream codedOutput =
78 CodedOutputStream.newInstance(output, bufferSize);
83 public void writeDelimitedTo(final OutputStream output) throws IOException {
84 final int serialized = getSerializedSize();
85 final int bufferSize = CodedOutputStream.computePreferredBufferSize(
86 CodedOutputStream.computeRawVarint32Size(serialized) + serialized);
87 final CodedOutputStream codedOutput =
88 CodedOutputStream.newInstance(output, bufferSize);
89 codedOutput.writeRawVarint32(serialized);
95 * Package private helper method for AbstractParser to create
96 * UninitializedMessageException.
98 UninitializedMessageException newUninitializedMessageException() {
99 return new UninitializedMessageException(this);
103 * A partial implementation of the {@link Message.Builder} interface which
104 * implements as many methods of that interface as possible in terms of
107 @SuppressWarnings("unchecked")
108 public static abstract class Builder<BuilderType extends Builder>
109 implements MessageLite.Builder {
110 // The compiler produces an error if this is not declared explicitly.
112 public abstract BuilderType clone();
114 public BuilderType mergeFrom(final CodedInputStream input)
116 return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
119 // Re-defined here for return type covariance.
120 public abstract BuilderType mergeFrom(
121 final CodedInputStream input,
122 final ExtensionRegistryLite extensionRegistry)
125 public BuilderType mergeFrom(final ByteString data)
126 throws InvalidProtocolBufferException {
128 final CodedInputStream input = data.newCodedInput();
130 input.checkLastTagWas(0);
131 return (BuilderType) this;
132 } catch (InvalidProtocolBufferException e) {
134 } catch (IOException e) {
135 throw new RuntimeException(
136 "Reading from a ByteString threw an IOException (should " +
137 "never happen).", e);
141 public BuilderType mergeFrom(
142 final ByteString data,
143 final ExtensionRegistryLite extensionRegistry)
144 throws InvalidProtocolBufferException {
146 final CodedInputStream input = data.newCodedInput();
147 mergeFrom(input, extensionRegistry);
148 input.checkLastTagWas(0);
149 return (BuilderType) this;
150 } catch (InvalidProtocolBufferException e) {
152 } catch (IOException e) {
153 throw new RuntimeException(
154 "Reading from a ByteString threw an IOException (should " +
155 "never happen).", e);
159 public BuilderType mergeFrom(final byte[] data)
160 throws InvalidProtocolBufferException {
161 return mergeFrom(data, 0, data.length);
164 public BuilderType mergeFrom(final byte[] data, final int off,
166 throws InvalidProtocolBufferException {
168 final CodedInputStream input =
169 CodedInputStream.newInstance(data, off, len);
171 input.checkLastTagWas(0);
172 return (BuilderType) this;
173 } catch (InvalidProtocolBufferException e) {
175 } catch (IOException e) {
176 throw new RuntimeException(
177 "Reading from a byte array threw an IOException (should " +
178 "never happen).", e);
182 public BuilderType mergeFrom(
184 final ExtensionRegistryLite extensionRegistry)
185 throws InvalidProtocolBufferException {
186 return mergeFrom(data, 0, data.length, extensionRegistry);
189 public BuilderType mergeFrom(
190 final byte[] data, final int off, final int len,
191 final ExtensionRegistryLite extensionRegistry)
192 throws InvalidProtocolBufferException {
194 final CodedInputStream input =
195 CodedInputStream.newInstance(data, off, len);
196 mergeFrom(input, extensionRegistry);
197 input.checkLastTagWas(0);
198 return (BuilderType) this;
199 } catch (InvalidProtocolBufferException e) {
201 } catch (IOException e) {
202 throw new RuntimeException(
203 "Reading from a byte array threw an IOException (should " +
204 "never happen).", e);
208 public BuilderType mergeFrom(final InputStream input) throws IOException {
209 final CodedInputStream codedInput = CodedInputStream.newInstance(input);
210 mergeFrom(codedInput);
211 codedInput.checkLastTagWas(0);
212 return (BuilderType) this;
215 public BuilderType mergeFrom(
216 final InputStream input,
217 final ExtensionRegistryLite extensionRegistry)
219 final CodedInputStream codedInput = CodedInputStream.newInstance(input);
220 mergeFrom(codedInput, extensionRegistry);
221 codedInput.checkLastTagWas(0);
222 return (BuilderType) this;
226 * An InputStream implementations which reads from some other InputStream
227 * but is limited to a particular number of bytes. Used by
228 * mergeDelimitedFrom(). This is intentionally package-private so that
229 * UnknownFieldSet can share it.
231 static final class LimitedInputStream extends FilterInputStream {
234 LimitedInputStream(InputStream in, int limit) {
240 public int available() throws IOException {
241 return Math.min(super.available(), limit);
245 public int read() throws IOException {
249 final int result = super.read();
257 public int read(final byte[] b, final int off, int len)
262 len = Math.min(len, limit);
263 final int result = super.read(b, off, len);
271 public long skip(final long n) throws IOException {
272 final long result = super.skip(Math.min(n, limit));
280 public boolean mergeDelimitedFrom(
281 final InputStream input,
282 final ExtensionRegistryLite extensionRegistry)
284 final int firstByte = input.read();
285 if (firstByte == -1) {
288 final int size = CodedInputStream.readRawVarint32(firstByte, input);
289 final InputStream limitedInput = new LimitedInputStream(input, size);
290 mergeFrom(limitedInput, extensionRegistry);
294 public boolean mergeDelimitedFrom(final InputStream input)
296 return mergeDelimitedFrom(input,
297 ExtensionRegistryLite.getEmptyRegistry());
301 * Construct an UninitializedMessageException reporting missing fields in
304 protected static UninitializedMessageException
305 newUninitializedMessageException(MessageLite message) {
306 return new UninitializedMessageException(message);
310 * Adds the {@code values} to the {@code list}. This is a helper method
311 * used by generated code. Users should ignore it.
313 * @throws NullPointerException if any of the elements of {@code values} is
316 protected static <T> void addAll(final Iterable<T> values,
317 final Collection<? super T> list) {
318 if (values instanceof LazyStringList) {
319 // For StringOrByteStringLists, check the underlying elements to avoid
320 // forcing conversions of ByteStrings to Strings.
321 checkForNullValues(((LazyStringList) values).getUnderlyingElements());
323 checkForNullValues(values);
325 if (values instanceof Collection) {
326 final Collection<T> collection = (Collection<T>) values;
327 list.addAll(collection);
329 for (final T value : values) {
335 private static void checkForNullValues(final Iterable<?> values) {
336 for (final Object value : values) {
338 throw new NullPointerException();