msoucy / dproto

D Protocol Buffer mixins to create structures at compile time
Boost Software License 1.0
37 stars 16 forks source link

How to add UDA's to fields? eg, to customize behavior of vibe serialization #118

Open timotheecour opened 7 years ago

timotheecour commented 7 years ago

@msoucy proto syntax supports annotations via option: https://developers.google.com/protocol-buffers/docs/proto

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
  optional float my_field_option = 50002;
}

message MyMessage {
  optional int32 foo = 1 [(my_field_option) = 4.5];
}

this could map into a UDA on D side, which I could then use to customize behavior for D code that uses these protos, eg, customizing vibe serialization (via tagging a field as @optional or @ignore, etc)

Is theer a simple way to do this?

looks like extend declarations are allowed but ignored in import/dproto/parse.d

/* Reads an extend declaration (just ignores the content). @todo /

Is there a simpler way (at least in meantime) to do what I want in my particular case, ie add a @optional or @ignore UDA for a particular field in a generated proto message?

msoucy commented 7 years ago

As a temporary workaround, you could run the proto file through dprotoc and add the UDAs to the output (might want to run dfmt on it first though)

The whole "extension" functionality has been on my roadmap, but due to a lack of motivation I haven't gotten around to working on it. I'll give it some thought, though - perhaps it can be done like you suggested, or a dproto specific custom option.

timotheecour commented 7 years ago

@msoucy how about the following simple but powerful hack?

module foo;

enum def=`
extend google.protobuf.FieldOptions {
  optional string uda = 50002;
}
message MyMessage {
  optional int32 foo = 1 [(udas) = "@optional @MyUDA(3) "];
}
`;

import vibe.data.serialization : optional;
struct MyUDA{
  int mynumber;
}
mixin ProtocolBufferFromString!def;

which generates the field foo with udas simply mixed in using the context where the udas are defined (here, @optional @MyUDA(3) ) NOTE: udas could potentially be anything inside the string for more flexibility, as shown above

What do you think?