5

C# アプリケーションでプロトコル バッファのニーズを処理するために、protobuf-netを使用しています。.proto ファイルを他の管理されていないアプリケーションと共有しているため、.proto ファイルからコードを生成しています (コード ファーストの protobuf-net アプローチは使用していません)。可能な限りDRYを維持するために、多くのインターフェース ドキュメントを .proto ファイル自体に保存しています。プロジェクト ビルド ターゲットによって呼び出される protogen.exe によって C# コードを生成します。

これらのコメントをコンパイル済みの C# コードに (自動的に) 転送する方法はありますか?

基本的に、次のような .proto が与えられます。

// This message is used to request a resource from the server
message GetResource
{
    // The identifier of the requested resource 
    required string resourceId = 1;
}

...次のようなものが欲しいです(読みやすくするためにIExtensibleメソッドは省略されています):

/// <summary>
/// This message is used to request a resource from the server
/// </summary>
[global::System.Serializable,global::ProtoBuf.ProtoContract(Name=@"GetResource")]
public partial class GetResource : global::ProtoBuf.IExtensible
{
    public GetResource() {}

    private string _resourceId;

    /// <summary>
    /// The identifier of the requested resource 
    /// [Required] <-- Would be nice...
    /// </summary>
    [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"resourceId", 
    DataFormat = global::ProtoBuf.DataFormat.Default)]
    public string ResourceId
    {
        get { return _resourceId; }
        set { _resourceId = value; }
    }
}
4

2 に答える 2

6

実際、現在のバージョンはコメントをサポートしています。--include_source_info で有効にできます。

コメントは、descriptor.Location[n].leading_comments および Trailing_comments で利用できます: https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto

対応するプロパティを protobuf-net Location クラスに追加しました。

private string _leading_comments = "";
[global::ProtoBuf.ProtoMember(3, IsRequired = false, Name = @"leading_comments", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue("")]
public string leading_comments
{
    get { return _leading_comments; }
    set { _leading_comments = value; }
}

private string _trailing_comments = "";
[global::ProtoBuf.ProtoMember(4, IsRequired = false, Name = @"trailing_comments", DataFormat = global::ProtoBuf.DataFormat.Default)]
[global::System.ComponentModel.DefaultValue("")]
public string trailing_comments
{
    get { return _trailing_comments; }
    set { _trailing_comments = value; }
}

また、protoc 呼び出しに --include_source_info を追加 (ProtoBuf.CodeGenerator.InputFileLoader)

コメント付きの場所が、生成された xml に追加されました。

<?xml version="1.0" encoding="utf-16"?>
<FileDescriptorSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <file>
    <FileDescriptorProto>
      <name>Test.proto</name>
      <dependency />
      <message_type>
        <DescriptorProto>
          <name>Test2</name>
          <field>
            <FieldDescriptorProto>
              <name>IntValue</name>
              <number>1</number>
              <type>TYPE_INT32</type>
            </FieldDescriptorProto>
          </field>
          <extension />
          <nested_type />
          <enum_type />
          <extension_range />
        </DescriptorProto>
      </message_type>
      <enum_type />
      <service />
      <extension />
      <source_code_info>
        <location>
...
        <Location>
            <path>
              <int>4</int>
              <int>0</int>
              <int>2</int>
              <int>0</int>
            </path>
            <span>
              <int>1</int>
              <int>0</int>
              <int>28</int>
            </span>
            <trailing_comments> some comment
</trailing_comments>
          </Location>
...
          </location>
      </source_code_info>
    </FileDescriptorProto>
  </file>
</FileDescriptorSet>

ソース .proto:

message Test2{
optional int32 IntValue = 1;// some comment
}

しかし、生成された CS ファイルにコメントを含めるように ProtoGen/csharp.xslt を更新する xslt は得意ではありません。

于 2013-04-17T20:41:00.777 に答える
3

現時点では、答えは「いいえ」だと思います。私の知る限りでは、"protoc" (ボンネットの下で使用される .proto ファイルを解析するための Google のツール) はコメントを黙って破棄するため、何も読み取ることができません。カスタム パーサーが作成されている場合は可能ですが、次のように、どのコメントがどの行に適用されるかという言語のあいまいさもあります。

// this probably relates to resourceId
required string resourceId = 1;

required int foo = 2; // but... is this foo? or bar?
                      // and what about this?

       // what does this relate to? and why?

// and this? what are the rules?
required int bar = 3;

したがって、2 つの異なる理由があります。現時点では、いいえです。ただし、すべての提案が考慮されます...特にカスタムパーサーが含まれている場合:)

知る限り、この情報はほとんどの (すべて?) 実装から欠落していることに注意してください。でも直ってくれると嬉しいです。

于 2013-02-12T14:58:58.747 に答える