Skip to content

Commit

Permalink
Fix gen-swagger to support more well known types (grpc-ecosystem#496)
Browse files Browse the repository at this point in the history
* Fix gen-swagger to support more well known types
  • Loading branch information
shouichi authored and achew22 committed Dec 23, 2017
1 parent cccb822 commit 0d072b2
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
23 changes: 23 additions & 0 deletions protoc-gen-swagger/genswagger/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,29 @@ var wktSchemas = map[string]schemaCore{
".google.protobuf.Duration": schemaCore{
Type: "string",
},
".google.protobuf.StringValue": schemaCore{
Type: "string",
},
".google.protobuf.Int32Value": schemaCore{
Type: "integer",
Format: "int32",
},
".google.protobuf.Int64Value": schemaCore{
Type: "integer",
Format: "int64",
},
".google.protobuf.FloatValue": schemaCore{
Type: "number",
Format: "float",
},
".google.protobuf.DoubleValue": schemaCore{
Type: "number",
Format: "double",
},
".google.protobuf.BoolValue": schemaCore{
Type: "boolean",
Format: "boolean",
},
}

func listEnumNames(enum *descriptor.Enum) (names []string) {
Expand Down
118 changes: 118 additions & 0 deletions protoc-gen-swagger/genswagger/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -787,3 +787,121 @@ func TestFQMNtoSwaggerName(t *testing.T) {
}
}
}

func TestSchemaOfField(t *testing.T) {
type test struct {
field *descriptor.Field
expected schemaCore
}

tests := []test{
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("primitive_field"),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
},
},
expected: schemaCore{
Type: "string",
},
},
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("repeated_primitive_field"),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
Label: protodescriptor.FieldDescriptorProto_LABEL_REPEATED.Enum(),
},
},
expected: schemaCore{
Type: "array",
Items: &swaggerItemsObject{
Type: "string",
},
},
},
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("wrapped_field"),
TypeName: proto.String(".google.protobuf.StringValue"),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
},
},
expected: schemaCore{
Type: "string",
},
},
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("repeated_wrapped_field"),
TypeName: proto.String(".google.protobuf.StringValue"),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
Label: protodescriptor.FieldDescriptorProto_LABEL_REPEATED.Enum(),
},
},
expected: schemaCore{
Type: "array",
Items: &swaggerItemsObject{
Type: "string",
},
},
},
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("message_field"),
TypeName: proto.String(".example.Message"),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
},
},
expected: schemaCore{
Ref: "#/definitions/exampleMessage",
},
},
}

reg := descriptor.NewRegistry()
reg.Load(&plugin.CodeGeneratorRequest{
ProtoFile: []*protodescriptor.FileDescriptorProto{
{
SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
Name: proto.String("example.proto"),
Package: proto.String("example"),
Dependency: []string{},
MessageType: []*protodescriptor.DescriptorProto{
{
Name: proto.String("Message"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("value"),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
},
},
},
},
EnumType: []*protodescriptor.EnumDescriptorProto{
{
Name: proto.String("Message"),
},
},
Service: []*protodescriptor.ServiceDescriptorProto{},
},
},
})

for _, test := range tests {
actual := schemaOfField(test.field, reg)
if e, a := test.expected.Type, actual.Type; e != a {
t.Errorf("Expected schemaOfField(%v).Type = %s, actual: %s", test.field, e, a)
}
if e, a := test.expected.Ref, actual.Ref; e != a {
t.Errorf("Expected schemaOfField(%v).Ref = %s, actual: %s", test.field, e, a)
}
if e, a := test.expected.Items.getType(), actual.Items.getType(); e != a {
t.Errorf("Expected schemaOfField(%v).Items.Type = %v, actual.Type: %v", test.field, e, a)
}
}
}
7 changes: 7 additions & 0 deletions protoc-gen-swagger/genswagger/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ type schemaCore struct {

type swaggerItemsObject schemaCore

func (o *swaggerItemsObject) getType() string {
if o == nil {
return ""
}
return o.Type
}

// http://swagger.io/specification/#responsesObject
type swaggerResponsesObject map[string]swaggerResponseObject

Expand Down

0 comments on commit 0d072b2

Please sign in to comment.