in serialization/src/main/java/com/twitter/serial/serializer/CoreSerializers.java [451:515]
public static <B> Serializer<B> getBaseClassSerializer(
@NotNull final List<SerializableClass<? extends B>> subclasses) {
return new ObjectSerializer<B>() {
private boolean mNeedToCheckBaseClassSerializer = true;
private void checkBaseClassSerializer(@NotNull SerializationContext context) {
if (mNeedToCheckBaseClassSerializer && context.isDebug()) {
mNeedToCheckBaseClassSerializer = false;
final int len = subclasses.size();
for (int i = 1; i < len; ++i) {
final SerializableClass<B> subclass = InternalSerialUtils.cast(subclasses.get(i));
if (!SerializableClass.isDummy(subclass)) {
for (int p = 0; p < i; ++p) {
if (!SerializableClass.isDummy(subclasses.get(p))) {
subclasses.get(p).klass.isAssignableFrom(subclass.klass);
}
}
}
}
}
}
@Override
protected void serializeObject(@NotNull SerializationContext context,
@NotNull SerializerOutput output, @NotNull B object) throws IOException {
checkBaseClassSerializer(context);
final int len = subclasses.size();
for (int i = 0; i < len; i++) {
final SerializableClass<B> subclass = InternalSerialUtils.cast(subclasses.get(i));
if (!SerializableClass.isDummy(subclass)) {
if (object.getClass().equals(subclass.klass)) {
output.writeInt(i)
.writeObject(context,
subclass.klass.cast(object), subclass.serializer);
return;
}
}
}
throw new SerializationException(
"Serializer not defined for base class serialization for : " +
object.getClass().getSimpleName());
}
@Nullable
@Override
protected B deserializeObject(@NotNull SerializationContext context,
@NotNull SerializerInput input, int versionNumber)
throws IOException, ClassNotFoundException {
checkBaseClassSerializer(context);
final int type = input.readInt();
if (type > subclasses.size()) {
throw new SerializationException(
"Invalid type found in base class deserialization: " + type);
}
final SerializableClass<? extends B> subclass = subclasses.get(type);
if (SerializableClass.isDummy(subclass)) {
SerializationUtils.skipObject(input);
return null;
}
return InternalSerialUtils.cast(subclass.serializer.deserializeNotNull(context, input));
}
};
}