/thirdparty/breakpad/third_party/protobuf/protobuf/java/src/main/java/com/google/protobuf/UnknownFieldSet.java

http://github.com/tomahawk-player/tomahawk · Java · 953 lines · 605 code · 89 blank · 259 comment · 100 complexity · 7aa7d1666417ca56e365cd246ccf798e MD5 · raw file

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