I'm using protobuf-net, and I'm trying to:
- 开发者_如何转开发
- Generate a C# class from a .proto file
- Generate a .proto file from a C# class
That's pretty easy using respectively:
protogen.exe
toolSerializer<T>.GetProto()
method
But the thing is that I need to support protobuffer custom options and it doesn't seem to be as straightforward as I though.
Let me explain:
- From a proto file containing custom options applied on messages and fields, I want to generate a C# class decorated by .NET custom attributes.
- From a C# class decorated by custom attributes, I would like to generate a proto file where custom options are applied on messages and fields.
Basically, given:
message person {
option (my_message_option) = true;
optional string firstname = 1 [(my_field_option) = 42];
optional string lastname = 2 [(my_field_option) = 12];
optional int age = 3;
}
I want to generate:
[ProtoContract, MyMessageOption(true)]
public class Person
{
[ProtoMember(1), MyFieldOption(42)]
public string Firstname;
[ProtoMember(2), MyFieldOption(12)]
public string Firstname;
[ProtoMember(3)]
public string Firstname;
}
...and vice versa.
Notes :
- The custom option definitions
(
my_message_option
andmy_field_option
) can already exist in a protofile (say, my_custom_options.proto), and the custom attributes classes can also exist somewhere (MyMessageOptionAttribute
andMyFieldOptionAttribute
). - I tried to use protogen.exe and a custom xslt but protogen doesn't seem to have support for custom options.
What's the preferred way to achieve that? The solution doesn't have to rely on protobuf-net.
I ended up by forking ProtoGen project from protobuf-csharp to make public some internal types (generators, for the most part) and to make the SourceGenerators
extensible by allowing custom generator registrations.
This way, I was able to use the proto descriptor object model to write my own C# generator.
One tricky point is to register your custom options types before launching the parsing :
- Generate C# types corresponding to your custom options (using
Protoc.exe
thenProtoGen.exe
) - Configure
ExtensionRegistry
by using the generatedRegisterAllExtensions
methods. - Start the code generation using your own C# generators. In each generator you can access to the contextual
Descriptor.Options
collection.
There isn't a simple way to do this at the moment. The changes required would primarily be to the csharp.xslt file. There is a bug reported about this but hasn't been fixed yet.
精彩评论