Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom options are missing from generated results #425

Open
aSapien opened this issue Jul 2, 2020 · 8 comments
Open

custom options are missing from generated results #425

aSapien opened this issue Jul 2, 2020 · 8 comments

Comments

@aSapien
Copy link

aSapien commented Jul 2, 2020

Hi, is there a plan to support custom, user-defined, options?

I'm willing to work on a PR if I can get some guidance and feedback.

Problem:

Custom options usages are missing from the generated descriptors:
Steps to reproduce:

  1. Given the following protos:

service.proto

syntax = "proto3";

package foo.bar;

import "google/protobuf/descriptor.proto";
import "extension.proto";

extend google.protobuf.MethodOptions {
    string a_method_option = 50007;
}

message Foo {
    string a = 1 [(a_field_option) = "field_option_value"];
}

message Bar {
    string a = 1;
}

service MyService {
    rpc GetResource(Foo) returns (Bar) {
        option (a_method_option) = "option_value";
    }
}

extension.proto

syntax = "proto2";

import "google/protobuf/descriptor.proto";

package foo.bar;

extend google.protobuf.FieldOptions {
    optional string a_field_option = 50008;
}
  1. Running protocc --doc_out=. --doc_opt=json,service.json service.proto will produce the following result (scalarValueTypes ommited):

Notice that a_field_option is completely missing from the result and a_method_option is only present as a definition, but not in usage.

NOTE: I noticed the efforts made and mentioned in issue #233, but they seem to hard-code a closed list of specific "supported" options.

service.json

{
  "files": [
    {
      "name": "service.proto",
      "description": "",
      "package": "foo.bar",
      "hasEnums": false,
      "hasExtensions": true,
      "hasMessages": true,
      "hasServices": true,
      "enums": [],
      "extensions": [
        {
          "name": "a_method_option",
          "longName": ".google.protobuf.MethodOptions.a_method_option",
          "fullName": ".google.protobuf.MethodOptions.a_method_option",
          "description": "",
          "label": "",
          "type": "string",
          "longType": "string",
          "fullType": "string",
          "number": 50007,
          "defaultValue": "",
          "containingType": "MethodOptions",
          "containingLongType": ".google.protobuf.MethodOptions",
          "containingFullType": "google.protobuf.MethodOptions"
        }
      ],
      "messages": [
        {
          "name": "Bar",
          "longName": "Bar",
          "fullName": "foo.bar.Bar",
          "description": "",
          "hasExtensions": false,
          "hasFields": true,
          "extensions": [],
          "fields": [
            {
              "name": "a",
              "description": "",
              "label": "",
              "type": "string",
              "longType": "string",
              "fullType": "string",
              "ismap": false,
              "defaultValue": ""
            }
          ]
        },
        {
          "name": "Foo",
          "longName": "Foo",
          "fullName": "foo.bar.Foo",
          "description": "",
          "hasExtensions": false,
          "hasFields": true,
          "extensions": [],
          "fields": [
            {
              "name": "a",
              "description": "",
              "label": "",
              "type": "string",
              "longType": "string",
              "fullType": "string",
              "ismap": false,
              "defaultValue": ""
            }
          ]
        }
      ],
      "services": [
        {
          "name": "MyService",
          "longName": "MyService",
          "fullName": "foo.bar.MyService",
          "description": "",
          "methods": [
            {
              "name": "GetResource",
              "description": "",
              "requestType": "Foo",
              "requestLongType": "Foo",
              "requestFullType": "foo.bar.Foo",
              "requestStreaming": false,
              "responseType": "Bar",
              "responseLongType": "Bar",
              "responseFullType": "foo.bar.Bar",
              "responseStreaming": false
            }
          ]
        }
      ]
    }
  ]
}

Ideally, I would like to see the options in the generated result like this:

