PageRenderTime 43ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/java/src/main/java/com/google/protobuf/nano/Extension.java

https://gitlab.com/1851616111/platform_external_protobuf
Java | 741 lines | 563 code | 40 blank | 138 comment | 65 complexity | 59729ad843061e156952552a2c05a169 MD5 | raw file
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2013 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.nano;
  31. import java.io.IOException;
  32. import java.lang.reflect.Array;
  33. import java.util.ArrayList;
  34. import java.util.List;
  35. /**
  36. * Represents an extension.
  37. *
  38. * @author bduff@google.com (Brian Duff)
  39. * @author maxtroy@google.com (Max Cai)
  40. * @param <M> the type of the extendable message this extension is for.
  41. * @param <T> the Java type of the extension; see {@link #clazz}.
  42. */
  43. public class Extension<M extends ExtendableMessageNano<M>, T> {
  44. /*
  45. * Because we typically only define message-typed extensions, the Extension class hierarchy is
  46. * designed as follows, to allow a big amount of code in this file to be removed by ProGuard:
  47. *
  48. * Extension // ready to use for message/group typed extensions
  49. * Δ
  50. * |
  51. * PrimitiveExtension // for primitive/enum typed extensions
  52. */
  53. public static final int TYPE_DOUBLE = 1;
  54. public static final int TYPE_FLOAT = 2;
  55. public static final int TYPE_INT64 = 3;
  56. public static final int TYPE_UINT64 = 4;
  57. public static final int TYPE_INT32 = 5;
  58. public static final int TYPE_FIXED64 = 6;
  59. public static final int TYPE_FIXED32 = 7;
  60. public static final int TYPE_BOOL = 8;
  61. public static final int TYPE_STRING = 9;
  62. public static final int TYPE_GROUP = 10;
  63. public static final int TYPE_MESSAGE = 11;
  64. public static final int TYPE_BYTES = 12;
  65. public static final int TYPE_UINT32 = 13;
  66. public static final int TYPE_ENUM = 14;
  67. public static final int TYPE_SFIXED32 = 15;
  68. public static final int TYPE_SFIXED64 = 16;
  69. public static final int TYPE_SINT32 = 17;
  70. public static final int TYPE_SINT64 = 18;
  71. /**
  72. * Creates an {@code Extension} of the given message type and tag number.
  73. * Should be used by the generated code only.
  74. *
  75. * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
  76. * @deprecated use {@link #createMessageTyped(int, Class, long)} instead.
  77. */
  78. @Deprecated
  79. public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
  80. Extension<M, T> createMessageTyped(int type, Class<T> clazz, int tag) {
  81. return new Extension<M, T>(type, clazz, tag, false);
  82. }
  83. // Note: these create...() methods take a long for the tag parameter,
  84. // because tags are represented as unsigned ints, and these values exist
  85. // in generated code as long values. However, they can fit in 32-bits, so
  86. // it's safe to cast them to int without loss of precision.
  87. /**
  88. * Creates an {@code Extension} of the given message type and tag number.
  89. * Should be used by the generated code only.
  90. *
  91. * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
  92. */
  93. public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
  94. Extension<M, T> createMessageTyped(int type, Class<T> clazz, long tag) {
  95. return new Extension<M, T>(type, clazz, (int) tag, false);
  96. }
  97. /**
  98. * Creates a repeated {@code Extension} of the given message type and tag number.
  99. * Should be used by the generated code only.
  100. *
  101. * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
  102. */
  103. public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
  104. Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, long tag) {
  105. return new Extension<M, T[]>(type, clazz, (int) tag, true);
  106. }
  107. /**
  108. * Creates an {@code Extension} of the given primitive type and tag number.
  109. * Should be used by the generated code only.
  110. *
  111. * @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
  112. * @param clazz the boxed Java type of this extension
  113. */
  114. public static <M extends ExtendableMessageNano<M>, T>
  115. Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, long tag) {
  116. return new PrimitiveExtension<M, T>(type, clazz, (int) tag, false, 0, 0);
  117. }
  118. /**
  119. * Creates a repeated {@code Extension} of the given primitive type and tag number.
  120. * Should be used by the generated code only.
  121. *
  122. * @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
  123. * @param clazz the Java array type of this extension, with an unboxed component type
  124. */
  125. public static <M extends ExtendableMessageNano<M>, T>
  126. Extension<M, T> createRepeatedPrimitiveTyped(
  127. int type, Class<T> clazz, long tag, long nonPackedTag, long packedTag) {
  128. return new PrimitiveExtension<M, T>(type, clazz, (int) tag, true,
  129. (int) nonPackedTag, (int) packedTag);
  130. }
  131. /**
  132. * Protocol Buffer type of this extension; one of the {@code TYPE_} constants.
  133. */
  134. protected final int type;
  135. /**
  136. * Java type of this extension. For a singular extension, this is the boxed Java type for the
  137. * Protocol Buffer {@link #type}; for a repeated extension, this is an array type whose
  138. * component type is the unboxed Java type for {@link #type}. For example, for a singular
  139. * {@code int32}/{@link #TYPE_INT32} extension, this equals {@code Integer.class}; for a
  140. * repeated {@code int32} extension, this equals {@code int[].class}.
  141. */
  142. protected final Class<T> clazz;
  143. /**
  144. * Tag number of this extension. The data should be viewed as an unsigned 32-bit value.
  145. */
  146. public final int tag;
  147. /**
  148. * Whether this extension is repeated.
  149. */
  150. protected final boolean repeated;
  151. private Extension(int type, Class<T> clazz, int tag, boolean repeated) {
  152. this.type = type;
  153. this.clazz = clazz;
  154. this.tag = tag;
  155. this.repeated = repeated;
  156. }
  157. /**
  158. * Returns the value of this extension stored in the given list of unknown fields, or
  159. * {@code null} if no unknown fields matches this extension.
  160. *
  161. * @param unknownFields a list of {@link UnknownFieldData}. All of the elements must have a tag
  162. * that matches this Extension's tag.
  163. *
  164. */
  165. final T getValueFrom(List<UnknownFieldData> unknownFields) {
  166. if (unknownFields == null) {
  167. return null;
  168. }
  169. return repeated ? getRepeatedValueFrom(unknownFields) : getSingularValueFrom(unknownFields);
  170. }
  171. private T getRepeatedValueFrom(List<UnknownFieldData> unknownFields) {
  172. // For repeated extensions, read all matching unknown fields in their original order.
  173. List<Object> resultList = new ArrayList<Object>();
  174. for (int i = 0; i < unknownFields.size(); i++) {
  175. UnknownFieldData data = unknownFields.get(i);
  176. if (data.bytes.length != 0) {
  177. readDataInto(data, resultList);
  178. }
  179. }
  180. int resultSize = resultList.size();
  181. if (resultSize == 0) {
  182. return null;
  183. } else {
  184. T result = clazz.cast(Array.newInstance(clazz.getComponentType(), resultSize));
  185. for (int i = 0; i < resultSize; i++) {
  186. Array.set(result, i, resultList.get(i));
  187. }
  188. return result;
  189. }
  190. }
  191. private T getSingularValueFrom(List<UnknownFieldData> unknownFields) {
  192. // For singular extensions, get the last piece of data stored under this extension.
  193. if (unknownFields.isEmpty()) {
  194. return null;
  195. }
  196. UnknownFieldData lastData = unknownFields.get(unknownFields.size() - 1);
  197. return clazz.cast(readData(CodedInputByteBufferNano.newInstance(lastData.bytes)));
  198. }
  199. protected Object readData(CodedInputByteBufferNano input) {
  200. // This implementation is for message/group extensions.
  201. Class<?> messageType = repeated ? clazz.getComponentType() : clazz;
  202. try {
  203. switch (type) {
  204. case TYPE_GROUP:
  205. MessageNano group = (MessageNano) messageType.newInstance();
  206. input.readGroup(group, WireFormatNano.getTagFieldNumber(tag));
  207. return group;
  208. case TYPE_MESSAGE:
  209. MessageNano message = (MessageNano) messageType.newInstance();
  210. input.readMessage(message);
  211. return message;
  212. default:
  213. throw new IllegalArgumentException("Unknown type " + type);
  214. }
  215. } catch (InstantiationException e) {
  216. throw new IllegalArgumentException(
  217. "Error creating instance of class " + messageType, e);
  218. } catch (IllegalAccessException e) {
  219. throw new IllegalArgumentException(
  220. "Error creating instance of class " + messageType, e);
  221. } catch (IOException e) {
  222. throw new IllegalArgumentException("Error reading extension field", e);
  223. }
  224. }
  225. protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
  226. // This implementation is for message/group extensions.
  227. resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
  228. }
  229. void writeTo(Object value, CodedOutputByteBufferNano output) throws IOException {
  230. if (repeated) {
  231. writeRepeatedData(value, output);
  232. } else {
  233. writeSingularData(value, output);
  234. }
  235. }
  236. protected void writeSingularData(Object value, CodedOutputByteBufferNano out) {
  237. // This implementation is for message/group extensions.
  238. try {
  239. out.writeRawVarint32(tag);
  240. switch (type) {
  241. case TYPE_GROUP:
  242. MessageNano groupValue = (MessageNano) value;
  243. int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
  244. out.writeGroupNoTag(groupValue);
  245. // The endgroup tag must be included in the data payload.
  246. out.writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
  247. break;
  248. case TYPE_MESSAGE:
  249. MessageNano messageValue = (MessageNano) value;
  250. out.writeMessageNoTag(messageValue);
  251. break;
  252. default:
  253. throw new IllegalArgumentException("Unknown type " + type);
  254. }
  255. } catch (IOException e) {
  256. // Should not happen
  257. throw new IllegalStateException(e);
  258. }
  259. }
  260. protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
  261. // This implementation is for non-packed extensions.
  262. int arrayLength = Array.getLength(array);
  263. for (int i = 0; i < arrayLength; i++) {
  264. Object element = Array.get(array, i);
  265. if (element != null) {
  266. writeSingularData(element, output);
  267. }
  268. }
  269. }
  270. int computeSerializedSize(Object value) {
  271. if (repeated) {
  272. return computeRepeatedSerializedSize(value);
  273. } else {
  274. return computeSingularSerializedSize(value);
  275. }
  276. }
  277. protected int computeRepeatedSerializedSize(Object array) {
  278. // This implementation is for non-packed extensions.
  279. int size = 0;
  280. int arrayLength = Array.getLength(array);
  281. for (int i = 0; i < arrayLength; i++) {
  282. Object element = Array.get(array, i);
  283. if (element != null) {
  284. size += computeSingularSerializedSize(Array.get(array, i));
  285. }
  286. }
  287. return size;
  288. }
  289. protected int computeSingularSerializedSize(Object value) {
  290. // This implementation is for message/group extensions.
  291. int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
  292. switch (type) {
  293. case TYPE_GROUP:
  294. MessageNano groupValue = (MessageNano) value;
  295. return CodedOutputByteBufferNano.computeGroupSize(fieldNumber, groupValue);
  296. case TYPE_MESSAGE:
  297. MessageNano messageValue = (MessageNano) value;
  298. return CodedOutputByteBufferNano.computeMessageSize(fieldNumber, messageValue);
  299. default:
  300. throw new IllegalArgumentException("Unknown type " + type);
  301. }
  302. }
  303. /**
  304. * Represents an extension of a primitive (including enum) type. If there is no primitive
  305. * extensions, this subclass will be removable by ProGuard.
  306. */
  307. private static class PrimitiveExtension<M extends ExtendableMessageNano<M>, T>
  308. extends Extension<M, T> {
  309. /**
  310. * Tag of a piece of non-packed data from the wire compatible with this extension.
  311. */
  312. private final int nonPackedTag;
  313. /**
  314. * Tag of a piece of packed data from the wire compatible with this extension.
  315. * 0 if the type of this extension is not packable.
  316. */
  317. private final int packedTag;
  318. public PrimitiveExtension(int type, Class<T> clazz, int tag, boolean repeated,
  319. int nonPackedTag, int packedTag) {
  320. super(type, clazz, tag, repeated);
  321. this.nonPackedTag = nonPackedTag;
  322. this.packedTag = packedTag;
  323. }
  324. @Override
  325. protected Object readData(CodedInputByteBufferNano input) {
  326. try {
  327. switch (type) {
  328. case TYPE_DOUBLE:
  329. return input.readDouble();
  330. case TYPE_FLOAT:
  331. return input.readFloat();
  332. case TYPE_INT64:
  333. return input.readInt64();
  334. case TYPE_UINT64:
  335. return input.readUInt64();
  336. case TYPE_INT32:
  337. return input.readInt32();
  338. case TYPE_FIXED64:
  339. return input.readFixed64();
  340. case TYPE_FIXED32:
  341. return input.readFixed32();
  342. case TYPE_BOOL:
  343. return input.readBool();
  344. case TYPE_STRING:
  345. return input.readString();
  346. case TYPE_BYTES:
  347. return input.readBytes();
  348. case TYPE_UINT32:
  349. return input.readUInt32();
  350. case TYPE_ENUM:
  351. return input.readEnum();
  352. case TYPE_SFIXED32:
  353. return input.readSFixed32();
  354. case TYPE_SFIXED64:
  355. return input.readSFixed64();
  356. case TYPE_SINT32:
  357. return input.readSInt32();
  358. case TYPE_SINT64:
  359. return input.readSInt64();
  360. default:
  361. throw new IllegalArgumentException("Unknown type " + type);
  362. }
  363. } catch (IOException e) {
  364. throw new IllegalArgumentException("Error reading extension field", e);
  365. }
  366. }
  367. @Override
  368. protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
  369. // This implementation is for primitive typed extensions,
  370. // which can read both packed and non-packed data.
  371. if (data.tag == nonPackedTag) {
  372. resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
  373. } else {
  374. CodedInputByteBufferNano buffer =
  375. CodedInputByteBufferNano.newInstance(data.bytes);
  376. try {
  377. buffer.pushLimit(buffer.readRawVarint32()); // length limit
  378. } catch (IOException e) {
  379. throw new IllegalArgumentException("Error reading extension field", e);
  380. }
  381. while (!buffer.isAtEnd()) {
  382. resultList.add(readData(buffer));
  383. }
  384. }
  385. }
  386. @Override
  387. protected final void writeSingularData(Object value, CodedOutputByteBufferNano output) {
  388. try {
  389. output.writeRawVarint32(tag);
  390. switch (type) {
  391. case TYPE_DOUBLE:
  392. Double doubleValue = (Double) value;
  393. output.writeDoubleNoTag(doubleValue);
  394. break;
  395. case TYPE_FLOAT:
  396. Float floatValue = (Float) value;
  397. output.writeFloatNoTag(floatValue);
  398. break;
  399. case TYPE_INT64:
  400. Long int64Value = (Long) value;
  401. output.writeInt64NoTag(int64Value);
  402. break;
  403. case TYPE_UINT64:
  404. Long uint64Value = (Long) value;
  405. output.writeUInt64NoTag(uint64Value);
  406. break;
  407. case TYPE_INT32:
  408. Integer int32Value = (Integer) value;
  409. output.writeInt32NoTag(int32Value);
  410. break;
  411. case TYPE_FIXED64:
  412. Long fixed64Value = (Long) value;
  413. output.writeFixed64NoTag(fixed64Value);
  414. break;
  415. case TYPE_FIXED32:
  416. Integer fixed32Value = (Integer) value;
  417. output.writeFixed32NoTag(fixed32Value);
  418. break;
  419. case TYPE_BOOL:
  420. Boolean boolValue = (Boolean) value;
  421. output.writeBoolNoTag(boolValue);
  422. break;
  423. case TYPE_STRING:
  424. String stringValue = (String) value;
  425. output.writeStringNoTag(stringValue);
  426. break;
  427. case TYPE_BYTES:
  428. byte[] bytesValue = (byte[]) value;
  429. output.writeBytesNoTag(bytesValue);
  430. break;
  431. case TYPE_UINT32:
  432. Integer uint32Value = (Integer) value;
  433. output.writeUInt32NoTag(uint32Value);
  434. break;
  435. case TYPE_ENUM:
  436. Integer enumValue = (Integer) value;
  437. output.writeEnumNoTag(enumValue);
  438. break;
  439. case TYPE_SFIXED32:
  440. Integer sfixed32Value = (Integer) value;
  441. output.writeSFixed32NoTag(sfixed32Value);
  442. break;
  443. case TYPE_SFIXED64:
  444. Long sfixed64Value = (Long) value;
  445. output.writeSFixed64NoTag(sfixed64Value);
  446. break;
  447. case TYPE_SINT32:
  448. Integer sint32Value = (Integer) value;
  449. output.writeSInt32NoTag(sint32Value);
  450. break;
  451. case TYPE_SINT64:
  452. Long sint64Value = (Long) value;
  453. output.writeSInt64NoTag(sint64Value);
  454. break;
  455. default:
  456. throw new IllegalArgumentException("Unknown type " + type);
  457. }
  458. } catch (IOException e) {
  459. // Should not happen
  460. throw new IllegalStateException(e);
  461. }
  462. }
  463. @Override
  464. protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
  465. if (tag == nonPackedTag) {
  466. // Use base implementation for non-packed data
  467. super.writeRepeatedData(array, output);
  468. } else if (tag == packedTag) {
  469. // Packed. Note that the array element type is guaranteed to be primitive, so there
  470. // won't be any null elements, so no null check in this block.
  471. int arrayLength = Array.getLength(array);
  472. int dataSize = computePackedDataSize(array);
  473. try {
  474. output.writeRawVarint32(tag);
  475. output.writeRawVarint32(dataSize);
  476. switch (type) {
  477. case TYPE_BOOL:
  478. for (int i = 0; i < arrayLength; i++) {
  479. output.writeBoolNoTag(Array.getBoolean(array, i));
  480. }
  481. break;
  482. case TYPE_FIXED32:
  483. for (int i = 0; i < arrayLength; i++) {
  484. output.writeFixed32NoTag(Array.getInt(array, i));
  485. }
  486. break;
  487. case TYPE_SFIXED32:
  488. for (int i = 0; i < arrayLength; i++) {
  489. output.writeSFixed32NoTag(Array.getInt(array, i));
  490. }
  491. break;
  492. case TYPE_FLOAT:
  493. for (int i = 0; i < arrayLength; i++) {
  494. output.writeFloatNoTag(Array.getFloat(array, i));
  495. }
  496. break;
  497. case TYPE_FIXED64:
  498. for (int i = 0; i < arrayLength; i++) {
  499. output.writeFixed64NoTag(Array.getLong(array, i));
  500. }
  501. break;
  502. case TYPE_SFIXED64:
  503. for (int i = 0; i < arrayLength; i++) {
  504. output.writeSFixed64NoTag(Array.getLong(array, i));
  505. }
  506. break;
  507. case TYPE_DOUBLE:
  508. for (int i = 0; i < arrayLength; i++) {
  509. output.writeDoubleNoTag(Array.getDouble(array, i));
  510. }
  511. break;
  512. case TYPE_INT32:
  513. for (int i = 0; i < arrayLength; i++) {
  514. output.writeInt32NoTag(Array.getInt(array, i));
  515. }
  516. break;
  517. case TYPE_SINT32:
  518. for (int i = 0; i < arrayLength; i++) {
  519. output.writeSInt32NoTag(Array.getInt(array, i));
  520. }
  521. break;
  522. case TYPE_UINT32:
  523. for (int i = 0; i < arrayLength; i++) {
  524. output.writeUInt32NoTag(Array.getInt(array, i));
  525. }
  526. break;
  527. case TYPE_INT64:
  528. for (int i = 0; i < arrayLength; i++) {
  529. output.writeInt64NoTag(Array.getLong(array, i));
  530. }
  531. break;
  532. case TYPE_SINT64:
  533. for (int i = 0; i < arrayLength; i++) {
  534. output.writeSInt64NoTag(Array.getLong(array, i));
  535. }
  536. break;
  537. case TYPE_UINT64:
  538. for (int i = 0; i < arrayLength; i++) {
  539. output.writeUInt64NoTag(Array.getLong(array, i));
  540. }
  541. break;
  542. case TYPE_ENUM:
  543. for (int i = 0; i < arrayLength; i++) {
  544. output.writeEnumNoTag(Array.getInt(array, i));
  545. }
  546. break;
  547. default:
  548. throw new IllegalArgumentException("Unpackable type " + type);
  549. }
  550. } catch (IOException e) {
  551. // Should not happen.
  552. throw new IllegalStateException(e);
  553. }
  554. } else {
  555. throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
  556. + ", unequal to both non-packed variant " + nonPackedTag
  557. + " and packed variant " + packedTag);
  558. }
  559. }
  560. private int computePackedDataSize(Object array) {
  561. int dataSize = 0;
  562. int arrayLength = Array.getLength(array);
  563. switch (type) {
  564. case TYPE_BOOL:
  565. // Bools are stored as int32 but just as 0 or 1, so 1 byte each.
  566. dataSize = arrayLength;
  567. break;
  568. case TYPE_FIXED32:
  569. case TYPE_SFIXED32:
  570. case TYPE_FLOAT:
  571. dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_32_SIZE;
  572. break;
  573. case TYPE_FIXED64:
  574. case TYPE_SFIXED64:
  575. case TYPE_DOUBLE:
  576. dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_64_SIZE;
  577. break;
  578. case TYPE_INT32:
  579. for (int i = 0; i < arrayLength; i++) {
  580. dataSize += CodedOutputByteBufferNano.computeInt32SizeNoTag(
  581. Array.getInt(array, i));
  582. }
  583. break;
  584. case TYPE_SINT32:
  585. for (int i = 0; i < arrayLength; i++) {
  586. dataSize += CodedOutputByteBufferNano.computeSInt32SizeNoTag(
  587. Array.getInt(array, i));
  588. }
  589. break;
  590. case TYPE_UINT32:
  591. for (int i = 0; i < arrayLength; i++) {
  592. dataSize += CodedOutputByteBufferNano.computeUInt32SizeNoTag(
  593. Array.getInt(array, i));
  594. }
  595. break;
  596. case TYPE_INT64:
  597. for (int i = 0; i < arrayLength; i++) {
  598. dataSize += CodedOutputByteBufferNano.computeInt64SizeNoTag(
  599. Array.getLong(array, i));
  600. }
  601. break;
  602. case TYPE_SINT64:
  603. for (int i = 0; i < arrayLength; i++) {
  604. dataSize += CodedOutputByteBufferNano.computeSInt64SizeNoTag(
  605. Array.getLong(array, i));
  606. }
  607. break;
  608. case TYPE_UINT64:
  609. for (int i = 0; i < arrayLength; i++) {
  610. dataSize += CodedOutputByteBufferNano.computeUInt64SizeNoTag(
  611. Array.getLong(array, i));
  612. }
  613. break;
  614. case TYPE_ENUM:
  615. for (int i = 0; i < arrayLength; i++) {
  616. dataSize += CodedOutputByteBufferNano.computeEnumSizeNoTag(
  617. Array.getInt(array, i));
  618. }
  619. break;
  620. default:
  621. throw new IllegalArgumentException("Unexpected non-packable type " + type);
  622. }
  623. return dataSize;
  624. }
  625. @Override
  626. protected int computeRepeatedSerializedSize(Object array) {
  627. if (tag == nonPackedTag) {
  628. // Use base implementation for non-packed data
  629. return super.computeRepeatedSerializedSize(array);
  630. } else if (tag == packedTag) {
  631. // Packed.
  632. int dataSize = computePackedDataSize(array);
  633. int payloadSize =
  634. dataSize + CodedOutputByteBufferNano.computeRawVarint32Size(dataSize);
  635. return payloadSize + CodedOutputByteBufferNano.computeRawVarint32Size(tag);
  636. } else {
  637. throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
  638. + ", unequal to both non-packed variant " + nonPackedTag
  639. + " and packed variant " + packedTag);
  640. }
  641. }
  642. @Override
  643. protected final int computeSingularSerializedSize(Object value) {
  644. int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
  645. switch (type) {
  646. case TYPE_DOUBLE:
  647. Double doubleValue = (Double) value;
  648. return CodedOutputByteBufferNano.computeDoubleSize(fieldNumber, doubleValue);
  649. case TYPE_FLOAT:
  650. Float floatValue = (Float) value;
  651. return CodedOutputByteBufferNano.computeFloatSize(fieldNumber, floatValue);
  652. case TYPE_INT64:
  653. Long int64Value = (Long) value;
  654. return CodedOutputByteBufferNano.computeInt64Size(fieldNumber, int64Value);
  655. case TYPE_UINT64:
  656. Long uint64Value = (Long) value;
  657. return CodedOutputByteBufferNano.computeUInt64Size(fieldNumber, uint64Value);
  658. case TYPE_INT32:
  659. Integer int32Value = (Integer) value;
  660. return CodedOutputByteBufferNano.computeInt32Size(fieldNumber, int32Value);
  661. case TYPE_FIXED64:
  662. Long fixed64Value = (Long) value;
  663. return CodedOutputByteBufferNano.computeFixed64Size(fieldNumber, fixed64Value);
  664. case TYPE_FIXED32:
  665. Integer fixed32Value = (Integer) value;
  666. return CodedOutputByteBufferNano.computeFixed32Size(fieldNumber, fixed32Value);
  667. case TYPE_BOOL:
  668. Boolean boolValue = (Boolean) value;
  669. return CodedOutputByteBufferNano.computeBoolSize(fieldNumber, boolValue);
  670. case TYPE_STRING:
  671. String stringValue = (String) value;
  672. return CodedOutputByteBufferNano.computeStringSize(fieldNumber, stringValue);
  673. case TYPE_BYTES:
  674. byte[] bytesValue = (byte[]) value;
  675. return CodedOutputByteBufferNano.computeBytesSize(fieldNumber, bytesValue);
  676. case TYPE_UINT32:
  677. Integer uint32Value = (Integer) value;
  678. return CodedOutputByteBufferNano.computeUInt32Size(fieldNumber, uint32Value);
  679. case TYPE_ENUM:
  680. Integer enumValue = (Integer) value;
  681. return CodedOutputByteBufferNano.computeEnumSize(fieldNumber, enumValue);
  682. case TYPE_SFIXED32:
  683. Integer sfixed32Value = (Integer) value;
  684. return CodedOutputByteBufferNano.computeSFixed32Size(fieldNumber,
  685. sfixed32Value);
  686. case TYPE_SFIXED64:
  687. Long sfixed64Value = (Long) value;
  688. return CodedOutputByteBufferNano.computeSFixed64Size(fieldNumber,
  689. sfixed64Value);
  690. case TYPE_SINT32:
  691. Integer sint32Value = (Integer) value;
  692. return CodedOutputByteBufferNano.computeSInt32Size(fieldNumber, sint32Value);
  693. case TYPE_SINT64:
  694. Long sint64Value = (Long) value;
  695. return CodedOutputByteBufferNano.computeSInt64Size(fieldNumber, sint64Value);
  696. default:
  697. throw new IllegalArgumentException("Unknown type " + type);
  698. }
  699. }
  700. }
  701. }