• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import java.io.OutputStream;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Collections;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.TreeMap;
44 
45 /**
46  * {@code UnknownFieldSet} is used to keep track of fields which were seen when
47  * parsing a protocol message but whose field numbers or types are unrecognized.
48  * This most frequently occurs when new fields are added to a message type
49  * and then messages containing those fields are read by old software that was
50  * compiled before the new types were added.
51  *
52  * <p>Every {@link Message} contains an {@code UnknownFieldSet} (and every
53  * {@link Message.Builder} contains an {@link Builder}).
54  *
55  * <p>Most users will never need to use this class.
56  *
57  * @author kenton@google.com Kenton Varda
58  */
59 public final class UnknownFieldSet implements MessageLite {
60 
UnknownFieldSet()61   private UnknownFieldSet() {}
62 
63   /** Create a new {@link Builder}. */
newBuilder()64   public static Builder newBuilder() {
65     return Builder.create();
66   }
67 
68   /**
69    * Create a new {@link Builder} and initialize it to be a copy
70    * of {@code copyFrom}.
71    */
newBuilder(final UnknownFieldSet copyFrom)72   public static Builder newBuilder(final UnknownFieldSet copyFrom) {
73     return newBuilder().mergeFrom(copyFrom);
74   }
75 
76   /** Get an empty {@code UnknownFieldSet}. */
getDefaultInstance()77   public static UnknownFieldSet getDefaultInstance() {
78     return defaultInstance;
79   }
80   @Override
getDefaultInstanceForType()81   public UnknownFieldSet getDefaultInstanceForType() {
82     return defaultInstance;
83   }
84   private static final UnknownFieldSet defaultInstance =
85     new UnknownFieldSet(Collections.<Integer, Field>emptyMap());
86 
87   /**
88    * Construct an {@code UnknownFieldSet} around the given map.  The map is
89    * expected to be immutable.
90    */
UnknownFieldSet(final Map<Integer, Field> fields)91   private UnknownFieldSet(final Map<Integer, Field> fields) {
92     this.fields = fields;
93   }
94   private Map<Integer, Field> fields;
95 
96 
97   @Override
equals(final Object other)98   public boolean equals(final Object other) {
99     if (this == other) {
100       return true;
101     }
102     return (other instanceof UnknownFieldSet) &&
103            fields.equals(((UnknownFieldSet) other).fields);
104   }
105 
106   @Override
hashCode()107   public int hashCode() {
108     return fields.hashCode();
109   }
110 
111   /** Get a map of fields in the set by number. */
asMap()112   public Map<Integer, Field> asMap() {
113     return fields;
114   }
115 
116   /** Check if the given field number is present in the set. */
hasField(final int number)117   public boolean hasField(final int number) {
118     return fields.containsKey(number);
119   }
120 
121   /**
122    * Get a field by number.  Returns an empty field if not present.  Never
123    * returns {@code null}.
124    */
getField(final int number)125   public Field getField(final int number) {
126     final Field result = fields.get(number);
127     return (result == null) ? Field.getDefaultInstance() : result;
128   }
129 
130   /** Serializes the set and writes it to {@code output}. */
131   @Override
writeTo(final CodedOutputStream output)132   public void writeTo(final CodedOutputStream output) throws IOException {
133     for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
134       Field field = entry.getValue();
135       field.writeTo(entry.getKey(), output);
136     }
137   }
138 
139   /**
140    * Converts the set to a string in protocol buffer text format. This is
141    * just a trivial wrapper around
142    * {@link TextFormat#printToString(UnknownFieldSet)}.
143    */
144   @Override
toString()145   public String toString() {
146     return TextFormat.printToString(this);
147   }
148 
149   /**
150    * Serializes the message to a {@code ByteString} and returns it. This is
151    * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
152    */
153   @Override
toByteString()154   public ByteString toByteString() {
155     try {
156       final ByteString.CodedBuilder out =
157         ByteString.newCodedBuilder(getSerializedSize());
158       writeTo(out.getCodedOutput());
159       return out.build();
160     } catch (final IOException e) {
161       throw new RuntimeException(
162         "Serializing to a ByteString threw an IOException (should " +
163         "never happen).", e);
164     }
165   }
166 
167   /**
168    * Serializes the message to a {@code byte} array and returns it.  This is
169    * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
170    */
171   @Override
toByteArray()172   public byte[] toByteArray() {
173     try {
174       final byte[] result = new byte[getSerializedSize()];
175       final CodedOutputStream output = CodedOutputStream.newInstance(result);
176       writeTo(output);
177       output.checkNoSpaceLeft();
178       return result;
179     } catch (final IOException e) {
180       throw new RuntimeException(
181         "Serializing to a byte array threw an IOException " +
182         "(should never happen).", e);
183     }
184   }
185 
186   /**
187    * Serializes the message and writes it to {@code output}.  This is just a
188    * trivial wrapper around {@link #writeTo(CodedOutputStream)}.
189    */
190   @Override
writeTo(final OutputStream output)191   public void writeTo(final OutputStream output) throws IOException {
192     final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
193     writeTo(codedOutput);
194     codedOutput.flush();
195   }
196 
197   @Override
writeDelimitedTo(OutputStream output)198   public void writeDelimitedTo(OutputStream output) throws IOException {
199     final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
200     codedOutput.writeRawVarint32(getSerializedSize());
201     writeTo(codedOutput);
202     codedOutput.flush();
203   }
204 
205   /** Get the number of bytes required to encode this set. */
206   @Override
getSerializedSize()207   public int getSerializedSize() {
208     int result = 0;
209     for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
210       result += entry.getValue().getSerializedSize(entry.getKey());
211     }
212     return result;
213   }
214 
215   /**
216    * Serializes the set and writes it to {@code output} using
217    * {@code MessageSet} wire format.
218    */
writeAsMessageSetTo(final CodedOutputStream output)219   public void writeAsMessageSetTo(final CodedOutputStream output)
220       throws IOException {
221     for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
222       entry.getValue().writeAsMessageSetExtensionTo(
223         entry.getKey(), output);
224     }
225   }
226 
227   /**
228    * Get the number of bytes required to encode this set using
229    * {@code MessageSet} wire format.
230    */
getSerializedSizeAsMessageSet()231   public int getSerializedSizeAsMessageSet() {
232     int result = 0;
233     for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
234       result += entry.getValue().getSerializedSizeAsMessageSetExtension(
235         entry.getKey());
236     }
237     return result;
238   }
239 
240   @Override
isInitialized()241   public boolean isInitialized() {
242     // UnknownFieldSets do not have required fields, so they are always
243     // initialized.
244     return true;
245   }
246 
247   /** Parse an {@code UnknownFieldSet} from the given input stream. */
parseFrom(final CodedInputStream input)248   public static UnknownFieldSet parseFrom(final CodedInputStream input)
249                                           throws IOException {
250     return newBuilder().mergeFrom(input).build();
251   }
252 
253   /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
parseFrom(final ByteString data)254   public static UnknownFieldSet parseFrom(final ByteString data)
255       throws InvalidProtocolBufferException {
256     return newBuilder().mergeFrom(data).build();
257   }
258 
259   /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
parseFrom(final byte[] data)260   public static UnknownFieldSet parseFrom(final byte[] data)
261       throws InvalidProtocolBufferException {
262     return newBuilder().mergeFrom(data).build();
263   }
264 
265   /** Parse an {@code UnknownFieldSet} from {@code input} and return it. */
parseFrom(final InputStream input)266   public static UnknownFieldSet parseFrom(final InputStream input)
267                                           throws IOException {
268     return newBuilder().mergeFrom(input).build();
269   }
270 
271   @Override
newBuilderForType()272   public Builder newBuilderForType() {
273     return newBuilder();
274   }
275 
276   @Override
toBuilder()277   public Builder toBuilder() {
278     return newBuilder().mergeFrom(this);
279   }
280 
281   /**
282    * Builder for {@link UnknownFieldSet}s.
283    *
284    * <p>Note that this class maintains {@link Field.Builder}s for all fields
285    * in the set.  Thus, adding one element to an existing {@link Field} does not
286    * require making a copy.  This is important for efficient parsing of
287    * unknown repeated fields.  However, it implies that {@link Field}s cannot
288    * be constructed independently, nor can two {@link UnknownFieldSet}s share
289    * the same {@code Field} object.
290    *
291    * <p>Use {@link UnknownFieldSet#newBuilder()} to construct a {@code Builder}.
292    */
293   public static final class Builder implements MessageLite.Builder {
294     // This constructor should never be called directly (except from 'create').
Builder()295     private Builder() {}
296 
297     private Map<Integer, Field> fields;
298 
299     // Optimization:  We keep around a builder for the last field that was
300     //   modified so that we can efficiently add to it multiple times in a
301     //   row (important when parsing an unknown repeated field).
302     private int lastFieldNumber;
303     private Field.Builder lastField;
304 
create()305     private static Builder create() {
306       Builder builder = new Builder();
307       builder.reinitialize();
308       return builder;
309     }
310 
311     /**
312      * Get a field builder for the given field number which includes any
313      * values that already exist.
314      */
getFieldBuilder(final int number)315     private Field.Builder getFieldBuilder(final int number) {
316       if (lastField != null) {
317         if (number == lastFieldNumber) {
318           return lastField;
319         }
320         // Note:  addField() will reset lastField and lastFieldNumber.
321         addField(lastFieldNumber, lastField.build());
322       }
323       if (number == 0) {
324         return null;
325       } else {
326         final Field existing = fields.get(number);
327         lastFieldNumber = number;
328         lastField = Field.newBuilder();
329         if (existing != null) {
330           lastField.mergeFrom(existing);
331         }
332         return lastField;
333       }
334     }
335 
336     /**
337      * Build the {@link UnknownFieldSet} and return it.
338      *
339      * <p>Once {@code build()} has been called, the {@code Builder} will no
340      * longer be usable.  Calling any method after {@code build()} will result
341      * in undefined behavior and can cause a {@code NullPointerException} to be
342      * thrown.
343      */
344     @Override
build()345     public UnknownFieldSet build() {
346       getFieldBuilder(0);  // Force lastField to be built.
347       final UnknownFieldSet result;
348       if (fields.isEmpty()) {
349         result = getDefaultInstance();
350       } else {
351         result = new UnknownFieldSet(Collections.unmodifiableMap(fields));
352       }
353       fields = null;
354       return result;
355     }
356 
357     @Override
buildPartial()358     public UnknownFieldSet buildPartial() {
359       // No required fields, so this is the same as build().
360       return build();
361     }
362 
363     @Override
clone()364     public Builder clone() {
365       getFieldBuilder(0);  // Force lastField to be built.
366       return UnknownFieldSet.newBuilder().mergeFrom(
367           new UnknownFieldSet(fields));
368     }
369 
370     @Override
getDefaultInstanceForType()371     public UnknownFieldSet getDefaultInstanceForType() {
372       return UnknownFieldSet.getDefaultInstance();
373     }
374 
reinitialize()375     private void reinitialize() {
376       fields = Collections.emptyMap();
377       lastFieldNumber = 0;
378       lastField = null;
379     }
380 
381     /** Reset the builder to an empty set. */
382     @Override
clear()383     public Builder clear() {
384       reinitialize();
385       return this;
386     }
387 
388     /** Clear fields from the set with a given field number. */
clearField(final int number)389     public Builder clearField(final int number) {
390       if (number == 0) {
391         throw new IllegalArgumentException("Zero is not a valid field number.");
392       }
393       if (lastField != null && lastFieldNumber == number) {
394         // Discard this.
395         lastField = null;
396         lastFieldNumber = 0;
397       }
398       if (fields.containsKey(number)) {
399         fields.remove(number);
400       }
401       return this;
402     }
403 
404     /**
405      * Merge the fields from {@code other} into this set.  If a field number
406      * exists in both sets, {@code other}'s values for that field will be
407      * appended to the values in this set.
408      */
mergeFrom(final UnknownFieldSet other)409     public Builder mergeFrom(final UnknownFieldSet other) {
410       if (other != getDefaultInstance()) {
411         for (final Map.Entry<Integer, Field> entry : other.fields.entrySet()) {
412           mergeField(entry.getKey(), entry.getValue());
413         }
414       }
415       return this;
416     }
417 
418     /**
419      * Add a field to the {@code UnknownFieldSet}.  If a field with the same
420      * number already exists, the two are merged.
421      */
mergeField(final int number, final Field field)422     public Builder mergeField(final int number, final Field field) {
423       if (number == 0) {
424         throw new IllegalArgumentException("Zero is not a valid field number.");
425       }
426       if (hasField(number)) {
427         getFieldBuilder(number).mergeFrom(field);
428       } else {
429         // Optimization:  We could call getFieldBuilder(number).mergeFrom(field)
430         // in this case, but that would create a copy of the Field object.
431         // We'd rather reuse the one passed to us, so call addField() instead.
432         addField(number, field);
433       }
434       return this;
435     }
436 
437     /**
438      * Convenience method for merging a new field containing a single varint
439      * value.  This is used in particular when an unknown enum value is
440      * encountered.
441      */
mergeVarintField(final int number, final int value)442     public Builder mergeVarintField(final int number, final int value) {
443       if (number == 0) {
444         throw new IllegalArgumentException("Zero is not a valid field number.");
445       }
446       getFieldBuilder(number).addVarint(value);
447       return this;
448     }
449 
450 
451     /**
452      * Convenience method for merging a length-delimited field.
453      *
454      * <p>For use by generated code only.
455      */
mergeLengthDelimitedField( final int number, final ByteString value)456     public Builder mergeLengthDelimitedField(
457         final int number, final ByteString value) {
458       if (number == 0) {
459         throw new IllegalArgumentException("Zero is not a valid field number.");
460       }
461       getFieldBuilder(number).addLengthDelimited(value);
462       return this;
463     }
464 
465     /** Check if the given field number is present in the set. */
hasField(final int number)466     public boolean hasField(final int number) {
467       if (number == 0) {
468         throw new IllegalArgumentException("Zero is not a valid field number.");
469       }
470       return number == lastFieldNumber || fields.containsKey(number);
471     }
472 
473     /**
474      * Add a field to the {@code UnknownFieldSet}.  If a field with the same
475      * number already exists, it is removed.
476      */
addField(final int number, final Field field)477     public Builder addField(final int number, final Field field) {
478       if (number == 0) {
479         throw new IllegalArgumentException("Zero is not a valid field number.");
480       }
481       if (lastField != null && lastFieldNumber == number) {
482         // Discard this.
483         lastField = null;
484         lastFieldNumber = 0;
485       }
486       if (fields.isEmpty()) {
487         fields = new TreeMap<Integer,Field>();
488       }
489       fields.put(number, field);
490       return this;
491     }
492 
493     /**
494      * Get all present {@code Field}s as an immutable {@code Map}.  If more
495      * fields are added, the changes may or may not be reflected in this map.
496      */
asMap()497     public Map<Integer, Field> asMap() {
498       getFieldBuilder(0);  // Force lastField to be built.
499       return Collections.unmodifiableMap(fields);
500     }
501 
502     /**
503      * Parse an entire message from {@code input} and merge its fields into
504      * this set.
505      */
506     @Override
mergeFrom(final CodedInputStream input)507     public Builder mergeFrom(final CodedInputStream input) throws IOException {
508       while (true) {
509         final int tag = input.readTag();
510         if (tag == 0 || !mergeFieldFrom(tag, input)) {
511           break;
512         }
513       }
514       return this;
515     }
516 
517     /**
518      * Parse a single field from {@code input} and merge it into this set.
519      * @param tag The field's tag number, which was already parsed.
520      * @return {@code false} if the tag is an end group tag.
521      */
mergeFieldFrom(final int tag, final CodedInputStream input)522     public boolean mergeFieldFrom(final int tag, final CodedInputStream input)
523                                   throws IOException {
524       final int number = WireFormat.getTagFieldNumber(tag);
525       switch (WireFormat.getTagWireType(tag)) {
526         case WireFormat.WIRETYPE_VARINT:
527           getFieldBuilder(number).addVarint(input.readInt64());
528           return true;
529         case WireFormat.WIRETYPE_FIXED64:
530           getFieldBuilder(number).addFixed64(input.readFixed64());
531           return true;
532         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
533           getFieldBuilder(number).addLengthDelimited(input.readBytes());
534           return true;
535         case WireFormat.WIRETYPE_START_GROUP:
536           final Builder subBuilder = newBuilder();
537           input.readGroup(number, subBuilder,
538                           ExtensionRegistry.getEmptyRegistry());
539           getFieldBuilder(number).addGroup(subBuilder.build());
540           return true;
541         case WireFormat.WIRETYPE_END_GROUP:
542           return false;
543         case WireFormat.WIRETYPE_FIXED32:
544           getFieldBuilder(number).addFixed32(input.readFixed32());
545           return true;
546         default:
547           throw InvalidProtocolBufferException.invalidWireType();
548       }
549     }
550 
551     /**
552      * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the
553      * set being built.  This is just a small wrapper around
554      * {@link #mergeFrom(CodedInputStream)}.
555      */
556     @Override
mergeFrom(final ByteString data)557     public Builder mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
558       try {
559         final CodedInputStream input = data.newCodedInput();
560         mergeFrom(input);
561         input.checkLastTagWas(0);
562         return this;
563       } catch (final InvalidProtocolBufferException e) {
564         throw e;
565       } catch (final IOException e) {
566         throw new RuntimeException(
567           "Reading from a ByteString threw an IOException (should " +
568           "never happen).", e);
569       }
570     }
571 
572     /**
573      * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the
574      * set being built.  This is just a small wrapper around
575      * {@link #mergeFrom(CodedInputStream)}.
576      */
577     @Override
mergeFrom(final byte[] data)578     public Builder mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
579       try {
580         final CodedInputStream input = CodedInputStream.newInstance(data);
581         mergeFrom(input);
582         input.checkLastTagWas(0);
583         return this;
584       } catch (final InvalidProtocolBufferException e) {
585         throw e;
586       } catch (final IOException e) {
587         throw new RuntimeException(
588           "Reading from a byte array threw an IOException (should " +
589           "never happen).", e);
590       }
591     }
592 
593     /**
594      * Parse an {@code UnknownFieldSet} from {@code input} and merge it with the
595      * set being built.  This is just a small wrapper around
596      * {@link #mergeFrom(CodedInputStream)}.
597      */
598     @Override
mergeFrom(final InputStream input)599     public Builder mergeFrom(final InputStream input) throws IOException {
600       final CodedInputStream codedInput = CodedInputStream.newInstance(input);
601       mergeFrom(codedInput);
602       codedInput.checkLastTagWas(0);
603       return this;
604     }
605 
606     @Override
mergeDelimitedFrom(InputStream input)607     public boolean mergeDelimitedFrom(InputStream input) throws IOException {
608       final int firstByte = input.read();
609       if (firstByte == -1) {
610         return false;
611       }
612       final int size = CodedInputStream.readRawVarint32(firstByte, input);
613       final InputStream limitedInput = new LimitedInputStream(input, size);
614       mergeFrom(limitedInput);
615       return true;
616     }
617 
618     @Override
mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)619     public boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
620         throws IOException {
621       // UnknownFieldSet has no extensions.
622       return mergeDelimitedFrom(input);
623     }
624 
625     @Override
mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)626     public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
627         throws IOException {
628       // UnknownFieldSet has no extensions.
629       return mergeFrom(input);
630     }
631 
632     @Override
mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)633     public Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
634         throws InvalidProtocolBufferException {
635       // UnknownFieldSet has no extensions.
636       return mergeFrom(data);
637     }
638 
639     @Override
mergeFrom(byte[] data, int off, int len)640     public Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException {
641       try {
642         final CodedInputStream input =
643             CodedInputStream.newInstance(data, off, len);
644         mergeFrom(input);
645         input.checkLastTagWas(0);
646         return this;
647       } catch (InvalidProtocolBufferException e) {
648         throw e;
649       } catch (IOException e) {
650         throw new RuntimeException(
651           "Reading from a byte array threw an IOException (should " +
652           "never happen).", e);
653       }
654     }
655 
656     @Override
mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry)657     public Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
658         throws InvalidProtocolBufferException {
659       // UnknownFieldSet has no extensions.
660       return mergeFrom(data);
661     }
662 
663     @Override
mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)664     public Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
665         throws InvalidProtocolBufferException {
666       // UnknownFieldSet has no extensions.
667       return mergeFrom(data, off, len);
668     }
669 
670     @Override
mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry)671     public Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
672         throws IOException {
673       // UnknownFieldSet has no extensions.
674       return mergeFrom(input);
675     }
676 
677     @Override
mergeFrom(MessageLite m)678     public Builder mergeFrom(MessageLite m) {
679       if (m instanceof UnknownFieldSet) {
680         return mergeFrom((UnknownFieldSet) m);
681       }
682       throw new IllegalArgumentException(
683           "mergeFrom(MessageLite) can only merge messages of the same type.");
684     }
685 
686     @Override
isInitialized()687     public boolean isInitialized() {
688       // UnknownFieldSets do not have required fields, so they are always
689       // initialized.
690       return true;
691     }
692   }
693 
694   /**
695    * Represents a single field in an {@code UnknownFieldSet}.
696    *
697    * <p>A {@code Field} consists of five lists of values.  The lists correspond
698    * to the five "wire types" used in the protocol buffer binary format.
699    * The wire type of each field can be determined from the encoded form alone,
700    * without knowing the field's declared type.  So, we are able to parse
701    * unknown values at least this far and separate them.  Normally, only one
702    * of the five lists will contain any values, since it is impossible to
703    * define a valid message type that declares two different types for the
704    * same field number.  However, the code is designed to allow for the case
705    * where the same unknown field number is encountered using multiple different
706    * wire types.
707    *
708    * <p>{@code Field} is an immutable class.  To construct one, you must use a
709    * {@link Builder}.
710    *
711    * @see UnknownFieldSet
712    */
713   public static final class Field {
Field()714     private Field() {}
715 
716     /** Construct a new {@link Builder}. */
newBuilder()717     public static Builder newBuilder() {
718       return Builder.create();
719     }
720 
721     /**
722      * Construct a new {@link Builder} and initialize it to a copy of
723      * {@code copyFrom}.
724      */
newBuilder(final Field copyFrom)725     public static Builder newBuilder(final Field copyFrom) {
726       return newBuilder().mergeFrom(copyFrom);
727     }
728 
729     /** Get an empty {@code Field}. */
getDefaultInstance()730     public static Field getDefaultInstance() {
731       return fieldDefaultInstance;
732     }
733     private static final Field fieldDefaultInstance = newBuilder().build();
734 
735     /** Get the list of varint values for this field. */
getVarintList()736     public List<Long> getVarintList()               { return varint;          }
737 
738     /** Get the list of fixed32 values for this field. */
getFixed32List()739     public List<Integer> getFixed32List()           { return fixed32;         }
740 
741     /** Get the list of fixed64 values for this field. */
getFixed64List()742     public List<Long> getFixed64List()              { return fixed64;         }
743 
744     /** Get the list of length-delimited values for this field. */
getLengthDelimitedList()745     public List<ByteString> getLengthDelimitedList() { return lengthDelimited; }
746 
747     /**
748      * Get the list of embedded group values for this field.  These are
749      * represented using {@link UnknownFieldSet}s rather than {@link Message}s
750      * since the group's type is presumably unknown.
751      */
getGroupList()752     public List<UnknownFieldSet> getGroupList()      { return group;           }
753 
754     @Override
equals(final Object other)755     public boolean equals(final Object other) {
756       if (this == other) {
757         return true;
758       }
759       if (!(other instanceof Field)) {
760         return false;
761       }
762       return Arrays.equals(getIdentityArray(),
763           ((Field) other).getIdentityArray());
764     }
765 
766     @Override
hashCode()767     public int hashCode() {
768       return Arrays.hashCode(getIdentityArray());
769     }
770 
771     /**
772      * Returns the array of objects to be used to uniquely identify this
773      * {@link Field} instance.
774      */
getIdentityArray()775     private Object[] getIdentityArray() {
776       return new Object[] {
777           varint,
778           fixed32,
779           fixed64,
780           lengthDelimited,
781           group};
782     }
783 
784     /**
785      * Serializes the field, including field number, and writes it to
786      * {@code output}.
787      */
writeTo(final int fieldNumber, final CodedOutputStream output)788     public void writeTo(final int fieldNumber, final CodedOutputStream output)
789                         throws IOException {
790       for (final long value : varint) {
791         output.writeUInt64(fieldNumber, value);
792       }
793       for (final int value : fixed32) {
794         output.writeFixed32(fieldNumber, value);
795       }
796       for (final long value : fixed64) {
797         output.writeFixed64(fieldNumber, value);
798       }
799       for (final ByteString value : lengthDelimited) {
800         output.writeBytes(fieldNumber, value);
801       }
802       for (final UnknownFieldSet value : group) {
803         output.writeGroup(fieldNumber, value);
804       }
805     }
806 
807     /**
808      * Get the number of bytes required to encode this field, including field
809      * number.
810      */
getSerializedSize(final int fieldNumber)811     public int getSerializedSize(final int fieldNumber) {
812       int result = 0;
813       for (final long value : varint) {
814         result += CodedOutputStream.computeUInt64Size(fieldNumber, value);
815       }
816       for (final int value : fixed32) {
817         result += CodedOutputStream.computeFixed32Size(fieldNumber, value);
818       }
819       for (final long value : fixed64) {
820         result += CodedOutputStream.computeFixed64Size(fieldNumber, value);
821       }
822       for (final ByteString value : lengthDelimited) {
823         result += CodedOutputStream.computeBytesSize(fieldNumber, value);
824       }
825       for (final UnknownFieldSet value : group) {
826         result += CodedOutputStream.computeGroupSize(fieldNumber, value);
827       }
828       return result;
829     }
830 
831     /**
832      * Serializes the field, including field number, and writes it to
833      * {@code output}, using {@code MessageSet} wire format.
834      */
writeAsMessageSetExtensionTo( final int fieldNumber, final CodedOutputStream output)835     public void writeAsMessageSetExtensionTo(
836         final int fieldNumber,
837         final CodedOutputStream output)
838         throws IOException {
839       for (final ByteString value : lengthDelimited) {
840         output.writeRawMessageSetExtension(fieldNumber, value);
841       }
842     }
843 
844     /**
845      * Get the number of bytes required to encode this field, including field
846      * number, using {@code MessageSet} wire format.
847      */
getSerializedSizeAsMessageSetExtension(final int fieldNumber)848     public int getSerializedSizeAsMessageSetExtension(final int fieldNumber) {
849       int result = 0;
850       for (final ByteString value : lengthDelimited) {
851         result += CodedOutputStream.computeRawMessageSetExtensionSize(
852           fieldNumber, value);
853       }
854       return result;
855     }
856 
857     private List<Long> varint;
858     private List<Integer> fixed32;
859     private List<Long> fixed64;
860     private List<ByteString> lengthDelimited;
861     private List<UnknownFieldSet> group;
862 
863     /**
864      * Used to build a {@link Field} within an {@link UnknownFieldSet}.
865      *
866      * <p>Use {@link Field#newBuilder()} to construct a {@code Builder}.
867      */
868     public static final class Builder {
869       // This constructor should never be called directly (except from 'create').
Builder()870       private Builder() {}
871 
create()872       private static Builder create() {
873         Builder builder = new Builder();
874         builder.result = new Field();
875         return builder;
876       }
877 
878       private Field result;
879 
880       /**
881        * Build the field.  After {@code build()} has been called, the
882        * {@code Builder} is no longer usable.  Calling any other method will
883        * result in undefined behavior and can cause a
884        * {@code NullPointerException} to be thrown.
885        */
build()886       public Field build() {
887         if (result.varint == null) {
888           result.varint = Collections.emptyList();
889         } else {
890           result.varint = Collections.unmodifiableList(result.varint);
891         }
892         if (result.fixed32 == null) {
893           result.fixed32 = Collections.emptyList();
894         } else {
895           result.fixed32 = Collections.unmodifiableList(result.fixed32);
896         }
897         if (result.fixed64 == null) {
898           result.fixed64 = Collections.emptyList();
899         } else {
900           result.fixed64 = Collections.unmodifiableList(result.fixed64);
901         }
902         if (result.lengthDelimited == null) {
903           result.lengthDelimited = Collections.emptyList();
904         } else {
905           result.lengthDelimited =
906             Collections.unmodifiableList(result.lengthDelimited);
907         }
908         if (result.group == null) {
909           result.group = Collections.emptyList();
910         } else {
911           result.group = Collections.unmodifiableList(result.group);
912         }
913 
914         final Field returnMe = result;
915         result = null;
916         return returnMe;
917       }
918 
919       /** Discard the field's contents. */
clear()920       public Builder clear() {
921         result = new Field();
922         return this;
923       }
924 
925       /**
926        * Merge the values in {@code other} into this field.  For each list
927        * of values, {@code other}'s values are append to the ones in this
928        * field.
929        */
mergeFrom(final Field other)930       public Builder mergeFrom(final Field other) {
931         if (!other.varint.isEmpty()) {
932           if (result.varint == null) {
933             result.varint = new ArrayList<Long>();
934           }
935           result.varint.addAll(other.varint);
936         }
937         if (!other.fixed32.isEmpty()) {
938           if (result.fixed32 == null) {
939             result.fixed32 = new ArrayList<Integer>();
940           }
941           result.fixed32.addAll(other.fixed32);
942         }
943         if (!other.fixed64.isEmpty()) {
944           if (result.fixed64 == null) {
945             result.fixed64 = new ArrayList<Long>();
946           }
947           result.fixed64.addAll(other.fixed64);
948         }
949         if (!other.lengthDelimited.isEmpty()) {
950           if (result.lengthDelimited == null) {
951             result.lengthDelimited = new ArrayList<ByteString>();
952           }
953           result.lengthDelimited.addAll(other.lengthDelimited);
954         }
955         if (!other.group.isEmpty()) {
956           if (result.group == null) {
957             result.group = new ArrayList<UnknownFieldSet>();
958           }
959           result.group.addAll(other.group);
960         }
961         return this;
962       }
963 
964       /** Add a varint value. */
addVarint(final long value)965       public Builder addVarint(final long value) {
966         if (result.varint == null) {
967           result.varint = new ArrayList<Long>();
968         }
969         result.varint.add(value);
970         return this;
971       }
972 
973       /** Add a fixed32 value. */
addFixed32(final int value)974       public Builder addFixed32(final int value) {
975         if (result.fixed32 == null) {
976           result.fixed32 = new ArrayList<Integer>();
977         }
978         result.fixed32.add(value);
979         return this;
980       }
981 
982       /** Add a fixed64 value. */
addFixed64(final long value)983       public Builder addFixed64(final long value) {
984         if (result.fixed64 == null) {
985           result.fixed64 = new ArrayList<Long>();
986         }
987         result.fixed64.add(value);
988         return this;
989       }
990 
991       /** Add a length-delimited value. */
addLengthDelimited(final ByteString value)992       public Builder addLengthDelimited(final ByteString value) {
993         if (result.lengthDelimited == null) {
994           result.lengthDelimited = new ArrayList<ByteString>();
995         }
996         result.lengthDelimited.add(value);
997         return this;
998       }
999 
1000       /** Add an embedded group. */
addGroup(final UnknownFieldSet value)1001       public Builder addGroup(final UnknownFieldSet value) {
1002         if (result.group == null) {
1003           result.group = new ArrayList<UnknownFieldSet>();
1004         }
1005         result.group.add(value);
1006         return this;
1007       }
1008     }
1009   }
1010 
1011   /**
1012    * Parser to implement MessageLite interface.
1013    */
1014   public static final class Parser extends AbstractParser<UnknownFieldSet> {
1015     @Override
parsePartialFrom( CodedInputStream input, ExtensionRegistryLite extensionRegistry)1016     public UnknownFieldSet parsePartialFrom(
1017         CodedInputStream input, ExtensionRegistryLite extensionRegistry)
1018         throws InvalidProtocolBufferException {
1019       Builder builder = newBuilder();
1020       try {
1021         builder.mergeFrom(input);
1022       } catch (InvalidProtocolBufferException e) {
1023         throw e.setUnfinishedMessage(builder.buildPartial());
1024       } catch (IOException e) {
1025         throw new InvalidProtocolBufferException(e.getMessage())
1026             .setUnfinishedMessage(builder.buildPartial());
1027       }
1028       return builder.buildPartial();
1029     }
1030   }
1031 
1032   private static final Parser PARSER = new Parser();
1033   @Override
getParserForType()1034   public final Parser getParserForType() {
1035     return PARSER;
1036   }
1037 }
1038