Support for annotations
cap'n proto defines annotations (https://capnproto.org/language.html). Annotations allows powerful features to be added.
Consider the following example
@0x934efea7f017fff0;
struct Range {
min @0 :UInt32;
max @1 :UInt32;
}
annotation checkRange(field) :Range;
struct Example {
val @0 :UInt32 $checkRange(min = 1, max = 5);
}
In the given example annotation was added for validation on a field value. It would be create to do something like the following
import capnp
import example_capnp
range = example_capnp.Example.fields['val'].annotations['checkRange']
a = 5
if a > range.min and a < range.max:
....
Basically this will allow users of the library to pass arbitrary information from the capnp file to the python parser. This has great potential for this like generating CLI form capnp file, custom validators and a lot more.
This will be extremely helpful. I could help with that but I am in need of some guidance.
Currently, this is possible to achieve, but it's really gruesome. Using example from @kfir-drivenets :
import capnpy
example_capnp = capnp.load("example_capnp")
val_field = example_capnp.Example.schema.fields['val']
val_ann = val_field.proto.annotations[0]
val_range = val_ann.value.struct.as_struct(example_capnp.Range)
This works if we know that there is only one annotation on the field val and that it is always of the type example_capnp.Range. However if that wasn't known:
-
val_ann.namedoesn't exist. But, it is possible to match the annotation idval_ann.idin the listexample_capnp.schema.node.nestedNodesand get the name from there - to change the
val_ann.valueto a struct we need to know which struct should capnp treat it as. If we already know its name we can doval_ann_type = example_capnp.schema.get_nested(NAME).node.annotation.type. From here for safety, we can doval_ann_type.which(). If it's a struct, we get itsidbyval_ann_type.struct.typeIdand match that again inexample_capnp.schema.node.nestedNodesto get the name of the struct.
As you can see, it is possible to achieve, even without hard-coding names or relying in a specific order of annotations. Hopefully this will help contributors to add a nicer way, e.g. as suggested above.