Skip to content

Commit b855144

Browse files
authored
Merge pull request #312 from fische/master
Do not add imports from methods with no bindings.
2 parents fdf0869 + bb3b7c7 commit b855144

File tree

8 files changed

+214
-96
lines changed

8 files changed

+214
-96
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Here's the recommended process of contribution.
99
4. Make sure that your change follows best practices in Go
1010
* [Effective Go](https://golang.org/doc/effective_go.html)
1111
* [Go Code Review Comments](https://golang.org/wiki/CodeReviewComments)
12-
5. Make sure that `make test` passes.
12+
5. Make sure that `make test` passes. (use swagger-codegen 2.1.6, not newer versions)
1313
6. Sign [a Contributor License Agreement](https://cla.developers.google.com/clas)
1414
7. Open a pull request in Github
1515

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package abe
2+
3+
import (
4+
)
5+
6+
type ProtobufDuration struct {
7+
Seconds string `json:"seconds,omitempty"`
8+
Nanos int32 `json:"nanos,omitempty"`
9+
10+
}

examples/examplepb/a_bit_of_everything.pb.go

Lines changed: 92 additions & 89 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/examplepb/a_bit_of_everything.proto

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package grpc.gateway.examples.examplepb;
44

55
import "google/api/annotations.proto";
66
import "google/protobuf/empty.proto";
7+
import "google/protobuf/duration.proto";
78
import "examples/sub/message.proto";
89
import "examples/sub2/message.proto";
910
import "google/protobuf/timestamp.proto";
@@ -123,7 +124,7 @@ service ABitOfEverythingService {
123124
body: "*"
124125
};
125126
}
126-
rpc NoBindings(google.protobuf.Empty) returns (google.protobuf.Empty) {}
127+
rpc NoBindings(google.protobuf.Duration) returns (google.protobuf.Empty) {}
127128
rpc Timeout(google.protobuf.Empty) returns (google.protobuf.Empty) {
128129
option (google.api.http) = {
129130
get: "/v2/example/timeout",

examples/examplepb/a_bit_of_everything.swagger.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,22 @@
718718
"default": "ZERO",
719719
"description": "NumericEnum is one or zero.\n\n - ZERO: ZERO means 0\n - ONE: ONE means 1"
720720
},
721+
"protobufDuration": {
722+
"type": "object",
723+
"properties": {
724+
"seconds": {
725+
"type": "string",
726+
"format": "int64",
727+
"description": "Signed seconds of the span of time. Must be from -315,576,000,000\nto +315,576,000,000 inclusive."
728+
},
729+
"nanos": {
730+
"type": "integer",
731+
"format": "int32",
732+
"description": "Signed fractions of a second at nanosecond resolution of the span\nof time. Durations less than one second are represented with a 0\n`seconds` field and a positive or negative `nanos` field. For durations\nof one second or more, a non-zero value for the `nanos` field must be\nof the same sign as the `seconds` field. Must be from -999,999,999\nto +999,999,999 inclusive."
733+
}
734+
},
735+
"description": "A Duration represents a signed, fixed-length span of time represented\nas a count of seconds and fractions of seconds at nanosecond\nresolution. It is independent of any calendar and concepts like \"day\"\nor \"month\". It is related to Timestamp in that the difference between\ntwo Timestamp values is a Duration and it can be added or subtracted\nfrom a Timestamp. Range is approximately +-10,000 years.\n\nExample 1: Compute Duration from two Timestamps in pseudo code.\n\n Timestamp start = ...;\n Timestamp end = ...;\n Duration duration = ...;\n\n duration.seconds = end.seconds - start.seconds;\n duration.nanos = end.nanos - start.nanos;\n\n if (duration.seconds \u003c 0 \u0026\u0026 duration.nanos \u003e 0) {\n duration.seconds += 1;\n duration.nanos -= 1000000000;\n } else if (durations.seconds \u003e 0 \u0026\u0026 duration.nanos \u003c 0) {\n duration.seconds -= 1;\n duration.nanos += 1000000000;\n }\n\nExample 2: Compute Timestamp from Timestamp + Duration in pseudo code.\n\n Timestamp start = ...;\n Duration duration = ...;\n Timestamp end = ...;\n\n end.seconds = start.seconds + duration.seconds;\n end.nanos = start.nanos + duration.nanos;\n\n if (end.nanos \u003c 0) {\n end.seconds -= 1;\n end.nanos += 1000000000;\n } else if (end.nanos \u003e= 1000000000) {\n end.seconds += 1;\n end.nanos -= 1000000000;\n }\n\nExample 3: Compute Duration from datetime.timedelta in Python.\n\n td = datetime.timedelta(days=3, minutes=10)\n duration = Duration()\n duration.FromTimedelta(td)"
736+
},
721737
"protobufEmpty": {
722738
"type": "object",
723739
"description": "service Foo {\n rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);\n }\n\nThe JSON representation for `Empty` is empty JSON object `{}`.",

examples/server/a_bit_of_everything.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"sync"
77

88
"github.com/golang/glog"
9+
"github.com/golang/protobuf/ptypes/duration"
910
"github.com/golang/protobuf/ptypes/empty"
1011
examples "github.com/grpc-ecosystem/grpc-gateway/examples/examplepb"
1112
sub "github.com/grpc-ecosystem/grpc-gateway/examples/sub"
@@ -234,7 +235,7 @@ func (s *_ABitOfEverythingServer) DeepPathEcho(ctx context.Context, msg *example
234235
return msg, nil
235236
}
236237

237-
func (s *_ABitOfEverythingServer) NoBindings(ctx context.Context, msg *empty.Empty) (*empty.Empty, error) {
238+
func (s *_ABitOfEverythingServer) NoBindings(ctx context.Context, msg *duration.Duration) (*empty.Empty, error) {
238239
return nil, nil
239240
}
240241

protoc-gen-grpc-gateway/gengateway/generator.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
1414
"github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
1515
gen "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator"
16+
options "github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api"
1617
)
1718

1819
var (
@@ -98,10 +99,8 @@ func (g *generator) generate(file *descriptor.File) (string, error) {
9899
for _, svc := range file.Services {
99100
for _, m := range svc.Methods {
100101
pkg := m.RequestType.File.GoPkg
101-
if pkg == file.GoPkg {
102-
continue
103-
}
104-
if pkgSeen[pkg.Path] {
102+
if m.Options == nil || !proto.HasExtension(m.Options, options.E_Http) ||
103+
pkg == file.GoPkg || pkgSeen[pkg.Path] {
105104
continue
106105
}
107106
pkgSeen[pkg.Path] = true
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package gengateway
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
"github.com/golang/protobuf/proto"
8+
protodescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
9+
"github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
10+
)
11+
12+
func TestGenerateServiceWithoutBindings(t *testing.T) {
13+
msgdesc := &protodescriptor.DescriptorProto{
14+
Name: proto.String("ExampleMessage"),
15+
}
16+
msg := &descriptor.Message{
17+
DescriptorProto: msgdesc,
18+
}
19+
msg1 := &descriptor.Message{
20+
DescriptorProto: msgdesc,
21+
File: &descriptor.File{
22+
GoPkg: descriptor.GoPackage{
23+
Path: "github.com/golang/protobuf/ptypes/empty",
24+
Name: "empty",
25+
},
26+
},
27+
}
28+
meth := &protodescriptor.MethodDescriptorProto{
29+
Name: proto.String("Example"),
30+
InputType: proto.String("ExampleMessage"),
31+
OutputType: proto.String("ExampleMessage"),
32+
}
33+
meth1 := &protodescriptor.MethodDescriptorProto{
34+
Name: proto.String("ExampleWithoutBindings"),
35+
InputType: proto.String("empty.Empty"),
36+
OutputType: proto.String("empty.Empty"),
37+
}
38+
svc := &protodescriptor.ServiceDescriptorProto{
39+
Name: proto.String("ExampleService"),
40+
Method: []*protodescriptor.MethodDescriptorProto{meth, meth1},
41+
}
42+
file := descriptor.File{
43+
FileDescriptorProto: &protodescriptor.FileDescriptorProto{
44+
Name: proto.String("example.proto"),
45+
Package: proto.String("example"),
46+
Dependency: []string{"a.example/b/c.proto", "a.example/d/e.proto"},
47+
MessageType: []*protodescriptor.DescriptorProto{msgdesc},
48+
Service: []*protodescriptor.ServiceDescriptorProto{svc},
49+
},
50+
GoPkg: descriptor.GoPackage{
51+
Path: "example.com/path/to/example/example.pb",
52+
Name: "example_pb",
53+
},
54+
Messages: []*descriptor.Message{msg},
55+
Services: []*descriptor.Service{
56+
{
57+
ServiceDescriptorProto: svc,
58+
Methods: []*descriptor.Method{
59+
{
60+
MethodDescriptorProto: meth,
61+
RequestType: msg,
62+
ResponseType: msg,
63+
Bindings: []*descriptor.Binding{
64+
{
65+
HTTPMethod: "GET",
66+
Body: &descriptor.Body{FieldPath: nil},
67+
},
68+
},
69+
},
70+
{
71+
MethodDescriptorProto: meth1,
72+
RequestType: msg1,
73+
ResponseType: msg1,
74+
},
75+
},
76+
},
77+
},
78+
}
79+
g := &generator{}
80+
got, err := g.generate(crossLinkFixture(&file))
81+
if err != nil {
82+
t.Errorf("generate(%#v) failed with %v; want success", file, err)
83+
return
84+
}
85+
if notwanted := `"github.com/golang/protobuf/ptypes/empty"`; strings.Contains(got, notwanted) {
86+
t.Errorf("generate(%#v) = %s; does not want to contain %s", file, got, notwanted)
87+
}
88+
}

0 commit comments

Comments
 (0)