use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class JsonUtils method processObject.
private static void processObject(ImmutableSerializationContext ctx, JsonParser parser, TagWriter writer, Descriptor messageDescriptor, Integer fieldNumber, boolean topLevel) throws IOException {
Set<String> requiredFields = messageDescriptor.getFields().stream().filter(FieldDescriptor::isRequired).map(FieldDescriptor::getName).collect(Collectors.toCollection(HashSet::new));
ByteArrayOutputStream baos = new ByteArrayOutputStream(ProtobufUtil.DEFAULT_ARRAY_BUFFER_SIZE);
TagWriter nestedWriter = TagWriterImpl.newInstanceNoBuffer(ctx, baos);
String currentField = null;
out: while (true) {
JsonToken token = parser.nextToken();
if (token == null) {
break;
}
switch(token) {
case END_OBJECT:
break out;
case START_ARRAY:
processArray(ctx, messageDescriptor.getFullName(), currentField, parser, nestedWriter);
break;
case START_OBJECT:
{
FieldDescriptor fd = messageDescriptor.findFieldByName(currentField);
Descriptor messageType = fd.getMessageType();
if (messageType == null) {
throw new IllegalStateException("Field '" + currentField + "' is not an object");
}
processObject(ctx, parser, nestedWriter, messageType, fd.getNumber(), false);
requiredFields.remove(currentField);
break;
}
case FIELD_NAME:
currentField = parser.getCurrentName();
break;
case VALUE_STRING:
case VALUE_NUMBER_INT:
case VALUE_NUMBER_FLOAT:
case VALUE_TRUE:
case VALUE_FALSE:
{
FieldDescriptor fd = messageDescriptor.findFieldByName(currentField);
if (fd == null) {
throw new IllegalStateException("The field '" + currentField + "' was not found in the Protobuf schema");
}
if (fd.getType() == Type.ENUM) {
writeEnumField(parser, nestedWriter, fd);
} else {
writeField(parser, nestedWriter, fd.getType(), fd.getNumber());
}
requiredFields.remove(currentField);
break;
}
case VALUE_NULL:
// we got null in, we write nothing out
break;
}
}
if (!requiredFields.isEmpty()) {
String missing = requiredFields.iterator().next();
throw new IllegalStateException("Required field '" + missing + "' missing");
}
if (topLevel) {
Integer topLevelTypeId = messageDescriptor.getTypeId();
if (topLevelTypeId == null) {
writer.writeString(WRAPPED_TYPE_NAME, messageDescriptor.getFullName());
} else {
writer.writeUInt32(WRAPPED_TYPE_ID, topLevelTypeId);
}
nestedWriter.flush();
writer.writeBytes(WRAPPED_MESSAGE, baos.toByteArray());
} else {
nestedWriter.flush();
writer.writeBytes(fieldNumber, baos.toByteArray());
}
writer.flush();
}
use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class MessageMarshallerDelegate method unmarshall.
@Override
public T unmarshall(ProtobufTagMarshaller.ReadContext ctx, FieldDescriptor fieldDescriptor) throws IOException {
ProtoStreamReaderImpl reader = ((TagReaderImpl) ctx).getProtoStreamReader();
ProtoStreamReaderImpl.ReadMessageContext messageContext = reader.enterContext(fieldDescriptor, messageDescriptor, (TagReaderImpl) ctx);
T message = marshaller.readFrom(reader);
UnknownFieldSet unknownFieldSet = messageContext.unknownFieldSet;
unknownFieldSet.readAllFields(ctx.getReader());
if (unknownFieldSetHandler != null && !unknownFieldSet.isEmpty()) {
unknownFieldSetHandler.setUnknownFieldSet(message, unknownFieldSet);
}
// check that all required fields were seen in the stream, even if not actually read (because are unknown)
for (FieldDescriptor fd : fieldDescriptors) {
if (fd.isRequired() && !messageContext.isFieldMarked(fd.getNumber()) && !unknownFieldSet.hasTag(fd.getWireTag())) {
throw new IOException("Required field \"" + fd.getFullName() + "\" was not encountered in the stream");
}
}
reader.exitContext();
return message;
}
use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class ProtoStreamReaderImpl method readObject.
@Override
public <E> E readObject(String fieldName, Class<E> clazz) throws IOException {
final FieldDescriptor fd = messageContext.getFieldByName(fieldName);
checkFieldRead(fd, false);
if (fd.getType() == Type.ENUM) {
return serCtx.getMarshallerDelegate(clazz).unmarshall(ctx, fd);
}
// todo validate type is compatible with readObject
final int expectedTag = fd.getWireTag();
Object o = messageContext.unknownFieldSet.consumeTag(expectedTag);
if (o != null) {
byte[] byteArray = (byte[]) o;
TagReaderImpl nested = TagReaderImpl.newNestedInstance(messageContext.in, byteArray);
return readNestedObject(fd, clazz, nested, byteArray.length);
}
while (true) {
int tag = messageContext.in.readTag();
if (tag == 0) {
break;
}
if (tag == expectedTag) {
return readNestedObject(fd, clazz, messageContext.in, -1);
}
messageContext.unknownFieldSet.readSingleField(tag, messageContext.in);
}
return null;
}
use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class ProtoStreamWriterImpl method writeBoolean.
@Override
public void writeBoolean(String fieldName, boolean value) throws IOException {
final FieldDescriptor fd = messageContext.getFieldByName(fieldName);
if (fd.getType() != Type.BOOL) {
throw new IllegalArgumentException("The Protobuf declared field type is not compatible with the written type : " + fd.getFullName());
}
checkFieldWrite(fd);
messageContext.out.writeBool(fd.getNumber(), value);
}
use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class ProtoStreamWriterImpl method writeObject.
@Override
public <E> void writeObject(String fieldName, E value, Class<? extends E> clazz) throws IOException {
final FieldDescriptor fd = messageContext.getFieldByName(fieldName);
checkFieldWrite(fd);
if (value == null) {
if (fd.isRequired()) {
throw new IllegalArgumentException("A required field cannot be null : " + fd.getFullName());
}
return;
}
if (fd.getType() == Type.GROUP) {
writeGroup(fd, value, clazz);
} else if (fd.getType() == Type.MESSAGE) {
writeMessage(fd, value, clazz);
} else if (fd.getType() == Type.ENUM) {
writeEnum(fd, (Enum) value);
} else {
throw new IllegalArgumentException("Declared field type is not a message or an enum : " + fd.getFullName());
}
}
Aggregations