use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class ProtoStreamWriterImpl method writeFloats.
@Override
public void writeFloats(String fieldName, float[] array) throws IOException {
final FieldDescriptor fd = messageContext.getFieldByName(fieldName);
if (fd.getType() != Type.FLOAT) {
throw new IllegalArgumentException("The Protobuf declared field type is not compatible with the written type : " + fd.getFullName());
}
checkRepeatedFieldWrite(fd);
if (array == null) {
// a repeated field can never be flagged as required
return;
}
final TagWriter out = messageContext.out;
final int fieldNumber = fd.getNumber();
for (float value : array) {
out.writeFloat(fieldNumber, value);
}
}
use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class JsonUtils method toCanonicalJSON.
private static void toCanonicalJSON(ImmutableSerializationContext ctx, byte[] bytes, StringBuilder jsonOut, int initNestingLevel) throws IOException {
if (bytes.length == 0) {
// only null values get to be encoded to an empty byte array
jsonOut.append("null");
return;
}
Descriptor wrapperDescriptor = ctx.getMessageDescriptor(WrappedMessage.PROTOBUF_TYPE_NAME);
boolean prettyPrint = initNestingLevel >= 0;
TagHandler messageHandler = new TagHandler() {
private JsonNestingLevel nestingLevel;
/**
* Have we written the "_type" field?
*/
private boolean missingType = true;
private void indent() {
jsonOut.append('\n');
for (int k = initNestingLevel + nestingLevel.indent; k > 0; k--) {
jsonOut.append(" ");
}
}
@Override
public void onStart(GenericDescriptor descriptor) {
nestingLevel = new JsonNestingLevel(null);
if (prettyPrint) {
indent();
nestingLevel.indent++;
}
jsonOut.append('{');
writeType(descriptor);
}
private void writeType(AnnotatedDescriptor descriptor) {
if (descriptor != null && nestingLevel.previous == null && nestingLevel.isFirstField) {
missingType = false;
nestingLevel.isFirstField = false;
if (prettyPrint) {
indent();
}
jsonOut.append('\"').append("_type").append('\"').append(':');
if (prettyPrint) {
jsonOut.append(' ');
}
String type;
if (descriptor instanceof FieldDescriptor) {
type = ((FieldDescriptor) descriptor).getTypeName();
} else {
type = descriptor.getFullName();
}
jsonOut.append('\"').append(type).append('\"');
}
}
@Override
public void onTag(int fieldNumber, FieldDescriptor fieldDescriptor, Object tagValue) {
if (fieldDescriptor == null) {
// unknown field, ignore
return;
}
if (missingType) {
writeType(fieldDescriptor);
}
startSlot(fieldDescriptor);
switch(fieldDescriptor.getType()) {
case STRING:
escapeJson((String) tagValue, jsonOut, true);
break;
case INT64:
case SINT64:
case UINT64:
case FIXED64:
jsonOut.append(tagValue);
break;
case FLOAT:
Float f = (Float) tagValue;
if (f.isInfinite() || f.isNaN()) {
// Infinity and NaN need to be quoted
jsonOut.append('\"').append(f).append('\"');
} else {
jsonOut.append(f);
}
break;
case DOUBLE:
Double d = (Double) tagValue;
if (d.isInfinite() || d.isNaN()) {
jsonOut.append('\"').append(d).append('\"');
} else {
jsonOut.append(d);
}
break;
case ENUM:
EnumValueDescriptor enumValue = fieldDescriptor.getEnumType().findValueByNumber((Integer) tagValue);
jsonOut.append('\"').append(enumValue.getName()).append('\"');
break;
case BYTES:
String base64encoded = Base64.getEncoder().encodeToString((byte[]) tagValue);
jsonOut.append('\"').append(base64encoded).append('\"');
break;
default:
if (tagValue instanceof Date) {
jsonOut.append('\"').append(formatDate((Date) tagValue)).append('\"');
} else if (fieldNumber == WRAPPED_ENUM) {
jsonOut.append('\"').append(tagValue).append('\"');
} else {
jsonOut.append(tagValue);
}
}
}
@Override
public void onStartNested(int fieldNumber, FieldDescriptor fieldDescriptor) {
if (fieldDescriptor == null) {
// unknown field, ignore
return;
}
startSlot(fieldDescriptor);
nestingLevel = new JsonNestingLevel(nestingLevel);
if (prettyPrint) {
indent();
nestingLevel.indent++;
}
jsonOut.append('{');
}
@Override
public void onEndNested(int fieldNumber, FieldDescriptor fieldDescriptor) {
if (nestingLevel.repeatedFieldDescriptor != null) {
endArraySlot();
}
if (prettyPrint) {
nestingLevel.indent--;
indent();
}
jsonOut.append('}');
nestingLevel = nestingLevel.previous;
}
@Override
public void onEnd() {
if (nestingLevel.repeatedFieldDescriptor != null) {
endArraySlot();
}
if (prettyPrint) {
nestingLevel.indent--;
indent();
}
jsonOut.append('}');
nestingLevel = null;
if (prettyPrint) {
jsonOut.append('\n');
}
}
private void startSlot(FieldDescriptor fieldDescriptor) {
if (nestingLevel.repeatedFieldDescriptor != null && nestingLevel.repeatedFieldDescriptor != fieldDescriptor) {
endArraySlot();
}
if (nestingLevel.isFirstField) {
nestingLevel.isFirstField = false;
} else {
jsonOut.append(',');
}
if (!fieldDescriptor.isRepeated() || nestingLevel.repeatedFieldDescriptor == null) {
if (prettyPrint) {
indent();
}
if (fieldDescriptor.getLabel() == Label.ONE_OF) {
jsonOut.append('"').append(JSON_VALUE_FIELD).append("\":");
} else {
jsonOut.append('"').append(fieldDescriptor.getName()).append("\":");
}
}
if (prettyPrint) {
jsonOut.append(' ');
}
if (fieldDescriptor.isRepeated() && nestingLevel.repeatedFieldDescriptor == null) {
nestingLevel.repeatedFieldDescriptor = fieldDescriptor;
jsonOut.append('[');
}
}
private void endArraySlot() {
if (prettyPrint && nestingLevel.repeatedFieldDescriptor.getType() == Type.MESSAGE) {
indent();
}
nestingLevel.repeatedFieldDescriptor = null;
jsonOut.append(']');
}
};
TagHandler wrapperHandler = new TagHandler() {
private Integer typeId;
private String typeName;
private byte[] wrappedMessage;
private Integer wrappedEnum;
private GenericDescriptor getDescriptor() {
return typeId != null ? ctx.getDescriptorByTypeId(typeId) : ctx.getDescriptorByName(typeName);
}
@Override
public void onTag(int fieldNumber, FieldDescriptor fieldDescriptor, Object tagValue) {
if (fieldDescriptor == null) {
// ignore unknown fields
return;
}
switch(fieldNumber) {
case WRAPPED_TYPE_ID:
typeId = (Integer) tagValue;
break;
case WRAPPED_TYPE_NAME:
typeName = (String) tagValue;
break;
case WRAPPED_MESSAGE:
wrappedMessage = (byte[]) tagValue;
break;
case WRAPPED_ENUM:
wrappedEnum = (Integer) tagValue;
break;
case WrappedMessage.WRAPPED_DOUBLE:
case WrappedMessage.WRAPPED_FLOAT:
case WrappedMessage.WRAPPED_INT64:
case WrappedMessage.WRAPPED_UINT64:
case WrappedMessage.WRAPPED_INT32:
case WrappedMessage.WRAPPED_FIXED64:
case WrappedMessage.WRAPPED_FIXED32:
case WrappedMessage.WRAPPED_BOOL:
case WrappedMessage.WRAPPED_STRING:
case WrappedMessage.WRAPPED_BYTES:
case WrappedMessage.WRAPPED_UINT32:
case WrappedMessage.WRAPPED_SFIXED32:
case WrappedMessage.WRAPPED_SFIXED64:
case WrappedMessage.WRAPPED_SINT32:
case WrappedMessage.WRAPPED_SINT64:
messageHandler.onStart(null);
messageHandler.onTag(fieldNumber, fieldDescriptor, tagValue);
messageHandler.onEnd();
break;
}
}
@Override
public void onEnd() {
if (wrappedEnum != null) {
EnumDescriptor enumDescriptor = (EnumDescriptor) getDescriptor();
String enumConstantName = enumDescriptor.findValueByNumber(wrappedEnum).getName();
FieldDescriptor fd = wrapperDescriptor.findFieldByNumber(WRAPPED_ENUM);
messageHandler.onStart(enumDescriptor);
messageHandler.onTag(WRAPPED_ENUM, fd, enumConstantName);
messageHandler.onEnd();
} else if (wrappedMessage != null) {
try {
Descriptor messageDescriptor = (Descriptor) getDescriptor();
ProtobufParser.INSTANCE.parse(messageHandler, messageDescriptor, wrappedMessage);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
};
ProtobufParser.INSTANCE.parse(wrapperHandler, wrapperDescriptor, bytes);
}
use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class MessageMarshallerDelegate method marshall.
@Override
public void marshall(ProtobufTagMarshaller.WriteContext ctx, FieldDescriptor fieldDescriptor, T message) throws IOException {
ProtoStreamWriterImpl writer = ((TagWriterImpl) ctx).getProtoStreamWriter();
ProtoStreamWriterImpl.WriteMessageContext messageContext = writer.enterContext(fieldDescriptor, messageDescriptor, (TagWriterImpl) ctx);
marshaller.writeTo(writer, message);
UnknownFieldSet unknownFieldSet = unknownFieldSetHandler != null ? unknownFieldSetHandler.getUnknownFieldSet(message) : null;
if (unknownFieldSet != null && !unknownFieldSet.isEmpty()) {
// validate that none of the unknown fields are actually declared by the known descriptor
for (FieldDescriptor fd : fieldDescriptors) {
if (unknownFieldSet.hasTag(fd.getWireTag())) {
throw new IOException("Field " + fd.getFullName() + " is a known field so it is illegal to be present in the unknown field set");
}
}
// write the unknown fields
unknownFieldSet.writeTo(messageContext.out);
}
// validate that all the required fields were written either by the marshaller or by the UnknownFieldSet
for (FieldDescriptor fd : fieldDescriptors) {
if (fd.isRequired() && !messageContext.isFieldMarked(fd.getNumber()) && (unknownFieldSet == null || !unknownFieldSet.hasTag(fd.getWireTag()))) {
throw new IllegalStateException("Required field \"" + fd.getFullName() + "\" should have been written by a calling a suitable method of " + MessageMarshaller.ProtoStreamWriter.class.getCanonicalName());
}
}
writer.exitContext();
}
use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class ProtoStreamReaderImpl method readCollection.
@Override
public <E, C extends Collection<? super E>> C readCollection(String fieldName, C collection, Class<E> elementClass) throws IOException {
final FieldDescriptor fd = messageContext.getFieldByName(fieldName);
checkFieldRead(fd, true);
if (primitiveTypes.contains(fd.getType())) {
readPrimitiveCollection(fd, (Collection<Object>) collection, elementClass);
return collection;
}
// todo validate type is compatible with readCollection
final int expectedTag = fd.getWireTag();
EnumMarshallerDelegate<?> enumMarshallerDelegate;
if (fd.getType() == Type.ENUM) {
enumMarshallerDelegate = (EnumMarshallerDelegate) serCtx.getMarshallerDelegate(elementClass);
} else {
enumMarshallerDelegate = null;
}
while (true) {
Object o = messageContext.unknownFieldSet.consumeTag(expectedTag);
if (o == null) {
break;
}
E e;
if (enumMarshallerDelegate != null) {
int enumValue = ((Number) o).intValue();
e = (E) enumMarshallerDelegate.decode(expectedTag, enumValue, messageContext.unknownFieldSet);
} else {
byte[] nestedMessageBytes = (byte[]) o;
TagReaderImpl in = TagReaderImpl.newNestedInstance(messageContext.in, nestedMessageBytes);
e = readNestedObject(fd, elementClass, in, nestedMessageBytes.length);
}
collection.add(e);
}
while (true) {
int tag = messageContext.in.readTag();
if (tag == 0) {
break;
}
if (tag == expectedTag) {
collection.add(readNestedObject(fd, elementClass, messageContext.in, -1));
} else {
messageContext.unknownFieldSet.readSingleField(tag, messageContext.in);
}
}
return collection;
}
use of org.infinispan.protostream.descriptors.FieldDescriptor in project protostream by infinispan.
the class DescriptorsTest method testDocAnnotations.
@Test
public void testDocAnnotations() {
String file1 = "package test1;\n" + "/** \n" + " * @Foo(fooValue) \n" + " * some more doc text \n" + " **/\n\n" + "message X {\n" + " /**\n" + " * @Bar(barValue) \n\n" + " */\n" + " optional int32 field1 = 1;\n" + "}\n";
Configuration config = Configuration.builder().annotationsConfig().annotation("Foo", AnnotationElement.AnnotationTarget.MESSAGE).attribute(AnnotationElement.Annotation.VALUE_DEFAULT_ATTRIBUTE).type(AnnotationElement.AttributeType.IDENTIFIER).metadataCreator((descriptor, annotation) -> annotation.getDefaultAttributeValue().getValue()).annotation("Bar", AnnotationElement.AnnotationTarget.FIELD).attribute(AnnotationElement.Annotation.VALUE_DEFAULT_ATTRIBUTE).type(AnnotationElement.AttributeType.IDENTIFIER).metadataCreator((fieldDescriptor, annotation) -> annotation.getDefaultAttributeValue().getValue()).build();
FileDescriptorSource fileDescriptorSource = new FileDescriptorSource();
fileDescriptorSource.addProtoFile("file1.proto", file1);
Map<String, FileDescriptor> descriptors = parseAndResolve(fileDescriptorSource, config);
assertEquals(1, descriptors.size());
assertTrue(descriptors.containsKey("file1.proto"));
Map<String, GenericDescriptor> types = descriptors.get("file1.proto").getTypes();
Descriptor typeX = (Descriptor) types.get("test1.X");
assertNotNull(typeX);
assertEquals(1, typeX.getFields().size());
FieldDescriptor field1 = typeX.getFields().get(0);
assertEquals("@Foo(fooValue) \n some more doc text", typeX.getDocumentation());
Map<String, AnnotationElement.Annotation> typeAnnotations = typeX.getAnnotations();
assertEquals("fooValue", typeAnnotations.get("Foo").getDefaultAttributeValue().getValue());
assertEquals("fooValue", typeX.getProcessedAnnotation("Foo"));
assertEquals("@Bar(barValue)", field1.getDocumentation());
Map<String, AnnotationElement.Annotation> fieldAnnotations = field1.getAnnotations();
assertEquals("barValue", fieldAnnotations.get("Bar").getDefaultAttributeValue().getValue());
assertEquals("barValue", field1.getProcessedAnnotation("Bar"));
}
Aggregations