EntrySerializer(String fieldId, Type type, BinarySerializerRepository serializerRepository) { this.entryId = fieldId; this.type = type; this.metaData = ObjectUtil.checkNotNull(serializerRepository.getMetaData(type.getMetaDataId())); this.serializerRepository = serializerRepository; }
@CheckForNull private GenericValue deserializeValue( ByteReader source, @CheckForNull Type declaredType, @CheckForNull MetaData declaredMetaData) { boolean optional = (declaredType == null || declaredType.isOptional()); MetaData actualMetaData = null; if (declaredMetaData == null || declaredMetaData.getMetaType().isPolymorphic()) { if ((declaredMetaData != null) && (declaredMetaData.getMetaType() == MetaType.ENTITY)) { actualMetaData = BootStrap.ENTITY_ID; } else { // Polymorphic type: Read actual type or 'null'-type. EntityId actualTypeId = serializerRepository.getEntityIdSerializer().deserialize(source); if (!BootStrap.ID_NULL_REFERENCE.equals(actualTypeId)) { actualMetaData = serializerRepository.getMetaData(actualTypeId); } } } else { // Non-polymorphic type: Do not read actual type. if (!optional || source.getVarInt() != 0) { actualMetaData = declaredMetaData; } } if (actualMetaData == null) { if (!optional) { throw new SerializerException("Non-optional entry found to be null!"); } return null; } switch (actualMetaData.getMetaType()) { case ENTITY: { EntityId entityId = serializerRepository.getEntityIdSerializer().deserialize(source); return BootStrap.ID_NULL_REFERENCE.equals(entityId) ? null : new EntityIdValue(entityId); } case PRIMITIVE: { Primitive primitive = Primitive.byEntityId(actualMetaData.getEntityId()); BinarySerializer<?> serializer = serializerRepository.getPrimitiveSerializer(actualMetaData.getEntityId()); return new PrimitiveValue(primitive, serializer.deserialize(source)); } case VALUE_OBJECT: { BinarySerializer<ObjectInfo> serializer = serializerRepository.getBinarySerializer(actualMetaData.getEntityId()); return new ValueObjectValue(serializer.deserialize(source)); } case COLLECTION: { // Read element MetaDataId. EntityId elementMetaDataId = serializerRepository.getEntityIdSerializer().deserialize(source); // Read element count. int count = MathUtil.longToInt(source.getVarInt()); // Read custom collection implementation data. BinarySerializer<ObjectInfo> serializer = serializerRepository.getBinarySerializer(actualMetaData.getEntityId()); ObjectInfo collectionInfo = serializer.deserialize(source); // Read all elements. ImmutableArrayList.Builder<GenericValue> builder = ImmutableArrayList.newBuilder(count); for (int i = 0; i < count; ++i) { Type elementType = (declaredType == null) ? null : declaredType.getElementType(); MetaData metaData = (elementType == null) ? null : serializerRepository.getMetaData(elementType.getMetaDataId()); GenericValue value = deserializeValue(source, elementType, metaData); builder.add((value == null) ? GenericValue.nullValue() : value); } return new CollectionValue(collectionInfo, elementMetaDataId, builder.build()); } default: throw new IllegalStateException("Unknown MetaType " + actualMetaData.getMetaType()); } }