{
  "files": [
+    {
+      "name": "extension.proto",
+      "description": "",
+      "package": "foo.bar",
+      "hasEnums": false,
+      "hasExtensions": true,
+      "hasMessages": false,
+      "hasServices": false,
+      "enums": [],
+      "extensions": [
+        {
+          "name": "a_field_option",
+          "longName": ".google.protobuf.FieldOptions.a_field_option",
+          "fullName": ".google.protobuf.FieldOptions.a_field_option",
+          "description": "",
+          "label": "",
+          "type": "string",
+          "longType": "string",
+          "fullType": "string",
+          "number": 50008,
+          "defaultValue": "",
+          "containingType": "MethodOptions",
+          "containingLongType": ".google.protobuf.FieldOptions",
+          "containingFullType": "google.protobuf.FieldOptions"
+        }
+      ]
+    },
    {
      "name": "service.proto",
      "description": "",
      "package": "foo.bar",
      "hasEnums": false,
      "hasExtensions": true,
      "hasMessages": true,
      "hasServices": true,
      "enums": [],
      "extensions": [
        {
          "name": "a_method_option",
          "longName": ".google.protobuf.MethodOptions.a_method_option",
          "fullName": ".google.protobuf.MethodOptions.a_method_option",
          "description": "",
          "label": "",
          "type": "string",
          "longType": "string",
          "fullType": "string",
          "number": 50007,
          "defaultValue": "",
          "containingType": "MethodOptions",
          "containingLongType": ".google.protobuf.MethodOptions",
          "containingFullType": "google.protobuf.MethodOptions"
        }
      ],
      "messages": [
        {
          "name": "Bar",
          "longName": "Bar",
          "fullName": "foo.bar.Bar",
          "description": "",
          "hasExtensions": false,
          "hasFields": true,
          "extensions": [],
          "fields": [
            {
              "name": "a",
              "description": "",
              "label": "",
              "type": "string",
              "longType": "string",
              "fullType": "string",
              "ismap": false,
              "defaultValue": ""
            }
          ]
        },
        {
          "name": "Foo",
          "longName": "Foo",
          "fullName": "foo.bar.Foo",
          "description": "",
          "hasExtensions": false,
          "hasFields": true,
          "extensions": [],
          "fields": [
            {
              "name": "a",
              "description": "",
              "label": "",
              "type": "string",
              "longType": "string",
              "fullType": "string",
              "ismap": false,
              "defaultValue": "",
+              "extensions": [                
+                {
+                  "fullName": ".google.protobuf.FieldOptions.a_field_option",
+                  "name": "a_field_option",
+                  "type": "string",
+                  "value": "field_option_value"
+                }
+              ]
            }
          ]
        }
      ],
      "services": [
        {
          "name": "MyService",
          "longName": "MyService",
          "fullName": "foo.bar.MyService",
          "description": "",
          "methods": [
            {
              "name": "GetResource",
              "description": "",
              "requestType": "Foo",
              "requestLongType": "Foo",
              "requestFullType": "foo.bar.Foo",
              "requestStreaming": false,
              "responseType": "Bar",
              "responseLongType": "Bar",
              "responseFullType": "foo.bar.Bar",
              "responseStreaming": false,
+              "extensions": [
+                {
+                  "fullName": ".google.protobuf.MethodOptions.a_method_option",
+                  "name": "a_method_option",
+                  "type": "string",
+                  "value": "option_value"
+                }
+              ]
            }
          ]
        }
      ]
    }
  ]

Any assistance on how to accomplish this and possible solutions discussions are highly appreciated.

Thanks!

@barakt11
Copy link

barakt11 commented Jul 14, 2020

@pseudomuto - can you assist? I find it really precious

@mehran-prs
Copy link

Any update?

@jase88
Copy link

jase88 commented Nov 25, 2021

Would be a great feature if custom options would be considered.

https://developers.google.com/protocol-buffers/docs/proto#customoptions lists some usages on messages, fields, enums, services etc

@bobtiernay-okta
Copy link

Agreed. This would be highly valuable for a number of scenarios.

@pseudomuto
Copy link
Owner

I'm fairly swamped atm. Anyone interested in giving this a go? I think we'd need to add the feature to https://github.com/pseudomuto/protokit and then update the rendering code here to print out the custom option details.

@abdelhalim
Copy link

I'm seeing some code related to options in the HTML template. what is the overall status of Field Options support in protoc-gen-doc ? is it supported only for subset as described above, or there is support but it's limited to HTML ?

@swinSpo
Copy link

swinSpo commented Feb 13, 2022

@pseudomuto can you give us an update on this please? This seems like a very important and useful feature.

@renjiexu
Copy link

Really looking forward to having this feature, bumping this thread again..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants