net.dongliu.prettypb.runtime.code.ObjectProtoFieldInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of prettypb-runtime Show documentation
Show all versions of prettypb-runtime Show documentation
Prettypb serialization runtime
package net.dongliu.prettypb.runtime.code;
import net.dongliu.prettypb.runtime.ExtensionRegistry;
import net.dongliu.prettypb.runtime.include.ProtoField;
import net.dongliu.prettypb.runtime.code.object.BytesProtoFieldInfo;
import net.dongliu.prettypb.runtime.code.object.EnumProtoFieldInfo;
import net.dongliu.prettypb.runtime.code.object.MessageProtoFieldInfo;
import net.dongliu.prettypb.runtime.code.object.StringProtoFieldInfo;
import net.dongliu.prettypb.runtime.exception.IllegalBeanException;
import net.dongliu.prettypb.runtime.exception.IllegalDataException;
import net.dongliu.prettypb.runtime.exception.MissRequiredFieldException;
import java.io.IOException;
import java.lang.reflect.Field;
/**
* @author Dong Liu
*/
abstract public class ObjectProtoFieldInfo extends ProtoFieldInfo {
private Field helperField;
protected ObjectProtoFieldInfo(Field field, Field helperField, ProtoField protoField) {
super(field, protoField);
this.helperField = helperField;
this.helperField.setAccessible(true);
}
@Override
public boolean primitive() {
return false;
}
@Override
public boolean hasField(T bean) throws IllegalAccessException {
return helperField.getBoolean(bean);
}
@Override
public void serializeField(T bean, ProtoBufWriter protoBufWriter)
throws IllegalAccessException, IOException, IllegalDataException,
IllegalBeanException, MissRequiredFieldException {
Object value = field.get(bean);
// if value is set to null, we treat it as not have value
boolean has = helperField.getBoolean(bean);
if (value == null) {
has = false;
}
if (checkRequired(has, required(), protoField.hasDefault()) && value != null) {
serializeFieldInternal(value, protoBufWriter);
}
}
/**
* for non-repeated types. check if this field has data, and if this field is required
*/
private boolean checkRequired(boolean hasValue, boolean required,
boolean hasDefault)
throws IllegalBeanException, MissRequiredFieldException {
if (!hasValue && required && !hasDefault) {
throw new MissRequiredFieldException(
"Field required not exists, may not be set, or value is null");
}
return hasValue;
}
abstract protected void serializeFieldInternal(Object obj, ProtoBufWriter protoBufWriter)
throws IllegalAccessException, IOException;
public static ProtoFieldInfo getObject(Field field, Field helperField,ProtoField protoField) {
switch (protoField.type()) {
case Enum:
return new EnumProtoFieldInfo(field, helperField, protoField);
case String:
return new StringProtoFieldInfo(field, helperField, protoField);
case Bytes:
return new BytesProtoFieldInfo(field, helperField, protoField);
case Message:
return new MessageProtoFieldInfo(field, helperField, protoField);
default:
throw new IllegalArgumentException();
}
}
@Override
public void deSerializeField(T bean, ProtoBufReader protoBufReader,
ExtensionRegistry extensionRegistry)
throws IllegalAccessException, IOException, IllegalDataException {
if (hasField(bean)) {
// has set a value
throw new IllegalDataException("Multi value for single field found");
}
Object value = deSerializeFieldInternal(protoBufReader, extensionRegistry);
field.set(bean, value);
helperField.setBoolean(bean, true);
}
protected abstract Object deSerializeFieldInternal(ProtoBufReader protoBufReader,
ExtensionRegistry extensionRegistry)
throws IOException;
}