Class MessageSchema<T>

java.lang.Object
com.google.protobuf.MessageSchema<T>
All Implemented Interfaces:
Schema<T>

@CheckReturnValue final class MessageSchema<T> extends Object implements Schema<T>
Schema used for standard messages.
  • Field Details

    • INTS_PER_FIELD

      private static final int INTS_PER_FIELD
      See Also:
    • OFFSET_BITS

      private static final int OFFSET_BITS
      See Also:
    • OFFSET_MASK

      private static final int OFFSET_MASK
      See Also:
    • FIELD_TYPE_MASK

      private static final int FIELD_TYPE_MASK
      See Also:
    • REQUIRED_MASK

      private static final int REQUIRED_MASK
      See Also:
    • ENFORCE_UTF8_MASK

      private static final int ENFORCE_UTF8_MASK
      See Also:
    • LEGACY_ENUM_IS_CLOSED_MASK

      private static final int LEGACY_ENUM_IS_CLOSED_MASK
      See Also:
    • NO_PRESENCE_SENTINEL

      private static final int NO_PRESENCE_SENTINEL
      See Also:
    • EMPTY_INT_ARRAY

      private static final int[] EMPTY_INT_ARRAY
    • REQUIRED_BIT

      private static final int REQUIRED_BIT
      Bit masks for field type extra feature bits encoded in Java gencode via GetExperimentalJavaFieldType in helpers.cc.
      See Also:
    • UTF8_CHECK_BIT

      private static final int UTF8_CHECK_BIT
      See Also:
    • CHECK_INITIALIZED_BIT

      private static final int CHECK_INITIALIZED_BIT
      See Also:
    • LEGACY_ENUM_IS_CLOSED_BIT

      private static final int LEGACY_ENUM_IS_CLOSED_BIT
      See Also:
    • HAS_HAS_BIT

      private static final int HAS_HAS_BIT
      See Also:
    • ONEOF_TYPE_OFFSET

      static final int ONEOF_TYPE_OFFSET
      An offset applied to the field type ID for scalar fields that are a member of a oneof.
      See Also:
    • UNSAFE

      private static final sun.misc.Unsafe UNSAFE
      Keep a direct reference to the unsafe object so we don't need to go through the UnsafeUtil wrapper for every call.
    • buffer

      private final int[] buffer
      Holds all information for accessing the message fields. The layout is as follows (field positions are relative to the offset of the start of the field in the buffer):

       buffer[i]
       [ 0 -    3] unused
       [ 4 -   31] field number
      
       buffer[i+1]
       [32 -   33] unused
       [34 -   34] whether UTF-8 enforcement should be applied to a string field.
       [35 -   35] whether the field is required
       [36 -   43] field type / for oneof: field type + ONEOF_TYPE_OFFSET
       [44 -   63] field offset / oneof value field offset
      
       buffer[i+2]
       [64 -   69] unused
       [70 -   75] field presence mask shift (unused for oneof/repeated fields)
       [76 -   95] presence field offset / oneof case field offset / cached size field offset
       
      Offset refer to the field offsets returned by Unsafe.objectFieldOffset() for reflective access to corresponding field.

      Note that presence field offset can only use 20 bits - 1. All bits set to 1 is the sentinel value for non-presence. This is not validated at runtime, we simply assume message layouts will not exceed 1MB (assuming ~10 bytes per field, that implies 100k fields which should hit other javac limits first). This corresponds to a shared bitFieldN_, which must have the field presence mask shift applied to get the corresponding field's presence.

    • objects

      private final Object[] objects
      Holds object references for fields. For each field entry in buffer, there are two corresponding entries in this array. The content is different from different field types:
         Map fields:
           objects[pos] = map default entry instance
           objects[pos + 1] = EnumVerifier if map value is enum, or message class reference if map
                              value is message.
         Message fields:
           objects[pos] = null or cached message schema
           objects[pos + 1] = message class reference
         Enum fields:
           objects[pos] = null
           objects[pos + 1] = EnumVerifier
       
    • minFieldNumber

      private final int minFieldNumber
    • maxFieldNumber

      private final int maxFieldNumber
    • defaultInstance

      private final MessageLite defaultInstance
    • hasExtensions

      private final boolean hasExtensions
    • lite

      private final boolean lite
    • useCachedSizeField

      private final boolean useCachedSizeField
    • intArray

      private final int[] intArray
      Represents [checkInitialized positions, map field positions, repeated field offsets].
    • checkInitializedCount

      private final int checkInitializedCount
      Values at indices 0 -> checkInitializedCount in intArray are positions to check for initialization.
    • repeatedFieldOffsetStart

      private final int repeatedFieldOffsetStart
      Values at indices checkInitializedCount -> repeatedFieldOffsetStart are map positions. Everything after that are repeated field offsets.
    • newInstanceSchema

      private final NewInstanceSchema newInstanceSchema
    • listFieldSchema

      private final ListFieldSchema listFieldSchema
    • unknownFieldSchema

      private final UnknownFieldSchema<?,?> unknownFieldSchema
    • extensionSchema

      private final ExtensionSchema<?> extensionSchema
    • mapFieldSchema

      private final MapFieldSchema mapFieldSchema
  • Constructor Details

  • Method Details

    • newSchema

      static <T> MessageSchema<T> newSchema(Class<T> messageClass, MessageInfo messageInfo, NewInstanceSchema newInstanceSchema, ListFieldSchema listFieldSchema, UnknownFieldSchema<?,?> unknownFieldSchema, ExtensionSchema<?> extensionSchema, MapFieldSchema mapFieldSchema)
    • newSchemaForRawMessageInfo

      static <T> MessageSchema<T> newSchemaForRawMessageInfo(RawMessageInfo messageInfo, NewInstanceSchema newInstanceSchema, ListFieldSchema listFieldSchema, UnknownFieldSchema<?,?> unknownFieldSchema, ExtensionSchema<?> extensionSchema, MapFieldSchema mapFieldSchema)
    • reflectField

      private static Field reflectField(Class<?> messageClass, String fieldName)
    • newSchemaForMessageInfo

      static <T> MessageSchema<T> newSchemaForMessageInfo(StructuralMessageInfo messageInfo, NewInstanceSchema newInstanceSchema, ListFieldSchema listFieldSchema, UnknownFieldSchema<?,?> unknownFieldSchema, ExtensionSchema<?> extensionSchema, MapFieldSchema mapFieldSchema)
    • storeFieldData

      private static void storeFieldData(FieldInfo fi, int[] buffer, int bufferIndex, Object[] objects)
    • newInstance

      public T newInstance()
      Description copied from interface: Schema
      Creates a new instance of the message class.
      Specified by:
      newInstance in interface Schema<T>
    • equals

      public boolean equals(T message, T other)
      Description copied from interface: Schema
      Determine of the two messages are equal.
      Specified by:
      equals in interface Schema<T>
    • equals

      private boolean equals(T message, T other, int pos)
    • hashCode

      public int hashCode(T message)
      Description copied from interface: Schema
      Compute a hashCode for the message.
      Specified by:
      hashCode in interface Schema<T>
    • mergeFrom

      public void mergeFrom(T message, T other)
      Description copied from interface: Schema
      Merge values from other into message. This method doesn't make the message immutable. To make the message immutable after merging, use Schema.makeImmutable(T).
      Specified by:
      mergeFrom in interface Schema<T>
    • mergeSingleField

      private void mergeSingleField(T message, T other, int pos)
    • mergeMessage

      private void mergeMessage(T targetParent, T sourceParent, int pos)
    • mergeOneofMessage

      private void mergeOneofMessage(T targetParent, T sourceParent, int pos)
    • getSerializedSize

      public int getSerializedSize(T message)
      Description copied from interface: Schema
      Compute the serialized size of the message.
      Specified by:
      getSerializedSize in interface Schema<T>
    • getUnknownFieldsSerializedSize

      private <UT, UB> int getUnknownFieldsSerializedSize(UnknownFieldSchema<UT,UB> schema, T message)
    • writeTo

      public void writeTo(T message, Writer writer) throws IOException
      Description copied from interface: Schema
      Writes the given message to the target Writer.
      Specified by:
      writeTo in interface Schema<T>
      Throws:
      IOException
    • writeFieldsInAscendingOrder

      private void writeFieldsInAscendingOrder(T message, Writer writer) throws IOException
      Throws:
      IOException
    • writeFieldsInDescendingOrder

      private void writeFieldsInDescendingOrder(T message, Writer writer) throws IOException
      Throws:
      IOException
    • writeMapHelper

      private <K, V> void writeMapHelper(Writer writer, int number, Object mapField, int pos) throws IOException
      Throws:
      IOException
    • writeUnknownInMessageTo

      private <UT, UB> void writeUnknownInMessageTo(UnknownFieldSchema<UT,UB> schema, T message, Writer writer) throws IOException
      Throws:
      IOException
    • mergeFrom

      public void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry) throws IOException
      Description copied from interface: Schema
      Reads fields from the given Reader and merges them into the message. It doesn't make the message immutable after parsing is done. To make the message immutable, use Schema.makeImmutable(T).
      Specified by:
      mergeFrom in interface Schema<T>
      Throws:
      IOException
    • mergeFromHelper

      private <UT, UB, ET extends FieldSet.FieldDescriptorLite<ET>> void mergeFromHelper(UnknownFieldSchema<UT,UB> unknownFieldSchema, ExtensionSchema<ET> extensionSchema, T message, Reader reader, ExtensionRegistryLite extensionRegistry) throws IOException
      A helper method for wildcard capture of unknownFieldSchema. See: https://docs.oracle.com/javase/tutorial/java/generics/capture.html
      Throws:
      IOException
    • getMutableUnknownFields

      static UnknownFieldSetLite getMutableUnknownFields(Object message)
    • decodeMapEntryValue

      private int decodeMapEntryValue(byte[] data, int position, int limit, WireFormat.FieldType fieldType, Class<?> messageType, ArrayDecoders.Registers registers) throws IOException
      Decodes a map entry key or value. Stores result in registers.object1.
      Throws:
      IOException
    • decodeMapEntry

      private <K, V> int decodeMapEntry(byte[] data, int position, int limit, MapEntryLite.Metadata<K,V> metadata, Map<K,V> target, ArrayDecoders.Registers registers) throws IOException
      Decodes a map entry.
      Throws:
      IOException
    • parseRepeatedField

      private int parseRepeatedField(T message, byte[] data, int position, int limit, int tag, int number, int wireType, int bufferPosition, long typeAndOffset, int fieldType, long fieldOffset, ArrayDecoders.Registers registers) throws IOException
      Throws:
      IOException
    • parseMapField

      private <K, V> int parseMapField(T message, byte[] data, int position, int limit, int bufferPosition, long fieldOffset, ArrayDecoders.Registers registers) throws IOException
      Throws:
      IOException
    • parseOneofField

      private int parseOneofField(T message, byte[] data, int position, int limit, int tag, int number, int wireType, int typeAndOffset, int fieldType, long fieldOffset, int bufferPosition, ArrayDecoders.Registers registers) throws IOException
      Throws:
      IOException
    • getMessageFieldSchema

      private Schema getMessageFieldSchema(int pos)
    • getMapFieldDefaultEntry

      private Object getMapFieldDefaultEntry(int pos)
    • getEnumFieldVerifier

      private Internal.EnumVerifier getEnumFieldVerifier(int pos)
    • parseMessage

      int parseMessage(T message, byte[] data, int position, int limit, int endDelimited, ArrayDecoders.Registers registers) throws IOException
      Parses a message and returns the position after the message/group. If it's parsing a LENGTH_PREFIXED message (endDelimited == 0), returns limit if parsing is successful; If it's parsing a DELIMITED message aka group (endDelimited != 0), parsing ends when a tag == endDelimited is encountered and the position after that tag is returned.
      Throws:
      IOException
    • mutableMessageFieldForMerge

      private Object mutableMessageFieldForMerge(T message, int pos)
    • storeMessageField

      private void storeMessageField(T message, int pos, Object field)
    • mutableOneofMessageFieldForMerge

      private Object mutableOneofMessageFieldForMerge(T message, int fieldNumber, int pos)
    • storeOneofMessageField

      private void storeOneofMessageField(T message, int fieldNumber, int pos, Object field)
    • mergeFrom

      public void mergeFrom(T message, byte[] data, int position, int limit, ArrayDecoders.Registers registers) throws IOException
      Description copied from interface: Schema
      Like the above but parses from a byte[] without extensions. Entry point of fast path. Note that this method may throw IndexOutOfBoundsException if the input data is not valid protobuf wire format. Protobuf public API methods should catch and convert that exception to InvalidProtocolBufferException.
      Specified by:
      mergeFrom in interface Schema<T>
      Throws:
      IOException
    • makeImmutable

      public void makeImmutable(T message)
      Description copied from interface: Schema
      Marks repeated/map/extension/unknown fields as immutable.
      Specified by:
      makeImmutable in interface Schema<T>
    • mergeMap

      private final <K, V> void mergeMap(Object message, int pos, Object mapDefaultEntry, ExtensionRegistryLite extensionRegistry, Reader reader) throws IOException
      Throws:
      IOException
    • filterMapUnknownEnumValues

      private <UT, UB> UB filterMapUnknownEnumValues(Object message, int pos, UB unknownFields, UnknownFieldSchema<UT,UB> unknownFieldSchema, Object containerMessage)
    • filterUnknownEnumMap

      private <K, V, UT, UB> UB filterUnknownEnumMap(int pos, int number, Map<K,V> mapData, Internal.EnumVerifier enumVerifier, UB unknownFields, UnknownFieldSchema<UT,UB> unknownFieldSchema, Object containerMessage)
    • isInitialized

      public final boolean isInitialized(T message)
      Description copied from interface: Schema
      Checks whether all required fields are set.
      Specified by:
      isInitialized in interface Schema<T>
    • isInitialized

      private static boolean isInitialized(Object message, int typeAndOffset, Schema schema)
    • isListInitialized

      private <N> boolean isListInitialized(Object message, int typeAndOffset, int pos)
    • isMapInitialized

      private boolean isMapInitialized(T message, int typeAndOffset, int pos)
    • writeString

      private void writeString(int fieldNumber, Object value, Writer writer) throws IOException
      Throws:
      IOException
    • readString

      private void readString(Object message, int typeAndOffset, Reader reader) throws IOException
      Throws:
      IOException
    • readStringList

      private void readStringList(Object message, int typeAndOffset, Reader reader) throws IOException
      Throws:
      IOException
    • readMessageList

      private <E> void readMessageList(Object message, int typeAndOffset, Reader reader, Schema<E> schema, ExtensionRegistryLite extensionRegistry) throws IOException
      Throws:
      IOException
    • readGroupList

      private <E> void readGroupList(Object message, long offset, Reader reader, Schema<E> schema, ExtensionRegistryLite extensionRegistry) throws IOException
      Throws:
      IOException
    • numberAt

      private int numberAt(int pos)
    • typeAndOffsetAt

      private int typeAndOffsetAt(int pos)
    • presenceMaskAndOffsetAt

      private int presenceMaskAndOffsetAt(int pos)
    • type

      private static int type(int value)
    • isRequired

      private static boolean isRequired(int value)
    • isEnforceUtf8

      private static boolean isEnforceUtf8(int value)
    • isLegacyEnumIsClosed

      private static boolean isLegacyEnumIsClosed(int value)
    • offset

      private static long offset(int value)
    • isMutable

      private static boolean isMutable(Object message)
    • checkMutable

      private static void checkMutable(Object message)
    • doubleAt

      private static <T> double doubleAt(T message, long offset)
    • floatAt

      private static <T> float floatAt(T message, long offset)
    • intAt

      private static <T> int intAt(T message, long offset)
    • longAt

      private static <T> long longAt(T message, long offset)
    • booleanAt

      private static <T> boolean booleanAt(T message, long offset)
    • oneofDoubleAt

      private static <T> double oneofDoubleAt(T message, long offset)
    • oneofFloatAt

      private static <T> float oneofFloatAt(T message, long offset)
    • oneofIntAt

      private static <T> int oneofIntAt(T message, long offset)
    • oneofLongAt

      private static <T> long oneofLongAt(T message, long offset)
    • oneofBooleanAt

      private static <T> boolean oneofBooleanAt(T message, long offset)
    • arePresentForEquals

      private boolean arePresentForEquals(T message, T other, int pos)
      Returns true the field is present in both messages, or neither.
    • isFieldPresent

      private boolean isFieldPresent(T message, int pos, int presenceFieldOffset, int presenceField, int presenceMask)
    • isFieldPresent

      private boolean isFieldPresent(T message, int pos)
    • setFieldPresent

      private void setFieldPresent(T message, int pos)
    • isOneofPresent

      private boolean isOneofPresent(T message, int fieldNumber, int pos)
    • isOneofCaseEqual

      private boolean isOneofCaseEqual(T message, T other, int pos)
    • setOneofPresent

      private void setOneofPresent(T message, int fieldNumber, int pos)
    • positionForFieldNumber

      private int positionForFieldNumber(int number)
    • positionForFieldNumber

      private int positionForFieldNumber(int number, int min)
    • slowPositionForFieldNumber

      private int slowPositionForFieldNumber(int number, int min)
    • getSchemaSize

      int getSchemaSize()