Search code examples
protobuf-netprotogen

protobuf-net - protogen command line arguments


I'm trying to generate a csharp (.cs) file from a .proto file. I've downloaded protobuf-net from github and built locally, so that I can use protogen to generate .cs files. My issue is that I want it in the format that previous versions of this API that had the output generated, so for instance the newly generated classes are not inheriting from ProtoBuf.IExtensible, whereas previous versions did inherit from ProtoBuf.IExtensible. For example protogen is generating:

[global::ProtoBuf.ProtoContract()]
    public partial class ClientMsg
    {
        [global::ProtoBuf.ProtoMember(100)]
        public Logon logon { get; set; }
        ...
    } 

where what I'd like is something like:

    [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"ClientMsg")]
    public partial class ClientMsg : global::ProtoBuf.IExtensible
    {
        public ClientMsg() {}


        private WebAPI_1.Logon _logon = null;
        [global::ProtoBuf.ProtoMember(100, IsRequired = false, Name=@"logon", DataFormat = global::ProtoBuf.DataFormat.Default)]
        [global::System.ComponentModel.DefaultValue(null)]
        public WebAPI_1.Logon logon
        {
          get { return _logon; }
          set { _logon = value; }
        }
...
}

Solution

  • Firstly: note that protogen is available for download here.

    Now; re IExtensible: this was actually deliberate and was to match the original Google v3.* behaviour - where unknown fields are no longer preserved (the v2.* behaviour). This behaviour has now changed again, though - from protobuf v3.5.0 (13 Nov 2017) of Google's code: unknown fields are once again preserved. I simply need to update protogen with this fact. If this is important to you, I can probably get this done pretty quickly - it just means removing the if tests in CSharpCodeGenerator lines 217 and 224.

    In theory you could also actually just inherit from CSharpCodeGenerator in your own code, but the API to use a custom generator isn't trivial right now.

    There is no command-line option to emit exactly the same code as the previous version, and I do not intend to add one. There is a switch to toggle the C# language version (to use down-level C#): for example +langver=3 at the command line, or it can be embedded into a .proto:

    import "protobuf-net/protogen.proto";
    option (.protobuf_net.fileopt).csharp_langver = "3";
    

    Note that since this is a partial class, you can also add additional code in a separate code file without editing the generated code. For example, in your own .cs file you could have:

    [Serializable]
    partial class ClientMsg {
        public ClientMsg() {}
    }
    

    to add the extra attribute and explicit constructor.