public int getSerializedSize()

in extra/protobuf/protobuf-24.4/java/core/src/main/java/com/google/protobuf/MessageSchema.java [1488:2080]


  public int getSerializedSize(T message) {
    int size = 0;

    final sun.misc.Unsafe unsafe = UNSAFE;
    int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL;
    int currentPresenceField = 0;
    for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) {
      final int typeAndOffset = typeAndOffsetAt(i);
      final int fieldType = type(typeAndOffset);
      final int number = numberAt(i);

      int presenceMask = 0;
      int presenceMaskAndOffset = buffer[i + 2];
      final int presenceOrCachedSizeFieldOffset = presenceMaskAndOffset & OFFSET_MASK;
      if (fieldType <= 17) {
        // Performance optimization to cache the presence field which is shared for multiple
        // fields.
        // TODO(b/279034699): Improve caching for case when fields alternate between having and not
        // having presence by caching presence field for last field with presence only.
        if (presenceOrCachedSizeFieldOffset != currentPresenceFieldOffset) {
          currentPresenceFieldOffset = presenceOrCachedSizeFieldOffset;
          currentPresenceField =
              currentPresenceFieldOffset == NO_PRESENCE_SENTINEL
                  ? 0
                  : unsafe.getInt(message, (long) currentPresenceFieldOffset);
        }
        // Mask for presence bit of the current field from the shared presence field.
        presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS);
      }

      final long offset = offset(typeAndOffset);
      final int cachedSizeOffset =
          fieldType >= FieldType.DOUBLE_LIST_PACKED.id()
                  && fieldType <= FieldType.SINT64_LIST_PACKED.id()
              ? presenceOrCachedSizeFieldOffset
              : 0;

      switch (fieldType) {
        case 0: // DOUBLE:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeDoubleSize(number, 0);
          }
          break;
        case 1: // FLOAT:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeFloatSize(number, 0);
          }
          break;
        case 2: // INT64:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeInt64Size(number, unsafe.getLong(message, offset));
          }
          break;
        case 3: // UINT64:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeUInt64Size(number, unsafe.getLong(message, offset));
          }
          break;
        case 4: // INT32:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeInt32Size(number, unsafe.getInt(message, offset));
          }
          break;
        case 5: // FIXED64:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeFixed64Size(number, 0);
          }
          break;
        case 6: // FIXED32:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeFixed32Size(number, 0);
          }
          break;
        case 7: // BOOL:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeBoolSize(number, true);
          }
          break;
        case 8: // STRING:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            Object value = unsafe.getObject(message, offset);
            if (value instanceof ByteString) {
              size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
            } else {
              size += CodedOutputStream.computeStringSize(number, (String) value);
            }
          }
          break;
        case 9: // MESSAGE:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            Object value = unsafe.getObject(message, offset);
            size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
          }
          break;
        case 10: // BYTES:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            ByteString value = (ByteString) unsafe.getObject(message, offset);
            size += CodedOutputStream.computeBytesSize(number, value);
          }
          break;
        case 11: // UINT32:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeUInt32Size(number, unsafe.getInt(message, offset));
          }
          break;
        case 12: // ENUM:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeEnumSize(number, unsafe.getInt(message, offset));
          }
          break;
        case 13: // SFIXED32:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeSFixed32Size(number, 0);
          }
          break;
        case 14: // SFIXED64:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeSFixed64Size(number, 0);
          }
          break;
        case 15: // SINT32:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeSInt32Size(number, unsafe.getInt(message, offset));
          }
          break;
        case 16: // SINT64:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size += CodedOutputStream.computeSInt64Size(number, unsafe.getLong(message, offset));
          }
          break;
        case 17: // GROUP:
          if (isFieldPresent(
              message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) {
            size +=
                CodedOutputStream.computeGroupSize(
                    number,
                    (MessageLite) unsafe.getObject(message, offset),
                    getMessageFieldSchema(i));
          }
          break;
        case 18: // DOUBLE_LIST:
          size +=
              SchemaUtil.computeSizeFixed64List(
                  number, (List<?>) unsafe.getObject(message, offset), false);
          break;
        case 19: // FLOAT_LIST:
          size +=
              SchemaUtil.computeSizeFixed32List(
                  number, (List<?>) unsafe.getObject(message, offset), false);
          break;
        case 20: // INT64_LIST:
          size +=
              SchemaUtil.computeSizeInt64List(
                  number, (List<Long>) unsafe.getObject(message, offset), false);
          break;
        case 21: // UINT64_LIST:
          size +=
              SchemaUtil.computeSizeUInt64List(
                  number, (List<Long>) unsafe.getObject(message, offset), false);
          break;
        case 22: // INT32_LIST:
          size +=
              SchemaUtil.computeSizeInt32List(
                  number, (List<Integer>) unsafe.getObject(message, offset), false);
          break;
        case 23: // FIXED64_LIST:
          size +=
              SchemaUtil.computeSizeFixed64List(
                  number, (List<?>) unsafe.getObject(message, offset), false);
          break;
        case 24: // FIXED32_LIST:
          size +=
              SchemaUtil.computeSizeFixed32List(
                  number, (List<?>) unsafe.getObject(message, offset), false);
          break;
        case 25: // BOOL_LIST:
          size +=
              SchemaUtil.computeSizeBoolList(
                  number, (List<?>) unsafe.getObject(message, offset), false);
          break;
        case 26: // STRING_LIST:
          size +=
              SchemaUtil.computeSizeStringList(number, (List<?>) unsafe.getObject(message, offset));
          break;
        case 27: // MESSAGE_LIST:
          size +=
              SchemaUtil.computeSizeMessageList(
                  number, (List<?>) unsafe.getObject(message, offset), getMessageFieldSchema(i));
          break;
        case 28: // BYTES_LIST:
          size +=
              SchemaUtil.computeSizeByteStringList(
                  number, (List<ByteString>) unsafe.getObject(message, offset));
          break;
        case 29: // UINT32_LIST:
          size +=
              SchemaUtil.computeSizeUInt32List(
                  number, (List<Integer>) unsafe.getObject(message, offset), false);
          break;
        case 30: // ENUM_LIST:
          size +=
              SchemaUtil.computeSizeEnumList(
                  number, (List<Integer>) unsafe.getObject(message, offset), false);
          break;
        case 31: // SFIXED32_LIST:
          size +=
              SchemaUtil.computeSizeFixed32List(
                  number, (List<Integer>) unsafe.getObject(message, offset), false);
          break;
        case 32: // SFIXED64_LIST:
          size +=
              SchemaUtil.computeSizeFixed64List(
                  number, (List<Long>) unsafe.getObject(message, offset), false);
          break;
        case 33: // SINT32_LIST:
          size +=
              SchemaUtil.computeSizeSInt32List(
                  number, (List<Integer>) unsafe.getObject(message, offset), false);
          break;
        case 34: // SINT64_LIST:
          size +=
              SchemaUtil.computeSizeSInt64List(
                  number, (List<Long>) unsafe.getObject(message, offset), false);
          break;
        case 35:
          { // DOUBLE_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeFixed64ListNoTag(
                    (List<Double>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 36:
          { // FLOAT_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeFixed32ListNoTag(
                    (List<Float>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 37:
          { // INT64_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeInt64ListNoTag(
                    (List<Long>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 38:
          { // UINT64_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeUInt64ListNoTag(
                    (List<Long>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 39:
          { // INT32_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeInt32ListNoTag(
                    (List<Integer>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 40:
          { // FIXED64_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeFixed64ListNoTag(
                    (List<Long>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 41:
          { // FIXED32_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeFixed32ListNoTag(
                    (List<Integer>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 42:
          { // BOOL_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeBoolListNoTag(
                    (List<Boolean>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 43:
          { // UINT32_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeUInt32ListNoTag(
                    (List<Integer>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 44:
          { // ENUM_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeEnumListNoTag(
                    (List<Integer>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 45:
          { // SFIXED32_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeFixed32ListNoTag(
                    (List<Integer>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 46:
          { // SFIXED64_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeFixed64ListNoTag(
                    (List<Long>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 47:
          { // SINT32_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeSInt32ListNoTag(
                    (List<Integer>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 48:
          { // SINT64_LIST_PACKED:
            int fieldSize =
                SchemaUtil.computeSizeSInt64ListNoTag(
                    (List<Long>) unsafe.getObject(message, offset));
            if (fieldSize > 0) {
              if (useCachedSizeField) {
                unsafe.putInt(message, (long) cachedSizeOffset, fieldSize);
              }
              size +=
                  CodedOutputStream.computeTagSize(number)
                      + CodedOutputStream.computeUInt32SizeNoTag(fieldSize)
                      + fieldSize;
            }
            break;
          }
        case 49: // GROUP_LIST:
          size +=
              SchemaUtil.computeSizeGroupList(
                  number,
                  (List<MessageLite>) unsafe.getObject(message, offset),
                  getMessageFieldSchema(i));
          break;
        case 50: // MAP:
          // TODO(dweis): Use schema cache.
          size +=
              mapFieldSchema.getSerializedSize(
                  number, unsafe.getObject(message, offset), getMapFieldDefaultEntry(i));
          break;
        case 51: // ONEOF_DOUBLE:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeDoubleSize(number, 0);
          }
          break;
        case 52: // ONEOF_FLOAT:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeFloatSize(number, 0);
          }
          break;
        case 53: // ONEOF_INT64:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeInt64Size(number, oneofLongAt(message, offset));
          }
          break;
        case 54: // ONEOF_UINT64:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeUInt64Size(number, oneofLongAt(message, offset));
          }
          break;
        case 55: // ONEOF_INT32:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeInt32Size(number, oneofIntAt(message, offset));
          }
          break;
        case 56: // ONEOF_FIXED64:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeFixed64Size(number, 0);
          }
          break;
        case 57: // ONEOF_FIXED32:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeFixed32Size(number, 0);
          }
          break;
        case 58: // ONEOF_BOOL:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeBoolSize(number, true);
          }
          break;
        case 59: // ONEOF_STRING:
          if (isOneofPresent(message, number, i)) {
            Object value = unsafe.getObject(message, offset);
            if (value instanceof ByteString) {
              size += CodedOutputStream.computeBytesSize(number, (ByteString) value);
            } else {
              size += CodedOutputStream.computeStringSize(number, (String) value);
            }
          }
          break;
        case 60: // ONEOF_MESSAGE:
          if (isOneofPresent(message, number, i)) {
            Object value = unsafe.getObject(message, offset);
            size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i));
          }
          break;
        case 61: // ONEOF_BYTES:
          if (isOneofPresent(message, number, i)) {
            size +=
                CodedOutputStream.computeBytesSize(
                    number, (ByteString) unsafe.getObject(message, offset));
          }
          break;
        case 62: // ONEOF_UINT32:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeUInt32Size(number, oneofIntAt(message, offset));
          }
          break;
        case 63: // ONEOF_ENUM:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeEnumSize(number, oneofIntAt(message, offset));
          }
          break;
        case 64: // ONEOF_SFIXED32:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeSFixed32Size(number, 0);
          }
          break;
        case 65: // ONEOF_SFIXED64:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeSFixed64Size(number, 0);
          }
          break;
        case 66: // ONEOF_SINT32:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeSInt32Size(number, oneofIntAt(message, offset));
          }
          break;
        case 67: // ONEOF_SINT64:
          if (isOneofPresent(message, number, i)) {
            size += CodedOutputStream.computeSInt64Size(number, oneofLongAt(message, offset));
          }
          break;
        case 68: // ONEOF_GROUP:
          if (isOneofPresent(message, number, i)) {
            size +=
                CodedOutputStream.computeGroupSize(
                    number,
                    (MessageLite) unsafe.getObject(message, offset),
                    getMessageFieldSchema(i));
          }
          break;
        default:
          // Assume it's an empty entry.
      }
    }

    size += getUnknownFieldsSerializedSize(unknownFieldSchema, message);

    if (hasExtensions) {
      size += extensionSchema.getExtensions(message).getSerializedSize();
    }

    return size;
  }