MessageSchema.java
Go to the documentation of this file.
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 static com.google.protobuf.ArrayDecoders.decodeBoolList;
34 import static com.google.protobuf.ArrayDecoders.decodeBytes;
35 import static com.google.protobuf.ArrayDecoders.decodeBytesList;
36 import static com.google.protobuf.ArrayDecoders.decodeDouble;
37 import static com.google.protobuf.ArrayDecoders.decodeDoubleList;
38 import static com.google.protobuf.ArrayDecoders.decodeExtensionOrUnknownField;
39 import static com.google.protobuf.ArrayDecoders.decodeFixed32;
40 import static com.google.protobuf.ArrayDecoders.decodeFixed32List;
41 import static com.google.protobuf.ArrayDecoders.decodeFixed64;
42 import static com.google.protobuf.ArrayDecoders.decodeFixed64List;
43 import static com.google.protobuf.ArrayDecoders.decodeFloat;
44 import static com.google.protobuf.ArrayDecoders.decodeFloatList;
45 import static com.google.protobuf.ArrayDecoders.decodeGroupField;
46 import static com.google.protobuf.ArrayDecoders.decodeGroupList;
47 import static com.google.protobuf.ArrayDecoders.decodeMessageField;
48 import static com.google.protobuf.ArrayDecoders.decodeMessageList;
49 import static com.google.protobuf.ArrayDecoders.decodePackedBoolList;
50 import static com.google.protobuf.ArrayDecoders.decodePackedDoubleList;
51 import static com.google.protobuf.ArrayDecoders.decodePackedFixed32List;
52 import static com.google.protobuf.ArrayDecoders.decodePackedFixed64List;
53 import static com.google.protobuf.ArrayDecoders.decodePackedFloatList;
54 import static com.google.protobuf.ArrayDecoders.decodePackedSInt32List;
55 import static com.google.protobuf.ArrayDecoders.decodePackedSInt64List;
56 import static com.google.protobuf.ArrayDecoders.decodePackedVarint32List;
57 import static com.google.protobuf.ArrayDecoders.decodePackedVarint64List;
58 import static com.google.protobuf.ArrayDecoders.decodeSInt32List;
59 import static com.google.protobuf.ArrayDecoders.decodeSInt64List;
60 import static com.google.protobuf.ArrayDecoders.decodeString;
61 import static com.google.protobuf.ArrayDecoders.decodeStringList;
62 import static com.google.protobuf.ArrayDecoders.decodeStringListRequireUtf8;
63 import static com.google.protobuf.ArrayDecoders.decodeStringRequireUtf8;
64 import static com.google.protobuf.ArrayDecoders.decodeUnknownField;
65 import static com.google.protobuf.ArrayDecoders.decodeVarint32;
66 import static com.google.protobuf.ArrayDecoders.decodeVarint32List;
67 import static com.google.protobuf.ArrayDecoders.decodeVarint64;
68 import static com.google.protobuf.ArrayDecoders.decodeVarint64List;
69 import static com.google.protobuf.ArrayDecoders.skipField;
70 
72 import com.google.protobuf.ByteString.CodedBuilder;
77 import java.io.IOException;
78 import java.lang.reflect.Field;
79 import java.util.Arrays;
80 import java.util.Iterator;
81 import java.util.List;
82 import java.util.Map;
83 
85 final class MessageSchema<T> implements Schema<T> {
86  private static final int INTS_PER_FIELD = 3;
87  private static final int OFFSET_BITS = 20;
88  private static final int OFFSET_MASK = 0XFFFFF;
89  private static final int FIELD_TYPE_MASK = 0x0FF00000;
90  private static final int REQUIRED_MASK = 0x10000000;
91  private static final int ENFORCE_UTF8_MASK = 0x20000000;
92  private static final int[] EMPTY_INT_ARRAY = new int[0];
93 
95  static final int ONEOF_TYPE_OFFSET = 51 /* FieldType.MAP + 1 */;
96 
101  private static final sun.misc.Unsafe UNSAFE = UnsafeUtil.getUnsafe();
102 
122  private final int[] buffer;
123 
141  private final Object[] objects;
142 
143  private final int minFieldNumber;
144  private final int maxFieldNumber;
145 
146  private final MessageLite defaultInstance;
147  private final boolean hasExtensions;
148  private final boolean lite;
149  private final boolean proto3;
150  // TODO(xiaofeng): Make both full-runtime and lite-runtime support cached field size.
151  private final boolean useCachedSizeField;
152 
154  private final int[] intArray;
155 
160  private final int checkInitializedCount;
161 
166  private final int repeatedFieldOffsetStart;
167 
168  private final NewInstanceSchema newInstanceSchema;
169  private final ListFieldSchema listFieldSchema;
170  private final UnknownFieldSchema<?, ?> unknownFieldSchema;
171  private final ExtensionSchema<?> extensionSchema;
172  private final MapFieldSchema mapFieldSchema;
173 
174  private MessageSchema(
175  int[] buffer,
176  Object[] objects,
177  int minFieldNumber,
178  int maxFieldNumber,
179  MessageLite defaultInstance,
180  boolean proto3,
181  boolean useCachedSizeField,
182  int[] intArray,
183  int checkInitialized,
184  int mapFieldPositions,
185  NewInstanceSchema newInstanceSchema,
186  ListFieldSchema listFieldSchema,
187  UnknownFieldSchema<?, ?> unknownFieldSchema,
188  ExtensionSchema<?> extensionSchema,
189  MapFieldSchema mapFieldSchema) {
190  this.buffer = buffer;
191  this.objects = objects;
192  this.minFieldNumber = minFieldNumber;
193  this.maxFieldNumber = maxFieldNumber;
194 
195  this.lite = defaultInstance instanceof GeneratedMessageLite;
196  this.proto3 = proto3;
197  this.hasExtensions = extensionSchema != null && extensionSchema.hasExtensions(defaultInstance);
198  this.useCachedSizeField = useCachedSizeField;
199 
200  this.intArray = intArray;
201  this.checkInitializedCount = checkInitialized;
202  this.repeatedFieldOffsetStart = mapFieldPositions;
203 
204  this.newInstanceSchema = newInstanceSchema;
205  this.listFieldSchema = listFieldSchema;
206  this.unknownFieldSchema = unknownFieldSchema;
207  this.extensionSchema = extensionSchema;
208  this.defaultInstance = defaultInstance;
209  this.mapFieldSchema = mapFieldSchema;
210  }
211 
212  static <T> MessageSchema<T> newSchema(
213  Class<T> messageClass,
214  MessageInfo messageInfo,
215  NewInstanceSchema newInstanceSchema,
216  ListFieldSchema listFieldSchema,
217  UnknownFieldSchema<?, ?> unknownFieldSchema,
218  ExtensionSchema<?> extensionSchema,
219  MapFieldSchema mapFieldSchema) {
220  if (messageInfo instanceof RawMessageInfo) {
221  return newSchemaForRawMessageInfo(
222  (RawMessageInfo) messageInfo,
223  newInstanceSchema,
224  listFieldSchema,
225  unknownFieldSchema,
226  extensionSchema,
227  mapFieldSchema);
228 
229  } else {
230  return newSchemaForMessageInfo(
231  (StructuralMessageInfo) messageInfo,
232  newInstanceSchema,
233  listFieldSchema,
234  unknownFieldSchema,
235  extensionSchema,
236  mapFieldSchema);
237  }
238  }
239 
240  static <T> MessageSchema<T> newSchemaForRawMessageInfo(
241  RawMessageInfo messageInfo,
242  NewInstanceSchema newInstanceSchema,
243  ListFieldSchema listFieldSchema,
244  UnknownFieldSchema<?, ?> unknownFieldSchema,
245  ExtensionSchema<?> extensionSchema,
246  MapFieldSchema mapFieldSchema) {
247  final boolean isProto3 = messageInfo.getSyntax() == ProtoSyntax.PROTO3;
248 
249  String info = messageInfo.getStringInfo();
250  final int length = info.length();
251  int i = 0;
252 
253  int next = info.charAt(i++);
254  if (next >= 0xD800) {
255  int result = next & 0x1FFF;
256  int shift = 13;
257  while ((next = info.charAt(i++)) >= 0xD800) {
258  result |= (next & 0x1FFF) << shift;
259  shift += 13;
260  }
261  next = result | (next << shift);
262  }
263  final int flags = next;
264 
265  next = info.charAt(i++);
266  if (next >= 0xD800) {
267  int result = next & 0x1FFF;
268  int shift = 13;
269  while ((next = info.charAt(i++)) >= 0xD800) {
270  result |= (next & 0x1FFF) << shift;
271  shift += 13;
272  }
273  next = result | (next << shift);
274  }
275  final int fieldCount = next;
276 
277  final int oneofCount;
278  final int hasBitsCount;
279  final int minFieldNumber;
280  final int maxFieldNumber;
281  final int numEntries;
282  final int mapFieldCount;
283  final int repeatedFieldCount;
284  final int checkInitialized;
285  final int[] intArray;
286  int objectsPosition;
287  if (fieldCount == 0) {
288  oneofCount = 0;
289  hasBitsCount = 0;
290  minFieldNumber = 0;
291  maxFieldNumber = 0;
292  numEntries = 0;
293  mapFieldCount = 0;
294  repeatedFieldCount = 0;
295  checkInitialized = 0;
296  intArray = EMPTY_INT_ARRAY;
297  objectsPosition = 0;
298  } else {
299  next = info.charAt(i++);
300  if (next >= 0xD800) {
301  int result = next & 0x1FFF;
302  int shift = 13;
303  while ((next = info.charAt(i++)) >= 0xD800) {
304  result |= (next & 0x1FFF) << shift;
305  shift += 13;
306  }
307  next = result | (next << shift);
308  }
309  oneofCount = next;
310 
311  next = info.charAt(i++);
312  if (next >= 0xD800) {
313  int result = next & 0x1FFF;
314  int shift = 13;
315  while ((next = info.charAt(i++)) >= 0xD800) {
316  result |= (next & 0x1FFF) << shift;
317  shift += 13;
318  }
319  next = result | (next << shift);
320  }
321  hasBitsCount = next;
322 
323  next = info.charAt(i++);
324  if (next >= 0xD800) {
325  int result = next & 0x1FFF;
326  int shift = 13;
327  while ((next = info.charAt(i++)) >= 0xD800) {
328  result |= (next & 0x1FFF) << shift;
329  shift += 13;
330  }
331  next = result | (next << shift);
332  }
333  minFieldNumber = next;
334 
335  next = info.charAt(i++);
336  if (next >= 0xD800) {
337  int result = next & 0x1FFF;
338  int shift = 13;
339  while ((next = info.charAt(i++)) >= 0xD800) {
340  result |= (next & 0x1FFF) << shift;
341  shift += 13;
342  }
343  next = result | (next << shift);
344  }
345  maxFieldNumber = next;
346 
347  next = info.charAt(i++);
348  if (next >= 0xD800) {
349  int result = next & 0x1FFF;
350  int shift = 13;
351  while ((next = info.charAt(i++)) >= 0xD800) {
352  result |= (next & 0x1FFF) << shift;
353  shift += 13;
354  }
355  next = result | (next << shift);
356  }
357  numEntries = next;
358 
359  next = info.charAt(i++);
360  if (next >= 0xD800) {
361  int result = next & 0x1FFF;
362  int shift = 13;
363  while ((next = info.charAt(i++)) >= 0xD800) {
364  result |= (next & 0x1FFF) << shift;
365  shift += 13;
366  }
367  next = result | (next << shift);
368  }
369  mapFieldCount = next;
370 
371  next = info.charAt(i++);
372  if (next >= 0xD800) {
373  int result = next & 0x1FFF;
374  int shift = 13;
375  while ((next = info.charAt(i++)) >= 0xD800) {
376  result |= (next & 0x1FFF) << shift;
377  shift += 13;
378  }
379  next = result | (next << shift);
380  }
381  repeatedFieldCount = next;
382 
383  next = info.charAt(i++);
384  if (next >= 0xD800) {
385  int result = next & 0x1FFF;
386  int shift = 13;
387  while ((next = info.charAt(i++)) >= 0xD800) {
388  result |= (next & 0x1FFF) << shift;
389  shift += 13;
390  }
391  next = result | (next << shift);
392  }
393  checkInitialized = next;
394  intArray = new int[checkInitialized + mapFieldCount + repeatedFieldCount];
395  // Field objects are after a list of (oneof, oneofCase) pairs + a list of hasbits fields.
396  objectsPosition = oneofCount * 2 + hasBitsCount;
397  }
398 
399  final sun.misc.Unsafe unsafe = UNSAFE;
400  final Object[] messageInfoObjects = messageInfo.getObjects();
401  int checkInitializedPosition = 0;
402  final Class<?> messageClass = messageInfo.getDefaultInstance().getClass();
403  int[] buffer = new int[numEntries * INTS_PER_FIELD];
404  Object[] objects = new Object[numEntries * 2];
405 
406  int mapFieldIndex = checkInitialized;
407  int repeatedFieldIndex = checkInitialized + mapFieldCount;
408 
409  int bufferIndex = 0;
410  while (i < length) {
411  final int fieldNumber;
412  final int fieldTypeWithExtraBits;
413  final int fieldType;
414 
415  next = info.charAt(i++);
416  if (next >= 0xD800) {
417  int result = next & 0x1FFF;
418  int shift = 13;
419  while ((next = info.charAt(i++)) >= 0xD800) {
420  result |= (next & 0x1FFF) << shift;
421  shift += 13;
422  }
423  next = result | (next << shift);
424  }
425  fieldNumber = next;
426 
427  next = info.charAt(i++);
428  if (next >= 0xD800) {
429  int result = next & 0x1FFF;
430  int shift = 13;
431  while ((next = info.charAt(i++)) >= 0xD800) {
432  result |= (next & 0x1FFF) << shift;
433  shift += 13;
434  }
435  next = result | (next << shift);
436  }
437  fieldTypeWithExtraBits = next;
438  fieldType = fieldTypeWithExtraBits & 0xFF;
439 
440  if ((fieldTypeWithExtraBits & 0x400) != 0) {
441  intArray[checkInitializedPosition++] = bufferIndex;
442  }
443 
444  final int fieldOffset;
445  final int presenceMaskShift;
446  final int presenceFieldOffset;
447 
448  // Oneof
449  if (fieldType >= ONEOF_TYPE_OFFSET) {
450  next = info.charAt(i++);
451  if (next >= 0xD800) {
452  int result = next & 0x1FFF;
453  int shift = 13;
454  while ((next = info.charAt(i++)) >= 0xD800) {
455  result |= (next & 0x1FFF) << shift;
456  shift += 13;
457  }
458  next = result | (next << shift);
459  }
460  int oneofIndex = next;
461 
462  final int oneofFieldType = fieldType - ONEOF_TYPE_OFFSET;
463  if (oneofFieldType == 9 /* FieldType.MESSAGE */
464  || oneofFieldType == 17 /* FieldType.GROUP */) {
465  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
466  } else if (oneofFieldType == 12 /* FieldType.ENUM */) {
467  // proto2
468  if ((flags & 0x1) == 0x1) {
469  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
470  }
471  }
472 
473  final java.lang.reflect.Field oneofField;
474  int index = oneofIndex * 2;
475  Object o = messageInfoObjects[index];
476  if (o instanceof java.lang.reflect.Field) {
477  oneofField = (java.lang.reflect.Field) o;
478  } else {
479  oneofField = reflectField(messageClass, (String) o);
480  // Memoize java.lang.reflect.Field instances for oneof/hasbits fields, since they're
481  // potentially used for many Protobuf fields. Since there's a 1-1 mapping from the
482  // Protobuf field to the Java Field for non-oneofs, there's no benefit for memoizing
483  // those.
484  messageInfoObjects[index] = oneofField;
485  }
486 
487  fieldOffset = (int) unsafe.objectFieldOffset(oneofField);
488 
489  final java.lang.reflect.Field oneofCaseField;
490  index++;
491  o = messageInfoObjects[index];
492  if (o instanceof java.lang.reflect.Field) {
493  oneofCaseField = (java.lang.reflect.Field) o;
494  } else {
495  oneofCaseField = reflectField(messageClass, (String) o);
496  messageInfoObjects[index] = oneofCaseField;
497  }
498 
499  presenceFieldOffset = (int) unsafe.objectFieldOffset(oneofCaseField);
500  presenceMaskShift = 0;
501  } else {
502  Field field = reflectField(messageClass, (String) messageInfoObjects[objectsPosition++]);
503  if (fieldType == 9 /* FieldType.MESSAGE */ || fieldType == 17 /* FieldType.GROUP */) {
504  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = field.getType();
505  } else if (fieldType == 27 /* FieldType.MESSAGE_LIST */
506  || fieldType == 49 /* FieldType.GROUP_LIST */) {
507  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
508  } else if (fieldType == 12 /* FieldType.ENUM */
509  || fieldType == 30 /* FieldType.ENUM_LIST */
510  || fieldType == 44 /* FieldType.ENUM_LIST_PACKED */) {
511  if ((flags & 0x1) == 0x1) {
512  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
513  }
514  } else if (fieldType == 50 /* FieldType.MAP */) {
515  intArray[mapFieldIndex++] = bufferIndex;
516  objects[bufferIndex / INTS_PER_FIELD * 2] = messageInfoObjects[objectsPosition++];
517  if ((fieldTypeWithExtraBits & 0x800) != 0) {
518  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++];
519  }
520  }
521 
522  fieldOffset = (int) unsafe.objectFieldOffset(field);
523  if ((flags & 0x1) == 0x1 && fieldType <= 17 /* FieldType.GROUP */) {
524  next = info.charAt(i++);
525  if (next >= 0xD800) {
526  int result = next & 0x1FFF;
527  int shift = 13;
528  while ((next = info.charAt(i++)) >= 0xD800) {
529  result |= (next & 0x1FFF) << shift;
530  shift += 13;
531  }
532  next = result | (next << shift);
533  }
534  int hasBitsIndex = next;
535 
536  final java.lang.reflect.Field hasBitsField;
537  int index = oneofCount * 2 + hasBitsIndex / 32;
538  Object o = messageInfoObjects[index];
539  if (o instanceof java.lang.reflect.Field) {
540  hasBitsField = (java.lang.reflect.Field) o;
541  } else {
542  hasBitsField = reflectField(messageClass, (String) o);
543  messageInfoObjects[index] = hasBitsField;
544  }
545 
546  presenceFieldOffset = (int) unsafe.objectFieldOffset(hasBitsField);
547  presenceMaskShift = hasBitsIndex % 32;
548  } else {
549  presenceFieldOffset = 0;
550  presenceMaskShift = 0;
551  }
552 
553  if (fieldType >= 18 && fieldType <= 49) {
554  // Field types of repeated fields are in a consecutive range from 18 (DOUBLE_LIST) to
555  // 49 (GROUP_LIST).
556  intArray[repeatedFieldIndex++] = fieldOffset;
557  }
558  }
559 
560  buffer[bufferIndex++] = fieldNumber;
561  buffer[bufferIndex++] =
562  ((fieldTypeWithExtraBits & 0x200) != 0 ? ENFORCE_UTF8_MASK : 0)
563  | ((fieldTypeWithExtraBits & 0x100) != 0 ? REQUIRED_MASK : 0)
564  | (fieldType << OFFSET_BITS)
565  | fieldOffset;
566  buffer[bufferIndex++] = (presenceMaskShift << OFFSET_BITS) | presenceFieldOffset;
567  }
568 
569  return new MessageSchema<T>(
570  buffer,
571  objects,
572  minFieldNumber,
573  maxFieldNumber,
574  messageInfo.getDefaultInstance(),
575  isProto3,
576  /* useCachedSizeField= */ false,
577  intArray,
578  checkInitialized,
579  checkInitialized + mapFieldCount,
580  newInstanceSchema,
581  listFieldSchema,
582  unknownFieldSchema,
583  extensionSchema,
584  mapFieldSchema);
585  }
586 
587  private static java.lang.reflect.Field reflectField(Class<?> messageClass, String fieldName) {
588  try {
589  return messageClass.getDeclaredField(fieldName);
590  } catch (NoSuchFieldException e) {
591  // Some Samsung devices lie about what fields are present via the getDeclaredField API so
592  // we do the for loop properly that they seem to have messed up...
593  java.lang.reflect.Field[] fields = messageClass.getDeclaredFields();
594  for (java.lang.reflect.Field field : fields) {
595  if (fieldName.equals(field.getName())) {
596  return field;
597  }
598  }
599 
600  // If we make it here, the runtime still lies about what we know to be true at compile
601  // time. We throw to alert server monitoring for further remediation.
602  throw new RuntimeException(
603  "Field "
604  + fieldName
605  + " for "
606  + messageClass.getName()
607  + " not found. Known fields are "
608  + Arrays.toString(fields));
609  }
610  }
611 
612  static <T> MessageSchema<T> newSchemaForMessageInfo(
613  StructuralMessageInfo messageInfo,
614  NewInstanceSchema newInstanceSchema,
615  ListFieldSchema listFieldSchema,
616  UnknownFieldSchema<?, ?> unknownFieldSchema,
617  ExtensionSchema<?> extensionSchema,
618  MapFieldSchema mapFieldSchema) {
619  final boolean isProto3 = messageInfo.getSyntax() == ProtoSyntax.PROTO3;
620  FieldInfo[] fis = messageInfo.getFields();
621  final int minFieldNumber;
622  final int maxFieldNumber;
623  if (fis.length == 0) {
624  minFieldNumber = 0;
625  maxFieldNumber = 0;
626  } else {
627  minFieldNumber = fis[0].getFieldNumber();
628  maxFieldNumber = fis[fis.length - 1].getFieldNumber();
629  }
630 
631  final int numEntries = fis.length;
632 
633  int[] buffer = new int[numEntries * INTS_PER_FIELD];
634  Object[] objects = new Object[numEntries * 2];
635 
636  int mapFieldCount = 0;
637  int repeatedFieldCount = 0;
638  for (FieldInfo fi : fis) {
639  if (fi.getType() == FieldType.MAP) {
640  mapFieldCount++;
641  } else if (fi.getType().id() >= 18 && fi.getType().id() <= 49) {
642  // Field types of repeated fields are in a consecutive range from 18 (DOUBLE_LIST) to
643  // 49 (GROUP_LIST).
644  repeatedFieldCount++;
645  }
646  }
647  int[] mapFieldPositions = mapFieldCount > 0 ? new int[mapFieldCount] : null;
648  int[] repeatedFieldOffsets = repeatedFieldCount > 0 ? new int[repeatedFieldCount] : null;
649  mapFieldCount = 0;
650  repeatedFieldCount = 0;
651 
652  int[] checkInitialized = messageInfo.getCheckInitialized();
653  if (checkInitialized == null) {
654  checkInitialized = EMPTY_INT_ARRAY;
655  }
656  int checkInitializedIndex = 0;
657  // Fill in the manifest data from the descriptors.
658  int fieldIndex = 0;
659  for (int bufferIndex = 0; fieldIndex < fis.length; bufferIndex += INTS_PER_FIELD) {
660  final FieldInfo fi = fis[fieldIndex];
661  final int fieldNumber = fi.getFieldNumber();
662 
663  // We found the entry for the next field. Store the entry in the manifest for
664  // this field and increment the field index.
665  storeFieldData(fi, buffer, bufferIndex, isProto3, objects);
666 
667  // Convert field number to index
668  if (checkInitializedIndex < checkInitialized.length
669  && checkInitialized[checkInitializedIndex] == fieldNumber) {
670  checkInitialized[checkInitializedIndex++] = bufferIndex;
671  }
672 
673  if (fi.getType() == FieldType.MAP) {
674  mapFieldPositions[mapFieldCount++] = bufferIndex;
675  } else if (fi.getType().id() >= 18 && fi.getType().id() <= 49) {
676  // Field types of repeated fields are in a consecutive range from 18 (DOUBLE_LIST) to
677  // 49 (GROUP_LIST).
678  repeatedFieldOffsets[repeatedFieldCount++] =
679  (int) UnsafeUtil.objectFieldOffset(fi.getField());
680  }
681 
682  fieldIndex++;
683  }
684 
685  if (mapFieldPositions == null) {
686  mapFieldPositions = EMPTY_INT_ARRAY;
687  }
688  if (repeatedFieldOffsets == null) {
689  repeatedFieldOffsets = EMPTY_INT_ARRAY;
690  }
691  int[] combined =
692  new int[checkInitialized.length + mapFieldPositions.length + repeatedFieldOffsets.length];
693  System.arraycopy(checkInitialized, 0, combined, 0, checkInitialized.length);
694  System.arraycopy(
695  mapFieldPositions, 0, combined, checkInitialized.length, mapFieldPositions.length);
696  System.arraycopy(
697  repeatedFieldOffsets,
698  0,
699  combined,
700  checkInitialized.length + mapFieldPositions.length,
701  repeatedFieldOffsets.length);
702 
703  return new MessageSchema<T>(
704  buffer,
705  objects,
706  minFieldNumber,
707  maxFieldNumber,
708  messageInfo.getDefaultInstance(),
709  isProto3,
710  /* useCachedSizeField= */ true,
711  combined,
712  checkInitialized.length,
713  checkInitialized.length + mapFieldPositions.length,
714  newInstanceSchema,
715  listFieldSchema,
716  unknownFieldSchema,
717  extensionSchema,
718  mapFieldSchema);
719  }
720 
721  private static void storeFieldData(
722  FieldInfo fi, int[] buffer, int bufferIndex, boolean proto3, Object[] objects) {
723  final int fieldOffset;
724  final int typeId;
725  final int presenceMaskShift;
726  final int presenceFieldOffset;
727 
728  OneofInfo oneof = fi.getOneof();
729  if (oneof != null) {
730  typeId = fi.getType().id() + ONEOF_TYPE_OFFSET;
731  fieldOffset = (int) UnsafeUtil.objectFieldOffset(oneof.getValueField());
732  presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(oneof.getCaseField());
733  presenceMaskShift = 0;
734  } else {
735  FieldType type = fi.getType();
736  fieldOffset = (int) UnsafeUtil.objectFieldOffset(fi.getField());
737  typeId = type.id();
738  if (!proto3 && !type.isList() && !type.isMap()) {
739  presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(fi.getPresenceField());
740  presenceMaskShift = Integer.numberOfTrailingZeros(fi.getPresenceMask());
741  } else {
742  if (fi.getCachedSizeField() == null) {
743  presenceFieldOffset = 0;
744  presenceMaskShift = 0;
745  } else {
746  presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(fi.getCachedSizeField());
747  presenceMaskShift = 0;
748  }
749  }
750  }
751 
752  buffer[bufferIndex] = fi.getFieldNumber();
753  buffer[bufferIndex + 1] =
754  (fi.isEnforceUtf8() ? ENFORCE_UTF8_MASK : 0)
755  | (fi.isRequired() ? REQUIRED_MASK : 0)
756  | (typeId << OFFSET_BITS)
757  | fieldOffset;
758  buffer[bufferIndex + 2] = (presenceMaskShift << OFFSET_BITS) | presenceFieldOffset;
759 
760  Object messageFieldClass = fi.getMessageFieldClass();
761  if (fi.getMapDefaultEntry() != null) {
762  objects[bufferIndex / INTS_PER_FIELD * 2] = fi.getMapDefaultEntry();
763  if (messageFieldClass != null) {
764  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageFieldClass;
765  } else if (fi.getEnumVerifier() != null) {
766  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = fi.getEnumVerifier();
767  }
768  } else {
769  if (messageFieldClass != null) {
770  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageFieldClass;
771  } else if (fi.getEnumVerifier() != null) {
772  objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = fi.getEnumVerifier();
773  }
774  }
775  }
776 
777  @SuppressWarnings("unchecked")
778  @Override
779  public T newInstance() {
780  return (T) newInstanceSchema.newInstance(defaultInstance);
781  }
782 
783  @Override
784  public boolean equals(T message, T other) {
785  final int bufferLength = buffer.length;
786  for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) {
787  if (!equals(message, other, pos)) {
788  return false;
789  }
790  }
791 
792  Object messageUnknown = unknownFieldSchema.getFromMessage(message);
793  Object otherUnknown = unknownFieldSchema.getFromMessage(other);
794  if (!messageUnknown.equals(otherUnknown)) {
795  return false;
796  }
797 
798  if (hasExtensions) {
799  FieldSet<?> messageExtensions = extensionSchema.getExtensions(message);
800  FieldSet<?> otherExtensions = extensionSchema.getExtensions(other);
801  return messageExtensions.equals(otherExtensions);
802  }
803  return true;
804  }
805 
806  private boolean equals(T message, T other, int pos) {
807  final int typeAndOffset = typeAndOffsetAt(pos);
808  final long offset = offset(typeAndOffset);
809 
810  switch (type(typeAndOffset)) {
811  case 0: // DOUBLE:
812  return arePresentForEquals(message, other, pos)
813  && Double.doubleToLongBits(UnsafeUtil.getDouble(message, offset))
814  == Double.doubleToLongBits(UnsafeUtil.getDouble(other, offset));
815  case 1: // FLOAT:
816  return arePresentForEquals(message, other, pos)
817  && Float.floatToIntBits(UnsafeUtil.getFloat(message, offset))
818  == Float.floatToIntBits(UnsafeUtil.getFloat(other, offset));
819  case 2: // INT64:
820  return arePresentForEquals(message, other, pos)
821  && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
822  case 3: // UINT64:
823  return arePresentForEquals(message, other, pos)
824  && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
825  case 4: // INT32:
826  return arePresentForEquals(message, other, pos)
827  && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
828  case 5: // FIXED64:
829  return arePresentForEquals(message, other, pos)
830  && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
831  case 6: // FIXED32:
832  return arePresentForEquals(message, other, pos)
833  && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
834  case 7: // BOOL:
835  return arePresentForEquals(message, other, pos)
836  && UnsafeUtil.getBoolean(message, offset) == UnsafeUtil.getBoolean(other, offset);
837  case 8: // STRING:
838  return arePresentForEquals(message, other, pos)
839  && SchemaUtil.safeEquals(
840  UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
841  case 9: // MESSAGE:
842  return arePresentForEquals(message, other, pos)
843  && SchemaUtil.safeEquals(
844  UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
845  case 10: // BYTES:
846  return arePresentForEquals(message, other, pos)
847  && SchemaUtil.safeEquals(
848  UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
849  case 11: // UINT32:
850  return arePresentForEquals(message, other, pos)
851  && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
852  case 12: // ENUM:
853  return arePresentForEquals(message, other, pos)
854  && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
855  case 13: // SFIXED32:
856  return arePresentForEquals(message, other, pos)
857  && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
858  case 14: // SFIXED64:
859  return arePresentForEquals(message, other, pos)
860  && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
861  case 15: // SINT32:
862  return arePresentForEquals(message, other, pos)
863  && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset);
864  case 16: // SINT64:
865  return arePresentForEquals(message, other, pos)
866  && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset);
867  case 17: // GROUP:
868  return arePresentForEquals(message, other, pos)
869  && SchemaUtil.safeEquals(
870  UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
871 
872  case 18: // DOUBLE_LIST:
873  case 19: // FLOAT_LIST:
874  case 20: // INT64_LIST:
875  case 21: // UINT64_LIST:
876  case 22: // INT32_LIST:
877  case 23: // FIXED64_LIST:
878  case 24: // FIXED32_LIST:
879  case 25: // BOOL_LIST:
880  case 26: // STRING_LIST:
881  case 27: // MESSAGE_LIST:
882  case 28: // BYTES_LIST:
883  case 29: // UINT32_LIST:
884  case 30: // ENUM_LIST:
885  case 31: // SFIXED32_LIST:
886  case 32: // SFIXED64_LIST:
887  case 33: // SINT32_LIST:
888  case 34: // SINT64_LIST:
889  case 35: // DOUBLE_LIST_PACKED:
890  case 36: // FLOAT_LIST_PACKED:
891  case 37: // INT64_LIST_PACKED:
892  case 38: // UINT64_LIST_PACKED:
893  case 39: // INT32_LIST_PACKED:
894  case 40: // FIXED64_LIST_PACKED:
895  case 41: // FIXED32_LIST_PACKED:
896  case 42: // BOOL_LIST_PACKED:
897  case 43: // UINT32_LIST_PACKED:
898  case 44: // ENUM_LIST_PACKED:
899  case 45: // SFIXED32_LIST_PACKED:
900  case 46: // SFIXED64_LIST_PACKED:
901  case 47: // SINT32_LIST_PACKED:
902  case 48: // SINT64_LIST_PACKED:
903  case 49: // GROUP_LIST:
904  return SchemaUtil.safeEquals(
905  UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
906  case 50: // MAP:
907  return SchemaUtil.safeEquals(
908  UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
909  case 51: // ONEOF_DOUBLE:
910  case 52: // ONEOF_FLOAT:
911  case 53: // ONEOF_INT64:
912  case 54: // ONEOF_UINT64:
913  case 55: // ONEOF_INT32:
914  case 56: // ONEOF_FIXED64:
915  case 57: // ONEOF_FIXED32:
916  case 58: // ONEOF_BOOL:
917  case 59: // ONEOF_STRING:
918  case 60: // ONEOF_MESSAGE:
919  case 61: // ONEOF_BYTES:
920  case 62: // ONEOF_UINT32:
921  case 63: // ONEOF_ENUM:
922  case 64: // ONEOF_SFIXED32:
923  case 65: // ONEOF_SFIXED64:
924  case 66: // ONEOF_SINT32:
925  case 67: // ONEOF_SINT64:
926  case 68: // ONEOF_GROUP:
927  return isOneofCaseEqual(message, other, pos)
928  && SchemaUtil.safeEquals(
929  UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset));
930  default:
931  // Assume it's an empty entry - just go to the next entry.
932  return true;
933  }
934  }
935 
936  @Override
937  public int hashCode(T message) {
938  int hashCode = 0;
939  final int bufferLength = buffer.length;
940  for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) {
941  final int typeAndOffset = typeAndOffsetAt(pos);
942  final int entryNumber = numberAt(pos);
943 
944  final long offset = offset(typeAndOffset);
945 
946  switch (type(typeAndOffset)) {
947  case 0: // DOUBLE:
948  hashCode =
949  (hashCode * 53)
950  + Internal.hashLong(
951  Double.doubleToLongBits(UnsafeUtil.getDouble(message, offset)));
952  break;
953  case 1: // FLOAT:
954  hashCode = (hashCode * 53) + Float.floatToIntBits(UnsafeUtil.getFloat(message, offset));
955  break;
956  case 2: // INT64:
957  hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
958  break;
959  case 3: // UINT64:
960  hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
961  break;
962  case 4: // INT32:
963  hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
964  break;
965  case 5: // FIXED64:
966  hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
967  break;
968  case 6: // FIXED32:
969  hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
970  break;
971  case 7: // BOOL:
972  hashCode = (hashCode * 53) + Internal.hashBoolean(UnsafeUtil.getBoolean(message, offset));
973  break;
974  case 8: // STRING:
975  hashCode = (hashCode * 53) + ((String) UnsafeUtil.getObject(message, offset)).hashCode();
976  break;
977  case 9: // MESSAGE:
978  {
979  int protoHash = 37;
980  Object submessage = UnsafeUtil.getObject(message, offset);
981  if (submessage != null) {
982  protoHash = submessage.hashCode();
983  }
984  hashCode = (53 * hashCode) + protoHash;
985  break;
986  }
987  case 10: // BYTES:
988  hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode();
989  break;
990  case 11: // UINT32:
991  hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
992  break;
993  case 12: // ENUM:
994  hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
995  break;
996  case 13: // SFIXED32:
997  hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
998  break;
999  case 14: // SFIXED64:
1000  hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
1001  break;
1002  case 15: // SINT32:
1003  hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset));
1004  break;
1005  case 16: // SINT64:
1006  hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset));
1007  break;
1008 
1009  case 17: // GROUP:
1010  {
1011  int protoHash = 37;
1012  Object submessage = UnsafeUtil.getObject(message, offset);
1013  if (submessage != null) {
1014  protoHash = submessage.hashCode();
1015  }
1016  hashCode = (53 * hashCode) + protoHash;
1017  break;
1018  }
1019  case 18: // DOUBLE_LIST:
1020  case 19: // FLOAT_LIST:
1021  case 20: // INT64_LIST:
1022  case 21: // UINT64_LIST:
1023  case 22: // INT32_LIST:
1024  case 23: // FIXED64_LIST:
1025  case 24: // FIXED32_LIST:
1026  case 25: // BOOL_LIST:
1027  case 26: // STRING_LIST:
1028  case 27: // MESSAGE_LIST:
1029  case 28: // BYTES_LIST:
1030  case 29: // UINT32_LIST:
1031  case 30: // ENUM_LIST:
1032  case 31: // SFIXED32_LIST:
1033  case 32: // SFIXED64_LIST:
1034  case 33: // SINT32_LIST:
1035  case 34: // SINT64_LIST:
1036  case 35: // DOUBLE_LIST_PACKED:
1037  case 36: // FLOAT_LIST_PACKED:
1038  case 37: // INT64_LIST_PACKED:
1039  case 38: // UINT64_LIST_PACKED:
1040  case 39: // INT32_LIST_PACKED:
1041  case 40: // FIXED64_LIST_PACKED:
1042  case 41: // FIXED32_LIST_PACKED:
1043  case 42: // BOOL_LIST_PACKED:
1044  case 43: // UINT32_LIST_PACKED:
1045  case 44: // ENUM_LIST_PACKED:
1046  case 45: // SFIXED32_LIST_PACKED:
1047  case 46: // SFIXED64_LIST_PACKED:
1048  case 47: // SINT32_LIST_PACKED:
1049  case 48: // SINT64_LIST_PACKED:
1050  case 49: // GROUP_LIST:
1051  hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode();
1052  break;
1053  case 50: // MAP:
1054  hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode();
1055  break;
1056  case 51: // ONEOF_DOUBLE:
1057  if (isOneofPresent(message, entryNumber, pos)) {
1058  hashCode =
1059  (hashCode * 53)
1060  + Internal.hashLong(Double.doubleToLongBits(oneofDoubleAt(message, offset)));
1061  }
1062  break;
1063  case 52: // ONEOF_FLOAT:
1064  if (isOneofPresent(message, entryNumber, pos)) {
1065  hashCode = (hashCode * 53) + Float.floatToIntBits(oneofFloatAt(message, offset));
1066  }
1067  break;
1068  case 53: // ONEOF_INT64:
1069  if (isOneofPresent(message, entryNumber, pos)) {
1070  hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
1071  }
1072  break;
1073  case 54: // ONEOF_UINT64:
1074  if (isOneofPresent(message, entryNumber, pos)) {
1075  hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
1076  }
1077  break;
1078  case 55: // ONEOF_INT32:
1079  if (isOneofPresent(message, entryNumber, pos)) {
1080  hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
1081  }
1082  break;
1083  case 56: // ONEOF_FIXED64:
1084  if (isOneofPresent(message, entryNumber, pos)) {
1085  hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
1086  }
1087  break;
1088  case 57: // ONEOF_FIXED32:
1089  if (isOneofPresent(message, entryNumber, pos)) {
1090  hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
1091  }
1092  break;
1093  case 58: // ONEOF_BOOL:
1094  if (isOneofPresent(message, entryNumber, pos)) {
1095  hashCode = (hashCode * 53) + Internal.hashBoolean(oneofBooleanAt(message, offset));
1096  }
1097  break;
1098  case 59: // ONEOF_STRING:
1099  if (isOneofPresent(message, entryNumber, pos)) {
1100  hashCode =
1101  (hashCode * 53) + ((String) UnsafeUtil.getObject(message, offset)).hashCode();
1102  }
1103  break;
1104  case 60: // ONEOF_MESSAGE:
1105  if (isOneofPresent(message, entryNumber, pos)) {
1106  Object submessage = UnsafeUtil.getObject(message, offset);
1107  hashCode = (53 * hashCode) + submessage.hashCode();
1108  }
1109  break;
1110  case 61: // ONEOF_BYTES:
1111  if (isOneofPresent(message, entryNumber, pos)) {
1112  hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode();
1113  }
1114  break;
1115  case 62: // ONEOF_UINT32:
1116  if (isOneofPresent(message, entryNumber, pos)) {
1117  hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
1118  }
1119  break;
1120  case 63: // ONEOF_ENUM:
1121  if (isOneofPresent(message, entryNumber, pos)) {
1122  hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
1123  }
1124  break;
1125  case 64: // ONEOF_SFIXED32:
1126  if (isOneofPresent(message, entryNumber, pos)) {
1127  hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
1128  }
1129  break;
1130  case 65: // ONEOF_SFIXED64:
1131  if (isOneofPresent(message, entryNumber, pos)) {
1132  hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
1133  }
1134  break;
1135  case 66: // ONEOF_SINT32:
1136  if (isOneofPresent(message, entryNumber, pos)) {
1137  hashCode = (hashCode * 53) + (oneofIntAt(message, offset));
1138  }
1139  break;
1140  case 67: // ONEOF_SINT64:
1141  if (isOneofPresent(message, entryNumber, pos)) {
1142  hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset));
1143  }
1144  break;
1145  case 68: // ONEOF_GROUP:
1146  if (isOneofPresent(message, entryNumber, pos)) {
1147  Object submessage = UnsafeUtil.getObject(message, offset);
1148  hashCode = (53 * hashCode) + submessage.hashCode();
1149  }
1150  break;
1151  default:
1152  // Assume it's an empty entry - just go to the next entry.
1153  break;
1154  }
1155  }
1156 
1157  hashCode = (hashCode * 53) + unknownFieldSchema.getFromMessage(message).hashCode();
1158 
1159  if (hasExtensions) {
1160  hashCode = (hashCode * 53) + extensionSchema.getExtensions(message).hashCode();
1161  }
1162 
1163  return hashCode;
1164  }
1165 
1166  @Override
1167  public void mergeFrom(T message, T other) {
1168  if (other == null) {
1169  throw new NullPointerException();
1170  }
1171  for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) {
1172  // A separate method allows for better JIT optimizations
1173  mergeSingleField(message, other, i);
1174  }
1175 
1176  if (!proto3) {
1177  SchemaUtil.mergeUnknownFields(unknownFieldSchema, message, other);
1178 
1179  if (hasExtensions) {
1180  SchemaUtil.mergeExtensions(extensionSchema, message, other);
1181  }
1182  }
1183  }
1184 
1185  private void mergeSingleField(T message, T other, int pos) {
1186  final int typeAndOffset = typeAndOffsetAt(pos);
1187  final long offset = offset(typeAndOffset);
1188  final int number = numberAt(pos);
1189 
1190  switch (type(typeAndOffset)) {
1191  case 0: // DOUBLE:
1192  if (isFieldPresent(other, pos)) {
1193  UnsafeUtil.putDouble(message, offset, UnsafeUtil.getDouble(other, offset));
1194  setFieldPresent(message, pos);
1195  }
1196  break;
1197  case 1: // FLOAT:
1198  if (isFieldPresent(other, pos)) {
1199  UnsafeUtil.putFloat(message, offset, UnsafeUtil.getFloat(other, offset));
1200  setFieldPresent(message, pos);
1201  }
1202  break;
1203  case 2: // INT64:
1204  if (isFieldPresent(other, pos)) {
1205  UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
1206  setFieldPresent(message, pos);
1207  }
1208  break;
1209  case 3: // UINT64:
1210  if (isFieldPresent(other, pos)) {
1211  UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
1212  setFieldPresent(message, pos);
1213  }
1214  break;
1215  case 4: // INT32:
1216  if (isFieldPresent(other, pos)) {
1217  UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
1218  setFieldPresent(message, pos);
1219  }
1220  break;
1221  case 5: // FIXED64:
1222  if (isFieldPresent(other, pos)) {
1223  UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
1224  setFieldPresent(message, pos);
1225  }
1226  break;
1227  case 6: // FIXED32:
1228  if (isFieldPresent(other, pos)) {
1229  UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
1230  setFieldPresent(message, pos);
1231  }
1232  break;
1233  case 7: // BOOL:
1234  if (isFieldPresent(other, pos)) {
1235  UnsafeUtil.putBoolean(message, offset, UnsafeUtil.getBoolean(other, offset));
1236  setFieldPresent(message, pos);
1237  }
1238  break;
1239  case 8: // STRING:
1240  if (isFieldPresent(other, pos)) {
1241  UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset));
1242  setFieldPresent(message, pos);
1243  }
1244  break;
1245  case 9: // MESSAGE:
1246  mergeMessage(message, other, pos);
1247  break;
1248  case 10: // BYTES:
1249  if (isFieldPresent(other, pos)) {
1250  UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset));
1251  setFieldPresent(message, pos);
1252  }
1253  break;
1254  case 11: // UINT32:
1255  if (isFieldPresent(other, pos)) {
1256  UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
1257  setFieldPresent(message, pos);
1258  }
1259  break;
1260  case 12: // ENUM:
1261  if (isFieldPresent(other, pos)) {
1262  UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
1263  setFieldPresent(message, pos);
1264  }
1265  break;
1266  case 13: // SFIXED32:
1267  if (isFieldPresent(other, pos)) {
1268  UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
1269  setFieldPresent(message, pos);
1270  }
1271  break;
1272  case 14: // SFIXED64:
1273  if (isFieldPresent(other, pos)) {
1274  UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
1275  setFieldPresent(message, pos);
1276  }
1277  break;
1278  case 15: // SINT32:
1279  if (isFieldPresent(other, pos)) {
1280  UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset));
1281  setFieldPresent(message, pos);
1282  }
1283  break;
1284  case 16: // SINT64:
1285  if (isFieldPresent(other, pos)) {
1286  UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset));
1287  setFieldPresent(message, pos);
1288  }
1289  break;
1290  case 17: // GROUP:
1291  mergeMessage(message, other, pos);
1292  break;
1293  case 18: // DOUBLE_LIST:
1294  case 19: // FLOAT_LIST:
1295  case 20: // INT64_LIST:
1296  case 21: // UINT64_LIST:
1297  case 22: // INT32_LIST:
1298  case 23: // FIXED64_LIST:
1299  case 24: // FIXED32_LIST:
1300  case 25: // BOOL_LIST:
1301  case 26: // STRING_LIST:
1302  case 27: // MESSAGE_LIST:
1303  case 28: // BYTES_LIST:
1304  case 29: // UINT32_LIST:
1305  case 30: // ENUM_LIST:
1306  case 31: // SFIXED32_LIST:
1307  case 32: // SFIXED64_LIST:
1308  case 33: // SINT32_LIST:
1309  case 34: // SINT64_LIST:
1310  case 35: // DOUBLE_LIST_PACKED:
1311  case 36: // FLOAT_LIST_PACKED:
1312  case 37: // INT64_LIST_PACKED:
1313  case 38: // UINT64_LIST_PACKED:
1314  case 39: // INT32_LIST_PACKED:
1315  case 40: // FIXED64_LIST_PACKED:
1316  case 41: // FIXED32_LIST_PACKED:
1317  case 42: // BOOL_LIST_PACKED:
1318  case 43: // UINT32_LIST_PACKED:
1319  case 44: // ENUM_LIST_PACKED:
1320  case 45: // SFIXED32_LIST_PACKED:
1321  case 46: // SFIXED64_LIST_PACKED:
1322  case 47: // SINT32_LIST_PACKED:
1323  case 48: // SINT64_LIST_PACKED:
1324  case 49: // GROUP_LIST:
1325  listFieldSchema.mergeListsAt(message, other, offset);
1326  break;
1327  case 50: // MAP:
1328  SchemaUtil.mergeMap(mapFieldSchema, message, other, offset);
1329  break;
1330  case 51: // ONEOF_DOUBLE:
1331  case 52: // ONEOF_FLOAT:
1332  case 53: // ONEOF_INT64:
1333  case 54: // ONEOF_UINT64:
1334  case 55: // ONEOF_INT32:
1335  case 56: // ONEOF_FIXED64:
1336  case 57: // ONEOF_FIXED32:
1337  case 58: // ONEOF_BOOL:
1338  case 59: // ONEOF_STRING:
1339  if (isOneofPresent(other, number, pos)) {
1340  UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset));
1341  setOneofPresent(message, number, pos);
1342  }
1343  break;
1344 
1345  case 60: // ONEOF_MESSAGE:
1346  mergeOneofMessage(message, other, pos);
1347  break;
1348  case 61: // ONEOF_BYTES:
1349  case 62: // ONEOF_UINT32:
1350  case 63: // ONEOF_ENUM:
1351  case 64: // ONEOF_SFIXED32:
1352  case 65: // ONEOF_SFIXED64:
1353  case 66: // ONEOF_SINT32:
1354  case 67: // ONEOF_SINT64:
1355  if (isOneofPresent(other, number, pos)) {
1356  UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset));
1357  setOneofPresent(message, number, pos);
1358  }
1359  break;
1360  case 68: // ONEOF_GROUP:
1361  mergeOneofMessage(message, other, pos);
1362  break;
1363  default:
1364  break;
1365  }
1366  }
1367 
1368  private void mergeMessage(T message, T other, int pos) {
1369  final int typeAndOffset = typeAndOffsetAt(pos);
1370  final long offset = offset(typeAndOffset);
1371 
1372  if (!isFieldPresent(other, pos)) {
1373  return;
1374  }
1375 
1376  Object mine = UnsafeUtil.getObject(message, offset);
1377  Object theirs = UnsafeUtil.getObject(other, offset);
1378  if (mine != null && theirs != null) {
1379  Object merged = Internal.mergeMessage(mine, theirs);
1380  UnsafeUtil.putObject(message, offset, merged);
1381  setFieldPresent(message, pos);
1382  } else if (theirs != null) {
1383  UnsafeUtil.putObject(message, offset, theirs);
1384  setFieldPresent(message, pos);
1385  }
1386  }
1387 
1388  private void mergeOneofMessage(T message, T other, int pos) {
1389  int typeAndOffset = typeAndOffsetAt(pos);
1390  int number = numberAt(pos);
1391  long offset = offset(typeAndOffset);
1392 
1393  if (!isOneofPresent(other, number, pos)) {
1394  return;
1395  }
1396 
1397  Object mine = UnsafeUtil.getObject(message, offset);
1398  Object theirs = UnsafeUtil.getObject(other, offset);
1399  if (mine != null && theirs != null) {
1400  Object merged = Internal.mergeMessage(mine, theirs);
1401  UnsafeUtil.putObject(message, offset, merged);
1402  setOneofPresent(message, number, pos);
1403  } else if (theirs != null) {
1404  UnsafeUtil.putObject(message, offset, theirs);
1405  setOneofPresent(message, number, pos);
1406  }
1407  }
1408 
1409  @Override
1410  public int getSerializedSize(T message) {
1411  return proto3 ? getSerializedSizeProto3(message) : getSerializedSizeProto2(message);
1412  }
1413 
1414  @SuppressWarnings("unchecked")
1415  private int getSerializedSizeProto2(T message) {
1416  int size = 0;
1417 
1418  final sun.misc.Unsafe unsafe = UNSAFE;
1419  int currentPresenceFieldOffset = -1;
1420  int currentPresenceField = 0;
1421  for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) {
1422  final int typeAndOffset = typeAndOffsetAt(i);
1423  final int number = numberAt(i);
1424 
1425  int fieldType = type(typeAndOffset);
1426  int presenceMaskAndOffset = 0;
1427  int presenceMask = 0;
1428  if (fieldType <= 17) {
1429  presenceMaskAndOffset = buffer[i + 2];
1430  final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
1431  presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
1432  if (presenceFieldOffset != currentPresenceFieldOffset) {
1433  currentPresenceFieldOffset = presenceFieldOffset;
1434  currentPresenceField = unsafe.getInt(message, (long) presenceFieldOffset);
1435  }
1436  } else if (useCachedSizeField
1437  && fieldType >= FieldType.DOUBLE_LIST_PACKED.id()
1438  && fieldType <= FieldType.SINT64_LIST_PACKED.id()) {
1439  presenceMaskAndOffset = buffer[i + 2] & OFFSET_MASK;
1440  }
1441 
1442  final long offset = offset(typeAndOffset);
1443 
1444  switch (fieldType) {
1445  case 0: // DOUBLE:
1446  if ((currentPresenceField & presenceMask) != 0) {
1447  size += CodedOutputStream.computeDoubleSize(number, 0);
1448  }
1449  break;
1450  case 1: // FLOAT:
1451  if ((currentPresenceField & presenceMask) != 0) {
1452  size += CodedOutputStream.computeFloatSize(number, 0);
1453  }
1454  break;
1455  case 2: // INT64:
1456  if ((currentPresenceField & presenceMask) != 0) {
1457  size += CodedOutputStream.computeInt64Size(number, unsafe.getLong(message, offset));
1458  }
1459  break;
1460  case 3: // UINT64:
1461  if ((currentPresenceField & presenceMask) != 0) {
1462  size += CodedOutputStream.computeUInt64Size(number, unsafe.getLong(message, offset));
1463  }
1464  break;
1465  case 4: // INT32:
1466  if ((currentPresenceField & presenceMask) != 0) {
1467  size += CodedOutputStream.computeInt32Size(number, unsafe.getInt(message, offset));
1468  }
1469  break;
1470  case 5: // FIXED64:
1471  if ((currentPresenceField & presenceMask) != 0) {
1472  size += CodedOutputStream.computeFixed64Size(number, 0);
1473  }
1474  break;
1475  case 6: // FIXED32:
1476  if ((currentPresenceField & presenceMask) != 0) {
1477  size += CodedOutputStream.computeFixed32Size(number, 0);
1478  }
1479  break;
1480  case 7: // BOOL:
1481  if ((currentPresenceField & presenceMask) != 0) {
1482  size += CodedOutputStream.computeBoolSize(number, true);
1483  }
1484  break;
1485  case 8: // STRING:
1486  if ((currentPresenceField & presenceMask) != 0) {
1487  Object value = unsafe.getObject(message, offset);
1488  if (value instanceof ByteString) {
1489  size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
1490  } else {
1491  size += CodedOutputStream.computeStringSize(number, (String) value);
1492  }
1493  }
1494  break;
1495  case 9: // MESSAGE:
1496  if ((currentPresenceField & presenceMask) != 0) {
1497  Object value = unsafe.getObject(message, offset);
1498  size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
1499  }
1500  break;
1501  case 10: // BYTES:
1502  if ((currentPresenceField & presenceMask) != 0) {
1503  ByteString value = (ByteString) unsafe.getObject(message, offset);
1504  size += CodedOutputStream.computeBytesSize(number, value);
1505  }
1506  break;
1507  case 11: // UINT32:
1508  if ((currentPresenceField & presenceMask) != 0) {
1509  size += CodedOutputStream.computeUInt32Size(number, unsafe.getInt(message, offset));
1510  }
1511  break;
1512  case 12: // ENUM:
1513  if ((currentPresenceField & presenceMask) != 0) {
1514  size += CodedOutputStream.computeEnumSize(number, unsafe.getInt(message, offset));
1515  }
1516  break;
1517  case 13: // SFIXED32:
1518  if ((currentPresenceField & presenceMask) != 0) {
1519  size += CodedOutputStream.computeSFixed32Size(number, 0);
1520  }
1521  break;
1522  case 14: // SFIXED64:
1523  if ((currentPresenceField & presenceMask) != 0) {
1524  size += CodedOutputStream.computeSFixed64Size(number, 0);
1525  }
1526  break;
1527  case 15: // SINT32:
1528  if ((currentPresenceField & presenceMask) != 0) {
1529  size += CodedOutputStream.computeSInt32Size(number, unsafe.getInt(message, offset));
1530  }
1531  break;
1532  case 16: // SINT64:
1533  if ((currentPresenceField & presenceMask) != 0) {
1534  size += CodedOutputStream.computeSInt64Size(number, unsafe.getLong(message, offset));
1535  }
1536  break;
1537  case 17: // GROUP:
1538  if ((currentPresenceField & presenceMask) != 0) {
1539  size +=
1540  CodedOutputStream.computeGroupSize(
1541  number,
1542  (MessageLite) unsafe.getObject(message, offset),
1543  getMessageFieldSchema(i));
1544  }
1545  break;
1546  case 18: // DOUBLE_LIST:
1547  size +=
1548  SchemaUtil.computeSizeFixed64List(
1549  number, (List<?>) unsafe.getObject(message, offset), false);
1550  break;
1551  case 19: // FLOAT_LIST:
1552  size +=
1553  SchemaUtil.computeSizeFixed32List(
1554  number, (List<?>) unsafe.getObject(message, offset), false);
1555  break;
1556  case 20: // INT64_LIST:
1557  size +=
1558  SchemaUtil.computeSizeInt64List(
1559  number, (List<Long>) unsafe.getObject(message, offset), false);
1560  break;
1561  case 21: // UINT64_LIST:
1562  size +=
1563  SchemaUtil.computeSizeUInt64List(
1564  number, (List<Long>) unsafe.getObject(message, offset), false);
1565  break;
1566  case 22: // INT32_LIST:
1567  size +=
1568  SchemaUtil.computeSizeInt32List(
1569  number, (List<Integer>) unsafe.getObject(message, offset), false);
1570  break;
1571  case 23: // FIXED64_LIST:
1572  size +=
1573  SchemaUtil.computeSizeFixed64List(
1574  number, (List<?>) unsafe.getObject(message, offset), false);
1575  break;
1576  case 24: // FIXED32_LIST:
1577  size +=
1578  SchemaUtil.computeSizeFixed32List(
1579  number, (List<?>) unsafe.getObject(message, offset), false);
1580  break;
1581  case 25: // BOOL_LIST:
1582  size +=
1583  SchemaUtil.computeSizeBoolList(
1584  number, (List<?>) unsafe.getObject(message, offset), false);
1585  break;
1586  case 26: // STRING_LIST:
1587  size +=
1588  SchemaUtil.computeSizeStringList(number, (List<?>) unsafe.getObject(message, offset));
1589  break;
1590  case 27: // MESSAGE_LIST:
1591  size +=
1592  SchemaUtil.computeSizeMessageList(
1593  number, (List<?>) unsafe.getObject(message, offset), getMessageFieldSchema(i));
1594  break;
1595  case 28: // BYTES_LIST:
1596  size +=
1597  SchemaUtil.computeSizeByteStringList(
1598  number, (List<ByteString>) unsafe.getObject(message, offset));
1599  break;
1600  case 29: // UINT32_LIST:
1601  size +=
1602  SchemaUtil.computeSizeUInt32List(
1603  number, (List<Integer>) unsafe.getObject(message, offset), false);
1604  break;
1605  case 30: // ENUM_LIST:
1606  size +=
1607  SchemaUtil.computeSizeEnumList(
1608  number, (List<Integer>) unsafe.getObject(message, offset), false);
1609  break;
1610  case 31: // SFIXED32_LIST:
1611  size +=
1612  SchemaUtil.computeSizeFixed32List(
1613  number, (List<Integer>) unsafe.getObject(message, offset), false);
1614  break;
1615  case 32: // SFIXED64_LIST:
1616  size +=
1617  SchemaUtil.computeSizeFixed64List(
1618  number, (List<Long>) unsafe.getObject(message, offset), false);
1619  break;
1620  case 33: // SINT32_LIST:
1621  size +=
1622  SchemaUtil.computeSizeSInt32List(
1623  number, (List<Integer>) unsafe.getObject(message, offset), false);
1624  break;
1625  case 34: // SINT64_LIST:
1626  size +=
1627  SchemaUtil.computeSizeSInt64List(
1628  number, (List<Long>) unsafe.getObject(message, offset), false);
1629  break;
1630  case 35:
1631  { // DOUBLE_LIST_PACKED:
1632  int fieldSize =
1633  SchemaUtil.computeSizeFixed64ListNoTag(
1634  (List<Double>) unsafe.getObject(message, offset));
1635  if (fieldSize > 0) {
1636  if (useCachedSizeField) {
1637  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1638  }
1639  size +=
1640  CodedOutputStream.computeTagSize(number)
1641  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1642  + fieldSize;
1643  }
1644  break;
1645  }
1646  case 36:
1647  { // FLOAT_LIST_PACKED:
1648  int fieldSize =
1649  SchemaUtil.computeSizeFixed32ListNoTag(
1650  (List<Float>) unsafe.getObject(message, offset));
1651  if (fieldSize > 0) {
1652  if (useCachedSizeField) {
1653  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1654  }
1655  size +=
1656  CodedOutputStream.computeTagSize(number)
1657  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1658  + fieldSize;
1659  }
1660  break;
1661  }
1662  case 37:
1663  { // INT64_LIST_PACKED:
1664  int fieldSize =
1665  SchemaUtil.computeSizeInt64ListNoTag(
1666  (List<Long>) unsafe.getObject(message, offset));
1667  if (fieldSize > 0) {
1668  if (useCachedSizeField) {
1669  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1670  }
1671  size +=
1672  CodedOutputStream.computeTagSize(number)
1673  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1674  + fieldSize;
1675  }
1676  break;
1677  }
1678  case 38:
1679  { // UINT64_LIST_PACKED:
1680  int fieldSize =
1681  SchemaUtil.computeSizeUInt64ListNoTag(
1682  (List<Long>) unsafe.getObject(message, offset));
1683  if (fieldSize > 0) {
1684  if (useCachedSizeField) {
1685  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1686  }
1687  size +=
1688  CodedOutputStream.computeTagSize(number)
1689  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1690  + fieldSize;
1691  }
1692  break;
1693  }
1694  case 39:
1695  { // INT32_LIST_PACKED:
1696  int fieldSize =
1697  SchemaUtil.computeSizeInt32ListNoTag(
1698  (List<Integer>) unsafe.getObject(message, offset));
1699  if (fieldSize > 0) {
1700  if (useCachedSizeField) {
1701  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1702  }
1703  size +=
1704  CodedOutputStream.computeTagSize(number)
1705  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1706  + fieldSize;
1707  }
1708  break;
1709  }
1710  case 40:
1711  { // FIXED64_LIST_PACKED:
1712  int fieldSize =
1713  SchemaUtil.computeSizeFixed64ListNoTag(
1714  (List<Long>) unsafe.getObject(message, offset));
1715  if (fieldSize > 0) {
1716  if (useCachedSizeField) {
1717  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1718  }
1719  size +=
1720  CodedOutputStream.computeTagSize(number)
1721  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1722  + fieldSize;
1723  }
1724  break;
1725  }
1726  case 41:
1727  { // FIXED32_LIST_PACKED:
1728  int fieldSize =
1729  SchemaUtil.computeSizeFixed32ListNoTag(
1730  (List<Integer>) unsafe.getObject(message, offset));
1731  if (fieldSize > 0) {
1732  if (useCachedSizeField) {
1733  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1734  }
1735  size +=
1736  CodedOutputStream.computeTagSize(number)
1737  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1738  + fieldSize;
1739  }
1740  break;
1741  }
1742  case 42:
1743  { // BOOL_LIST_PACKED:
1744  int fieldSize =
1745  SchemaUtil.computeSizeBoolListNoTag(
1746  (List<Boolean>) unsafe.getObject(message, offset));
1747  if (fieldSize > 0) {
1748  if (useCachedSizeField) {
1749  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1750  }
1751  size +=
1752  CodedOutputStream.computeTagSize(number)
1753  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1754  + fieldSize;
1755  }
1756  break;
1757  }
1758  case 43:
1759  { // UINT32_LIST_PACKED:
1760  int fieldSize =
1761  SchemaUtil.computeSizeUInt32ListNoTag(
1762  (List<Integer>) unsafe.getObject(message, offset));
1763  if (fieldSize > 0) {
1764  if (useCachedSizeField) {
1765  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1766  }
1767  size +=
1768  CodedOutputStream.computeTagSize(number)
1769  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1770  + fieldSize;
1771  }
1772  break;
1773  }
1774  case 44:
1775  { // ENUM_LIST_PACKED:
1776  int fieldSize =
1777  SchemaUtil.computeSizeEnumListNoTag(
1778  (List<Integer>) unsafe.getObject(message, offset));
1779  if (fieldSize > 0) {
1780  if (useCachedSizeField) {
1781  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1782  }
1783  size +=
1784  CodedOutputStream.computeTagSize(number)
1785  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1786  + fieldSize;
1787  }
1788  break;
1789  }
1790  case 45:
1791  { // SFIXED32_LIST_PACKED:
1792  int fieldSize =
1793  SchemaUtil.computeSizeFixed32ListNoTag(
1794  (List<Integer>) unsafe.getObject(message, offset));
1795  if (fieldSize > 0) {
1796  if (useCachedSizeField) {
1797  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1798  }
1799  size +=
1800  CodedOutputStream.computeTagSize(number)
1801  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1802  + fieldSize;
1803  }
1804  break;
1805  }
1806  case 46:
1807  { // SFIXED64_LIST_PACKED:
1808  int fieldSize =
1809  SchemaUtil.computeSizeFixed64ListNoTag(
1810  (List<Long>) unsafe.getObject(message, offset));
1811  if (fieldSize > 0) {
1812  if (useCachedSizeField) {
1813  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1814  }
1815  size +=
1816  CodedOutputStream.computeTagSize(number)
1817  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1818  + fieldSize;
1819  }
1820  break;
1821  }
1822  case 47:
1823  { // SINT32_LIST_PACKED:
1824  int fieldSize =
1825  SchemaUtil.computeSizeSInt32ListNoTag(
1826  (List<Integer>) unsafe.getObject(message, offset));
1827  if (fieldSize > 0) {
1828  if (useCachedSizeField) {
1829  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1830  }
1831  size +=
1832  CodedOutputStream.computeTagSize(number)
1833  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1834  + fieldSize;
1835  }
1836  break;
1837  }
1838  case 48:
1839  { // SINT64_LIST_PACKED:
1840  int fieldSize =
1841  SchemaUtil.computeSizeSInt64ListNoTag(
1842  (List<Long>) unsafe.getObject(message, offset));
1843  if (fieldSize > 0) {
1844  if (useCachedSizeField) {
1845  unsafe.putInt(message, (long) presenceMaskAndOffset, fieldSize);
1846  }
1847  size +=
1848  CodedOutputStream.computeTagSize(number)
1849  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
1850  + fieldSize;
1851  }
1852  break;
1853  }
1854  case 49: // GROUP_LIST:
1855  size +=
1856  SchemaUtil.computeSizeGroupList(
1857  number,
1858  (List<MessageLite>) unsafe.getObject(message, offset),
1859  getMessageFieldSchema(i));
1860  break;
1861  case 50: // MAP:
1862  // TODO(dweis): Use schema cache.
1863  size +=
1864  mapFieldSchema.getSerializedSize(
1865  number, unsafe.getObject(message, offset), getMapFieldDefaultEntry(i));
1866  break;
1867  case 51: // ONEOF_DOUBLE:
1868  if (isOneofPresent(message, number, i)) {
1869  size += CodedOutputStream.computeDoubleSize(number, 0);
1870  }
1871  break;
1872  case 52: // ONEOF_FLOAT:
1873  if (isOneofPresent(message, number, i)) {
1874  size += CodedOutputStream.computeFloatSize(number, 0);
1875  }
1876  break;
1877  case 53: // ONEOF_INT64:
1878  if (isOneofPresent(message, number, i)) {
1879  size += CodedOutputStream.computeInt64Size(number, oneofLongAt(message, offset));
1880  }
1881  break;
1882  case 54: // ONEOF_UINT64:
1883  if (isOneofPresent(message, number, i)) {
1884  size += CodedOutputStream.computeUInt64Size(number, oneofLongAt(message, offset));
1885  }
1886  break;
1887  case 55: // ONEOF_INT32:
1888  if (isOneofPresent(message, number, i)) {
1889  size += CodedOutputStream.computeInt32Size(number, oneofIntAt(message, offset));
1890  }
1891  break;
1892  case 56: // ONEOF_FIXED64:
1893  if (isOneofPresent(message, number, i)) {
1894  size += CodedOutputStream.computeFixed64Size(number, 0);
1895  }
1896  break;
1897  case 57: // ONEOF_FIXED32:
1898  if (isOneofPresent(message, number, i)) {
1899  size += CodedOutputStream.computeFixed32Size(number, 0);
1900  }
1901  break;
1902  case 58: // ONEOF_BOOL:
1903  if (isOneofPresent(message, number, i)) {
1904  size += CodedOutputStream.computeBoolSize(number, true);
1905  }
1906  break;
1907  case 59: // ONEOF_STRING:
1908  if (isOneofPresent(message, number, i)) {
1909  Object value = unsafe.getObject(message, offset);
1910  if (value instanceof ByteString) {
1911  size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
1912  } else {
1913  size += CodedOutputStream.computeStringSize(number, (String) value);
1914  }
1915  }
1916  break;
1917  case 60: // ONEOF_MESSAGE:
1918  if (isOneofPresent(message, number, i)) {
1919  Object value = unsafe.getObject(message, offset);
1920  size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
1921  }
1922  break;
1923  case 61: // ONEOF_BYTES:
1924  if (isOneofPresent(message, number, i)) {
1925  size +=
1926  CodedOutputStream.computeBytesSize(
1927  number, (ByteString) unsafe.getObject(message, offset));
1928  }
1929  break;
1930  case 62: // ONEOF_UINT32:
1931  if (isOneofPresent(message, number, i)) {
1932  size += CodedOutputStream.computeUInt32Size(number, oneofIntAt(message, offset));
1933  }
1934  break;
1935  case 63: // ONEOF_ENUM:
1936  if (isOneofPresent(message, number, i)) {
1937  size += CodedOutputStream.computeEnumSize(number, oneofIntAt(message, offset));
1938  }
1939  break;
1940  case 64: // ONEOF_SFIXED32:
1941  if (isOneofPresent(message, number, i)) {
1942  size += CodedOutputStream.computeSFixed32Size(number, 0);
1943  }
1944  break;
1945  case 65: // ONEOF_SFIXED64:
1946  if (isOneofPresent(message, number, i)) {
1947  size += CodedOutputStream.computeSFixed64Size(number, 0);
1948  }
1949  break;
1950  case 66: // ONEOF_SINT32:
1951  if (isOneofPresent(message, number, i)) {
1952  size += CodedOutputStream.computeSInt32Size(number, oneofIntAt(message, offset));
1953  }
1954  break;
1955  case 67: // ONEOF_SINT64:
1956  if (isOneofPresent(message, number, i)) {
1957  size += CodedOutputStream.computeSInt64Size(number, oneofLongAt(message, offset));
1958  }
1959  break;
1960  case 68: // ONEOF_GROUP:
1961  if (isOneofPresent(message, number, i)) {
1962  size +=
1963  CodedOutputStream.computeGroupSize(
1964  number,
1965  (MessageLite) unsafe.getObject(message, offset),
1966  getMessageFieldSchema(i));
1967  }
1968  break;
1969  default:
1970  // Assume it's an empty entry.
1971  }
1972  }
1973 
1974  size += getUnknownFieldsSerializedSize(unknownFieldSchema, message);
1975 
1976  if (hasExtensions) {
1977  size += extensionSchema.getExtensions(message).getSerializedSize();
1978  }
1979 
1980  return size;
1981  }
1982 
1983  private int getSerializedSizeProto3(T message) {
1984  final sun.misc.Unsafe unsafe = UNSAFE;
1985  int size = 0;
1986  for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) {
1987  final int typeAndOffset = typeAndOffsetAt(i);
1988  final int fieldType = type(typeAndOffset);
1989  final int number = numberAt(i);
1990 
1991  final long offset = offset(typeAndOffset);
1992  final int cachedSizeOffset =
1993  fieldType >= FieldType.DOUBLE_LIST_PACKED.id()
1994  && fieldType <= FieldType.SINT64_LIST_PACKED.id()
1995  ? buffer[i + 2] & OFFSET_MASK
1996  : 0;
1997 
1998  switch (fieldType) {
1999  case 0: // DOUBLE:
2000  if (isFieldPresent(message, i)) {
2001  size += CodedOutputStream.computeDoubleSize(number, 0);
2002  }
2003  break;
2004  case 1: // FLOAT:
2005  if (isFieldPresent(message, i)) {
2006  size += CodedOutputStream.computeFloatSize(number, 0);
2007  }
2008  break;
2009  case 2: // INT64:
2010  if (isFieldPresent(message, i)) {
2011  size += CodedOutputStream.computeInt64Size(number, UnsafeUtil.getLong(message, offset));
2012  }
2013  break;
2014  case 3: // UINT64:
2015  if (isFieldPresent(message, i)) {
2016  size +=
2017  CodedOutputStream.computeUInt64Size(number, UnsafeUtil.getLong(message, offset));
2018  }
2019  break;
2020  case 4: // INT32:
2021  if (isFieldPresent(message, i)) {
2022  size += CodedOutputStream.computeInt32Size(number, UnsafeUtil.getInt(message, offset));
2023  }
2024  break;
2025  case 5: // FIXED64:
2026  if (isFieldPresent(message, i)) {
2027  size += CodedOutputStream.computeFixed64Size(number, 0);
2028  }
2029  break;
2030  case 6: // FIXED32:
2031  if (isFieldPresent(message, i)) {
2032  size += CodedOutputStream.computeFixed32Size(number, 0);
2033  }
2034  break;
2035  case 7: // BOOL:
2036  if (isFieldPresent(message, i)) {
2037  size += CodedOutputStream.computeBoolSize(number, true);
2038  }
2039  break;
2040  case 8: // STRING:
2041  if (isFieldPresent(message, i)) {
2042  Object value = UnsafeUtil.getObject(message, offset);
2043  if (value instanceof ByteString) {
2044  size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
2045  } else {
2046  size += CodedOutputStream.computeStringSize(number, (String) value);
2047  }
2048  }
2049  break;
2050  case 9: // MESSAGE:
2051  if (isFieldPresent(message, i)) {
2052  Object value = UnsafeUtil.getObject(message, offset);
2053  size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
2054  }
2055  break;
2056  case 10: // BYTES:
2057  if (isFieldPresent(message, i)) {
2058  ByteString value = (ByteString) UnsafeUtil.getObject(message, offset);
2059  size += CodedOutputStream.computeBytesSize(number, value);
2060  }
2061  break;
2062  case 11: // UINT32:
2063  if (isFieldPresent(message, i)) {
2064  size += CodedOutputStream.computeUInt32Size(number, UnsafeUtil.getInt(message, offset));
2065  }
2066  break;
2067  case 12: // ENUM:
2068  if (isFieldPresent(message, i)) {
2069  size += CodedOutputStream.computeEnumSize(number, UnsafeUtil.getInt(message, offset));
2070  }
2071  break;
2072  case 13: // SFIXED32:
2073  if (isFieldPresent(message, i)) {
2074  size += CodedOutputStream.computeSFixed32Size(number, 0);
2075  }
2076  break;
2077  case 14: // SFIXED64:
2078  if (isFieldPresent(message, i)) {
2079  size += CodedOutputStream.computeSFixed64Size(number, 0);
2080  }
2081  break;
2082  case 15: // SINT32:
2083  if (isFieldPresent(message, i)) {
2084  size += CodedOutputStream.computeSInt32Size(number, UnsafeUtil.getInt(message, offset));
2085  }
2086  break;
2087  case 16: // SINT64:
2088  if (isFieldPresent(message, i)) {
2089  size +=
2090  CodedOutputStream.computeSInt64Size(number, UnsafeUtil.getLong(message, offset));
2091  }
2092  break;
2093  case 17: // GROUP:
2094  if (isFieldPresent(message, i)) {
2095  size +=
2096  CodedOutputStream.computeGroupSize(
2097  number,
2098  (MessageLite) UnsafeUtil.getObject(message, offset),
2099  getMessageFieldSchema(i));
2100  }
2101  break;
2102  case 18: // DOUBLE_LIST:
2103  size += SchemaUtil.computeSizeFixed64List(number, listAt(message, offset), false);
2104  break;
2105  case 19: // FLOAT_LIST:
2106  size += SchemaUtil.computeSizeFixed32List(number, listAt(message, offset), false);
2107  break;
2108  case 20: // INT64_LIST:
2109  size +=
2110  SchemaUtil.computeSizeInt64List(number, (List<Long>) listAt(message, offset), false);
2111  break;
2112  case 21: // UINT64_LIST:
2113  size +=
2114  SchemaUtil.computeSizeUInt64List(number, (List<Long>) listAt(message, offset), false);
2115  break;
2116  case 22: // INT32_LIST:
2117  size +=
2118  SchemaUtil.computeSizeInt32List(
2119  number, (List<Integer>) listAt(message, offset), false);
2120  break;
2121  case 23: // FIXED64_LIST:
2122  size += SchemaUtil.computeSizeFixed64List(number, listAt(message, offset), false);
2123  break;
2124  case 24: // FIXED32_LIST:
2125  size += SchemaUtil.computeSizeFixed32List(number, listAt(message, offset), false);
2126  break;
2127  case 25: // BOOL_LIST:
2128  size += SchemaUtil.computeSizeBoolList(number, listAt(message, offset), false);
2129  break;
2130  case 26: // STRING_LIST:
2131  size += SchemaUtil.computeSizeStringList(number, listAt(message, offset));
2132  break;
2133  case 27: // MESSAGE_LIST:
2134  size +=
2135  SchemaUtil.computeSizeMessageList(
2136  number, listAt(message, offset), getMessageFieldSchema(i));
2137  break;
2138  case 28: // BYTES_LIST:
2139  size +=
2140  SchemaUtil.computeSizeByteStringList(
2141  number, (List<ByteString>) listAt(message, offset));
2142  break;
2143  case 29: // UINT32_LIST:
2144  size +=
2145  SchemaUtil.computeSizeUInt32List(
2146  number, (List<Integer>) listAt(message, offset), false);
2147  break;
2148  case 30: // ENUM_LIST:
2149  size +=
2150  SchemaUtil.computeSizeEnumList(
2151  number, (List<Integer>) listAt(message, offset), false);
2152  break;
2153  case 31: // SFIXED32_LIST:
2154  size += SchemaUtil.computeSizeFixed32List(number, listAt(message, offset), false);
2155  break;
2156  case 32: // SFIXED64_LIST:
2157  size += SchemaUtil.computeSizeFixed64List(number, listAt(message, offset), false);
2158  break;
2159  case 33: // SINT32_LIST:
2160  size +=
2161  SchemaUtil.computeSizeSInt32List(
2162  number, (List<Integer>) listAt(message, offset), false);
2163  break;
2164  case 34: // SINT64_LIST:
2165  size +=
2166  SchemaUtil.computeSizeSInt64List(number, (List<Long>) listAt(message, offset), false);
2167  break;
2168  case 35:
2169  { // DOUBLE_LIST_PACKED:
2170  int fieldSize =
2171  SchemaUtil.computeSizeFixed64ListNoTag(
2172  (List<Double>) unsafe.getObject(message, offset));
2173  if (fieldSize > 0) {
2174  if (useCachedSizeField) {
2175  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2176  }
2177  size +=
2178  CodedOutputStream.computeTagSize(number)
2179  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2180  + fieldSize;
2181  }
2182  break;
2183  }
2184  case 36:
2185  { // FLOAT_LIST_PACKED:
2186  int fieldSize =
2187  SchemaUtil.computeSizeFixed32ListNoTag(
2188  (List<Float>) unsafe.getObject(message, offset));
2189  if (fieldSize > 0) {
2190  if (useCachedSizeField) {
2191  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2192  }
2193  size +=
2194  CodedOutputStream.computeTagSize(number)
2195  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2196  + fieldSize;
2197  }
2198  break;
2199  }
2200  case 37:
2201  { // INT64_LIST_PACKED:
2202  int fieldSize =
2203  SchemaUtil.computeSizeInt64ListNoTag(
2204  (List<Long>) unsafe.getObject(message, offset));
2205  if (fieldSize > 0) {
2206  if (useCachedSizeField) {
2207  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2208  }
2209  size +=
2210  CodedOutputStream.computeTagSize(number)
2211  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2212  + fieldSize;
2213  }
2214  break;
2215  }
2216  case 38:
2217  { // UINT64_LIST_PACKED:
2218  int fieldSize =
2219  SchemaUtil.computeSizeUInt64ListNoTag(
2220  (List<Long>) unsafe.getObject(message, offset));
2221  if (fieldSize > 0) {
2222  if (useCachedSizeField) {
2223  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2224  }
2225  size +=
2226  CodedOutputStream.computeTagSize(number)
2227  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2228  + fieldSize;
2229  }
2230  break;
2231  }
2232  case 39:
2233  { // INT32_LIST_PACKED:
2234  int fieldSize =
2235  SchemaUtil.computeSizeInt32ListNoTag(
2236  (List<Integer>) unsafe.getObject(message, offset));
2237  if (fieldSize > 0) {
2238  if (useCachedSizeField) {
2239  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2240  }
2241  size +=
2242  CodedOutputStream.computeTagSize(number)
2243  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2244  + fieldSize;
2245  }
2246  break;
2247  }
2248  case 40:
2249  { // FIXED64_LIST_PACKED:
2250  int fieldSize =
2251  SchemaUtil.computeSizeFixed64ListNoTag(
2252  (List<Long>) unsafe.getObject(message, offset));
2253  if (fieldSize > 0) {
2254  if (useCachedSizeField) {
2255  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2256  }
2257  size +=
2258  CodedOutputStream.computeTagSize(number)
2259  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2260  + fieldSize;
2261  }
2262  break;
2263  }
2264  case 41:
2265  { // FIXED32_LIST_PACKED:
2266  int fieldSize =
2267  SchemaUtil.computeSizeFixed32ListNoTag(
2268  (List<Integer>) unsafe.getObject(message, offset));
2269  if (fieldSize > 0) {
2270  if (useCachedSizeField) {
2271  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2272  }
2273  size +=
2274  CodedOutputStream.computeTagSize(number)
2275  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2276  + fieldSize;
2277  }
2278  break;
2279  }
2280  case 42:
2281  { // BOOL_LIST_PACKED:
2282  int fieldSize =
2283  SchemaUtil.computeSizeBoolListNoTag(
2284  (List<Boolean>) unsafe.getObject(message, offset));
2285  if (fieldSize > 0) {
2286  if (useCachedSizeField) {
2287  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2288  }
2289  size +=
2290  CodedOutputStream.computeTagSize(number)
2291  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2292  + fieldSize;
2293  }
2294  break;
2295  }
2296  case 43:
2297  { // UINT32_LIST_PACKED:
2298  int fieldSize =
2299  SchemaUtil.computeSizeUInt32ListNoTag(
2300  (List<Integer>) unsafe.getObject(message, offset));
2301  if (fieldSize > 0) {
2302  if (useCachedSizeField) {
2303  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2304  }
2305  size +=
2306  CodedOutputStream.computeTagSize(number)
2307  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2308  + fieldSize;
2309  }
2310  break;
2311  }
2312  case 44:
2313  { // ENUM_LIST_PACKED:
2314  int fieldSize =
2315  SchemaUtil.computeSizeEnumListNoTag(
2316  (List<Integer>) unsafe.getObject(message, offset));
2317  if (fieldSize > 0) {
2318  if (useCachedSizeField) {
2319  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2320  }
2321  size +=
2322  CodedOutputStream.computeTagSize(number)
2323  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2324  + fieldSize;
2325  }
2326  break;
2327  }
2328  case 45:
2329  { // SFIXED32_LIST_PACKED:
2330  int fieldSize =
2331  SchemaUtil.computeSizeFixed32ListNoTag(
2332  (List<Integer>) unsafe.getObject(message, offset));
2333  if (fieldSize > 0) {
2334  if (useCachedSizeField) {
2335  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2336  }
2337  size +=
2338  CodedOutputStream.computeTagSize(number)
2339  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2340  + fieldSize;
2341  }
2342  break;
2343  }
2344  case 46:
2345  { // SFIXED64_LIST_PACKED:
2346  int fieldSize =
2347  SchemaUtil.computeSizeFixed64ListNoTag(
2348  (List<Long>) unsafe.getObject(message, offset));
2349  if (fieldSize > 0) {
2350  if (useCachedSizeField) {
2351  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2352  }
2353  size +=
2354  CodedOutputStream.computeTagSize(number)
2355  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2356  + fieldSize;
2357  }
2358  break;
2359  }
2360  case 47:
2361  { // SINT32_LIST_PACKED:
2362  int fieldSize =
2363  SchemaUtil.computeSizeSInt32ListNoTag(
2364  (List<Integer>) unsafe.getObject(message, offset));
2365  if (fieldSize > 0) {
2366  if (useCachedSizeField) {
2367  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2368  }
2369  size +=
2370  CodedOutputStream.computeTagSize(number)
2371  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2372  + fieldSize;
2373  }
2374  break;
2375  }
2376  case 48:
2377  { // SINT64_LIST_PACKED:
2378  int fieldSize =
2379  SchemaUtil.computeSizeSInt64ListNoTag(
2380  (List<Long>) unsafe.getObject(message, offset));
2381  if (fieldSize > 0) {
2382  if (useCachedSizeField) {
2383  unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
2384  }
2385  size +=
2386  CodedOutputStream.computeTagSize(number)
2387  + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
2388  + fieldSize;
2389  }
2390  break;
2391  }
2392  case 49: // GROUP_LIST:
2393  size +=
2394  SchemaUtil.computeSizeGroupList(
2395  number, (List<MessageLite>) listAt(message, offset), getMessageFieldSchema(i));
2396  break;
2397  case 50: // MAP:
2398  // TODO(dweis): Use schema cache.
2399  size +=
2400  mapFieldSchema.getSerializedSize(
2401  number, UnsafeUtil.getObject(message, offset), getMapFieldDefaultEntry(i));
2402  break;
2403  case 51: // ONEOF_DOUBLE:
2404  if (isOneofPresent(message, number, i)) {
2405  size += CodedOutputStream.computeDoubleSize(number, 0);
2406  }
2407  break;
2408  case 52: // ONEOF_FLOAT:
2409  if (isOneofPresent(message, number, i)) {
2410  size += CodedOutputStream.computeFloatSize(number, 0);
2411  }
2412  break;
2413  case 53: // ONEOF_INT64:
2414  if (isOneofPresent(message, number, i)) {
2415  size += CodedOutputStream.computeInt64Size(number, oneofLongAt(message, offset));
2416  }
2417  break;
2418  case 54: // ONEOF_UINT64:
2419  if (isOneofPresent(message, number, i)) {
2420  size += CodedOutputStream.computeUInt64Size(number, oneofLongAt(message, offset));
2421  }
2422  break;
2423  case 55: // ONEOF_INT32:
2424  if (isOneofPresent(message, number, i)) {
2425  size += CodedOutputStream.computeInt32Size(number, oneofIntAt(message, offset));
2426  }
2427  break;
2428  case 56: // ONEOF_FIXED64:
2429  if (isOneofPresent(message, number, i)) {
2430  size += CodedOutputStream.computeFixed64Size(number, 0);
2431  }
2432  break;
2433  case 57: // ONEOF_FIXED32:
2434  if (isOneofPresent(message, number, i)) {
2435  size += CodedOutputStream.computeFixed32Size(number, 0);
2436  }
2437  break;
2438  case 58: // ONEOF_BOOL:
2439  if (isOneofPresent(message, number, i)) {
2440  size += CodedOutputStream.computeBoolSize(number, true);
2441  }
2442  break;
2443  case 59: // ONEOF_STRING:
2444  if (isOneofPresent(message, number, i)) {
2445  Object value = UnsafeUtil.getObject(message, offset);
2446  if (value instanceof ByteString) {
2447  size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
2448  } else {
2449  size += CodedOutputStream.computeStringSize(number, (String) value);
2450  }
2451  }
2452  break;
2453  case 60: // ONEOF_MESSAGE:
2454  if (isOneofPresent(message, number, i)) {
2455  Object value = UnsafeUtil.getObject(message, offset);
2456  size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
2457  }
2458  break;
2459  case 61: // ONEOF_BYTES:
2460  if (isOneofPresent(message, number, i)) {
2461  size +=
2462  CodedOutputStream.computeBytesSize(
2463  number, (ByteString) UnsafeUtil.getObject(message, offset));
2464  }
2465  break;
2466  case 62: // ONEOF_UINT32:
2467  if (isOneofPresent(message, number, i)) {
2468  size += CodedOutputStream.computeUInt32Size(number, oneofIntAt(message, offset));
2469  }
2470  break;
2471  case 63: // ONEOF_ENUM:
2472  if (isOneofPresent(message, number, i)) {
2473  size += CodedOutputStream.computeEnumSize(number, oneofIntAt(message, offset));
2474  }
2475  break;
2476  case 64: // ONEOF_SFIXED32:
2477  if (isOneofPresent(message, number, i)) {
2478  size += CodedOutputStream.computeSFixed32Size(number, 0);
2479  }
2480  break;
2481  case 65: // ONEOF_SFIXED64:
2482  if (isOneofPresent(message, number, i)) {
2483  size += CodedOutputStream.computeSFixed64Size(number, 0);
2484  }
2485  break;
2486  case 66: // ONEOF_SINT32:
2487  if (isOneofPresent(message, number, i)) {
2488  size += CodedOutputStream.computeSInt32Size(number, oneofIntAt(message, offset));
2489  }
2490  break;
2491  case 67: // ONEOF_SINT64:
2492  if (isOneofPresent(message, number, i)) {
2493  size += CodedOutputStream.computeSInt64Size(number, oneofLongAt(message, offset));
2494  }
2495  break;
2496  case 68: // ONEOF_GROUP:
2497  if (isOneofPresent(message, number, i)) {
2498  size +=
2499  CodedOutputStream.computeGroupSize(
2500  number,
2501  (MessageLite) UnsafeUtil.getObject(message, offset),
2502  getMessageFieldSchema(i));
2503  }
2504  break;
2505  default:
2506  // Assume it's an empty entry.
2507  }
2508  }
2509 
2510  size += getUnknownFieldsSerializedSize(unknownFieldSchema, message);
2511 
2512  return size;
2513  }
2514 
2515  private <UT, UB> int getUnknownFieldsSerializedSize(
2516  UnknownFieldSchema<UT, UB> schema, T message) {
2517  UT unknowns = schema.getFromMessage(message);
2518  return schema.getSerializedSize(unknowns);
2519  }
2520 
2521  private static List<?> listAt(Object message, long offset) {
2522  return (List<?>) UnsafeUtil.getObject(message, offset);
2523  }
2524 
2525  @SuppressWarnings("unchecked")
2526  @Override
2527  // TODO(nathanmittler): Consider serializing oneof fields last so that only one entry per
2528  // oneof is actually serialized. This would mean that we would violate the serialization order
2529  // contract. It should also be noted that Go currently does this.
2530  public void writeTo(T message, Writer writer) throws IOException {
2531  if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
2532  writeFieldsInDescendingOrder(message, writer);
2533  } else {
2534  if (proto3) {
2535  writeFieldsInAscendingOrderProto3(message, writer);
2536  } else {
2537  writeFieldsInAscendingOrderProto2(message, writer);
2538  }
2539  }
2540  }
2541 
2542  @SuppressWarnings("unchecked")
2543  private void writeFieldsInAscendingOrderProto2(T message, Writer writer) throws IOException {
2544  Iterator<? extends Map.Entry<?, ?>> extensionIterator = null;
2545  Map.Entry nextExtension = null;
2546  if (hasExtensions) {
2547  FieldSet<?> extensions = extensionSchema.getExtensions(message);
2548  if (!extensions.isEmpty()) {
2549  extensionIterator = extensions.iterator();
2550  nextExtension = extensionIterator.next();
2551  }
2552  }
2553  int currentPresenceFieldOffset = -1;
2554  int currentPresenceField = 0;
2555  final int bufferLength = buffer.length;
2556  final sun.misc.Unsafe unsafe = UNSAFE;
2557  for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) {
2558  final int typeAndOffset = typeAndOffsetAt(pos);
2559  final int number = numberAt(pos);
2560  final int fieldType = type(typeAndOffset);
2561 
2562  int presenceMaskAndOffset = 0;
2563  int presenceMask = 0;
2564  if (!proto3 && fieldType <= 17) {
2565  presenceMaskAndOffset = buffer[pos + 2];
2566  final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
2567  if (presenceFieldOffset != currentPresenceFieldOffset) {
2568  currentPresenceFieldOffset = presenceFieldOffset;
2569  currentPresenceField = unsafe.getInt(message, (long) presenceFieldOffset);
2570  }
2571  presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
2572  }
2573 
2574  // Write any extensions that need to be written before the current field.
2575  while (nextExtension != null && extensionSchema.extensionNumber(nextExtension) <= number) {
2576  extensionSchema.serializeExtension(writer, nextExtension);
2577  nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
2578  }
2579  final long offset = offset(typeAndOffset);
2580 
2581  switch (fieldType) {
2582  case 0: // DOUBLE:
2583  if ((currentPresenceField & presenceMask) != 0) {
2584  writer.writeDouble(number, doubleAt(message, offset));
2585  }
2586  break;
2587  case 1: // FLOAT:
2588  if ((currentPresenceField & presenceMask) != 0) {
2589  writer.writeFloat(number, floatAt(message, offset));
2590  }
2591  break;
2592  case 2: // INT64:
2593  if ((currentPresenceField & presenceMask) != 0) {
2594  writer.writeInt64(number, unsafe.getLong(message, offset));
2595  }
2596  break;
2597  case 3: // UINT64:
2598  if ((currentPresenceField & presenceMask) != 0) {
2599  writer.writeUInt64(number, unsafe.getLong(message, offset));
2600  }
2601  break;
2602  case 4: // INT32:
2603  if ((currentPresenceField & presenceMask) != 0) {
2604  writer.writeInt32(number, unsafe.getInt(message, offset));
2605  }
2606  break;
2607  case 5: // FIXED64:
2608  if ((currentPresenceField & presenceMask) != 0) {
2609  writer.writeFixed64(number, unsafe.getLong(message, offset));
2610  }
2611  break;
2612  case 6: // FIXED32:
2613  if ((currentPresenceField & presenceMask) != 0) {
2614  writer.writeFixed32(number, unsafe.getInt(message, offset));
2615  }
2616  break;
2617  case 7: // BOOL:
2618  if ((currentPresenceField & presenceMask) != 0) {
2619  writer.writeBool(number, booleanAt(message, offset));
2620  }
2621  break;
2622  case 8: // STRING:
2623  if ((currentPresenceField & presenceMask) != 0) {
2624  writeString(number, unsafe.getObject(message, offset), writer);
2625  }
2626  break;
2627  case 9: // MESSAGE:
2628  if ((currentPresenceField & presenceMask) != 0) {
2629  Object value = unsafe.getObject(message, offset);
2630  writer.writeMessage(number, value, getMessageFieldSchema(pos));
2631  }
2632  break;
2633  case 10: // BYTES:
2634  if ((currentPresenceField & presenceMask) != 0) {
2635  writer.writeBytes(number, (ByteString) unsafe.getObject(message, offset));
2636  }
2637  break;
2638  case 11: // UINT32:
2639  if ((currentPresenceField & presenceMask) != 0) {
2640  writer.writeUInt32(number, unsafe.getInt(message, offset));
2641  }
2642  break;
2643  case 12: // ENUM:
2644  if ((currentPresenceField & presenceMask) != 0) {
2645  writer.writeEnum(number, unsafe.getInt(message, offset));
2646  }
2647  break;
2648  case 13: // SFIXED32:
2649  if ((currentPresenceField & presenceMask) != 0) {
2650  writer.writeSFixed32(number, unsafe.getInt(message, offset));
2651  }
2652  break;
2653  case 14: // SFIXED64:
2654  if ((currentPresenceField & presenceMask) != 0) {
2655  writer.writeSFixed64(number, unsafe.getLong(message, offset));
2656  }
2657  break;
2658  case 15: // SINT32:
2659  if ((currentPresenceField & presenceMask) != 0) {
2660  writer.writeSInt32(number, unsafe.getInt(message, offset));
2661  }
2662  break;
2663  case 16: // SINT64:
2664  if ((currentPresenceField & presenceMask) != 0) {
2665  writer.writeSInt64(number, unsafe.getLong(message, offset));
2666  }
2667  break;
2668  case 17: // GROUP:
2669  if ((currentPresenceField & presenceMask) != 0) {
2670  writer.writeGroup(
2671  number, unsafe.getObject(message, offset), getMessageFieldSchema(pos));
2672  }
2673  break;
2674  case 18: // DOUBLE_LIST:
2675  SchemaUtil.writeDoubleList(
2676  numberAt(pos), (List<Double>) unsafe.getObject(message, offset), writer, false);
2677  break;
2678  case 19: // FLOAT_LIST:
2679  SchemaUtil.writeFloatList(
2680  numberAt(pos), (List<Float>) unsafe.getObject(message, offset), writer, false);
2681  break;
2682  case 20: // INT64_LIST:
2683  SchemaUtil.writeInt64List(
2684  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
2685  break;
2686  case 21: // UINT64_LIST:
2687  SchemaUtil.writeUInt64List(
2688  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
2689  break;
2690  case 22: // INT32_LIST:
2691  SchemaUtil.writeInt32List(
2692  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
2693  break;
2694  case 23: // FIXED64_LIST:
2695  SchemaUtil.writeFixed64List(
2696  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
2697  break;
2698  case 24: // FIXED32_LIST:
2699  SchemaUtil.writeFixed32List(
2700  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
2701  break;
2702  case 25: // BOOL_LIST:
2703  SchemaUtil.writeBoolList(
2704  numberAt(pos), (List<Boolean>) unsafe.getObject(message, offset), writer, false);
2705  break;
2706  case 26: // STRING_LIST:
2707  SchemaUtil.writeStringList(
2708  numberAt(pos), (List<String>) unsafe.getObject(message, offset), writer);
2709  break;
2710  case 27: // MESSAGE_LIST:
2711  SchemaUtil.writeMessageList(
2712  numberAt(pos),
2713  (List<?>) unsafe.getObject(message, offset),
2714  writer,
2715  getMessageFieldSchema(pos));
2716  break;
2717  case 28: // BYTES_LIST:
2718  SchemaUtil.writeBytesList(
2719  numberAt(pos), (List<ByteString>) unsafe.getObject(message, offset), writer);
2720  break;
2721  case 29: // UINT32_LIST:
2722  SchemaUtil.writeUInt32List(
2723  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
2724  break;
2725  case 30: // ENUM_LIST:
2726  SchemaUtil.writeEnumList(
2727  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
2728  break;
2729  case 31: // SFIXED32_LIST:
2730  SchemaUtil.writeSFixed32List(
2731  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
2732  break;
2733  case 32: // SFIXED64_LIST:
2734  SchemaUtil.writeSFixed64List(
2735  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
2736  break;
2737  case 33: // SINT32_LIST:
2738  SchemaUtil.writeSInt32List(
2739  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false);
2740  break;
2741  case 34: // SINT64_LIST:
2742  SchemaUtil.writeSInt64List(
2743  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false);
2744  break;
2745  case 35: // DOUBLE_LIST_PACKED:
2746  // TODO(xiaofeng): Make use of cached field size to speed up serialization.
2747  SchemaUtil.writeDoubleList(
2748  numberAt(pos), (List<Double>) unsafe.getObject(message, offset), writer, true);
2749  break;
2750  case 36: // FLOAT_LIST_PACKED:
2751  SchemaUtil.writeFloatList(
2752  numberAt(pos), (List<Float>) unsafe.getObject(message, offset), writer, true);
2753  break;
2754  case 37: // INT64_LIST_PACKED:
2755  SchemaUtil.writeInt64List(
2756  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
2757  break;
2758  case 38: // UINT64_LIST_PACKED:
2759  SchemaUtil.writeUInt64List(
2760  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
2761  break;
2762  case 39: // INT32_LIST_PACKED:
2763  SchemaUtil.writeInt32List(
2764  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
2765  break;
2766  case 40: // FIXED64_LIST_PACKED:
2767  SchemaUtil.writeFixed64List(
2768  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
2769  break;
2770  case 41: // FIXED32_LIST_PACKED:
2771  SchemaUtil.writeFixed32List(
2772  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
2773 
2774  break;
2775  case 42: // BOOL_LIST_PACKED:
2776  SchemaUtil.writeBoolList(
2777  numberAt(pos), (List<Boolean>) unsafe.getObject(message, offset), writer, true);
2778  break;
2779  case 43: // UINT32_LIST_PACKED:
2780  SchemaUtil.writeUInt32List(
2781  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
2782  break;
2783  case 44: // ENUM_LIST_PACKED:
2784  SchemaUtil.writeEnumList(
2785  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
2786  break;
2787  case 45: // SFIXED32_LIST_PACKED:
2788  SchemaUtil.writeSFixed32List(
2789  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
2790  break;
2791  case 46: // SFIXED64_LIST_PACKED:
2792  SchemaUtil.writeSFixed64List(
2793  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
2794  break;
2795  case 47: // SINT32_LIST_PACKED:
2796  SchemaUtil.writeSInt32List(
2797  numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true);
2798  break;
2799  case 48: // SINT64_LIST_PACKED:
2800  SchemaUtil.writeSInt64List(
2801  numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true);
2802  break;
2803  case 49: // GROUP_LIST:
2804  SchemaUtil.writeGroupList(
2805  numberAt(pos),
2806  (List<?>) unsafe.getObject(message, offset),
2807  writer,
2808  getMessageFieldSchema(pos));
2809  break;
2810  case 50: // MAP:
2811  // TODO(dweis): Use schema cache.
2812  writeMapHelper(writer, number, unsafe.getObject(message, offset), pos);
2813  break;
2814  case 51: // ONEOF_DOUBLE:
2815  if (isOneofPresent(message, number, pos)) {
2816  writer.writeDouble(number, oneofDoubleAt(message, offset));
2817  }
2818  break;
2819  case 52: // ONEOF_FLOAT:
2820  if (isOneofPresent(message, number, pos)) {
2821  writer.writeFloat(number, oneofFloatAt(message, offset));
2822  }
2823  break;
2824  case 53: // ONEOF_INT64:
2825  if (isOneofPresent(message, number, pos)) {
2826  writer.writeInt64(number, oneofLongAt(message, offset));
2827  }
2828  break;
2829  case 54: // ONEOF_UINT64:
2830  if (isOneofPresent(message, number, pos)) {
2831  writer.writeUInt64(number, oneofLongAt(message, offset));
2832  }
2833  break;
2834  case 55: // ONEOF_INT32:
2835  if (isOneofPresent(message, number, pos)) {
2836  writer.writeInt32(number, oneofIntAt(message, offset));
2837  }
2838  break;
2839  case 56: // ONEOF_FIXED64:
2840  if (isOneofPresent(message, number, pos)) {
2841  writer.writeFixed64(number, oneofLongAt(message, offset));
2842  }
2843  break;
2844  case 57: // ONEOF_FIXED32:
2845  if (isOneofPresent(message, number, pos)) {
2846  writer.writeFixed32(number, oneofIntAt(message, offset));
2847  }
2848  break;
2849  case 58: // ONEOF_BOOL:
2850  if (isOneofPresent(message, number, pos)) {
2851  writer.writeBool(number, oneofBooleanAt(message, offset));
2852  }
2853  break;
2854  case 59: // ONEOF_STRING:
2855  if (isOneofPresent(message, number, pos)) {
2856  writeString(number, unsafe.getObject(message, offset), writer);
2857  }
2858  break;
2859  case 60: // ONEOF_MESSAGE:
2860  if (isOneofPresent(message, number, pos)) {
2861  Object value = unsafe.getObject(message, offset);
2862  writer.writeMessage(number, value, getMessageFieldSchema(pos));
2863  }
2864  break;
2865  case 61: // ONEOF_BYTES:
2866  if (isOneofPresent(message, number, pos)) {
2867  writer.writeBytes(number, (ByteString) unsafe.getObject(message, offset));
2868  }
2869  break;
2870  case 62: // ONEOF_UINT32:
2871  if (isOneofPresent(message, number, pos)) {
2872  writer.writeUInt32(number, oneofIntAt(message, offset));
2873  }
2874  break;
2875  case 63: // ONEOF_ENUM:
2876  if (isOneofPresent(message, number, pos)) {
2877  writer.writeEnum(number, oneofIntAt(message, offset));
2878  }
2879  break;
2880  case 64: // ONEOF_SFIXED32:
2881  if (isOneofPresent(message, number, pos)) {
2882  writer.writeSFixed32(number, oneofIntAt(message, offset));
2883  }
2884  break;
2885  case 65: // ONEOF_SFIXED64:
2886  if (isOneofPresent(message, number, pos)) {
2887  writer.writeSFixed64(number, oneofLongAt(message, offset));
2888  }
2889  break;
2890  case 66: // ONEOF_SINT32:
2891  if (isOneofPresent(message, number, pos)) {
2892  writer.writeSInt32(number, oneofIntAt(message, offset));
2893  }
2894  break;
2895  case 67: // ONEOF_SINT64:
2896  if (isOneofPresent(message, number, pos)) {
2897  writer.writeSInt64(number, oneofLongAt(message, offset));
2898  }
2899  break;
2900  case 68: // ONEOF_GROUP:
2901  if (isOneofPresent(message, number, pos)) {
2902  writer.writeGroup(
2903  number, unsafe.getObject(message, offset), getMessageFieldSchema(pos));
2904  }
2905  break;
2906  default:
2907  // Assume it's an empty entry - just go to the next entry.
2908  break;
2909  }
2910  }
2911  while (nextExtension != null) {
2912  extensionSchema.serializeExtension(writer, nextExtension);
2913  nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
2914  }
2915  writeUnknownInMessageTo(unknownFieldSchema, message, writer);
2916  }
2917 
2918  @SuppressWarnings("unchecked")
2919  private void writeFieldsInAscendingOrderProto3(T message, Writer writer) throws IOException {
2920  Iterator<? extends Map.Entry<?, ?>> extensionIterator = null;
2921  Map.Entry nextExtension = null;
2922  if (hasExtensions) {
2923  FieldSet<?> extensions = extensionSchema.getExtensions(message);
2924  if (!extensions.isEmpty()) {
2925  extensionIterator = extensions.iterator();
2926  nextExtension = extensionIterator.next();
2927  }
2928  }
2929 
2930  final int bufferLength = buffer.length;
2931  for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) {
2932  final int typeAndOffset = typeAndOffsetAt(pos);
2933  final int number = numberAt(pos);
2934 
2935  // Write any extensions that need to be written before the current field.
2936  while (nextExtension != null && extensionSchema.extensionNumber(nextExtension) <= number) {
2937  extensionSchema.serializeExtension(writer, nextExtension);
2938  nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
2939  }
2940 
2941  switch (type(typeAndOffset)) {
2942  case 0: // DOUBLE:
2943  if (isFieldPresent(message, pos)) {
2944  writer.writeDouble(number, doubleAt(message, offset(typeAndOffset)));
2945  }
2946  break;
2947  case 1: // FLOAT:
2948  if (isFieldPresent(message, pos)) {
2949  writer.writeFloat(number, floatAt(message, offset(typeAndOffset)));
2950  }
2951  break;
2952  case 2: // INT64:
2953  if (isFieldPresent(message, pos)) {
2954  writer.writeInt64(number, longAt(message, offset(typeAndOffset)));
2955  }
2956  break;
2957  case 3: // UINT64:
2958  if (isFieldPresent(message, pos)) {
2959  writer.writeUInt64(number, longAt(message, offset(typeAndOffset)));
2960  }
2961  break;
2962  case 4: // INT32:
2963  if (isFieldPresent(message, pos)) {
2964  writer.writeInt32(number, intAt(message, offset(typeAndOffset)));
2965  }
2966  break;
2967  case 5: // FIXED64:
2968  if (isFieldPresent(message, pos)) {
2969  writer.writeFixed64(number, longAt(message, offset(typeAndOffset)));
2970  }
2971  break;
2972  case 6: // FIXED32:
2973  if (isFieldPresent(message, pos)) {
2974  writer.writeFixed32(number, intAt(message, offset(typeAndOffset)));
2975  }
2976  break;
2977  case 7: // BOOL:
2978  if (isFieldPresent(message, pos)) {
2979  writer.writeBool(number, booleanAt(message, offset(typeAndOffset)));
2980  }
2981  break;
2982  case 8: // STRING:
2983  if (isFieldPresent(message, pos)) {
2984  writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer);
2985  }
2986  break;
2987  case 9: // MESSAGE:
2988  if (isFieldPresent(message, pos)) {
2989  Object value = UnsafeUtil.getObject(message, offset(typeAndOffset));
2990  writer.writeMessage(number, value, getMessageFieldSchema(pos));
2991  }
2992  break;
2993  case 10: // BYTES:
2994  if (isFieldPresent(message, pos)) {
2995  writer.writeBytes(
2996  number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset)));
2997  }
2998  break;
2999  case 11: // UINT32:
3000  if (isFieldPresent(message, pos)) {
3001  writer.writeUInt32(number, intAt(message, offset(typeAndOffset)));
3002  }
3003  break;
3004  case 12: // ENUM:
3005  if (isFieldPresent(message, pos)) {
3006  writer.writeEnum(number, intAt(message, offset(typeAndOffset)));
3007  }
3008  break;
3009  case 13: // SFIXED32:
3010  if (isFieldPresent(message, pos)) {
3011  writer.writeSFixed32(number, intAt(message, offset(typeAndOffset)));
3012  }
3013  break;
3014  case 14: // SFIXED64:
3015  if (isFieldPresent(message, pos)) {
3016  writer.writeSFixed64(number, longAt(message, offset(typeAndOffset)));
3017  }
3018  break;
3019  case 15: // SINT32:
3020  if (isFieldPresent(message, pos)) {
3021  writer.writeSInt32(number, intAt(message, offset(typeAndOffset)));
3022  }
3023  break;
3024  case 16: // SINT64:
3025  if (isFieldPresent(message, pos)) {
3026  writer.writeSInt64(number, longAt(message, offset(typeAndOffset)));
3027  }
3028  break;
3029  case 17: // GROUP:
3030  if (isFieldPresent(message, pos)) {
3031  writer.writeGroup(
3032  number,
3033  UnsafeUtil.getObject(message, offset(typeAndOffset)),
3034  getMessageFieldSchema(pos));
3035  }
3036  break;
3037  case 18: // DOUBLE_LIST:
3038  SchemaUtil.writeDoubleList(
3039  numberAt(pos),
3040  (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3041  writer,
3042  false);
3043  break;
3044  case 19: // FLOAT_LIST:
3045  SchemaUtil.writeFloatList(
3046  numberAt(pos),
3047  (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3048  writer,
3049  false);
3050  break;
3051  case 20: // INT64_LIST:
3052  SchemaUtil.writeInt64List(
3053  numberAt(pos),
3054  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3055  writer,
3056  false);
3057  break;
3058  case 21: // UINT64_LIST:
3059  SchemaUtil.writeUInt64List(
3060  numberAt(pos),
3061  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3062  writer,
3063  false);
3064  break;
3065  case 22: // INT32_LIST:
3066  SchemaUtil.writeInt32List(
3067  numberAt(pos),
3068  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3069  writer,
3070  false);
3071  break;
3072  case 23: // FIXED64_LIST:
3073  SchemaUtil.writeFixed64List(
3074  numberAt(pos),
3075  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3076  writer,
3077  false);
3078  break;
3079  case 24: // FIXED32_LIST:
3080  SchemaUtil.writeFixed32List(
3081  numberAt(pos),
3082  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3083  writer,
3084  false);
3085  break;
3086  case 25: // BOOL_LIST:
3087  SchemaUtil.writeBoolList(
3088  numberAt(pos),
3089  (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3090  writer,
3091  false);
3092  break;
3093  case 26: // STRING_LIST:
3094  SchemaUtil.writeStringList(
3095  numberAt(pos),
3096  (List<String>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3097  writer);
3098  break;
3099  case 27: // MESSAGE_LIST:
3100  SchemaUtil.writeMessageList(
3101  numberAt(pos),
3102  (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3103  writer,
3104  getMessageFieldSchema(pos));
3105  break;
3106  case 28: // BYTES_LIST:
3107  SchemaUtil.writeBytesList(
3108  numberAt(pos),
3109  (List<ByteString>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3110  writer);
3111  break;
3112  case 29: // UINT32_LIST:
3113  SchemaUtil.writeUInt32List(
3114  numberAt(pos),
3115  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3116  writer,
3117  false);
3118  break;
3119  case 30: // ENUM_LIST:
3120  SchemaUtil.writeEnumList(
3121  numberAt(pos),
3122  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3123  writer,
3124  false);
3125  break;
3126  case 31: // SFIXED32_LIST:
3127  SchemaUtil.writeSFixed32List(
3128  numberAt(pos),
3129  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3130  writer,
3131  false);
3132  break;
3133  case 32: // SFIXED64_LIST:
3134  SchemaUtil.writeSFixed64List(
3135  numberAt(pos),
3136  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3137  writer,
3138  false);
3139  break;
3140  case 33: // SINT32_LIST:
3141  SchemaUtil.writeSInt32List(
3142  numberAt(pos),
3143  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3144  writer,
3145  false);
3146  break;
3147  case 34: // SINT64_LIST:
3148  SchemaUtil.writeSInt64List(
3149  numberAt(pos),
3150  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3151  writer,
3152  false);
3153  break;
3154  case 35: // DOUBLE_LIST_PACKED:
3155  // TODO(xiaofeng): Make use of cached field size to speed up serialization.
3156  SchemaUtil.writeDoubleList(
3157  numberAt(pos),
3158  (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3159  writer,
3160  true);
3161  break;
3162  case 36: // FLOAT_LIST_PACKED:
3163  SchemaUtil.writeFloatList(
3164  numberAt(pos),
3165  (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3166  writer,
3167  true);
3168  break;
3169  case 37: // INT64_LIST_PACKED:
3170  SchemaUtil.writeInt64List(
3171  numberAt(pos),
3172  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3173  writer,
3174  true);
3175  break;
3176  case 38: // UINT64_LIST_PACKED:
3177  SchemaUtil.writeUInt64List(
3178  numberAt(pos),
3179  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3180  writer,
3181  true);
3182  break;
3183  case 39: // INT32_LIST_PACKED:
3184  SchemaUtil.writeInt32List(
3185  numberAt(pos),
3186  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3187  writer,
3188  true);
3189  break;
3190  case 40: // FIXED64_LIST_PACKED:
3191  SchemaUtil.writeFixed64List(
3192  numberAt(pos),
3193  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3194  writer,
3195  true);
3196  break;
3197  case 41: // FIXED32_LIST_PACKED:
3198  SchemaUtil.writeFixed32List(
3199  numberAt(pos),
3200  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3201  writer,
3202  true);
3203 
3204  break;
3205  case 42: // BOOL_LIST_PACKED:
3206  SchemaUtil.writeBoolList(
3207  numberAt(pos),
3208  (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3209  writer,
3210  true);
3211  break;
3212  case 43: // UINT32_LIST_PACKED:
3213  SchemaUtil.writeUInt32List(
3214  numberAt(pos),
3215  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3216  writer,
3217  true);
3218  break;
3219  case 44: // ENUM_LIST_PACKED:
3220  SchemaUtil.writeEnumList(
3221  numberAt(pos),
3222  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3223  writer,
3224  true);
3225  break;
3226  case 45: // SFIXED32_LIST_PACKED:
3227  SchemaUtil.writeSFixed32List(
3228  numberAt(pos),
3229  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3230  writer,
3231  true);
3232  break;
3233  case 46: // SFIXED64_LIST_PACKED:
3234  SchemaUtil.writeSFixed64List(
3235  numberAt(pos),
3236  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3237  writer,
3238  true);
3239  break;
3240  case 47: // SINT32_LIST_PACKED:
3241  SchemaUtil.writeSInt32List(
3242  numberAt(pos),
3243  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3244  writer,
3245  true);
3246  break;
3247  case 48: // SINT64_LIST_PACKED:
3248  SchemaUtil.writeSInt64List(
3249  numberAt(pos),
3250  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3251  writer,
3252  true);
3253  break;
3254  case 49: // GROUP_LIST:
3255  SchemaUtil.writeGroupList(
3256  numberAt(pos),
3257  (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3258  writer,
3259  getMessageFieldSchema(pos));
3260  break;
3261  case 50: // MAP:
3262  // TODO(dweis): Use schema cache.
3263  writeMapHelper(writer, number, UnsafeUtil.getObject(message, offset(typeAndOffset)), pos);
3264  break;
3265  case 51: // ONEOF_DOUBLE:
3266  if (isOneofPresent(message, number, pos)) {
3267  writer.writeDouble(number, oneofDoubleAt(message, offset(typeAndOffset)));
3268  }
3269  break;
3270  case 52: // ONEOF_FLOAT:
3271  if (isOneofPresent(message, number, pos)) {
3272  writer.writeFloat(number, oneofFloatAt(message, offset(typeAndOffset)));
3273  }
3274  break;
3275  case 53: // ONEOF_INT64:
3276  if (isOneofPresent(message, number, pos)) {
3277  writer.writeInt64(number, oneofLongAt(message, offset(typeAndOffset)));
3278  }
3279  break;
3280  case 54: // ONEOF_UINT64:
3281  if (isOneofPresent(message, number, pos)) {
3282  writer.writeUInt64(number, oneofLongAt(message, offset(typeAndOffset)));
3283  }
3284  break;
3285  case 55: // ONEOF_INT32:
3286  if (isOneofPresent(message, number, pos)) {
3287  writer.writeInt32(number, oneofIntAt(message, offset(typeAndOffset)));
3288  }
3289  break;
3290  case 56: // ONEOF_FIXED64:
3291  if (isOneofPresent(message, number, pos)) {
3292  writer.writeFixed64(number, oneofLongAt(message, offset(typeAndOffset)));
3293  }
3294  break;
3295  case 57: // ONEOF_FIXED32:
3296  if (isOneofPresent(message, number, pos)) {
3297  writer.writeFixed32(number, oneofIntAt(message, offset(typeAndOffset)));
3298  }
3299  break;
3300  case 58: // ONEOF_BOOL:
3301  if (isOneofPresent(message, number, pos)) {
3302  writer.writeBool(number, oneofBooleanAt(message, offset(typeAndOffset)));
3303  }
3304  break;
3305  case 59: // ONEOF_STRING:
3306  if (isOneofPresent(message, number, pos)) {
3307  writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer);
3308  }
3309  break;
3310  case 60: // ONEOF_MESSAGE:
3311  if (isOneofPresent(message, number, pos)) {
3312  Object value = UnsafeUtil.getObject(message, offset(typeAndOffset));
3313  writer.writeMessage(number, value, getMessageFieldSchema(pos));
3314  }
3315  break;
3316  case 61: // ONEOF_BYTES:
3317  if (isOneofPresent(message, number, pos)) {
3318  writer.writeBytes(
3319  number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset)));
3320  }
3321  break;
3322  case 62: // ONEOF_UINT32:
3323  if (isOneofPresent(message, number, pos)) {
3324  writer.writeUInt32(number, oneofIntAt(message, offset(typeAndOffset)));
3325  }
3326  break;
3327  case 63: // ONEOF_ENUM:
3328  if (isOneofPresent(message, number, pos)) {
3329  writer.writeEnum(number, oneofIntAt(message, offset(typeAndOffset)));
3330  }
3331  break;
3332  case 64: // ONEOF_SFIXED32:
3333  if (isOneofPresent(message, number, pos)) {
3334  writer.writeSFixed32(number, oneofIntAt(message, offset(typeAndOffset)));
3335  }
3336  break;
3337  case 65: // ONEOF_SFIXED64:
3338  if (isOneofPresent(message, number, pos)) {
3339  writer.writeSFixed64(number, oneofLongAt(message, offset(typeAndOffset)));
3340  }
3341  break;
3342  case 66: // ONEOF_SINT32:
3343  if (isOneofPresent(message, number, pos)) {
3344  writer.writeSInt32(number, oneofIntAt(message, offset(typeAndOffset)));
3345  }
3346  break;
3347  case 67: // ONEOF_SINT64:
3348  if (isOneofPresent(message, number, pos)) {
3349  writer.writeSInt64(number, oneofLongAt(message, offset(typeAndOffset)));
3350  }
3351  break;
3352  case 68: // ONEOF_GROUP:
3353  if (isOneofPresent(message, number, pos)) {
3354  writer.writeGroup(
3355  number,
3356  UnsafeUtil.getObject(message, offset(typeAndOffset)),
3357  getMessageFieldSchema(pos));
3358  }
3359  break;
3360  default:
3361  // Assume it's an empty entry - just go to the next entry.
3362  break;
3363  }
3364  }
3365  while (nextExtension != null) {
3366  extensionSchema.serializeExtension(writer, nextExtension);
3367  nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
3368  }
3369  writeUnknownInMessageTo(unknownFieldSchema, message, writer);
3370  }
3371 
3372  @SuppressWarnings("unchecked")
3373  private void writeFieldsInDescendingOrder(T message, Writer writer) throws IOException {
3374  writeUnknownInMessageTo(unknownFieldSchema, message, writer);
3375 
3376  Iterator<? extends Map.Entry<?, ?>> extensionIterator = null;
3377  Map.Entry nextExtension = null;
3378  if (hasExtensions) {
3379  FieldSet<?> extensions = extensionSchema.getExtensions(message);
3380  if (!extensions.isEmpty()) {
3381  extensionIterator = extensions.descendingIterator();
3382  nextExtension = extensionIterator.next();
3383  }
3384  }
3385 
3386  for (int pos = buffer.length - INTS_PER_FIELD; pos >= 0; pos -= INTS_PER_FIELD) {
3387  final int typeAndOffset = typeAndOffsetAt(pos);
3388  final int number = numberAt(pos);
3389 
3390  // Write any extensions that need to be written before the current field.
3391  while (nextExtension != null && extensionSchema.extensionNumber(nextExtension) > number) {
3392  extensionSchema.serializeExtension(writer, nextExtension);
3393  nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
3394  }
3395 
3396  switch (type(typeAndOffset)) {
3397  case 0: // DOUBLE:
3398  if (isFieldPresent(message, pos)) {
3399  writer.writeDouble(number, doubleAt(message, offset(typeAndOffset)));
3400  }
3401  break;
3402  case 1: // FLOAT:
3403  if (isFieldPresent(message, pos)) {
3404  writer.writeFloat(number, floatAt(message, offset(typeAndOffset)));
3405  }
3406  break;
3407  case 2: // INT64:
3408  if (isFieldPresent(message, pos)) {
3409  writer.writeInt64(number, longAt(message, offset(typeAndOffset)));
3410  }
3411  break;
3412  case 3: // UINT64:
3413  if (isFieldPresent(message, pos)) {
3414  writer.writeUInt64(number, longAt(message, offset(typeAndOffset)));
3415  }
3416  break;
3417  case 4: // INT32:
3418  if (isFieldPresent(message, pos)) {
3419  writer.writeInt32(number, intAt(message, offset(typeAndOffset)));
3420  }
3421  break;
3422  case 5: // FIXED64:
3423  if (isFieldPresent(message, pos)) {
3424  writer.writeFixed64(number, longAt(message, offset(typeAndOffset)));
3425  }
3426  break;
3427  case 6: // FIXED32:
3428  if (isFieldPresent(message, pos)) {
3429  writer.writeFixed32(number, intAt(message, offset(typeAndOffset)));
3430  }
3431  break;
3432  case 7: // BOOL:
3433  if (isFieldPresent(message, pos)) {
3434  writer.writeBool(number, booleanAt(message, offset(typeAndOffset)));
3435  }
3436  break;
3437  case 8: // STRING:
3438  if (isFieldPresent(message, pos)) {
3439  writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer);
3440  }
3441  break;
3442  case 9: // MESSAGE:
3443  if (isFieldPresent(message, pos)) {
3444  Object value = UnsafeUtil.getObject(message, offset(typeAndOffset));
3445  writer.writeMessage(number, value, getMessageFieldSchema(pos));
3446  }
3447  break;
3448  case 10: // BYTES:
3449  if (isFieldPresent(message, pos)) {
3450  writer.writeBytes(
3451  number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset)));
3452  }
3453  break;
3454  case 11: // UINT32:
3455  if (isFieldPresent(message, pos)) {
3456  writer.writeUInt32(number, intAt(message, offset(typeAndOffset)));
3457  }
3458  break;
3459  case 12: // ENUM:
3460  if (isFieldPresent(message, pos)) {
3461  writer.writeEnum(number, intAt(message, offset(typeAndOffset)));
3462  }
3463  break;
3464  case 13: // SFIXED32:
3465  if (isFieldPresent(message, pos)) {
3466  writer.writeSFixed32(number, intAt(message, offset(typeAndOffset)));
3467  }
3468  break;
3469  case 14: // SFIXED64:
3470  if (isFieldPresent(message, pos)) {
3471  writer.writeSFixed64(number, longAt(message, offset(typeAndOffset)));
3472  }
3473  break;
3474  case 15: // SINT32:
3475  if (isFieldPresent(message, pos)) {
3476  writer.writeSInt32(number, intAt(message, offset(typeAndOffset)));
3477  }
3478  break;
3479  case 16: // SINT64:
3480  if (isFieldPresent(message, pos)) {
3481  writer.writeSInt64(number, longAt(message, offset(typeAndOffset)));
3482  }
3483  break;
3484  case 17: // GROUP:
3485  if (isFieldPresent(message, pos)) {
3486  writer.writeGroup(
3487  number,
3488  UnsafeUtil.getObject(message, offset(typeAndOffset)),
3489  getMessageFieldSchema(pos));
3490  }
3491  break;
3492  case 18: // DOUBLE_LIST:
3493  SchemaUtil.writeDoubleList(
3494  numberAt(pos),
3495  (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3496  writer,
3497  false);
3498  break;
3499  case 19: // FLOAT_LIST:
3500  SchemaUtil.writeFloatList(
3501  numberAt(pos),
3502  (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3503  writer,
3504  false);
3505  break;
3506  case 20: // INT64_LIST:
3507  SchemaUtil.writeInt64List(
3508  numberAt(pos),
3509  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3510  writer,
3511  false);
3512  break;
3513  case 21: // UINT64_LIST:
3514  SchemaUtil.writeUInt64List(
3515  numberAt(pos),
3516  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3517  writer,
3518  false);
3519  break;
3520  case 22: // INT32_LIST:
3521  SchemaUtil.writeInt32List(
3522  numberAt(pos),
3523  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3524  writer,
3525  false);
3526  break;
3527  case 23: // FIXED64_LIST:
3528  SchemaUtil.writeFixed64List(
3529  numberAt(pos),
3530  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3531  writer,
3532  false);
3533  break;
3534  case 24: // FIXED32_LIST:
3535  SchemaUtil.writeFixed32List(
3536  numberAt(pos),
3537  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3538  writer,
3539  false);
3540  break;
3541  case 25: // BOOL_LIST:
3542  SchemaUtil.writeBoolList(
3543  numberAt(pos),
3544  (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3545  writer,
3546  false);
3547  break;
3548  case 26: // STRING_LIST:
3549  SchemaUtil.writeStringList(
3550  numberAt(pos),
3551  (List<String>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3552  writer);
3553  break;
3554  case 27: // MESSAGE_LIST:
3555  SchemaUtil.writeMessageList(
3556  numberAt(pos),
3557  (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3558  writer,
3559  getMessageFieldSchema(pos));
3560  break;
3561  case 28: // BYTES_LIST:
3562  SchemaUtil.writeBytesList(
3563  numberAt(pos),
3564  (List<ByteString>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3565  writer);
3566  break;
3567  case 29: // UINT32_LIST:
3568  SchemaUtil.writeUInt32List(
3569  numberAt(pos),
3570  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3571  writer,
3572  false);
3573  break;
3574  case 30: // ENUM_LIST:
3575  SchemaUtil.writeEnumList(
3576  numberAt(pos),
3577  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3578  writer,
3579  false);
3580  break;
3581  case 31: // SFIXED32_LIST:
3582  SchemaUtil.writeSFixed32List(
3583  numberAt(pos),
3584  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3585  writer,
3586  false);
3587  break;
3588  case 32: // SFIXED64_LIST:
3589  SchemaUtil.writeSFixed64List(
3590  numberAt(pos),
3591  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3592  writer,
3593  false);
3594  break;
3595  case 33: // SINT32_LIST:
3596  SchemaUtil.writeSInt32List(
3597  numberAt(pos),
3598  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3599  writer,
3600  false);
3601  break;
3602  case 34: // SINT64_LIST:
3603  SchemaUtil.writeSInt64List(
3604  numberAt(pos),
3605  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3606  writer,
3607  false);
3608  break;
3609  case 35: // DOUBLE_LIST_PACKED:
3610  SchemaUtil.writeDoubleList(
3611  numberAt(pos),
3612  (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3613  writer,
3614  true);
3615  break;
3616  case 36: // FLOAT_LIST_PACKED:
3617  SchemaUtil.writeFloatList(
3618  numberAt(pos),
3619  (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3620  writer,
3621  true);
3622  break;
3623  case 37: // INT64_LIST_PACKED:
3624  SchemaUtil.writeInt64List(
3625  numberAt(pos),
3626  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3627  writer,
3628  true);
3629  break;
3630  case 38: // UINT64_LIST_PACKED:
3631  SchemaUtil.writeUInt64List(
3632  numberAt(pos),
3633  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3634  writer,
3635  true);
3636  break;
3637  case 39: // INT32_LIST_PACKED:
3638  SchemaUtil.writeInt32List(
3639  numberAt(pos),
3640  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3641  writer,
3642  true);
3643  break;
3644  case 40: // FIXED64_LIST_PACKED:
3645  SchemaUtil.writeFixed64List(
3646  numberAt(pos),
3647  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3648  writer,
3649  true);
3650  break;
3651  case 41: // FIXED32_LIST_PACKED:
3652  SchemaUtil.writeFixed32List(
3653  numberAt(pos),
3654  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3655  writer,
3656  true);
3657 
3658  break;
3659  case 42: // BOOL_LIST_PACKED:
3660  SchemaUtil.writeBoolList(
3661  numberAt(pos),
3662  (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3663  writer,
3664  true);
3665  break;
3666  case 43: // UINT32_LIST_PACKED:
3667  SchemaUtil.writeUInt32List(
3668  numberAt(pos),
3669  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3670  writer,
3671  true);
3672  break;
3673  case 44: // ENUM_LIST_PACKED:
3674  SchemaUtil.writeEnumList(
3675  numberAt(pos),
3676  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3677  writer,
3678  true);
3679  break;
3680  case 45: // SFIXED32_LIST_PACKED:
3681  SchemaUtil.writeSFixed32List(
3682  numberAt(pos),
3683  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3684  writer,
3685  true);
3686  break;
3687  case 46: // SFIXED64_LIST_PACKED:
3688  SchemaUtil.writeSFixed64List(
3689  numberAt(pos),
3690  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3691  writer,
3692  true);
3693  break;
3694  case 47: // SINT32_LIST_PACKED:
3695  SchemaUtil.writeSInt32List(
3696  numberAt(pos),
3697  (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3698  writer,
3699  true);
3700  break;
3701  case 48: // SINT64_LIST_PACKED:
3702  SchemaUtil.writeSInt64List(
3703  numberAt(pos),
3704  (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3705  writer,
3706  true);
3707  break;
3708  case 49: // GROUP_LIST:
3709  SchemaUtil.writeGroupList(
3710  numberAt(pos),
3711  (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)),
3712  writer,
3713  getMessageFieldSchema(pos));
3714  break;
3715  case 50: // MAP:
3716  // TODO(dweis): Use schema cache.
3717  writeMapHelper(writer, number, UnsafeUtil.getObject(message, offset(typeAndOffset)), pos);
3718  break;
3719  case 51: // ONEOF_DOUBLE:
3720  if (isOneofPresent(message, number, pos)) {
3721  writer.writeDouble(number, oneofDoubleAt(message, offset(typeAndOffset)));
3722  }
3723  break;
3724  case 52: // ONEOF_FLOAT:
3725  if (isOneofPresent(message, number, pos)) {
3726  writer.writeFloat(number, oneofFloatAt(message, offset(typeAndOffset)));
3727  }
3728  break;
3729  case 53: // ONEOF_INT64:
3730  if (isOneofPresent(message, number, pos)) {
3731  writer.writeInt64(number, oneofLongAt(message, offset(typeAndOffset)));
3732  }
3733  break;
3734  case 54: // ONEOF_UINT64:
3735  if (isOneofPresent(message, number, pos)) {
3736  writer.writeUInt64(number, oneofLongAt(message, offset(typeAndOffset)));
3737  }
3738  break;
3739  case 55: // ONEOF_INT32:
3740  if (isOneofPresent(message, number, pos)) {
3741  writer.writeInt32(number, oneofIntAt(message, offset(typeAndOffset)));
3742  }
3743  break;
3744  case 56: // ONEOF_FIXED64:
3745  if (isOneofPresent(message, number, pos)) {
3746  writer.writeFixed64(number, oneofLongAt(message, offset(typeAndOffset)));
3747  }
3748  break;
3749  case 57: // ONEOF_FIXED32:
3750  if (isOneofPresent(message, number, pos)) {
3751  writer.writeFixed32(number, oneofIntAt(message, offset(typeAndOffset)));
3752  }
3753  break;
3754  case 58: // ONEOF_BOOL:
3755  if (isOneofPresent(message, number, pos)) {
3756  writer.writeBool(number, oneofBooleanAt(message, offset(typeAndOffset)));
3757  }
3758  break;
3759  case 59: // ONEOF_STRING:
3760  if (isOneofPresent(message, number, pos)) {
3761  writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer);
3762  }
3763  break;
3764  case 60: // ONEOF_MESSAGE:
3765  if (isOneofPresent(message, number, pos)) {
3766  Object value = UnsafeUtil.getObject(message, offset(typeAndOffset));
3767  writer.writeMessage(number, value, getMessageFieldSchema(pos));
3768  }
3769  break;
3770  case 61: // ONEOF_BYTES:
3771  if (isOneofPresent(message, number, pos)) {
3772  writer.writeBytes(
3773  number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset)));
3774  }
3775  break;
3776  case 62: // ONEOF_UINT32:
3777  if (isOneofPresent(message, number, pos)) {
3778  writer.writeUInt32(number, oneofIntAt(message, offset(typeAndOffset)));
3779  }
3780  break;
3781  case 63: // ONEOF_ENUM:
3782  if (isOneofPresent(message, number, pos)) {
3783  writer.writeEnum(number, oneofIntAt(message, offset(typeAndOffset)));
3784  }
3785  break;
3786  case 64: // ONEOF_SFIXED32:
3787  if (isOneofPresent(message, number, pos)) {
3788  writer.writeSFixed32(number, oneofIntAt(message, offset(typeAndOffset)));
3789  }
3790  break;
3791  case 65: // ONEOF_SFIXED64:
3792  if (isOneofPresent(message, number, pos)) {
3793  writer.writeSFixed64(number, oneofLongAt(message, offset(typeAndOffset)));
3794  }
3795  break;
3796  case 66: // ONEOF_SINT32:
3797  if (isOneofPresent(message, number, pos)) {
3798  writer.writeSInt32(number, oneofIntAt(message, offset(typeAndOffset)));
3799  }
3800  break;
3801  case 67: // ONEOF_SINT64:
3802  if (isOneofPresent(message, number, pos)) {
3803  writer.writeSInt64(number, oneofLongAt(message, offset(typeAndOffset)));
3804  }
3805  break;
3806  case 68: // ONEOF_GROUP:
3807  if (isOneofPresent(message, number, pos)) {
3808  writer.writeGroup(
3809  number,
3810  UnsafeUtil.getObject(message, offset(typeAndOffset)),
3811  getMessageFieldSchema(pos));
3812  }
3813  break;
3814  default:
3815  break;
3816  }
3817  }
3818  while (nextExtension != null) {
3819  extensionSchema.serializeExtension(writer, nextExtension);
3820  nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null;
3821  }
3822  }
3823 
3824  @SuppressWarnings("unchecked")
3825  private <K, V> void writeMapHelper(Writer writer, int number, Object mapField, int pos)
3826  throws IOException {
3827  if (mapField != null) {
3828  writer.writeMap(
3829  number,
3830  (MapEntryLite.Metadata<K, V>) mapFieldSchema.forMapMetadata(getMapFieldDefaultEntry(pos)),
3831  (Map<K, V>) mapFieldSchema.forMapData(mapField));
3832  }
3833  }
3834 
3835  private <UT, UB> void writeUnknownInMessageTo(
3836  UnknownFieldSchema<UT, UB> schema, T message, Writer writer) throws IOException {
3837  schema.writeTo(schema.getFromMessage(message), writer);
3838  }
3839 
3840  @Override
3841  public void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
3842  throws IOException {
3843  if (extensionRegistry == null) {
3844  throw new NullPointerException();
3845  }
3846  mergeFromHelper(unknownFieldSchema, extensionSchema, message, reader, extensionRegistry);
3847  }
3848 
3853  private <UT, UB, ET extends FieldDescriptorLite<ET>> void mergeFromHelper(
3854  UnknownFieldSchema<UT, UB> unknownFieldSchema,
3855  ExtensionSchema<ET> extensionSchema,
3856  T message,
3857  Reader reader,
3858  ExtensionRegistryLite extensionRegistry)
3859  throws IOException {
3860  UB unknownFields = null;
3861  FieldSet<ET> extensions = null;
3862  try {
3863  while (true) {
3864  final int number = reader.getFieldNumber();
3865  final int pos = positionForFieldNumber(number);
3866  if (pos < 0) {
3867  if (number == Reader.READ_DONE) {
3868  return;
3869  }
3870  // Check if it's an extension.
3871  Object extension =
3872  !hasExtensions
3873  ? null
3874  : extensionSchema.findExtensionByNumber(
3875  extensionRegistry, defaultInstance, number);
3876  if (extension != null) {
3877  if (extensions == null) {
3878  extensions = extensionSchema.getMutableExtensions(message);
3879  }
3880  unknownFields =
3881  extensionSchema.parseExtension(
3882  reader,
3883  extension,
3884  extensionRegistry,
3885  extensions,
3886  unknownFields,
3887  unknownFieldSchema);
3888  continue;
3889  }
3890  if (unknownFieldSchema.shouldDiscardUnknownFields(reader)) {
3891  if (reader.skipField()) {
3892  continue;
3893  }
3894  } else {
3895  if (unknownFields == null) {
3896  unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
3897  }
3898  // Unknown field.
3899  if (unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
3900  continue;
3901  }
3902  }
3903  // Done reading.
3904  return;
3905  }
3906  final int typeAndOffset = typeAndOffsetAt(pos);
3907 
3908  try {
3909  switch (type(typeAndOffset)) {
3910  case 0: // DOUBLE:
3911  UnsafeUtil.putDouble(message, offset(typeAndOffset), reader.readDouble());
3912  setFieldPresent(message, pos);
3913  break;
3914  case 1: // FLOAT:
3915  UnsafeUtil.putFloat(message, offset(typeAndOffset), reader.readFloat());
3916  setFieldPresent(message, pos);
3917  break;
3918  case 2: // INT64:
3919  UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readInt64());
3920  setFieldPresent(message, pos);
3921  break;
3922  case 3: // UINT64:
3923  UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readUInt64());
3924  setFieldPresent(message, pos);
3925  break;
3926  case 4: // INT32:
3927  UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readInt32());
3928  setFieldPresent(message, pos);
3929  break;
3930  case 5: // FIXED64:
3931  UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readFixed64());
3932  setFieldPresent(message, pos);
3933  break;
3934  case 6: // FIXED32:
3935  UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readFixed32());
3936  setFieldPresent(message, pos);
3937  break;
3938  case 7: // BOOL:
3939  UnsafeUtil.putBoolean(message, offset(typeAndOffset), reader.readBool());
3940  setFieldPresent(message, pos);
3941  break;
3942  case 8: // STRING:
3943  readString(message, typeAndOffset, reader);
3944  setFieldPresent(message, pos);
3945  break;
3946  case 9:
3947  { // MESSAGE:
3948  if (isFieldPresent(message, pos)) {
3949  Object mergedResult =
3950  Internal.mergeMessage(
3951  UnsafeUtil.getObject(message, offset(typeAndOffset)),
3952  reader.readMessageBySchemaWithCheck(
3953  (Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
3954  UnsafeUtil.putObject(message, offset(typeAndOffset), mergedResult);
3955  } else {
3956  UnsafeUtil.putObject(
3957  message,
3958  offset(typeAndOffset),
3959  reader.readMessageBySchemaWithCheck(
3960  (Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
3961  setFieldPresent(message, pos);
3962  }
3963  break;
3964  }
3965  case 10: // BYTES:
3966  UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes());
3967  setFieldPresent(message, pos);
3968  break;
3969  case 11: // UINT32:
3970  UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readUInt32());
3971  setFieldPresent(message, pos);
3972  break;
3973  case 12: // ENUM:
3974  {
3975  int enumValue = reader.readEnum();
3976  EnumVerifier enumVerifier = getEnumFieldVerifier(pos);
3977  if (enumVerifier == null || enumVerifier.isInRange(enumValue)) {
3978  UnsafeUtil.putInt(message, offset(typeAndOffset), enumValue);
3979  setFieldPresent(message, pos);
3980  } else {
3981  unknownFields =
3982  SchemaUtil.storeUnknownEnum(
3983  number, enumValue, unknownFields, unknownFieldSchema);
3984  }
3985  break;
3986  }
3987  case 13: // SFIXED32:
3988  UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readSFixed32());
3989  setFieldPresent(message, pos);
3990  break;
3991  case 14: // SFIXED64:
3992  UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readSFixed64());
3993  setFieldPresent(message, pos);
3994  break;
3995  case 15: // SINT32:
3996  UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readSInt32());
3997  setFieldPresent(message, pos);
3998  break;
3999  case 16: // SINT64:
4000  UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readSInt64());
4001  setFieldPresent(message, pos);
4002  break;
4003  case 17:
4004  { // GROUP:
4005  if (isFieldPresent(message, pos)) {
4006  Object mergedResult =
4007  Internal.mergeMessage(
4008  UnsafeUtil.getObject(message, offset(typeAndOffset)),
4009  reader.readGroupBySchemaWithCheck(
4010  (Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
4011  UnsafeUtil.putObject(message, offset(typeAndOffset), mergedResult);
4012  } else {
4013  UnsafeUtil.putObject(
4014  message,
4015  offset(typeAndOffset),
4016  reader.readGroupBySchemaWithCheck(
4017  (Schema<T>) getMessageFieldSchema(pos), extensionRegistry));
4018  setFieldPresent(message, pos);
4019  }
4020  break;
4021  }
4022  case 18: // DOUBLE_LIST:
4023  reader.readDoubleList(
4024  listFieldSchema.<Double>mutableListAt(message, offset(typeAndOffset)));
4025  break;
4026  case 19: // FLOAT_LIST:
4027  reader.readFloatList(
4028  listFieldSchema.<Float>mutableListAt(message, offset(typeAndOffset)));
4029  break;
4030  case 20: // INT64_LIST:
4031  reader.readInt64List(
4032  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4033  break;
4034  case 21: // UINT64_LIST:
4035  reader.readUInt64List(
4036  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4037  break;
4038  case 22: // INT32_LIST:
4039  reader.readInt32List(
4040  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4041  break;
4042  case 23: // FIXED64_LIST:
4043  reader.readFixed64List(
4044  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4045  break;
4046  case 24: // FIXED32_LIST:
4047  reader.readFixed32List(
4048  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4049  break;
4050  case 25: // BOOL_LIST:
4051  reader.readBoolList(
4052  listFieldSchema.<Boolean>mutableListAt(message, offset(typeAndOffset)));
4053  break;
4054  case 26: // STRING_LIST:
4055  readStringList(message, typeAndOffset, reader);
4056  break;
4057  case 27:
4058  { // MESSAGE_LIST:
4059  readMessageList(
4060  message,
4061  typeAndOffset,
4062  reader,
4063  (Schema<T>) getMessageFieldSchema(pos),
4064  extensionRegistry);
4065  break;
4066  }
4067  case 28: // BYTES_LIST:
4068  reader.readBytesList(
4069  listFieldSchema.<ByteString>mutableListAt(message, offset(typeAndOffset)));
4070  break;
4071  case 29: // UINT32_LIST:
4072  reader.readUInt32List(
4073  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4074  break;
4075  case 30: // ENUM_LIST:
4076  {
4077  List<Integer> enumList =
4078  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset));
4079  reader.readEnumList(enumList);
4080  unknownFields =
4081  SchemaUtil.filterUnknownEnumList(
4082  number,
4083  enumList,
4084  getEnumFieldVerifier(pos),
4085  unknownFields,
4086  unknownFieldSchema);
4087  break;
4088  }
4089  case 31: // SFIXED32_LIST:
4090  reader.readSFixed32List(
4091  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4092  break;
4093  case 32: // SFIXED64_LIST:
4094  reader.readSFixed64List(
4095  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4096  break;
4097  case 33: // SINT32_LIST:
4098  reader.readSInt32List(
4099  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4100  break;
4101  case 34: // SINT64_LIST:
4102  reader.readSInt64List(
4103  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4104  break;
4105  case 35: // DOUBLE_LIST_PACKED:
4106  reader.readDoubleList(
4107  listFieldSchema.<Double>mutableListAt(message, offset(typeAndOffset)));
4108  break;
4109  case 36: // FLOAT_LIST_PACKED:
4110  reader.readFloatList(
4111  listFieldSchema.<Float>mutableListAt(message, offset(typeAndOffset)));
4112  break;
4113  case 37: // INT64_LIST_PACKED:
4114  reader.readInt64List(
4115  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4116  break;
4117  case 38: // UINT64_LIST_PACKED:
4118  reader.readUInt64List(
4119  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4120  break;
4121  case 39: // INT32_LIST_PACKED:
4122  reader.readInt32List(
4123  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4124  break;
4125  case 40: // FIXED64_LIST_PACKED:
4126  reader.readFixed64List(
4127  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4128  break;
4129  case 41: // FIXED32_LIST_PACKED:
4130  reader.readFixed32List(
4131  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4132  break;
4133  case 42: // BOOL_LIST_PACKED:
4134  reader.readBoolList(
4135  listFieldSchema.<Boolean>mutableListAt(message, offset(typeAndOffset)));
4136  break;
4137  case 43: // UINT32_LIST_PACKED:
4138  reader.readUInt32List(
4139  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4140  break;
4141  case 44: // ENUM_LIST_PACKED:
4142  {
4143  List<Integer> enumList =
4144  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset));
4145  reader.readEnumList(enumList);
4146  unknownFields =
4147  SchemaUtil.filterUnknownEnumList(
4148  number,
4149  enumList,
4150  getEnumFieldVerifier(pos),
4151  unknownFields,
4152  unknownFieldSchema);
4153  break;
4154  }
4155  case 45: // SFIXED32_LIST_PACKED:
4156  reader.readSFixed32List(
4157  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4158  break;
4159  case 46: // SFIXED64_LIST_PACKED:
4160  reader.readSFixed64List(
4161  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4162  break;
4163  case 47: // SINT32_LIST_PACKED:
4164  reader.readSInt32List(
4165  listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)));
4166  break;
4167  case 48: // SINT64_LIST_PACKED:
4168  reader.readSInt64List(
4169  listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset)));
4170  break;
4171  case 49:
4172  { // GROUP_LIST:
4173  readGroupList(
4174  message,
4175  offset(typeAndOffset),
4176  reader,
4177  (Schema<T>) getMessageFieldSchema(pos),
4178  extensionRegistry);
4179  break;
4180  }
4181  case 50: // MAP:
4182  mergeMap(message, pos, getMapFieldDefaultEntry(pos), extensionRegistry, reader);
4183  break;
4184  case 51: // ONEOF_DOUBLE:
4185  UnsafeUtil.putObject(
4186  message, offset(typeAndOffset), Double.valueOf(reader.readDouble()));
4187  setOneofPresent(message, number, pos);
4188  break;
4189  case 52: // ONEOF_FLOAT:
4190  UnsafeUtil.putObject(
4191  message, offset(typeAndOffset), Float.valueOf(reader.readFloat()));
4192  setOneofPresent(message, number, pos);
4193  break;
4194  case 53: // ONEOF_INT64:
4195  UnsafeUtil.putObject(
4196  message, offset(typeAndOffset), Long.valueOf(reader.readInt64()));
4197  setOneofPresent(message, number, pos);
4198  break;
4199  case 54: // ONEOF_UINT64:
4200  UnsafeUtil.putObject(
4201  message, offset(typeAndOffset), Long.valueOf(reader.readUInt64()));
4202  setOneofPresent(message, number, pos);
4203  break;
4204  case 55: // ONEOF_INT32:
4205  UnsafeUtil.putObject(
4206  message, offset(typeAndOffset), Integer.valueOf(reader.readInt32()));
4207  setOneofPresent(message, number, pos);
4208  break;
4209  case 56: // ONEOF_FIXED64:
4210  UnsafeUtil.putObject(
4211  message, offset(typeAndOffset), Long.valueOf(reader.readFixed64()));
4212  setOneofPresent(message, number, pos);
4213  break;
4214  case 57: // ONEOF_FIXED32:
4215  UnsafeUtil.putObject(
4216  message, offset(typeAndOffset), Integer.valueOf(reader.readFixed32()));
4217  setOneofPresent(message, number, pos);
4218  break;
4219  case 58: // ONEOF_BOOL:
4220  UnsafeUtil.putObject(
4221  message, offset(typeAndOffset), Boolean.valueOf(reader.readBool()));
4222  setOneofPresent(message, number, pos);
4223  break;
4224  case 59: // ONEOF_STRING:
4225  readString(message, typeAndOffset, reader);
4226  setOneofPresent(message, number, pos);
4227  break;
4228  case 60: // ONEOF_MESSAGE:
4229  if (isOneofPresent(message, number, pos)) {
4230  Object mergedResult =
4231  Internal.mergeMessage(
4232  UnsafeUtil.getObject(message, offset(typeAndOffset)),
4233  reader.readMessageBySchemaWithCheck(
4234  getMessageFieldSchema(pos), extensionRegistry));
4235  UnsafeUtil.putObject(message, offset(typeAndOffset), mergedResult);
4236  } else {
4237  UnsafeUtil.putObject(
4238  message,
4239  offset(typeAndOffset),
4240  reader.readMessageBySchemaWithCheck(
4241  getMessageFieldSchema(pos), extensionRegistry));
4242  setFieldPresent(message, pos);
4243  }
4244  setOneofPresent(message, number, pos);
4245  break;
4246  case 61: // ONEOF_BYTES:
4247  UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes());
4248  setOneofPresent(message, number, pos);
4249  break;
4250  case 62: // ONEOF_UINT32:
4251  UnsafeUtil.putObject(
4252  message, offset(typeAndOffset), Integer.valueOf(reader.readUInt32()));
4253  setOneofPresent(message, number, pos);
4254  break;
4255  case 63: // ONEOF_ENUM:
4256  {
4257  int enumValue = reader.readEnum();
4258  EnumVerifier enumVerifier = getEnumFieldVerifier(pos);
4259  if (enumVerifier == null || enumVerifier.isInRange(enumValue)) {
4260  UnsafeUtil.putObject(message, offset(typeAndOffset), enumValue);
4261  setOneofPresent(message, number, pos);
4262  } else {
4263  unknownFields =
4264  SchemaUtil.storeUnknownEnum(
4265  number, enumValue, unknownFields, unknownFieldSchema);
4266  }
4267  break;
4268  }
4269  case 64: // ONEOF_SFIXED32:
4270  UnsafeUtil.putObject(
4271  message, offset(typeAndOffset), Integer.valueOf(reader.readSFixed32()));
4272  setOneofPresent(message, number, pos);
4273  break;
4274  case 65: // ONEOF_SFIXED64:
4275  UnsafeUtil.putObject(
4276  message, offset(typeAndOffset), Long.valueOf(reader.readSFixed64()));
4277  setOneofPresent(message, number, pos);
4278  break;
4279  case 66: // ONEOF_SINT32:
4280  UnsafeUtil.putObject(
4281  message, offset(typeAndOffset), Integer.valueOf(reader.readSInt32()));
4282  setOneofPresent(message, number, pos);
4283  break;
4284  case 67: // ONEOF_SINT64:
4285  UnsafeUtil.putObject(
4286  message, offset(typeAndOffset), Long.valueOf(reader.readSInt64()));
4287  setOneofPresent(message, number, pos);
4288  break;
4289  case 68: // ONEOF_GROUP:
4290  UnsafeUtil.putObject(
4291  message,
4292  offset(typeAndOffset),
4293  reader.readGroupBySchemaWithCheck(getMessageFieldSchema(pos), extensionRegistry));
4294  setOneofPresent(message, number, pos);
4295  break;
4296  default:
4297  // Assume we've landed on an empty entry. Treat it as an unknown field.
4298  if (unknownFields == null) {
4299  unknownFields = unknownFieldSchema.newBuilder();
4300  }
4301  if (!unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
4302  return;
4303  }
4304  break;
4305  }
4306  } catch (InvalidProtocolBufferException.InvalidWireTypeException e) {
4307  // Treat fields with an invalid wire type as unknown fields
4308  // (i.e. same as the default case).
4309  if (unknownFieldSchema.shouldDiscardUnknownFields(reader)) {
4310  if (!reader.skipField()) {
4311  return;
4312  }
4313  } else {
4314  if (unknownFields == null) {
4315  unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
4316  }
4317  if (!unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader)) {
4318  return;
4319  }
4320  }
4321  }
4322  }
4323  } finally {
4324  for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) {
4325  unknownFields =
4326  filterMapUnknownEnumValues(message, intArray[i], unknownFields, unknownFieldSchema);
4327  }
4328  if (unknownFields != null) {
4329  unknownFieldSchema.setBuilderToMessage(message, unknownFields);
4330  }
4331  }
4332  }
4333 
4334  @SuppressWarnings("ReferenceEquality")
4335  static UnknownFieldSetLite getMutableUnknownFields(Object message) {
4336  UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
4337  if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
4338  unknownFields = UnknownFieldSetLite.newInstance();
4339  ((GeneratedMessageLite) message).unknownFields = unknownFields;
4340  }
4341  return unknownFields;
4342  }
4343 
4345  private int decodeMapEntryValue(
4346  byte[] data,
4347  int position,
4348  int limit,
4349  WireFormat.FieldType fieldType,
4350  Class<?> messageType,
4351  Registers registers)
4352  throws IOException {
4353  switch (fieldType) {
4354  case BOOL:
4355  position = decodeVarint64(data, position, registers);
4356  registers.object1 = registers.long1 != 0;
4357  break;
4358  case BYTES:
4359  position = decodeBytes(data, position, registers);
4360  break;
4361  case DOUBLE:
4362  registers.object1 = decodeDouble(data, position);
4363  position += 8;
4364  break;
4365  case FIXED32:
4366  case SFIXED32:
4367  registers.object1 = decodeFixed32(data, position);
4368  position += 4;
4369  break;
4370  case FIXED64:
4371  case SFIXED64:
4372  registers.object1 = decodeFixed64(data, position);
4373  position += 8;
4374  break;
4375  case FLOAT:
4376  registers.object1 = decodeFloat(data, position);
4377  position += 4;
4378  break;
4379  case ENUM:
4380  case INT32:
4381  case UINT32:
4382  position = decodeVarint32(data, position, registers);
4383  registers.object1 = registers.int1;
4384  break;
4385  case INT64:
4386  case UINT64:
4387  position = decodeVarint64(data, position, registers);
4388  registers.object1 = registers.long1;
4389  break;
4390  case MESSAGE:
4391  position =
4392  decodeMessageField(
4393  Protobuf.getInstance().schemaFor(messageType), data, position, limit, registers);
4394  break;
4395  case SINT32:
4396  position = decodeVarint32(data, position, registers);
4397  registers.object1 = CodedInputStream.decodeZigZag32(registers.int1);
4398  break;
4399  case SINT64:
4400  position = decodeVarint64(data, position, registers);
4401  registers.object1 = CodedInputStream.decodeZigZag64(registers.long1);
4402  break;
4403  case STRING:
4404  position = decodeStringRequireUtf8(data, position, registers);
4405  break;
4406  default:
4407  throw new RuntimeException("unsupported field type.");
4408  }
4409  return position;
4410  }
4411 
4413  private <K, V> int decodeMapEntry(
4414  byte[] data,
4415  int position,
4416  int limit,
4417  MapEntryLite.Metadata<K, V> metadata,
4418  Map<K, V> target,
4419  Registers registers)
4420  throws IOException {
4421  position = decodeVarint32(data, position, registers);
4422  final int length = registers.int1;
4423  if (length < 0 || length > limit - position) {
4424  throw InvalidProtocolBufferException.truncatedMessage();
4425  }
4426  final int end = position + length;
4427  K key = metadata.defaultKey;
4428  V value = metadata.defaultValue;
4429  while (position < end) {
4430  int tag = data[position++];
4431  if (tag < 0) {
4432  position = decodeVarint32(tag, data, position, registers);
4433  tag = registers.int1;
4434  }
4435  final int fieldNumber = tag >>> 3;
4436  final int wireType = tag & 0x7;
4437  switch (fieldNumber) {
4438  case 1:
4439  if (wireType == metadata.keyType.getWireType()) {
4440  position =
4441  decodeMapEntryValue(data, position, limit, metadata.keyType, null, registers);
4442  key = (K) registers.object1;
4443  continue;
4444  }
4445  break;
4446  case 2:
4447  if (wireType == metadata.valueType.getWireType()) {
4448  position =
4449  decodeMapEntryValue(
4450  data,
4451  position,
4452  limit,
4453  metadata.valueType,
4454  metadata.defaultValue.getClass(),
4455  registers);
4456  value = (V) registers.object1;
4457  continue;
4458  }
4459  break;
4460  default:
4461  break;
4462  }
4463  position = skipField(tag, data, position, limit, registers);
4464  }
4465  if (position != end) {
4466  throw InvalidProtocolBufferException.parseFailure();
4467  }
4468  target.put(key, value);
4469  return end;
4470  }
4471 
4472  @SuppressWarnings("ReferenceEquality")
4473  private int parseRepeatedField(
4474  T message,
4475  byte[] data,
4476  int position,
4477  int limit,
4478  int tag,
4479  int number,
4480  int wireType,
4481  int bufferPosition,
4482  long typeAndOffset,
4483  int fieldType,
4484  long fieldOffset,
4485  Registers registers)
4486  throws IOException {
4487  ProtobufList<?> list = (ProtobufList<?>) UNSAFE.getObject(message, fieldOffset);
4488  if (!list.isModifiable()) {
4489  final int size = list.size();
4490  list =
4491  list.mutableCopyWithCapacity(
4492  size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
4493  UNSAFE.putObject(message, fieldOffset, list);
4494  }
4495  switch (fieldType) {
4496  case 18: // DOUBLE_LIST:
4497  case 35: // DOUBLE_LIST_PACKED:
4498  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4499  position = decodePackedDoubleList(data, position, list, registers);
4500  } else if (wireType == WireFormat.WIRETYPE_FIXED64) {
4501  position = decodeDoubleList(tag, data, position, limit, list, registers);
4502  }
4503  break;
4504  case 19: // FLOAT_LIST:
4505  case 36: // FLOAT_LIST_PACKED:
4506  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4507  position = decodePackedFloatList(data, position, list, registers);
4508  } else if (wireType == WireFormat.WIRETYPE_FIXED32) {
4509  position = decodeFloatList(tag, data, position, limit, list, registers);
4510  }
4511  break;
4512  case 20: // INT64_LIST:
4513  case 21: // UINT64_LIST:
4514  case 37: // INT64_LIST_PACKED:
4515  case 38: // UINT64_LIST_PACKED:
4516  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4517  position = decodePackedVarint64List(data, position, list, registers);
4518  } else if (wireType == WireFormat.WIRETYPE_VARINT) {
4519  position = decodeVarint64List(tag, data, position, limit, list, registers);
4520  }
4521  break;
4522  case 22: // INT32_LIST:
4523  case 29: // UINT32_LIST:
4524  case 39: // INT32_LIST_PACKED:
4525  case 43: // UINT32_LIST_PACKED:
4526  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4527  position = decodePackedVarint32List(data, position, list, registers);
4528  } else if (wireType == WireFormat.WIRETYPE_VARINT) {
4529  position = decodeVarint32List(tag, data, position, limit, list, registers);
4530  }
4531  break;
4532  case 23: // FIXED64_LIST:
4533  case 32: // SFIXED64_LIST:
4534  case 40: // FIXED64_LIST_PACKED:
4535  case 46: // SFIXED64_LIST_PACKED:
4536  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4537  position = decodePackedFixed64List(data, position, list, registers);
4538  } else if (wireType == WireFormat.WIRETYPE_FIXED64) {
4539  position = decodeFixed64List(tag, data, position, limit, list, registers);
4540  }
4541  break;
4542  case 24: // FIXED32_LIST:
4543  case 31: // SFIXED32_LIST:
4544  case 41: // FIXED32_LIST_PACKED:
4545  case 45: // SFIXED32_LIST_PACKED:
4546  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4547  position = decodePackedFixed32List(data, position, list, registers);
4548  } else if (wireType == WireFormat.WIRETYPE_FIXED32) {
4549  position = decodeFixed32List(tag, data, position, limit, list, registers);
4550  }
4551  break;
4552  case 25: // BOOL_LIST:
4553  case 42: // BOOL_LIST_PACKED:
4554  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4555  position = decodePackedBoolList(data, position, list, registers);
4556  } else if (wireType == WireFormat.WIRETYPE_VARINT) {
4557  position = decodeBoolList(tag, data, position, limit, list, registers);
4558  }
4559  break;
4560  case 26: // STRING_LIST:
4561  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4562  if ((typeAndOffset & ENFORCE_UTF8_MASK) == 0) {
4563  position = decodeStringList(tag, data, position, limit, list, registers);
4564  } else {
4565  position = decodeStringListRequireUtf8(tag, data, position, limit, list, registers);
4566  }
4567  }
4568  break;
4569  case 27: // MESSAGE_LIST:
4570  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4571  position =
4572  decodeMessageList(
4573  getMessageFieldSchema(bufferPosition),
4574  tag,
4575  data,
4576  position,
4577  limit,
4578  list,
4579  registers);
4580  }
4581  break;
4582  case 28: // BYTES_LIST:
4583  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4584  position = decodeBytesList(tag, data, position, limit, list, registers);
4585  }
4586  break;
4587  case 30: // ENUM_LIST:
4588  case 44: // ENUM_LIST_PACKED:
4589  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4590  position = decodePackedVarint32List(data, position, list, registers);
4591  } else if (wireType == WireFormat.WIRETYPE_VARINT) {
4592  position = decodeVarint32List(tag, data, position, limit, list, registers);
4593  } else {
4594  break;
4595  }
4596  UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
4597  if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
4598  // filterUnknownEnumList() expects the unknownFields parameter to be mutable or null.
4599  // Since we don't know yet whether there exist unknown enum values, we'd better pass
4600  // null to it instead of allocating a mutable instance. This is also needed to be
4601  // consistent with the behavior of generated parser/builder.
4602  unknownFields = null;
4603  }
4604  unknownFields =
4605  SchemaUtil.filterUnknownEnumList(
4606  number,
4607  (ProtobufList<Integer>) list,
4608  getEnumFieldVerifier(bufferPosition),
4609  unknownFields,
4610  (UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema);
4611  if (unknownFields != null) {
4612  ((GeneratedMessageLite) message).unknownFields = unknownFields;
4613  }
4614  break;
4615  case 33: // SINT32_LIST:
4616  case 47: // SINT32_LIST_PACKED:
4617  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4618  position = decodePackedSInt32List(data, position, list, registers);
4619  } else if (wireType == WireFormat.WIRETYPE_VARINT) {
4620  position = decodeSInt32List(tag, data, position, limit, list, registers);
4621  }
4622  break;
4623  case 34: // SINT64_LIST:
4624  case 48: // SINT64_LIST_PACKED:
4625  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4626  position = decodePackedSInt64List(data, position, list, registers);
4627  } else if (wireType == WireFormat.WIRETYPE_VARINT) {
4628  position = decodeSInt64List(tag, data, position, limit, list, registers);
4629  }
4630  break;
4631  case 49: // GROUP_LIST:
4632  if (wireType == WireFormat.WIRETYPE_START_GROUP) {
4633  position =
4634  decodeGroupList(
4635  getMessageFieldSchema(bufferPosition),
4636  tag,
4637  data,
4638  position,
4639  limit,
4640  list,
4641  registers);
4642  }
4643  break;
4644  default:
4645  break;
4646  }
4647  return position;
4648  }
4649 
4650  private <K, V> int parseMapField(
4651  T message,
4652  byte[] data,
4653  int position,
4654  int limit,
4655  int bufferPosition,
4656  long fieldOffset,
4657  Registers registers)
4658  throws IOException {
4659  final sun.misc.Unsafe unsafe = UNSAFE;
4660  Object mapDefaultEntry = getMapFieldDefaultEntry(bufferPosition);
4661  Object mapField = unsafe.getObject(message, fieldOffset);
4662  if (mapFieldSchema.isImmutable(mapField)) {
4663  Object oldMapField = mapField;
4664  mapField = mapFieldSchema.newMapField(mapDefaultEntry);
4665  mapFieldSchema.mergeFrom(mapField, oldMapField);
4666  unsafe.putObject(message, fieldOffset, mapField);
4667  }
4668  return decodeMapEntry(
4669  data,
4670  position,
4671  limit,
4672  (Metadata<K, V>) mapFieldSchema.forMapMetadata(mapDefaultEntry),
4673  (Map<K, V>) mapFieldSchema.forMutableMapData(mapField),
4674  registers);
4675  }
4676 
4677  private int parseOneofField(
4678  T message,
4679  byte[] data,
4680  int position,
4681  int limit,
4682  int tag,
4683  int number,
4684  int wireType,
4685  int typeAndOffset,
4686  int fieldType,
4687  long fieldOffset,
4688  int bufferPosition,
4689  Registers registers)
4690  throws IOException {
4691  final sun.misc.Unsafe unsafe = UNSAFE;
4692  final long oneofCaseOffset = buffer[bufferPosition + 2] & OFFSET_MASK;
4693  switch (fieldType) {
4694  case 51: // ONEOF_DOUBLE:
4695  if (wireType == WireFormat.WIRETYPE_FIXED64) {
4696  unsafe.putObject(message, fieldOffset, decodeDouble(data, position));
4697  position += 8;
4698  unsafe.putInt(message, oneofCaseOffset, number);
4699  }
4700  break;
4701  case 52: // ONEOF_FLOAT:
4702  if (wireType == WireFormat.WIRETYPE_FIXED32) {
4703  unsafe.putObject(message, fieldOffset, decodeFloat(data, position));
4704  position += 4;
4705  unsafe.putInt(message, oneofCaseOffset, number);
4706  }
4707  break;
4708  case 53: // ONEOF_INT64:
4709  case 54: // ONEOF_UINT64:
4710  if (wireType == WireFormat.WIRETYPE_VARINT) {
4711  position = decodeVarint64(data, position, registers);
4712  unsafe.putObject(message, fieldOffset, registers.long1);
4713  unsafe.putInt(message, oneofCaseOffset, number);
4714  }
4715  break;
4716  case 55: // ONEOF_INT32:
4717  case 62: // ONEOF_UINT32:
4718  if (wireType == WireFormat.WIRETYPE_VARINT) {
4719  position = decodeVarint32(data, position, registers);
4720  unsafe.putObject(message, fieldOffset, registers.int1);
4721  unsafe.putInt(message, oneofCaseOffset, number);
4722  }
4723  break;
4724  case 56: // ONEOF_FIXED64:
4725  case 65: // ONEOF_SFIXED64:
4726  if (wireType == WireFormat.WIRETYPE_FIXED64) {
4727  unsafe.putObject(message, fieldOffset, decodeFixed64(data, position));
4728  position += 8;
4729  unsafe.putInt(message, oneofCaseOffset, number);
4730  }
4731  break;
4732  case 57: // ONEOF_FIXED32:
4733  case 64: // ONEOF_SFIXED32:
4734  if (wireType == WireFormat.WIRETYPE_FIXED32) {
4735  unsafe.putObject(message, fieldOffset, decodeFixed32(data, position));
4736  position += 4;
4737  unsafe.putInt(message, oneofCaseOffset, number);
4738  }
4739  break;
4740  case 58: // ONEOF_BOOL:
4741  if (wireType == WireFormat.WIRETYPE_VARINT) {
4742  position = decodeVarint64(data, position, registers);
4743  unsafe.putObject(message, fieldOffset, registers.long1 != 0);
4744  unsafe.putInt(message, oneofCaseOffset, number);
4745  }
4746  break;
4747  case 59: // ONEOF_STRING:
4748  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4749  position = decodeVarint32(data, position, registers);
4750  final int length = registers.int1;
4751  if (length == 0) {
4752  unsafe.putObject(message, fieldOffset, "");
4753  } else {
4754  if ((typeAndOffset & ENFORCE_UTF8_MASK) != 0
4755  && !Utf8.isValidUtf8(data, position, position + length)) {
4756  throw InvalidProtocolBufferException.invalidUtf8();
4757  }
4758  final String value = new String(data, position, length, Internal.UTF_8);
4759  unsafe.putObject(message, fieldOffset, value);
4760  position += length;
4761  }
4762  unsafe.putInt(message, oneofCaseOffset, number);
4763  }
4764  break;
4765  case 60: // ONEOF_MESSAGE:
4766  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4767  position =
4768  decodeMessageField(
4769  getMessageFieldSchema(bufferPosition), data, position, limit, registers);
4770  final Object oldValue =
4771  unsafe.getInt(message, oneofCaseOffset) == number
4772  ? unsafe.getObject(message, fieldOffset)
4773  : null;
4774  if (oldValue == null) {
4775  unsafe.putObject(message, fieldOffset, registers.object1);
4776  } else {
4777  unsafe.putObject(
4778  message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1));
4779  }
4780  unsafe.putInt(message, oneofCaseOffset, number);
4781  }
4782  break;
4783  case 61: // ONEOF_BYTES:
4784  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4785  position = decodeBytes(data, position, registers);
4786  unsafe.putObject(message, fieldOffset, registers.object1);
4787  unsafe.putInt(message, oneofCaseOffset, number);
4788  }
4789  break;
4790  case 63: // ONEOF_ENUM:
4791  if (wireType == WireFormat.WIRETYPE_VARINT) {
4792  position = decodeVarint32(data, position, registers);
4793  final int enumValue = registers.int1;
4794  EnumVerifier enumVerifier = getEnumFieldVerifier(bufferPosition);
4795  if (enumVerifier == null || enumVerifier.isInRange(enumValue)) {
4796  unsafe.putObject(message, fieldOffset, enumValue);
4797  unsafe.putInt(message, oneofCaseOffset, number);
4798  } else {
4799  // UnknownFieldSetLite requires varint to be represented as Long.
4800  getMutableUnknownFields(message).storeField(tag, (long) enumValue);
4801  }
4802  }
4803  break;
4804  case 66: // ONEOF_SINT32:
4805  if (wireType == WireFormat.WIRETYPE_VARINT) {
4806  position = decodeVarint32(data, position, registers);
4807  unsafe.putObject(message, fieldOffset, CodedInputStream.decodeZigZag32(registers.int1));
4808  unsafe.putInt(message, oneofCaseOffset, number);
4809  }
4810  break;
4811  case 67: // ONEOF_SINT64:
4812  if (wireType == WireFormat.WIRETYPE_VARINT) {
4813  position = decodeVarint64(data, position, registers);
4814  unsafe.putObject(message, fieldOffset, CodedInputStream.decodeZigZag64(registers.long1));
4815  unsafe.putInt(message, oneofCaseOffset, number);
4816  }
4817  break;
4818  case 68: // ONEOF_GROUP:
4819  if (wireType == WireFormat.WIRETYPE_START_GROUP) {
4820  final int endTag = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP;
4821  position =
4822  decodeGroupField(
4823  getMessageFieldSchema(bufferPosition), data, position, limit, endTag, registers);
4824  final Object oldValue =
4825  unsafe.getInt(message, oneofCaseOffset) == number
4826  ? unsafe.getObject(message, fieldOffset)
4827  : null;
4828  if (oldValue == null) {
4829  unsafe.putObject(message, fieldOffset, registers.object1);
4830  } else {
4831  unsafe.putObject(
4832  message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1));
4833  }
4834  unsafe.putInt(message, oneofCaseOffset, number);
4835  }
4836  break;
4837  default:
4838  break;
4839  }
4840  return position;
4841  }
4842 
4843  private Schema getMessageFieldSchema(int pos) {
4844  final int index = pos / INTS_PER_FIELD * 2;
4845  Schema schema = (Schema) objects[index];
4846  if (schema != null) {
4847  return schema;
4848  }
4849  schema = Protobuf.getInstance().schemaFor((Class) objects[index + 1]);
4850  objects[index] = schema;
4851  return schema;
4852  }
4853 
4854  private Object getMapFieldDefaultEntry(int pos) {
4855  return objects[pos / INTS_PER_FIELD * 2];
4856  }
4857 
4858  private EnumVerifier getEnumFieldVerifier(int pos) {
4859  return (EnumVerifier) objects[pos / INTS_PER_FIELD * 2 + 1];
4860  }
4861 
4868  int parseProto2Message(
4869  T message, byte[] data, int position, int limit, int endGroup, Registers registers)
4870  throws IOException {
4871  final sun.misc.Unsafe unsafe = UNSAFE;
4872  int currentPresenceFieldOffset = -1;
4873  int currentPresenceField = 0;
4874  int tag = 0;
4875  int oldNumber = -1;
4876  int pos = 0;
4877  while (position < limit) {
4878  tag = data[position++];
4879  if (tag < 0) {
4880  position = decodeVarint32(tag, data, position, registers);
4881  tag = registers.int1;
4882  }
4883  final int number = tag >>> 3;
4884  final int wireType = tag & 0x7;
4885  if (number > oldNumber) {
4886  pos = positionForFieldNumber(number, pos / INTS_PER_FIELD);
4887  } else {
4888  pos = positionForFieldNumber(number);
4889  }
4890  oldNumber = number;
4891  if (pos == -1) {
4892  // need to reset
4893  pos = 0;
4894  } else {
4895  final int typeAndOffset = buffer[pos + 1];
4896  final int fieldType = type(typeAndOffset);
4897  final long fieldOffset = offset(typeAndOffset);
4898  if (fieldType <= 17) {
4899  // Proto2 optional fields have has-bits.
4900  final int presenceMaskAndOffset = buffer[pos + 2];
4901  final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
4902  final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
4903  // We cache the 32-bit has-bits integer value and only write it back when parsing a field
4904  // using a different has-bits integer.
4905  if (presenceFieldOffset != currentPresenceFieldOffset) {
4906  if (currentPresenceFieldOffset != -1) {
4907  unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField);
4908  }
4909  currentPresenceFieldOffset = presenceFieldOffset;
4910  currentPresenceField = unsafe.getInt(message, (long) presenceFieldOffset);
4911  }
4912  switch (fieldType) {
4913  case 0: // DOUBLE
4914  if (wireType == WireFormat.WIRETYPE_FIXED64) {
4915  UnsafeUtil.putDouble(message, fieldOffset, decodeDouble(data, position));
4916  position += 8;
4917  currentPresenceField |= presenceMask;
4918  continue;
4919  }
4920  break;
4921  case 1: // FLOAT
4922  if (wireType == WireFormat.WIRETYPE_FIXED32) {
4923  UnsafeUtil.putFloat(message, fieldOffset, decodeFloat(data, position));
4924  position += 4;
4925  currentPresenceField |= presenceMask;
4926  continue;
4927  }
4928  break;
4929  case 2: // INT64
4930  case 3: // UINT64
4931  if (wireType == WireFormat.WIRETYPE_VARINT) {
4932  position = decodeVarint64(data, position, registers);
4933  unsafe.putLong(message, fieldOffset, registers.long1);
4934  currentPresenceField |= presenceMask;
4935  continue;
4936  }
4937  break;
4938  case 4: // INT32
4939  case 11: // UINT32
4940  if (wireType == WireFormat.WIRETYPE_VARINT) {
4941  position = decodeVarint32(data, position, registers);
4942  unsafe.putInt(message, fieldOffset, registers.int1);
4943  currentPresenceField |= presenceMask;
4944  continue;
4945  }
4946  break;
4947  case 5: // FIXED64
4948  case 14: // SFIXED64
4949  if (wireType == WireFormat.WIRETYPE_FIXED64) {
4950  unsafe.putLong(message, fieldOffset, decodeFixed64(data, position));
4951  position += 8;
4952  currentPresenceField |= presenceMask;
4953  continue;
4954  }
4955  break;
4956  case 6: // FIXED32
4957  case 13: // SFIXED32
4958  if (wireType == WireFormat.WIRETYPE_FIXED32) {
4959  unsafe.putInt(message, fieldOffset, decodeFixed32(data, position));
4960  position += 4;
4961  currentPresenceField |= presenceMask;
4962  continue;
4963  }
4964  break;
4965  case 7: // BOOL
4966  if (wireType == WireFormat.WIRETYPE_VARINT) {
4967  position = decodeVarint64(data, position, registers);
4968  UnsafeUtil.putBoolean(message, fieldOffset, registers.long1 != 0);
4969  currentPresenceField |= presenceMask;
4970  continue;
4971  }
4972  break;
4973  case 8: // STRING
4974  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4975  if ((typeAndOffset & ENFORCE_UTF8_MASK) == 0) {
4976  position = decodeString(data, position, registers);
4977  } else {
4978  position = decodeStringRequireUtf8(data, position, registers);
4979  }
4980  unsafe.putObject(message, fieldOffset, registers.object1);
4981  currentPresenceField |= presenceMask;
4982  continue;
4983  }
4984  break;
4985  case 9: // MESSAGE
4986  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
4987  position =
4988  decodeMessageField(
4989  getMessageFieldSchema(pos), data, position, limit, registers);
4990  if ((currentPresenceField & presenceMask) == 0) {
4991  unsafe.putObject(message, fieldOffset, registers.object1);
4992  } else {
4993  unsafe.putObject(
4994  message,
4995  fieldOffset,
4996  Internal.mergeMessage(
4997  unsafe.getObject(message, fieldOffset), registers.object1));
4998  }
4999  currentPresenceField |= presenceMask;
5000  continue;
5001  }
5002  break;
5003  case 10: // BYTES
5004  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
5005  position = decodeBytes(data, position, registers);
5006  unsafe.putObject(message, fieldOffset, registers.object1);
5007  currentPresenceField |= presenceMask;
5008  continue;
5009  }
5010  break;
5011  case 12: // ENUM
5012  if (wireType == WireFormat.WIRETYPE_VARINT) {
5013  position = decodeVarint32(data, position, registers);
5014  final int enumValue = registers.int1;
5015  EnumVerifier enumVerifier = getEnumFieldVerifier(pos);
5016  if (enumVerifier == null || enumVerifier.isInRange(enumValue)) {
5017  unsafe.putInt(message, fieldOffset, enumValue);
5018  currentPresenceField |= presenceMask;
5019  } else {
5020  // UnknownFieldSetLite requires varint to be represented as Long.
5021  getMutableUnknownFields(message).storeField(tag, (long) enumValue);
5022  }
5023  continue;
5024  }
5025  break;
5026  case 15: // SINT32
5027  if (wireType == WireFormat.WIRETYPE_VARINT) {
5028  position = decodeVarint32(data, position, registers);
5029  unsafe.putInt(
5030  message, fieldOffset, CodedInputStream.decodeZigZag32(registers.int1));
5031  currentPresenceField |= presenceMask;
5032  continue;
5033  }
5034  break;
5035  case 16: // SINT64
5036  if (wireType == WireFormat.WIRETYPE_VARINT) {
5037  position = decodeVarint64(data, position, registers);
5038  unsafe.putLong(
5039  message, fieldOffset, CodedInputStream.decodeZigZag64(registers.long1));
5040 
5041  currentPresenceField |= presenceMask;
5042  continue;
5043  }
5044  break;
5045  case 17: // GROUP
5046  if (wireType == WireFormat.WIRETYPE_START_GROUP) {
5047  final int endTag = (number << 3) | WireFormat.WIRETYPE_END_GROUP;
5048  position =
5049  decodeGroupField(
5050  getMessageFieldSchema(pos), data, position, limit, endTag, registers);
5051  if ((currentPresenceField & presenceMask) == 0) {
5052  unsafe.putObject(message, fieldOffset, registers.object1);
5053  } else {
5054  unsafe.putObject(
5055  message,
5056  fieldOffset,
5057  Internal.mergeMessage(
5058  unsafe.getObject(message, fieldOffset), registers.object1));
5059  }
5060 
5061  currentPresenceField |= presenceMask;
5062  continue;
5063  }
5064  break;
5065  default:
5066  break;
5067  }
5068  } else if (fieldType == 27) {
5069  // Handle repeated message fields.
5070  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
5071  ProtobufList<?> list = (ProtobufList<?>) unsafe.getObject(message, fieldOffset);
5072  if (!list.isModifiable()) {
5073  final int size = list.size();
5074  list =
5075  list.mutableCopyWithCapacity(
5076  size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
5077  unsafe.putObject(message, fieldOffset, list);
5078  }
5079  position =
5080  decodeMessageList(
5081  getMessageFieldSchema(pos), tag, data, position, limit, list, registers);
5082  continue;
5083  }
5084  } else if (fieldType <= 49) {
5085  // Handle all other repeated fields.
5086  final int oldPosition = position;
5087  position =
5088  parseRepeatedField(
5089  message,
5090  data,
5091  position,
5092  limit,
5093  tag,
5094  number,
5095  wireType,
5096  pos,
5097  typeAndOffset,
5098  fieldType,
5099  fieldOffset,
5100  registers);
5101  if (position != oldPosition) {
5102  continue;
5103  }
5104  } else if (fieldType == 50) {
5105  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
5106  final int oldPosition = position;
5107  position = parseMapField(message, data, position, limit, pos, fieldOffset, registers);
5108  if (position != oldPosition) {
5109  continue;
5110  }
5111  }
5112  } else {
5113  final int oldPosition = position;
5114  position =
5115  parseOneofField(
5116  message,
5117  data,
5118  position,
5119  limit,
5120  tag,
5121  number,
5122  wireType,
5123  typeAndOffset,
5124  fieldType,
5125  fieldOffset,
5126  pos,
5127  registers);
5128  if (position != oldPosition) {
5129  continue;
5130  }
5131  }
5132  }
5133  if (tag == endGroup && endGroup != 0) {
5134  break;
5135  }
5136 
5137  if (hasExtensions
5138  && registers.extensionRegistry != ExtensionRegistryLite.getEmptyRegistry()) {
5139  position = decodeExtensionOrUnknownField(
5140  tag, data, position, limit, message, defaultInstance,
5141  (UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema,
5142  registers);
5143  } else {
5144  position = decodeUnknownField(
5145  tag, data, position, limit, getMutableUnknownFields(message), registers);
5146  }
5147  }
5148  if (currentPresenceFieldOffset != -1) {
5149  unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField);
5150  }
5151  UnknownFieldSetLite unknownFields = null;
5152  for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) {
5153  unknownFields =
5154  filterMapUnknownEnumValues(
5155  message,
5156  intArray[i],
5157  unknownFields,
5158  (UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema);
5159  }
5160  if (unknownFields != null) {
5161  ((UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema)
5162  .setBuilderToMessage(message, unknownFields);
5163  }
5164  if (endGroup == 0) {
5165  if (position != limit) {
5166  throw InvalidProtocolBufferException.parseFailure();
5167  }
5168  } else {
5169  if (position > limit || tag != endGroup) {
5170  throw InvalidProtocolBufferException.parseFailure();
5171  }
5172  }
5173  return position;
5174  }
5175 
5177  private int parseProto3Message(
5178  T message, byte[] data, int position, int limit, Registers registers) throws IOException {
5179  final sun.misc.Unsafe unsafe = UNSAFE;
5180  int tag = 0;
5181  int oldNumber = -1;
5182  int pos = 0;
5183  while (position < limit) {
5184  tag = data[position++];
5185  if (tag < 0) {
5186  position = decodeVarint32(tag, data, position, registers);
5187  tag = registers.int1;
5188  }
5189  final int number = tag >>> 3;
5190  final int wireType = tag & 0x7;
5191  if (number > oldNumber) {
5192  pos = positionForFieldNumber(number, pos / INTS_PER_FIELD);
5193  } else {
5194  pos = positionForFieldNumber(number);
5195  }
5196  oldNumber = number;
5197  if (pos == -1) {
5198  // need to reset
5199  pos = 0;
5200  } else {
5201  final int typeAndOffset = buffer[pos + 1];
5202  final int fieldType = type(typeAndOffset);
5203  final long fieldOffset = offset(typeAndOffset);
5204  if (fieldType <= 17) {
5205  switch (fieldType) {
5206  case 0: // DOUBLE:
5207  if (wireType == WireFormat.WIRETYPE_FIXED64) {
5208  UnsafeUtil.putDouble(message, fieldOffset, decodeDouble(data, position));
5209  position += 8;
5210  continue;
5211  }
5212  break;
5213  case 1: // FLOAT:
5214  if (wireType == WireFormat.WIRETYPE_FIXED32) {
5215  UnsafeUtil.putFloat(message, fieldOffset, decodeFloat(data, position));
5216  position += 4;
5217  continue;
5218  }
5219  break;
5220  case 2: // INT64:
5221  case 3: // UINT64:
5222  if (wireType == WireFormat.WIRETYPE_VARINT) {
5223  position = decodeVarint64(data, position, registers);
5224  unsafe.putLong(message, fieldOffset, registers.long1);
5225  continue;
5226  }
5227  break;
5228  case 4: // INT32:
5229  case 11: // UINT32:
5230  if (wireType == WireFormat.WIRETYPE_VARINT) {
5231  position = decodeVarint32(data, position, registers);
5232  unsafe.putInt(message, fieldOffset, registers.int1);
5233  continue;
5234  }
5235  break;
5236  case 5: // FIXED64:
5237  case 14: // SFIXED64:
5238  if (wireType == WireFormat.WIRETYPE_FIXED64) {
5239  unsafe.putLong(message, fieldOffset, decodeFixed64(data, position));
5240  position += 8;
5241  continue;
5242  }
5243  break;
5244  case 6: // FIXED32:
5245  case 13: // SFIXED32:
5246  if (wireType == WireFormat.WIRETYPE_FIXED32) {
5247  unsafe.putInt(message, fieldOffset, decodeFixed32(data, position));
5248  position += 4;
5249  continue;
5250  }
5251  break;
5252  case 7: // BOOL:
5253  if (wireType == WireFormat.WIRETYPE_VARINT) {
5254  position = decodeVarint64(data, position, registers);
5255  UnsafeUtil.putBoolean(message, fieldOffset, registers.long1 != 0);
5256  continue;
5257  }
5258  break;
5259  case 8: // STRING:
5260  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
5261  if ((typeAndOffset & ENFORCE_UTF8_MASK) == 0) {
5262  position = decodeString(data, position, registers);
5263  } else {
5264  position = decodeStringRequireUtf8(data, position, registers);
5265  }
5266  unsafe.putObject(message, fieldOffset, registers.object1);
5267  continue;
5268  }
5269  break;
5270  case 9: // MESSAGE:
5271  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
5272  position =
5273  decodeMessageField(
5274  getMessageFieldSchema(pos), data, position, limit, registers);
5275  final Object oldValue = unsafe.getObject(message, fieldOffset);
5276  if (oldValue == null) {
5277  unsafe.putObject(message, fieldOffset, registers.object1);
5278  } else {
5279  unsafe.putObject(
5280  message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1));
5281  }
5282  continue;
5283  }
5284  break;
5285  case 10: // BYTES:
5286  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
5287  position = decodeBytes(data, position, registers);
5288  unsafe.putObject(message, fieldOffset, registers.object1);
5289  continue;
5290  }
5291  break;
5292  case 12: // ENUM:
5293  if (wireType == WireFormat.WIRETYPE_VARINT) {
5294  position = decodeVarint32(data, position, registers);
5295  unsafe.putInt(message, fieldOffset, registers.int1);
5296  continue;
5297  }
5298  break;
5299  case 15: // SINT32:
5300  if (wireType == WireFormat.WIRETYPE_VARINT) {
5301  position = decodeVarint32(data, position, registers);
5302  unsafe.putInt(
5303  message, fieldOffset, CodedInputStream.decodeZigZag32(registers.int1));
5304  continue;
5305  }
5306  break;
5307  case 16: // SINT64:
5308  if (wireType == WireFormat.WIRETYPE_VARINT) {
5309  position = decodeVarint64(data, position, registers);
5310  unsafe.putLong(
5311  message, fieldOffset, CodedInputStream.decodeZigZag64(registers.long1));
5312  continue;
5313  }
5314  break;
5315  default:
5316  break;
5317  }
5318  } else if (fieldType == 27) {
5319  // Handle repeated message field.
5320  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
5321  ProtobufList<?> list = (ProtobufList<?>) unsafe.getObject(message, fieldOffset);
5322  if (!list.isModifiable()) {
5323  final int size = list.size();
5324  list =
5325  list.mutableCopyWithCapacity(
5326  size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
5327  unsafe.putObject(message, fieldOffset, list);
5328  }
5329  position =
5330  decodeMessageList(
5331  getMessageFieldSchema(pos), tag, data, position, limit, list, registers);
5332  continue;
5333  }
5334  } else if (fieldType <= 49) {
5335  // Handle all other repeated fields.
5336  final int oldPosition = position;
5337  position =
5338  parseRepeatedField(
5339  message,
5340  data,
5341  position,
5342  limit,
5343  tag,
5344  number,
5345  wireType,
5346  pos,
5347  typeAndOffset,
5348  fieldType,
5349  fieldOffset,
5350  registers);
5351  if (position != oldPosition) {
5352  continue;
5353  }
5354  } else if (fieldType == 50) {
5355  if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
5356  final int oldPosition = position;
5357  position = parseMapField(message, data, position, limit, pos, fieldOffset, registers);
5358  if (position != oldPosition) {
5359  continue;
5360  }
5361  }
5362  } else {
5363  final int oldPosition = position;
5364  position =
5365  parseOneofField(
5366  message,
5367  data,
5368  position,
5369  limit,
5370  tag,
5371  number,
5372  wireType,
5373  typeAndOffset,
5374  fieldType,
5375  fieldOffset,
5376  pos,
5377  registers);
5378  if (position != oldPosition) {
5379  continue;
5380  }
5381  }
5382  }
5383  position = decodeUnknownField(
5384  tag, data, position, limit, getMutableUnknownFields(message), registers);
5385  }
5386  if (position != limit) {
5387  throw InvalidProtocolBufferException.parseFailure();
5388  }
5389  return position;
5390  }
5391 
5392  @Override
5393  public void mergeFrom(T message, byte[] data, int position, int limit, Registers registers)
5394  throws IOException {
5395  if (proto3) {
5396  parseProto3Message(message, data, position, limit, registers);
5397  } else {
5398  parseProto2Message(message, data, position, limit, 0, registers);
5399  }
5400  }
5401 
5402  @Override
5403  public void makeImmutable(T message) {
5404  // Make all repeated/map fields immutable.
5405  for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) {
5406  long offset = offset(typeAndOffsetAt(intArray[i]));
5407  Object mapField = UnsafeUtil.getObject(message, offset);
5408  if (mapField == null) {
5409  continue;
5410  }
5411  UnsafeUtil.putObject(message, offset, mapFieldSchema.toImmutable(mapField));
5412  }
5413  final int length = intArray.length;
5414  for (int i = repeatedFieldOffsetStart; i < length; i++) {
5415  listFieldSchema.makeImmutableListAt(message, intArray[i]);
5416  }
5417  unknownFieldSchema.makeImmutable(message);
5418  if (hasExtensions) {
5419  extensionSchema.makeImmutable(message);
5420  }
5421  }
5422 
5423  @SuppressWarnings("unchecked")
5424  private final <K, V> void mergeMap(
5425  Object message,
5426  int pos,
5427  Object mapDefaultEntry,
5428  ExtensionRegistryLite extensionRegistry,
5429  Reader reader)
5430  throws IOException {
5431  long offset = offset(typeAndOffsetAt(pos));
5432  Object mapField = UnsafeUtil.getObject(message, offset);
5433  // TODO(xiaofeng): Consider creating separate implementations for full and lite. In lite
5434  // runtime map field will never be null but here we still need to check null because the
5435  // code is shared by both full and lite. It might be better if full/lite uses different
5436  // schema implementations.
5437  if (mapField == null) {
5438  mapField = mapFieldSchema.newMapField(mapDefaultEntry);
5439  UnsafeUtil.putObject(message, offset, mapField);
5440  } else if (mapFieldSchema.isImmutable(mapField)) {
5441  Object oldMapField = mapField;
5442  mapField = mapFieldSchema.newMapField(mapDefaultEntry);
5443  mapFieldSchema.mergeFrom(mapField, oldMapField);
5444  UnsafeUtil.putObject(message, offset, mapField);
5445  }
5446  reader.readMap(
5447  (Map<K, V>) mapFieldSchema.forMutableMapData(mapField),
5448  (Metadata<K, V>) mapFieldSchema.forMapMetadata(mapDefaultEntry),
5449  extensionRegistry);
5450  }
5451 
5452  private final <UT, UB> UB filterMapUnknownEnumValues(
5453  Object message, int pos, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema) {
5454  int fieldNumber = numberAt(pos);
5455  long offset = offset(typeAndOffsetAt(pos));
5456  Object mapField = UnsafeUtil.getObject(message, offset);
5457  if (mapField == null) {
5458  return unknownFields;
5459  }
5460  EnumVerifier enumVerifier = getEnumFieldVerifier(pos);
5461  if (enumVerifier == null) {
5462  return unknownFields;
5463  }
5464  Map<?, ?> mapData = mapFieldSchema.forMutableMapData(mapField);
5465  // Filter unknown enum values.
5466  unknownFields =
5467  filterUnknownEnumMap(
5468  pos, fieldNumber, mapData, enumVerifier, unknownFields, unknownFieldSchema);
5469  return unknownFields;
5470  }
5471 
5472  @SuppressWarnings("unchecked")
5473  private final <K, V, UT, UB> UB filterUnknownEnumMap(
5474  int pos,
5475  int number,
5476  Map<K, V> mapData,
5477  EnumVerifier enumVerifier,
5478  UB unknownFields,
5479  UnknownFieldSchema<UT, UB> unknownFieldSchema) {
5480  Metadata<K, V> metadata =
5481  (Metadata<K, V>) mapFieldSchema.forMapMetadata(getMapFieldDefaultEntry(pos));
5482  for (Iterator<Map.Entry<K, V>> it = mapData.entrySet().iterator(); it.hasNext(); ) {
5483  Map.Entry<K, V> entry = it.next();
5484  if (!enumVerifier.isInRange((Integer) entry.getValue())) {
5485  if (unknownFields == null) {
5486  unknownFields = unknownFieldSchema.newBuilder();
5487  }
5488  int entrySize =
5489  MapEntryLite.computeSerializedSize(metadata, entry.getKey(), entry.getValue());
5490  CodedBuilder codedBuilder = ByteString.newCodedBuilder(entrySize);
5491  CodedOutputStream codedOutput = codedBuilder.getCodedOutput();
5492  try {
5493  MapEntryLite.writeTo(codedOutput, metadata, entry.getKey(), entry.getValue());
5494  } catch (IOException e) {
5495  // Writing to ByteString CodedOutputStream should not throw IOException.
5496  throw new RuntimeException(e);
5497  }
5498  unknownFieldSchema.addLengthDelimited(unknownFields, number, codedBuilder.build());
5499  it.remove();
5500  }
5501  }
5502  return unknownFields;
5503  }
5504 
5505  @Override
5506  public final boolean isInitialized(T message) {
5507  int currentPresenceFieldOffset = -1;
5508  int currentPresenceField = 0;
5509  for (int i = 0; i < checkInitializedCount; i++) {
5510  final int pos = intArray[i];
5511  final int number = numberAt(pos);
5512 
5513  final int typeAndOffset = typeAndOffsetAt(pos);
5514 
5515  int presenceMaskAndOffset = 0;
5516  int presenceMask = 0;
5517  if (!proto3) {
5518  presenceMaskAndOffset = buffer[pos + 2];
5519  final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
5520  presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
5521  if (presenceFieldOffset != currentPresenceFieldOffset) {
5522  currentPresenceFieldOffset = presenceFieldOffset;
5523  currentPresenceField = UNSAFE.getInt(message, (long) presenceFieldOffset);
5524  }
5525  }
5526 
5527  if (isRequired(typeAndOffset)) {
5528  if (!isFieldPresent(message, pos, currentPresenceField, presenceMask)) {
5529  return false;
5530  }
5531  // If a required message field is set but has no required fields of it's own, we still
5532  // proceed and check the message is initialized. It should be fairly cheap to check these
5533  // messages but is worth documenting.
5534  }
5535  // Check nested message and groups.
5536  switch (type(typeAndOffset)) {
5537  case 9: // MESSAGE
5538  case 17: // GROUP
5539  if (isFieldPresent(message, pos, currentPresenceField, presenceMask)
5540  && !isInitialized(message, typeAndOffset, getMessageFieldSchema(pos))) {
5541  return false;
5542  }
5543  break;
5544  case 27: // MESSAGE_LIST
5545  case 49: // GROUP_LIST
5546  if (!isListInitialized(message, typeAndOffset, pos)) {
5547  return false;
5548  }
5549  break;
5550  case 60: // ONEOF_MESSAGE
5551  case 68: // ONEOF_GROUP
5552  if (isOneofPresent(message, number, pos)
5553  && !isInitialized(message, typeAndOffset, getMessageFieldSchema(pos))) {
5554  return false;
5555  }
5556  break;
5557  case 50: // MAP
5558  if (!isMapInitialized(message, typeAndOffset, pos)) {
5559  return false;
5560  }
5561  break;
5562  default:
5563  break;
5564  }
5565  }
5566 
5567  if (hasExtensions) {
5568  if (!extensionSchema.getExtensions(message).isInitialized()) {
5569  return false;
5570  }
5571  }
5572 
5573  return true;
5574  }
5575 
5576  private static boolean isInitialized(Object message, int typeAndOffset, Schema schema) {
5577  Object nested = UnsafeUtil.getObject(message, offset(typeAndOffset));
5578  return schema.isInitialized(nested);
5579  }
5580 
5581  private <N> boolean isListInitialized(Object message, int typeAndOffset, int pos) {
5582  @SuppressWarnings("unchecked")
5583  List<N> list = (List<N>) UnsafeUtil.getObject(message, offset(typeAndOffset));
5584  if (list.isEmpty()) {
5585  return true;
5586  }
5587 
5588  Schema schema = getMessageFieldSchema(pos);
5589  for (int i = 0; i < list.size(); i++) {
5590  N nested = list.get(i);
5591  if (!schema.isInitialized(nested)) {
5592  return false;
5593  }
5594  }
5595  return true;
5596  }
5597 
5598  private boolean isMapInitialized(T message, int typeAndOffset, int pos) {
5599  Map<?, ?> map = mapFieldSchema.forMapData(UnsafeUtil.getObject(message, offset(typeAndOffset)));
5600  if (map.isEmpty()) {
5601  return true;
5602  }
5603  Object mapDefaultEntry = getMapFieldDefaultEntry(pos);
5604  MapEntryLite.Metadata<?, ?> metadata = mapFieldSchema.forMapMetadata(mapDefaultEntry);
5605  if (metadata.valueType.getJavaType() != WireFormat.JavaType.MESSAGE) {
5606  return true;
5607  }
5608  // TODO(dweis): Use schema cache.
5609  Schema schema = null;
5610  for (Object nested : map.values()) {
5611  if (schema == null) {
5612  schema = Protobuf.getInstance().schemaFor(nested.getClass());
5613  }
5614  if (!schema.isInitialized(nested)) {
5615  return false;
5616  }
5617  }
5618  return true;
5619  }
5620 
5621  private void writeString(int fieldNumber, Object value, Writer writer) throws IOException {
5622  if (value instanceof String) {
5623  writer.writeString(fieldNumber, (String) value);
5624  } else {
5625  writer.writeBytes(fieldNumber, (ByteString) value);
5626  }
5627  }
5628 
5629  private void readString(Object message, int typeAndOffset, Reader reader) throws IOException {
5630  if (isEnforceUtf8(typeAndOffset)) {
5631  // Enforce valid UTF-8 on the read.
5632  UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readStringRequireUtf8());
5633  } else if (lite) {
5634  // Lite messages use String fields to store strings. Read a string but do not
5635  // enforce UTF-8
5636  UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readString());
5637  } else {
5638  // Full runtime messages use Objects to store either a String or ByteString. Read
5639  // the string as a ByteString and do not enforce UTF-8.
5640  UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes());
5641  }
5642  }
5643 
5644  private void readStringList(Object message, int typeAndOffset, Reader reader) throws IOException {
5645  if (isEnforceUtf8(typeAndOffset)) {
5646  reader.readStringListRequireUtf8(
5647  listFieldSchema.<String>mutableListAt(message, offset(typeAndOffset)));
5648  } else {
5649  reader.readStringList(listFieldSchema.<String>mutableListAt(message, offset(typeAndOffset)));
5650  }
5651  }
5652 
5653  private <E> void readMessageList(
5654  Object message,
5655  int typeAndOffset,
5656  Reader reader,
5657  Schema<E> schema,
5658  ExtensionRegistryLite extensionRegistry)
5659  throws IOException {
5660  long offset = offset(typeAndOffset);
5661  reader.readMessageList(
5662  listFieldSchema.<E>mutableListAt(message, offset), schema, extensionRegistry);
5663  }
5664 
5665  private <E> void readGroupList(
5666  Object message,
5667  long offset,
5668  Reader reader,
5669  Schema<E> schema,
5670  ExtensionRegistryLite extensionRegistry)
5671  throws IOException {
5672  reader.readGroupList(
5673  listFieldSchema.<E>mutableListAt(message, offset), schema, extensionRegistry);
5674  }
5675 
5676  private int numberAt(int pos) {
5677  return buffer[pos];
5678  }
5679 
5680  private int typeAndOffsetAt(int pos) {
5681  return buffer[pos + 1];
5682  }
5683 
5684  private int presenceMaskAndOffsetAt(int pos) {
5685  return buffer[pos + 2];
5686  }
5687 
5688  private static int type(int value) {
5689  return (value & FIELD_TYPE_MASK) >>> OFFSET_BITS;
5690  }
5691 
5692  private static boolean isRequired(int value) {
5693  return (value & REQUIRED_MASK) != 0;
5694  }
5695 
5696  private static boolean isEnforceUtf8(int value) {
5697  return (value & ENFORCE_UTF8_MASK) != 0;
5698  }
5699 
5700  private static long offset(int value) {
5701  return value & OFFSET_MASK;
5702  }
5703 
5704  private static <T> double doubleAt(T message, long offset) {
5705  return UnsafeUtil.getDouble(message, offset);
5706  }
5707 
5708  private static <T> float floatAt(T message, long offset) {
5709  return UnsafeUtil.getFloat(message, offset);
5710  }
5711 
5712  private static <T> int intAt(T message, long offset) {
5713  return UnsafeUtil.getInt(message, offset);
5714  }
5715 
5716  private static <T> long longAt(T message, long offset) {
5717  return UnsafeUtil.getLong(message, offset);
5718  }
5719 
5720  private static <T> boolean booleanAt(T message, long offset) {
5721  return UnsafeUtil.getBoolean(message, offset);
5722  }
5723 
5724  private static <T> double oneofDoubleAt(T message, long offset) {
5725  return ((Double) UnsafeUtil.getObject(message, offset)).doubleValue();
5726  }
5727 
5728  private static <T> float oneofFloatAt(T message, long offset) {
5729  return ((Float) UnsafeUtil.getObject(message, offset)).floatValue();
5730  }
5731 
5732  private static <T> int oneofIntAt(T message, long offset) {
5733  return ((Integer) UnsafeUtil.getObject(message, offset)).intValue();
5734  }
5735 
5736  private static <T> long oneofLongAt(T message, long offset) {
5737  return ((Long) UnsafeUtil.getObject(message, offset)).longValue();
5738  }
5739 
5740  private static <T> boolean oneofBooleanAt(T message, long offset) {
5741  return ((Boolean) UnsafeUtil.getObject(message, offset)).booleanValue();
5742  }
5743 
5745  private boolean arePresentForEquals(T message, T other, int pos) {
5746  return isFieldPresent(message, pos) == isFieldPresent(other, pos);
5747  }
5748 
5749  private boolean isFieldPresent(T message, int pos, int presenceField, int presenceMask) {
5750  if (proto3) {
5751  return isFieldPresent(message, pos);
5752  } else {
5753  return (presenceField & presenceMask) != 0;
5754  }
5755  }
5756 
5757  private boolean isFieldPresent(T message, int pos) {
5758  if (proto3) {
5759  final int typeAndOffset = typeAndOffsetAt(pos);
5760  final long offset = offset(typeAndOffset);
5761  switch (type(typeAndOffset)) {
5762  case 0: // DOUBLE:
5763  return UnsafeUtil.getDouble(message, offset) != 0D;
5764  case 1: // FLOAT:
5765  return UnsafeUtil.getFloat(message, offset) != 0F;
5766  case 2: // INT64:
5767  return UnsafeUtil.getLong(message, offset) != 0L;
5768  case 3: // UINT64:
5769  return UnsafeUtil.getLong(message, offset) != 0L;
5770  case 4: // INT32:
5771  return UnsafeUtil.getInt(message, offset) != 0;
5772  case 5: // FIXED64:
5773  return UnsafeUtil.getLong(message, offset) != 0L;
5774  case 6: // FIXED32:
5775  return UnsafeUtil.getInt(message, offset) != 0;
5776  case 7: // BOOL:
5777  return UnsafeUtil.getBoolean(message, offset);
5778  case 8: // STRING:
5779  Object value = UnsafeUtil.getObject(message, offset);
5780  if (value instanceof String) {
5781  return !((String) value).isEmpty();
5782  } else if (value instanceof ByteString) {
5783  return !ByteString.EMPTY.equals(value);
5784  } else {
5785  throw new IllegalArgumentException();
5786  }
5787  case 9: // MESSAGE:
5788  return UnsafeUtil.getObject(message, offset) != null;
5789  case 10: // BYTES:
5790  return !ByteString.EMPTY.equals(UnsafeUtil.getObject(message, offset));
5791  case 11: // UINT32:
5792  return UnsafeUtil.getInt(message, offset) != 0;
5793  case 12: // ENUM:
5794  return UnsafeUtil.getInt(message, offset) != 0;
5795  case 13: // SFIXED32:
5796  return UnsafeUtil.getInt(message, offset) != 0;
5797  case 14: // SFIXED64:
5798  return UnsafeUtil.getLong(message, offset) != 0L;
5799  case 15: // SINT32:
5800  return UnsafeUtil.getInt(message, offset) != 0;
5801  case 16: // SINT64:
5802  return UnsafeUtil.getLong(message, offset) != 0L;
5803  case 17: // GROUP:
5804  return UnsafeUtil.getObject(message, offset) != null;
5805  default:
5806  throw new IllegalArgumentException();
5807  }
5808  } else {
5809  int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
5810  final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
5811  return (UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK) & presenceMask) != 0;
5812  }
5813  }
5814 
5815  private void setFieldPresent(T message, int pos) {
5816  if (proto3) {
5817  // Proto3 doesn't have presence fields
5818  return;
5819  }
5820  int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
5821  final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
5822  final long presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
5823  UnsafeUtil.putInt(
5824  message,
5825  presenceFieldOffset,
5826  UnsafeUtil.getInt(message, presenceFieldOffset) | presenceMask);
5827  }
5828 
5829  private boolean isOneofPresent(T message, int fieldNumber, int pos) {
5830  int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
5831  return UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK) == fieldNumber;
5832  }
5833 
5834  private boolean isOneofCaseEqual(T message, T other, int pos) {
5835  int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
5836  return UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK)
5837  == UnsafeUtil.getInt(other, presenceMaskAndOffset & OFFSET_MASK);
5838  }
5839 
5840  private void setOneofPresent(T message, int fieldNumber, int pos) {
5841  int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos);
5842  UnsafeUtil.putInt(message, presenceMaskAndOffset & OFFSET_MASK, fieldNumber);
5843  }
5844 
5845  private int positionForFieldNumber(final int number) {
5846  if (number >= minFieldNumber && number <= maxFieldNumber) {
5847  return slowPositionForFieldNumber(number, 0);
5848  }
5849  return -1;
5850  }
5851 
5852  private int positionForFieldNumber(final int number, final int min) {
5853  if (number >= minFieldNumber && number <= maxFieldNumber) {
5854  return slowPositionForFieldNumber(number, min);
5855  }
5856  return -1;
5857  }
5858 
5859  private int slowPositionForFieldNumber(final int number, int min) {
5860  int max = buffer.length / INTS_PER_FIELD - 1;
5861  while (min <= max) {
5862  // Find the midpoint address.
5863  final int mid = (max + min) >>> 1;
5864  final int pos = mid * INTS_PER_FIELD;
5865  final int midFieldNumber = numberAt(pos);
5866  if (number == midFieldNumber) {
5867  // Found the field.
5868  return pos;
5869  }
5870  if (number < midFieldNumber) {
5871  // Search the lower half.
5872  max = mid - 1;
5873  } else {
5874  // Search the upper half.
5875  min = mid + 1;
5876  }
5877  }
5878  return -1;
5879  }
5880 
5881  int getSchemaSize() {
5882  return buffer.length * 3;
5883  }
5884 }
java::lang
K
#define K(t)
Definition: sha1.c:43
Json::writeString
std::string JSON_API writeString(StreamWriter::Factory const &factory, Value const &root)
Write into stringstream, then return string, for convenience. A StreamWriter will be created from the...
Definition: jsoncpp.cpp:5169
Map
Definition: ruby/ext/google/protobuf_c/protobuf.h:442
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: src/google/protobuf/descriptor.h:2001
end
GLuint GLuint end
Definition: glcorearb.h:2858
com.google.protobuf.MapEntryLite.Metadata
Definition: MapEntryLite.java:47
length
GLenum GLuint GLenum GLsizei length
Definition: glcorearb.h:2695
com.google.protobuf.ArrayDecoders
Definition: ArrayDecoders.java:46
merged
static bool merged(const upb_refcounted *r, const upb_refcounted *r2)
Definition: ruby/ext/google/protobuf_c/upb.c:6184
bufferIndex
GLuint bufferIndex
Definition: glcorearb.h:4257
com.google.protobuf.ArrayDecoders.Registers
Definition: ArrayDecoders.java:56
benchmarks.util.result_uploader.metadata
def metadata
Definition: result_uploader.py:97
if
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END if(!upb_strtable_init(&intern->table, UPB_CTYPE_UINT64))
Definition: php/ext/google/protobuf/map.c:232
com.google.protobuf
Definition: ProtoCaliperBenchmark.java:2
target
GLenum target
Definition: glcorearb.h:3739
java::lang::reflect
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:473
T
#define T(upbtypeconst, upbtype, ctype, default_value)
flags
GLbitfield flags
Definition: glcorearb.h:3585
testing::internal::Double
FloatingPoint< double > Double
Definition: gtest-internal.h:429
testing::internal::Float
FloatingPoint< float > Float
Definition: gtest-internal.h:428
offset
GLintptr offset
Definition: glcorearb.h:2944
buffer
GLuint buffer
Definition: glcorearb.h:2939
buffer::length
size_t length
Definition: buffer_processor.h:45
isInitialized
ROSCPP_DECL bool isInitialized()
size
#define size
Definition: glcorearb.h:2944
buffer
Definition: buffer_processor.h:43
F
#define F(msg, field)
Definition: ruby/ext/google/protobuf_c/upb.c:9347
position
intern position
Definition: array.c:487
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
key
const SETUP_TEARDOWN_TESTCONTEXT char * key
Definition: test_wss_transport.cpp:10
com.google.protobuf.Internal.EnumVerifier
Definition: Internal.java:215
i
int i
Definition: gmock-matchers_test.cc:764
java
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
type
GLenum type
Definition: glcorearb.h:2695
com.google.protobuf.FieldSet
Definition: FieldSet.java:51
com.google.protobuf.Internal.ProtobufList
Definition: Internal.java:570
size
GLsizeiptr size
Definition: glcorearb.h:2943
com.google
com.google.protobuf.MapEntryLite
Definition: MapEntryLite.java:45
com
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
com.google.protobuf.Internal
Definition: Internal.java:54
next
static size_t next(const upb_table *t, size_t i)
Definition: php/ext/google/protobuf/upb.c:4889
Field
Definition: type.pb.h:416
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
google::protobuf.internal::FieldType
uint8 FieldType
Definition: extension_set.h:87
index
GLuint index
Definition: glcorearb.h:3055
number
double number
Definition: cJSON.h:326
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
com.google.protobuf.FieldSet.FieldDescriptorLite
Definition: FieldSet.java:57
com.google.protobuf.ByteString
Definition: ByteString.java:67


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:57