├── .circleci └── config.yml ├── .gitignore ├── .gitmodules ├── Makefile ├── README.md ├── call.go ├── call_test.go ├── conn.go ├── fallback_resolver.go ├── go.mod ├── go.sum ├── integration_test.go ├── internal ├── echo_service.go ├── echo_service_v2.go ├── everything_service.go ├── run.go ├── server │ ├── .gitignore │ └── main.go └── testdata │ ├── echo_service.pb.go │ ├── echo_service.proto │ ├── everything.pb.go │ ├── everything.proto │ └── v2 │ ├── v2.pb.go │ └── v2.proto ├── list_services.go ├── list_services_test.go ├── main.go └── root.go /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | jobs: 4 | build: 5 | docker: 6 | - image: golang:1.17-bullseye 7 | working_directory: /go/src/github.com/kazegusuri/grpcurl 8 | steps: 9 | - checkout 10 | - run: 11 | name: install dependencies 12 | command: | 13 | make dep 14 | 15 | - run: 16 | name: run tests 17 | command: | 18 | make test 19 | - run: 20 | name: run build 21 | command: | 22 | make build 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /grpcurl 2 | /vendor/ 3 | /_output/ 4 | *.test 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/googleapis"] 2 | path = third_party/googleapis 3 | url = git@github.com:googleapis/googleapis.git 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PKG=github.com/kazegusuri/grpcurl 2 | OUTPUT_DIR=_output 3 | 4 | all: build 5 | 6 | dep: 7 | go mod download 8 | 9 | build: 10 | go build -o grpcurl . 11 | 12 | generate: 13 | mkdir -p $(OUTPUT_DIR) 14 | protoc -I. -Ithird_party/googleapis --go_out=plugins=grpc:$(OUTPUT_DIR) internal/testdata/*.proto 15 | protoc -I. -Ithird_party/googleapis --go_out=plugins=grpc:$(OUTPUT_DIR) internal/testdata/v2/*.proto 16 | cp $(OUTPUT_DIR)/$(PKG)/internal/testdata/*.go internal/testdata/ 17 | cp $(OUTPUT_DIR)/$(PKG)/internal/testdata/v2/*.go internal/testdata/v2/ 18 | 19 | clean: 20 | rm -f internal/testdata/*.pb.go 21 | 22 | .PHONY: test 23 | test: 24 | go test -v github.com/kazegusuri/grpcurl 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **This repository is no longer maintained** 2 | 3 | Instead, I recommend for others to use [grpcurl](https://github.com/fullstorydev/grpcurl) or [evans](https://github.com/ktr0731/evans). 4 | 5 | # grpcurl 6 | 7 | [![CircleCI](https://circleci.com/gh/kazegusuri/grpcurl.svg?style=svg)](https://circleci.com/gh/kazegusuri/grpcurl) 8 | 9 | super experimental 10 | 11 | # Installation 12 | 13 | ``` 14 | go install github.com/kazegusuri/grpcurl@latest 15 | ``` 16 | 17 | # Usage 18 | 19 | ``` 20 | $ grpcurl 21 | A handy and universal gRPC command line client 22 | 23 | Usage: 24 | grpcurl [flags] 25 | grpcurl [command] 26 | 27 | Available Commands: 28 | call Call gRPC method with JSON 29 | help Help about any command 30 | list_services List services and methods provided by gRPC server 31 | 32 | Flags: 33 | -h, --help help for grpcurl 34 | -k, --insecure with insecure 35 | -v, --verbose verbose output 36 | 37 | Use "grpcurl [command] --help" for more information about a command. 38 | ``` 39 | 40 | ### List services 41 | 42 | ``` 43 | $ grpcurl -k ls localhost:8080 44 | test.EchoService 45 | grpc.reflection.v1alpha.ServerReflection 46 | 47 | $ grpcurl -k ls localhost:8080 test.EchoService 48 | test.Test.Echo 49 | ``` 50 | 51 | ### Call gRPC method 52 | 53 | ``` 54 | $ echo '{"Message": "hello"} | grpcurl -k call localhost:8080 test.EchoService.Echo 55 | {"Message":"hello"} 56 | ``` 57 | -------------------------------------------------------------------------------- /call.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "io/ioutil" 7 | "strings" 8 | 9 | "github.com/golang/protobuf/jsonpb" 10 | "github.com/jhump/protoreflect/desc" 11 | "github.com/jhump/protoreflect/dynamic" 12 | "github.com/jhump/protoreflect/dynamic/grpcdynamic" 13 | "github.com/jhump/protoreflect/grpcreflect" 14 | "github.com/spf13/cobra" 15 | "golang.org/x/net/context" 16 | "google.golang.org/grpc" 17 | "google.golang.org/grpc/metadata" 18 | "google.golang.org/grpc/status" 19 | 20 | _ "google.golang.org/genproto/googleapis/rpc/errdetails" 21 | ) 22 | 23 | const ( 24 | requestMessageMarker = "==> Request Message" 25 | responseMessageMarker = "<== Response Message" 26 | responseHeaderMarker = "<== Response Headers" 27 | responseTrailerMarker = "<== Response Trailer" 28 | ) 29 | 30 | type CallCommand struct { 31 | cmd *cobra.Command 32 | opts *GlobalOptions 33 | headers []string 34 | addr string 35 | rcli *grpcreflect.Client 36 | stub grpcdynamic.Stub 37 | marshaler *jsonpb.Marshaler 38 | unmarshaler *jsonpb.Unmarshaler 39 | } 40 | 41 | func NewCallCommand(opts *GlobalOptions) *CallCommand { 42 | c := &CallCommand{ 43 | cmd: &cobra.Command{ 44 | Use: "call ADDR FULL_METHOD_NAME", 45 | Short: "Call gRPC method with JSON", 46 | Example: ` 47 | * call 48 | echo '{"message": "hello"}' | grpcurl call localhost:8888 test.Test.Echo 49 | `, 50 | Args: cobra.ExactArgs(2), 51 | SilenceUsage: true, 52 | }, 53 | opts: opts, 54 | } 55 | c.cmd.RunE = c.Run 56 | c.cmd.Flags().StringArrayVarP(&c.headers, "header", "H", nil, "header") 57 | return c 58 | } 59 | 60 | func (c *CallCommand) Command() *cobra.Command { 61 | return c.cmd 62 | } 63 | 64 | func (c *CallCommand) Run(cmd *cobra.Command, args []string) error { 65 | ctx := context.Background() 66 | 67 | c.addr = args[0] 68 | conn, err := NewGRPCConnection(ctx, c.addr, c.opts.Insecure) 69 | if err != nil { 70 | return err 71 | } 72 | defer conn.Close() 73 | c.rcli = NewServerReflectionClient(ctx, conn) 74 | c.stub = grpcdynamic.NewStub(conn) 75 | c.marshaler = &jsonpb.Marshaler{ 76 | OrigName: true, 77 | EmitDefaults: true, 78 | AnyResolver: DynamicAnyResolver{}, 79 | } 80 | c.unmarshaler = &jsonpb.Unmarshaler{ 81 | AllowUnknownFields: true, 82 | } 83 | 84 | if err := c.call(ctx, args[1], c.opts.Input); err != nil { 85 | return err 86 | } 87 | return nil 88 | } 89 | 90 | func buildOutgoingMetadata(header []string) metadata.MD { 91 | var pairs []string 92 | for i := range header { 93 | parts := strings.SplitN(header[i], ":", 2) 94 | if len(parts) < 2 { 95 | // todo: logging? 96 | continue 97 | } 98 | 99 | k, v := strings.TrimLeft(parts[0], " "), strings.TrimLeft(parts[1], " ") 100 | pairs = append(pairs, k, v) 101 | } 102 | return metadata.Pairs(pairs...) 103 | } 104 | 105 | func (c CallCommand) resolveMessage(fullMethodName string) (*desc.MethodDescriptor, error) { 106 | // assume that fully-qualified method name cosists of 107 | // FULL_SERVER_NAME + "." + METHOD_NAME 108 | // so split the last dot to get service name 109 | n := strings.LastIndex(fullMethodName, ".") 110 | if n < 0 { 111 | return nil, fmt.Errorf("invalid method name: %v", fullMethodName) 112 | } 113 | serviceName := fullMethodName[0:n] 114 | methodName := fullMethodName[n+1:] 115 | 116 | sdesc, err := c.rcli.ResolveService(serviceName) 117 | if err != nil { 118 | return nil, fmt.Errorf("service couldn't be resolve: %v: %v", err, serviceName) 119 | } 120 | 121 | mdesc := sdesc.FindMethodByName(methodName) 122 | if mdesc == nil { 123 | return nil, fmt.Errorf("method couldn't be found") 124 | } 125 | 126 | return mdesc, nil 127 | } 128 | 129 | func (c CallCommand) createMessage(mdesc *desc.MethodDescriptor, r io.Reader) (*dynamic.Message, error) { 130 | msg := dynamic.NewMessage(mdesc.GetInputType()) 131 | input, err := ioutil.ReadAll(r) 132 | if err != nil { 133 | return nil, fmt.Errorf("failed to ReadAll %v", err) 134 | } 135 | if err = msg.UnmarshalJSONPB(c.unmarshaler, input); err != nil { 136 | return nil, fmt.Errorf("unmarshal %v", err) 137 | } 138 | return msg, nil 139 | } 140 | 141 | func (c CallCommand) call(ctx context.Context, fullMethodName string, reader io.Reader) error { 142 | mdesc, err := c.resolveMessage(fullMethodName) 143 | if err != nil { 144 | return err 145 | } 146 | 147 | ctx = metadata.NewOutgoingContext(ctx, buildOutgoingMetadata(c.headers)) 148 | 149 | msg, err := c.createMessage(mdesc, reader) 150 | if err != nil { 151 | return err 152 | } 153 | 154 | if c.opts.Verbose { 155 | reqJSON, err := msg.MarshalJSONPB(c.marshaler) 156 | if err != nil { 157 | return fmt.Errorf("marshal %v", err) 158 | } 159 | fmt.Fprintln(c.opts.Output, requestMessageMarker) 160 | fmt.Fprintf(c.opts.Output, "%s\n", string(reqJSON)) 161 | } 162 | 163 | var headerMD metadata.MD 164 | var trailerMD metadata.MD 165 | resp, err := c.stub.InvokeRpc(ctx, mdesc, msg, grpc.Header(&headerMD), grpc.Trailer(&trailerMD)) 166 | if err != nil { 167 | st, ok := status.FromError(err) 168 | if !ok { 169 | return fmt.Errorf("unknown error: %v", err) 170 | } 171 | 172 | resp = st.Proto() 173 | } 174 | 175 | respJSON, err := c.marshaler.MarshalToString(resp) 176 | if err != nil { 177 | return fmt.Errorf("marshal %v", err) 178 | } 179 | 180 | if c.opts.Verbose { 181 | fmt.Fprintln(c.opts.Output, responseMessageMarker) 182 | } 183 | fmt.Fprintf(c.opts.Output, "%s\n", respJSON) 184 | if c.opts.Verbose { 185 | fmt.Fprintln(c.opts.Output, responseHeaderMarker) 186 | for k, vs := range headerMD { 187 | for i := range vs { 188 | fmt.Fprintf(c.opts.Output, "%s: %s\n", k, vs[i]) 189 | } 190 | } 191 | 192 | fmt.Fprintln(c.opts.Output, responseTrailerMarker) 193 | for k, vs := range trailerMD { 194 | for i := range vs { 195 | fmt.Fprintf(c.opts.Output, "%s: %s\n", k, vs[i]) 196 | } 197 | } 198 | } 199 | 200 | return nil 201 | } 202 | -------------------------------------------------------------------------------- /call_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "os" 6 | "strings" 7 | "testing" 8 | 9 | "github.com/golang/protobuf/jsonpb" 10 | pb "github.com/kazegusuri/grpcurl/internal/testdata" 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | ) 14 | 15 | func ExampleCall() { 16 | cmd := NewRootCommand(strings.NewReader(`{"value": "hello"}`), os.Stdout) 17 | cmd.Command().SetArgs([]string{"-k", "call", addr, "grpcurl.test.Echo.Echo"}) 18 | cmd.Command().Execute() 19 | // Output: 20 | // {"value":"hello","error_code":0} 21 | } 22 | 23 | func testCall(method, msg string) (*bytes.Buffer, error) { 24 | buf := &bytes.Buffer{} 25 | buf.Grow(1024) 26 | cmd := NewRootCommand(strings.NewReader(msg), buf) 27 | cmd.Command().SetArgs([]string{"-k", "call", "-v", addr, method}) 28 | return buf, cmd.Command().Execute() 29 | } 30 | 31 | type testResponse struct { 32 | RequestMessage string 33 | ResponseMessage string 34 | RequestHeader map[string][]string 35 | ResponseHeader map[string][]string 36 | ResponseTrailer map[string][]string 37 | } 38 | 39 | func parseTestResponse(s string) *testResponse { 40 | lines := strings.Split(s, "\n") 41 | 42 | msgs := map[string][]string{} 43 | marker := "" 44 | for i := range lines { 45 | switch lines[i] { 46 | case requestMessageMarker: 47 | marker = requestMessageMarker 48 | case responseMessageMarker: 49 | marker = responseMessageMarker 50 | case responseHeaderMarker: 51 | marker = responseHeaderMarker 52 | case responseTrailerMarker: 53 | marker = responseTrailerMarker 54 | default: 55 | msgs[marker] = append(msgs[marker], lines[i]) 56 | } 57 | } 58 | 59 | return &testResponse{ 60 | RequestMessage: strings.Join(msgs[requestMessageMarker], "\n"), 61 | ResponseMessage: strings.Join(msgs[responseMessageMarker], "\n"), 62 | } 63 | } 64 | 65 | func TestCallEcho(t *testing.T) { 66 | buf, err := testCall("grpcurl.test.Echo.Echo", `{"value": "xxx"}`) 67 | require.NoError(t, err) 68 | resp := parseTestResponse(buf.String()) 69 | expected := `{"value":"xxx","error_code":0}` 70 | assert.Equal(t, expected, resp.RequestMessage, "request message") 71 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 72 | } 73 | 74 | func TestCallEchoEmpty(t *testing.T) { 75 | buf, err := testCall("grpcurl.test.Echo.Echo", `{}`) 76 | require.NoError(t, err) 77 | resp := parseTestResponse(buf.String()) 78 | expected := `{"value":"","error_code":0}` 79 | assert.Equal(t, expected, resp.RequestMessage, "request message") 80 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 81 | } 82 | 83 | func TestCallEchoUnknownField(t *testing.T) { 84 | buf, err := testCall("grpcurl.test.Echo.Echo", `{"xxx": "vvvv"}`) 85 | require.NoError(t, err) 86 | resp := parseTestResponse(buf.String()) 87 | expected := `{"value":"","error_code":0}` 88 | assert.Equal(t, expected, resp.RequestMessage, "request message") 89 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 90 | } 91 | 92 | func TestEverythingSimple(t *testing.T) { 93 | buf, err := testCall( 94 | "grpcurl.test.Everything.Simple", 95 | `{"string_value": "aaa", "bool_value": true}`) 96 | require.NoError(t, err) 97 | resp := parseTestResponse(buf.String()) 98 | expected := `{"string_value":"aaa","bool_value":true}` 99 | assert.Equal(t, expected, resp.RequestMessage, "request message") 100 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 101 | } 102 | 103 | func TestEverythingSimpleEmpty(t *testing.T) { 104 | buf, err := testCall( 105 | "grpcurl.test.Everything.Simple", 106 | `{}`) 107 | require.NoError(t, err) 108 | resp := parseTestResponse(buf.String()) 109 | expected := `{"string_value":"","bool_value":false}` 110 | assert.Equal(t, expected, resp.RequestMessage, "request message") 111 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 112 | } 113 | 114 | func TestEverythingNumber(t *testing.T) { 115 | m := &jsonpb.Marshaler{OrigName: true} 116 | msg, err := m.MarshalToString(&pb.NumberMessage{ 117 | FloatValue: 1.1, 118 | DoubleValue: 2.2, 119 | Int32Value: 3, 120 | Int64Value: 4, 121 | Uint32Value: 5, 122 | Uint64Value: 6, 123 | Sint32Value: 7, 124 | Sint64Value: 8, 125 | Fixed32Value: 9, 126 | Fixed64Value: 10, 127 | Sfixed32Value: 11, 128 | Sfixed64Value: 12, 129 | }) 130 | require.NoError(t, err) 131 | t.Logf("request messge: %q", msg) 132 | 133 | buf, err := testCall("grpcurl.test.Everything.Number", msg) 134 | require.NoError(t, err) 135 | resp := parseTestResponse(buf.String()) 136 | expected := `{"float_value":1.1,"double_value":2.2,"int32_value":3,"int64_value":4,"uint32_value":5,"uint64_value":6,"sint32_value":7,"sint64_value":8,"fixed32_value":9,"fixed64_value":10,"sfixed32_value":11,"sfixed64_value":12}` 137 | assert.Equal(t, expected, resp.RequestMessage, "request message") 138 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 139 | } 140 | 141 | func TestEverythingNumberEmpty(t *testing.T) { 142 | buf, err := testCall("grpcurl.test.Everything.Number", `{}`) 143 | require.NoError(t, err) 144 | resp := parseTestResponse(buf.String()) 145 | expected := `{"float_value":0,"double_value":0,"int32_value":0,"int64_value":0,"uint32_value":0,"uint64_value":0,"sint32_value":0,"sint64_value":0,"fixed32_value":0,"fixed64_value":0,"sfixed32_value":0,"sfixed64_value":0}` 146 | assert.Equal(t, expected, resp.RequestMessage, "request message") 147 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 148 | } 149 | 150 | func TestEverythingEnum(t *testing.T) { 151 | m := &jsonpb.Marshaler{OrigName: true} 152 | msg, err := m.MarshalToString(&pb.EnumMessage{ 153 | NumericEnumValue: pb.NumericEnum_ONE, 154 | RepeatedNumericEnumValues: []pb.NumericEnum{ 155 | pb.NumericEnum_ONE, 156 | pb.NumericEnum_TWO, 157 | }, 158 | AliasedEnumValue: pb.AliasedEnum_RUNNING, 159 | NestedEnumValue: pb.EnumMessage_PENDING, 160 | RepeatedNestedEnumValues: []pb.EnumMessage_Nested{ 161 | pb.EnumMessage_PENDING, 162 | pb.EnumMessage_COMPLETED, 163 | }, 164 | }) 165 | require.NoError(t, err) 166 | t.Logf("request messge: %q", msg) 167 | 168 | buf, err := testCall("grpcurl.test.Everything.Enum", msg) 169 | require.NoError(t, err) 170 | resp := parseTestResponse(buf.String()) 171 | expected := `{"numeric_enum_value":"ONE","repeated_numeric_enum_values":["ONE","TWO"],"aliased_enum_value":"STARTED","nested_enum_value":"PENDING","repeated_nested_enum_values":["PENDING","COMPLETED"]}` 172 | assert.Equal(t, expected, resp.RequestMessage, "request message") 173 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 174 | } 175 | 176 | func TestEverythingEnumAsInt(t *testing.T) { 177 | m := &jsonpb.Marshaler{EnumsAsInts: true, OrigName: true} 178 | msg, err := m.MarshalToString(&pb.EnumMessage{ 179 | NumericEnumValue: pb.NumericEnum_ONE, 180 | RepeatedNumericEnumValues: []pb.NumericEnum{ 181 | pb.NumericEnum_ONE, 182 | pb.NumericEnum_TWO, 183 | }, 184 | AliasedEnumValue: pb.AliasedEnum_RUNNING, 185 | NestedEnumValue: pb.EnumMessage_PENDING, 186 | RepeatedNestedEnumValues: []pb.EnumMessage_Nested{ 187 | pb.EnumMessage_PENDING, 188 | pb.EnumMessage_COMPLETED, 189 | }, 190 | }) 191 | require.NoError(t, err) 192 | t.Logf("request messge: %q", msg) 193 | 194 | buf, err := testCall("grpcurl.test.Everything.Enum", msg) 195 | require.NoError(t, err) 196 | resp := parseTestResponse(buf.String()) 197 | expected := `{"numeric_enum_value":"ONE","repeated_numeric_enum_values":["ONE","TWO"],"aliased_enum_value":"STARTED","nested_enum_value":"PENDING","repeated_nested_enum_values":["PENDING","COMPLETED"]}` 198 | assert.Equal(t, expected, resp.RequestMessage, "request message") 199 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 200 | } 201 | 202 | func TestEverythingEnumEmpty(t *testing.T) { 203 | buf, err := testCall("grpcurl.test.Everything.Enum", `{}`) 204 | require.NoError(t, err) 205 | resp := parseTestResponse(buf.String()) 206 | expected := `{"numeric_enum_value":"ZERO","repeated_numeric_enum_values":[],"aliased_enum_value":"UNKNOWN","nested_enum_value":"UNKNOWN","repeated_nested_enum_values":[]}` 207 | assert.Equal(t, expected, resp.RequestMessage, "request message") 208 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 209 | } 210 | 211 | func TestEverythingOneof1(t *testing.T) { 212 | buf, err := testCall("grpcurl.test.Everything.Oneof", `{"int32_value": 100}`) 213 | require.NoError(t, err) 214 | resp := parseTestResponse(buf.String()) 215 | expected := `{"int32_value":100,"string_value":"","repeated_oneof_values":[]}` 216 | assert.Equal(t, expected, resp.RequestMessage, "request message") 217 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 218 | } 219 | 220 | func TestEverythingOneof2(t *testing.T) { 221 | buf, err := testCall("grpcurl.test.Everything.Oneof", `{"string_value": "xxx"}`) 222 | require.NoError(t, err) 223 | resp := parseTestResponse(buf.String()) 224 | expected := `{"int32_value":0,"string_value":"xxx","repeated_oneof_values":[]}` 225 | assert.Equal(t, expected, resp.RequestMessage, "request message") 226 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 227 | } 228 | 229 | func TestEverythingOneof3(t *testing.T) { 230 | m := &jsonpb.Marshaler{EnumsAsInts: true, OrigName: true} 231 | msg, err := m.MarshalToString(&pb.OneofMessage{ 232 | OneofValue: &pb.OneofMessage_Int32Value{Int32Value: 2000}, 233 | }) 234 | require.NoError(t, err) 235 | t.Logf("request messge: %q", msg) 236 | 237 | buf, err := testCall("grpcurl.test.Everything.Oneof", msg) 238 | require.NoError(t, err) 239 | resp := parseTestResponse(buf.String()) 240 | expected := `{"int32_value":2000,"string_value":"","repeated_oneof_values":[]}` 241 | assert.Equal(t, expected, resp.RequestMessage, "request message") 242 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 243 | } 244 | 245 | func TestEverythingOneofEmpty(t *testing.T) { 246 | buf, err := testCall("grpcurl.test.Everything.Oneof", `{}`) 247 | require.NoError(t, err) 248 | resp := parseTestResponse(buf.String()) 249 | expected := `{"int32_value":0,"string_value":"","repeated_oneof_values":[]}` 250 | assert.Equal(t, expected, resp.RequestMessage, "request message") 251 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 252 | } 253 | 254 | func TestEverythingMap(t *testing.T) { 255 | t.Skip("todo: fix map message order issue") 256 | m := &jsonpb.Marshaler{OrigName: true} 257 | msg, err := m.MarshalToString(&pb.MapMessage{ 258 | MappedValue: map[string]string{ 259 | "foo": "foo1", 260 | "bar": "bar1", 261 | }, 262 | MappedEnumValue: map[string]pb.NumericEnum{ 263 | "one": pb.NumericEnum_ONE, 264 | "two": pb.NumericEnum_TWO, 265 | }, 266 | MappedNestedValue: map[string]*pb.NestedMessage{ 267 | "foo": &pb.NestedMessage{ 268 | NestedValue: &pb.NestedMessage_Nested{ 269 | Int32Value: 100, 270 | StringValue: "xxx", 271 | }, 272 | RepeatedNestedValues: []*pb.NestedMessage_Nested{ 273 | { 274 | Int32Value: 200, 275 | StringValue: "yyy", 276 | }, 277 | { 278 | Int32Value: 300, 279 | StringValue: "zzz", 280 | }, 281 | }, 282 | }, 283 | }, 284 | }) 285 | require.NoError(t, err) 286 | t.Logf("request messge: %q", msg) 287 | 288 | buf, err := testCall("grpcurl.test.Everything.Map", msg) 289 | require.NoError(t, err) 290 | resp := parseTestResponse(buf.String()) 291 | expectedJSON := `{"mapped_value":{"bar":"bar1","foo":"foo1"},"mapped_enum_value":{},"mapped_nested_value":{"foo":{"nested_value":{"int32_value":100,"string_value":"xxx"},"repeated_nested_values":[{"int32_value":200,"string_value":"yyy"},{"int32_value":300,"string_value":"zzz"}]}}}` 292 | 293 | var expected, reqProto, respProto pb.MapMessage 294 | err = jsonpb.UnmarshalString(expectedJSON, &expected) 295 | require.NoError(t, err) 296 | err = jsonpb.UnmarshalString(resp.RequestMessage, &reqProto) 297 | require.NoError(t, err) 298 | err = jsonpb.UnmarshalString(resp.ResponseMessage, &respProto) 299 | require.NoError(t, err) 300 | assert.Equal(t, expected, reqProto, "request message") 301 | assert.Equal(t, expected, respProto, "response message") 302 | } 303 | 304 | func TestEverythingMapEmpty(t *testing.T) { 305 | buf, err := testCall("grpcurl.test.Everything.Map", `{}`) 306 | require.NoError(t, err) 307 | resp := parseTestResponse(buf.String()) 308 | expected := `{"mapped_value":{},"mapped_enum_value":{},"mapped_nested_value":{}}` 309 | assert.Equal(t, expected, resp.RequestMessage, "request message") 310 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 311 | } 312 | 313 | func TestEverythingGoogle(t *testing.T) { 314 | buf, err := testCall( 315 | "grpcurl.test.Everything.Google", 316 | `{"info":{"request_id":"xxx","serving_data":"xyz"}}`) 317 | require.NoError(t, err) 318 | resp := parseTestResponse(buf.String()) 319 | expected := `{"info":{"request_id":"xxx","serving_data":"xyz"}}` 320 | assert.Equal(t, expected, resp.RequestMessage, "request message") 321 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 322 | } 323 | 324 | func TestEchoV2Echo(t *testing.T) { 325 | // cross package message 326 | buf, err := testCall( 327 | "grpcurl.test.v2.Echo.Echo", 328 | `{"value": "xxx"}`) 329 | require.NoError(t, err) 330 | resp := parseTestResponse(buf.String()) 331 | expected := `{"value":"xxx","error_code":0}` 332 | assert.Equal(t, expected, resp.RequestMessage, "request message") 333 | assert.Equal(t, expected, resp.ResponseMessage, "response message") 334 | } 335 | -------------------------------------------------------------------------------- /conn.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/jhump/protoreflect/grpcreflect" 5 | "golang.org/x/net/context" 6 | "google.golang.org/grpc" 7 | "google.golang.org/grpc/credentials" 8 | rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" 9 | ) 10 | 11 | func NewGRPCConnection(ctx context.Context, addr string, insecure bool) (*grpc.ClientConn, error) { 12 | var dialOpts []grpc.DialOption 13 | if insecure { 14 | dialOpts = append(dialOpts, grpc.WithInsecure()) 15 | } else { 16 | dialOpts = append(dialOpts, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, ""))) 17 | } 18 | 19 | return grpc.DialContext(ctx, addr, dialOpts...) 20 | } 21 | 22 | func NewServerReflectionClient(ctx context.Context, conn *grpc.ClientConn) *grpcreflect.Client { 23 | cli := rpb.NewServerReflectionClient(conn) 24 | return grpcreflect.NewClient(ctx, cli) 25 | } 26 | -------------------------------------------------------------------------------- /fallback_resolver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "strings" 7 | 8 | "github.com/golang/protobuf/jsonpb" 9 | "github.com/golang/protobuf/proto" 10 | "github.com/golang/protobuf/ptypes/empty" 11 | ) 12 | 13 | // DynamicAnyResolver is like the default jsonpb.AnyResolver but, instead of 14 | // returning error, it will fallback to an Empty type if the type is not 15 | // registered. This allows the jsonpb Marshaler to not simply give up in case 16 | // an unknown type is encountered. Because the type is Empty, all fields in 17 | // that the unknown type will implicitly end up as unrecognized, and the JSON 18 | // marshaler will emit them as map key/values. 19 | type DynamicAnyResolver struct { 20 | jsonpb.AnyResolver // https://godoc.org/github.com/golang/protobuf/jsonpb#AnyResolver 21 | } 22 | 23 | // Resolve implements jsonpb.AnyResolver.Resolve 24 | func (DynamicAnyResolver) Resolve(typeURL string) (proto.Message, error) { 25 | msg, err := defaultResolveAny(typeURL) 26 | if err == nil { 27 | return msg, nil 28 | } 29 | return &empty.Empty{}, nil 30 | } 31 | 32 | // copied from https://github.com/golang/protobuf/blob/c823c79ea1570fb5ff454033735a8e68575d1d0f/jsonpb/jsonpb.go#L92-L103 33 | func defaultResolveAny(typeURL string) (proto.Message, error) { 34 | // Only the part of typeUrl after the last slash is relevant. 35 | mname := typeURL 36 | if slash := strings.LastIndex(mname, "/"); slash >= 0 { 37 | mname = mname[slash+1:] 38 | } 39 | mt := proto.MessageType(mname) 40 | if mt == nil { 41 | return nil, fmt.Errorf("unknown message type %q", mname) 42 | } 43 | return reflect.New(mt.Elem()).Interface().(proto.Message), nil 44 | } 45 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/kazegusuri/grpcurl 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/golang/glog v1.0.0 7 | github.com/golang/protobuf v1.5.2 8 | github.com/jhump/protoreflect v0.0.0-20180728174811-86d31fcaca06 9 | github.com/spf13/cobra v1.4.0 10 | github.com/stretchr/testify v1.7.0 11 | golang.org/x/net v0.8.0 12 | google.golang.org/api v0.76.0 13 | google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4 14 | google.golang.org/grpc v1.45.0 15 | ) 16 | 17 | require ( 18 | cloud.google.com/go/compute v1.6.0 // indirect 19 | github.com/davecgh/go-spew v1.1.0 // indirect 20 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect 21 | github.com/googleapis/gax-go/v2 v2.3.0 // indirect 22 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 23 | github.com/pmezard/go-difflib v1.0.0 // indirect 24 | github.com/spf13/pflag v1.0.5 // indirect 25 | go.opencensus.io v0.23.0 // indirect 26 | golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect 27 | golang.org/x/sys v0.6.0 // indirect 28 | golang.org/x/text v0.8.0 // indirect 29 | google.golang.org/appengine v1.6.7 // indirect 30 | google.golang.org/protobuf v1.28.0 // indirect 31 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect 32 | ) 33 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 16 | cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= 17 | cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= 18 | cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= 19 | cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= 20 | cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= 21 | cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= 22 | cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= 23 | cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= 24 | cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= 25 | cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= 26 | cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= 27 | cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= 28 | cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= 29 | cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= 30 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 31 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 32 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 33 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 34 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 35 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 36 | cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= 37 | cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= 38 | cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= 39 | cloud.google.com/go/compute v1.6.0 h1:XdQIN5mdPTSBVwSIVDuY5e8ZzVAccsHvD3qTEz4zIps= 40 | cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= 41 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 42 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 43 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 44 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 45 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 46 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 47 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 48 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 49 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 50 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 51 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 52 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 53 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 54 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 55 | github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 56 | github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= 57 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 58 | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= 59 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 60 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 61 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 62 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 63 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 64 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 65 | github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 66 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 67 | github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= 68 | github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 69 | github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 70 | github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 71 | github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 72 | github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 73 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 74 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 75 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 76 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 77 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 78 | github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 79 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 80 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 81 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= 82 | github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= 83 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 84 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 85 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 86 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 87 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 88 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 89 | github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= 90 | github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= 91 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 92 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 93 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= 94 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 95 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 96 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 97 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 98 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 99 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 100 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 101 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 102 | github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= 103 | github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 104 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 105 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 106 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 107 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 108 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 109 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 110 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 111 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 112 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 113 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 114 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 115 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 116 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 117 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 118 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 119 | github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= 120 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 121 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 122 | github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 123 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 124 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 125 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 126 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 127 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 128 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 129 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 130 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 131 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 132 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 133 | github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 134 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 135 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 136 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 137 | github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= 138 | github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= 139 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 140 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 141 | github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 142 | github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= 143 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 144 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 145 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 146 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 147 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 148 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 149 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 150 | github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 151 | github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 152 | github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 153 | github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 154 | github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 155 | github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 156 | github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 157 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 158 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 159 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 160 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 161 | github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= 162 | github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= 163 | github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= 164 | github.com/googleapis/gax-go/v2 v2.3.0 h1:nRJtk3y8Fm770D42QV6T90ZnvFZyk7agSo3Q+Z9p3WI= 165 | github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= 166 | github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 167 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 168 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 169 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 170 | github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 171 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 172 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 173 | github.com/jhump/protoreflect v0.0.0-20180728174811-86d31fcaca06 h1:V8H9P+ZDQ/R8yLAJsSNKxPOFM1jH2XRMc3Wr4wXapcU= 174 | github.com/jhump/protoreflect v0.0.0-20180728174811-86d31fcaca06/go.mod h1:eki7DI0mJrpRlDikO63gRZIG0keYYxgKDUdI2QmkZCQ= 175 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 176 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 177 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 178 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 179 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 180 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 181 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 182 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 183 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 184 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 185 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 186 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= 187 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 188 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 189 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 190 | github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= 191 | github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= 192 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 193 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 194 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 195 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 196 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 197 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 198 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 199 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 200 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 201 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 202 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 203 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 204 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 205 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 206 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 207 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 208 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 209 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 210 | go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= 211 | go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= 212 | go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 213 | go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 214 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 215 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 216 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 217 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 218 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 219 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 220 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 221 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 222 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 223 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 224 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 225 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 226 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 227 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 228 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 229 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 230 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 231 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 232 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 233 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 234 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 235 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 236 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 237 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 238 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 239 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 240 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 241 | golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 242 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 243 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 244 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 245 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 246 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 247 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 248 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 249 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 250 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 251 | golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 252 | golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 253 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 254 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 255 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 256 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 257 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 258 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 259 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 260 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 261 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 262 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 263 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 264 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 265 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 266 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 267 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 268 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 269 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 270 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 271 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 272 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 273 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 274 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 275 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 276 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 277 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 278 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 279 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 280 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 281 | golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 282 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 283 | golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 284 | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 285 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 286 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= 287 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 288 | golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 289 | golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 290 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 291 | golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 292 | golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 293 | golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= 294 | golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= 295 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 296 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 297 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 298 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 299 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 300 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 301 | golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 302 | golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 303 | golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 304 | golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 305 | golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 306 | golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 307 | golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 308 | golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 309 | golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 310 | golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 311 | golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= 312 | golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= 313 | golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= 314 | golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= 315 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 316 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 317 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 318 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 319 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 320 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 321 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 322 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 323 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 324 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 325 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 326 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 327 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 328 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 329 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 330 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 331 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 332 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 333 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 334 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 335 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 336 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 337 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 338 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 339 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 340 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 341 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 342 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 343 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 344 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 345 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 346 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 347 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 348 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 349 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 350 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 351 | golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 352 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 353 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 354 | golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 355 | golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 356 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 357 | golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 358 | golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 359 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 360 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 361 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 362 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 363 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 364 | golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 365 | golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 366 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 367 | golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 368 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 369 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 370 | golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 371 | golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 372 | golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 373 | golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 374 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 375 | golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 376 | golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 377 | golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 378 | golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 379 | golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 380 | golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= 381 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 382 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 383 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 384 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 385 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 386 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 387 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 388 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 389 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 390 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 391 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 392 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 393 | golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= 394 | golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 395 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 396 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 397 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 398 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 399 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 400 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 401 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 402 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 403 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 404 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 405 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 406 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 407 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 408 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 409 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 410 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 411 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 412 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 413 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 414 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 415 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 416 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 417 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 418 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 419 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 420 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 421 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 422 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 423 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 424 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 425 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 426 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 427 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 428 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 429 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 430 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 431 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 432 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 433 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 434 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 435 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 436 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 437 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 438 | golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= 439 | golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 440 | golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 441 | golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 442 | golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 443 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 444 | golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 445 | golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 446 | golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 447 | golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 448 | golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 449 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 450 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 451 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 452 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 453 | golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= 454 | golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 455 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 456 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 457 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 458 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 459 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 460 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 461 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 462 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 463 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 464 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 465 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 466 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 467 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 468 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 469 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 470 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 471 | google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= 472 | google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= 473 | google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= 474 | google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= 475 | google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= 476 | google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= 477 | google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= 478 | google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= 479 | google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= 480 | google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= 481 | google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= 482 | google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= 483 | google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= 484 | google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= 485 | google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= 486 | google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= 487 | google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= 488 | google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= 489 | google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= 490 | google.golang.org/api v0.76.0 h1:UkZl25bR1FHNqtK/EKs3vCdpZtUO6gea3YElTwc8pQg= 491 | google.golang.org/api v0.76.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= 492 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 493 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 494 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 495 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 496 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 497 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 498 | google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= 499 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 500 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 501 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 502 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 503 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 504 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 505 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 506 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 507 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 508 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 509 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 510 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 511 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 512 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 513 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 514 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 515 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 516 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 517 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 518 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 519 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 520 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 521 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 522 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 523 | google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 524 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 525 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 526 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 527 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 528 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 529 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 530 | google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 531 | google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 532 | google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 533 | google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 534 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 535 | google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 536 | google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 537 | google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 538 | google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 539 | google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= 540 | google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= 541 | google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= 542 | google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= 543 | google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= 544 | google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= 545 | google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= 546 | google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= 547 | google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= 548 | google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= 549 | google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= 550 | google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= 551 | google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= 552 | google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= 553 | google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= 554 | google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= 555 | google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 556 | google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 557 | google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 558 | google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 559 | google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 560 | google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 561 | google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 562 | google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= 563 | google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= 564 | google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= 565 | google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= 566 | google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= 567 | google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= 568 | google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= 569 | google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4 h1:myaecH64R0bIEDjNORIel4iXubqzaHU1K2z8ajBwWcM= 570 | google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= 571 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 572 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 573 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 574 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 575 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 576 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 577 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 578 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 579 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 580 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 581 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 582 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 583 | google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 584 | google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= 585 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= 586 | google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= 587 | google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 588 | google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 589 | google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 590 | google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 591 | google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 592 | google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 593 | google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= 594 | google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= 595 | google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= 596 | google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= 597 | google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= 598 | google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= 599 | google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= 600 | google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 601 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 602 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 603 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 604 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 605 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 606 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 607 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 608 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 609 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 610 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 611 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 612 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 613 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 614 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 615 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 616 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 617 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 618 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 619 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 620 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 621 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 622 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 623 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 624 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 625 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 626 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 627 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 628 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 629 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 630 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 631 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 632 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 633 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 634 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 635 | -------------------------------------------------------------------------------- /integration_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "testing" 8 | 9 | "github.com/kazegusuri/grpcurl/internal" 10 | ) 11 | 12 | var ( 13 | testPort = 35982 14 | addr = fmt.Sprintf("localhost:%d", testPort) 15 | ) 16 | 17 | func TestMain(m *testing.M) { 18 | ctx := context.Background() 19 | go func() { 20 | if err := test.RunServer(ctx, testPort); err != nil { 21 | fmt.Fprintf(os.Stderr, "failed to start server: %v", err) 22 | os.Exit(1) 23 | } 24 | }() 25 | os.Exit(m.Run()) 26 | } 27 | -------------------------------------------------------------------------------- /internal/echo_service.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "io" 5 | 6 | pb "github.com/kazegusuri/grpcurl/internal/testdata" 7 | "golang.org/x/net/context" 8 | "google.golang.org/grpc" 9 | "google.golang.org/grpc/codes" 10 | ) 11 | 12 | type EchoService struct{} 13 | 14 | func NewEchoService() *EchoService { 15 | return &EchoService{} 16 | } 17 | 18 | func (s *EchoService) Echo(ctx context.Context, in *pb.EchoMessage) (*pb.EchoMessage, error) { 19 | if in.ErrorCode != 0 { 20 | return nil, grpc.Errorf(codes.Code(in.ErrorCode), "error msg: %v", in.Value) 21 | } 22 | 23 | return &pb.EchoMessage{Value: in.Value}, nil 24 | } 25 | 26 | func (s *EchoService) ClientStreamingEcho(stream pb.Echo_ClientStreamingEchoServer) error { 27 | value := "" 28 | for { 29 | msg, err := stream.Recv() 30 | if err == io.EOF { 31 | break 32 | } 33 | if err != nil { 34 | return err 35 | } 36 | 37 | value = msg.Value 38 | if msg.ErrorCode != 0 { 39 | return grpc.Errorf(codes.Code(msg.ErrorCode), "error msg: %v", msg.Value) 40 | } 41 | } 42 | 43 | if err := stream.SendAndClose(&pb.EchoMessage{Value: value}); err != nil { 44 | return err 45 | } 46 | 47 | return nil 48 | } 49 | 50 | func (s *EchoService) ServerStreamingEcho(in *pb.EchoMessage, stream pb.Echo_ServerStreamingEchoServer) error { 51 | if in.ErrorCode != 0 { 52 | return grpc.Errorf(codes.Code(in.ErrorCode), "error msg: %v", in.Value) 53 | } 54 | 55 | for i := 0; i < 10; i++ { 56 | if err := stream.Send(&pb.EchoMessage{Value: in.Value}); err != nil { 57 | return err 58 | } 59 | } 60 | return nil 61 | } 62 | 63 | func (s *EchoService) BidiStreamingBulkEcho(stream pb.Echo_BidiStreamingBulkEchoServer) error { 64 | for { 65 | msg, err := stream.Recv() 66 | if err == io.EOF { 67 | break 68 | } 69 | if err != nil { 70 | return err 71 | } 72 | 73 | if msg.ErrorCode != 0 { 74 | return grpc.Errorf(codes.Code(msg.ErrorCode), "error msg: %v", msg.Value) 75 | } 76 | 77 | if err := stream.Send(msg); err != nil { 78 | return err 79 | } 80 | } 81 | 82 | return nil 83 | } 84 | -------------------------------------------------------------------------------- /internal/echo_service_v2.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | pb "github.com/kazegusuri/grpcurl/internal/testdata" 5 | "golang.org/x/net/context" 6 | ) 7 | 8 | type EchoServiceV2 struct{} 9 | 10 | func NewEchoServiceV2() *EchoServiceV2 { 11 | return &EchoServiceV2{} 12 | } 13 | 14 | func (s *EchoServiceV2) Echo(ctx context.Context, in *pb.EchoMessage) (*pb.EchoMessage, error) { 15 | return &pb.EchoMessage{Value: in.Value}, nil 16 | } 17 | -------------------------------------------------------------------------------- /internal/everything_service.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | pb "github.com/kazegusuri/grpcurl/internal/testdata" 5 | "golang.org/x/net/context" 6 | ) 7 | 8 | type EverythingService struct{} 9 | 10 | func NewEverythingService() *EverythingService { 11 | return &EverythingService{} 12 | } 13 | 14 | func (s *EverythingService) Simple(ctx context.Context, in *pb.SimpleMessage) (*pb.SimpleMessage, error) { 15 | return in, nil 16 | } 17 | 18 | func (s *EverythingService) Number(ctx context.Context, in *pb.NumberMessage) (*pb.NumberMessage, error) { 19 | return in, nil 20 | } 21 | 22 | func (s *EverythingService) Enum(ctx context.Context, in *pb.EnumMessage) (*pb.EnumMessage, error) { 23 | return in, nil 24 | } 25 | 26 | func (s *EverythingService) Oneof(ctx context.Context, in *pb.OneofMessage) (*pb.OneofMessage, error) { 27 | return in, nil 28 | } 29 | 30 | func (s *EverythingService) Map(ctx context.Context, in *pb.MapMessage) (*pb.MapMessage, error) { 31 | return in, nil 32 | } 33 | 34 | func (s *EverythingService) Google(ctx context.Context, in *pb.GoogleMessage) (*pb.GoogleMessage, error) { 35 | return in, nil 36 | } 37 | -------------------------------------------------------------------------------- /internal/run.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | 8 | pb "github.com/kazegusuri/grpcurl/internal/testdata" 9 | pbv2 "github.com/kazegusuri/grpcurl/internal/testdata/v2" 10 | "google.golang.org/grpc" 11 | "google.golang.org/grpc/reflection" 12 | ) 13 | 14 | func RunServer(ctx context.Context, port int) error { 15 | ctx, cancel := context.WithCancel(ctx) 16 | defer cancel() 17 | 18 | l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) 19 | if err != nil { 20 | return fmt.Errorf("failed to list: %v", err) 21 | } 22 | s := grpc.NewServer() 23 | defer s.Stop() 24 | 25 | go func() { 26 | pb.RegisterEchoServer(s, NewEchoService()) 27 | pbv2.RegisterEchoServer(s, NewEchoServiceV2()) 28 | pb.RegisterEverythingServer(s, NewEverythingService()) 29 | reflection.Register(s) 30 | 31 | s.Serve(l) 32 | cancel() 33 | }() 34 | 35 | select { 36 | case <-ctx.Done(): 37 | s.Stop() 38 | } 39 | 40 | return nil 41 | } 42 | -------------------------------------------------------------------------------- /internal/server/.gitignore: -------------------------------------------------------------------------------- 1 | /server 2 | -------------------------------------------------------------------------------- /internal/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "flag" 6 | 7 | "github.com/golang/glog" 8 | "github.com/kazegusuri/grpcurl/internal" 9 | ) 10 | 11 | var ( 12 | port = flag.Int("port", 8888, "port") 13 | ) 14 | 15 | func main() { 16 | flag.Parse() 17 | defer glog.Flush() 18 | 19 | ctx := context.Background() 20 | if err := test.RunServer(ctx, *port); err != nil { 21 | glog.Exit(err) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /internal/testdata/echo_service.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: internal/testdata/echo_service.proto 3 | // DO NOT EDIT! 4 | 5 | /* 6 | Package testdata is a generated protocol buffer package. 7 | 8 | It is generated from these files: 9 | internal/testdata/echo_service.proto 10 | internal/testdata/everything.proto 11 | 12 | It has these top-level messages: 13 | EchoMessage 14 | SimpleMessage 15 | NumberMessage 16 | NestedMessage 17 | EnumMessage 18 | Oneof 19 | OneofMessage 20 | MapMessage 21 | GoogleMessage 22 | */ 23 | package testdata 24 | 25 | import proto "github.com/golang/protobuf/proto" 26 | import fmt "fmt" 27 | import math "math" 28 | 29 | import ( 30 | context "golang.org/x/net/context" 31 | grpc "google.golang.org/grpc" 32 | ) 33 | 34 | // Reference imports to suppress errors if they are not otherwise used. 35 | var _ = proto.Marshal 36 | var _ = fmt.Errorf 37 | var _ = math.Inf 38 | 39 | // This is a compile-time assertion to ensure that this generated file 40 | // is compatible with the proto package it is being compiled against. 41 | // A compilation error at this line likely means your copy of the 42 | // proto package needs to be updated. 43 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 44 | 45 | type EchoMessage struct { 46 | Value string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` 47 | ErrorCode uint32 `protobuf:"varint,2,opt,name=error_code,json=errorCode" json:"error_code,omitempty"` 48 | } 49 | 50 | func (m *EchoMessage) Reset() { *m = EchoMessage{} } 51 | func (m *EchoMessage) String() string { return proto.CompactTextString(m) } 52 | func (*EchoMessage) ProtoMessage() {} 53 | func (*EchoMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } 54 | 55 | func (m *EchoMessage) GetValue() string { 56 | if m != nil { 57 | return m.Value 58 | } 59 | return "" 60 | } 61 | 62 | func (m *EchoMessage) GetErrorCode() uint32 { 63 | if m != nil { 64 | return m.ErrorCode 65 | } 66 | return 0 67 | } 68 | 69 | func init() { 70 | proto.RegisterType((*EchoMessage)(nil), "grpcurl.test.EchoMessage") 71 | } 72 | 73 | // Reference imports to suppress errors if they are not otherwise used. 74 | var _ context.Context 75 | var _ grpc.ClientConn 76 | 77 | // This is a compile-time assertion to ensure that this generated file 78 | // is compatible with the grpc package it is being compiled against. 79 | const _ = grpc.SupportPackageIsVersion4 80 | 81 | // Client API for Echo service 82 | 83 | type EchoClient interface { 84 | Echo(ctx context.Context, in *EchoMessage, opts ...grpc.CallOption) (*EchoMessage, error) 85 | ClientStreamingEcho(ctx context.Context, opts ...grpc.CallOption) (Echo_ClientStreamingEchoClient, error) 86 | ServerStreamingEcho(ctx context.Context, in *EchoMessage, opts ...grpc.CallOption) (Echo_ServerStreamingEchoClient, error) 87 | BidiStreamingBulkEcho(ctx context.Context, opts ...grpc.CallOption) (Echo_BidiStreamingBulkEchoClient, error) 88 | } 89 | 90 | type echoClient struct { 91 | cc *grpc.ClientConn 92 | } 93 | 94 | func NewEchoClient(cc *grpc.ClientConn) EchoClient { 95 | return &echoClient{cc} 96 | } 97 | 98 | func (c *echoClient) Echo(ctx context.Context, in *EchoMessage, opts ...grpc.CallOption) (*EchoMessage, error) { 99 | out := new(EchoMessage) 100 | err := grpc.Invoke(ctx, "/grpcurl.test.Echo/Echo", in, out, c.cc, opts...) 101 | if err != nil { 102 | return nil, err 103 | } 104 | return out, nil 105 | } 106 | 107 | func (c *echoClient) ClientStreamingEcho(ctx context.Context, opts ...grpc.CallOption) (Echo_ClientStreamingEchoClient, error) { 108 | stream, err := grpc.NewClientStream(ctx, &_Echo_serviceDesc.Streams[0], c.cc, "/grpcurl.test.Echo/ClientStreamingEcho", opts...) 109 | if err != nil { 110 | return nil, err 111 | } 112 | x := &echoClientStreamingEchoClient{stream} 113 | return x, nil 114 | } 115 | 116 | type Echo_ClientStreamingEchoClient interface { 117 | Send(*EchoMessage) error 118 | CloseAndRecv() (*EchoMessage, error) 119 | grpc.ClientStream 120 | } 121 | 122 | type echoClientStreamingEchoClient struct { 123 | grpc.ClientStream 124 | } 125 | 126 | func (x *echoClientStreamingEchoClient) Send(m *EchoMessage) error { 127 | return x.ClientStream.SendMsg(m) 128 | } 129 | 130 | func (x *echoClientStreamingEchoClient) CloseAndRecv() (*EchoMessage, error) { 131 | if err := x.ClientStream.CloseSend(); err != nil { 132 | return nil, err 133 | } 134 | m := new(EchoMessage) 135 | if err := x.ClientStream.RecvMsg(m); err != nil { 136 | return nil, err 137 | } 138 | return m, nil 139 | } 140 | 141 | func (c *echoClient) ServerStreamingEcho(ctx context.Context, in *EchoMessage, opts ...grpc.CallOption) (Echo_ServerStreamingEchoClient, error) { 142 | stream, err := grpc.NewClientStream(ctx, &_Echo_serviceDesc.Streams[1], c.cc, "/grpcurl.test.Echo/ServerStreamingEcho", opts...) 143 | if err != nil { 144 | return nil, err 145 | } 146 | x := &echoServerStreamingEchoClient{stream} 147 | if err := x.ClientStream.SendMsg(in); err != nil { 148 | return nil, err 149 | } 150 | if err := x.ClientStream.CloseSend(); err != nil { 151 | return nil, err 152 | } 153 | return x, nil 154 | } 155 | 156 | type Echo_ServerStreamingEchoClient interface { 157 | Recv() (*EchoMessage, error) 158 | grpc.ClientStream 159 | } 160 | 161 | type echoServerStreamingEchoClient struct { 162 | grpc.ClientStream 163 | } 164 | 165 | func (x *echoServerStreamingEchoClient) Recv() (*EchoMessage, error) { 166 | m := new(EchoMessage) 167 | if err := x.ClientStream.RecvMsg(m); err != nil { 168 | return nil, err 169 | } 170 | return m, nil 171 | } 172 | 173 | func (c *echoClient) BidiStreamingBulkEcho(ctx context.Context, opts ...grpc.CallOption) (Echo_BidiStreamingBulkEchoClient, error) { 174 | stream, err := grpc.NewClientStream(ctx, &_Echo_serviceDesc.Streams[2], c.cc, "/grpcurl.test.Echo/BidiStreamingBulkEcho", opts...) 175 | if err != nil { 176 | return nil, err 177 | } 178 | x := &echoBidiStreamingBulkEchoClient{stream} 179 | return x, nil 180 | } 181 | 182 | type Echo_BidiStreamingBulkEchoClient interface { 183 | Send(*EchoMessage) error 184 | Recv() (*EchoMessage, error) 185 | grpc.ClientStream 186 | } 187 | 188 | type echoBidiStreamingBulkEchoClient struct { 189 | grpc.ClientStream 190 | } 191 | 192 | func (x *echoBidiStreamingBulkEchoClient) Send(m *EchoMessage) error { 193 | return x.ClientStream.SendMsg(m) 194 | } 195 | 196 | func (x *echoBidiStreamingBulkEchoClient) Recv() (*EchoMessage, error) { 197 | m := new(EchoMessage) 198 | if err := x.ClientStream.RecvMsg(m); err != nil { 199 | return nil, err 200 | } 201 | return m, nil 202 | } 203 | 204 | // Server API for Echo service 205 | 206 | type EchoServer interface { 207 | Echo(context.Context, *EchoMessage) (*EchoMessage, error) 208 | ClientStreamingEcho(Echo_ClientStreamingEchoServer) error 209 | ServerStreamingEcho(*EchoMessage, Echo_ServerStreamingEchoServer) error 210 | BidiStreamingBulkEcho(Echo_BidiStreamingBulkEchoServer) error 211 | } 212 | 213 | func RegisterEchoServer(s *grpc.Server, srv EchoServer) { 214 | s.RegisterService(&_Echo_serviceDesc, srv) 215 | } 216 | 217 | func _Echo_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 218 | in := new(EchoMessage) 219 | if err := dec(in); err != nil { 220 | return nil, err 221 | } 222 | if interceptor == nil { 223 | return srv.(EchoServer).Echo(ctx, in) 224 | } 225 | info := &grpc.UnaryServerInfo{ 226 | Server: srv, 227 | FullMethod: "/grpcurl.test.Echo/Echo", 228 | } 229 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 230 | return srv.(EchoServer).Echo(ctx, req.(*EchoMessage)) 231 | } 232 | return interceptor(ctx, in, info, handler) 233 | } 234 | 235 | func _Echo_ClientStreamingEcho_Handler(srv interface{}, stream grpc.ServerStream) error { 236 | return srv.(EchoServer).ClientStreamingEcho(&echoClientStreamingEchoServer{stream}) 237 | } 238 | 239 | type Echo_ClientStreamingEchoServer interface { 240 | SendAndClose(*EchoMessage) error 241 | Recv() (*EchoMessage, error) 242 | grpc.ServerStream 243 | } 244 | 245 | type echoClientStreamingEchoServer struct { 246 | grpc.ServerStream 247 | } 248 | 249 | func (x *echoClientStreamingEchoServer) SendAndClose(m *EchoMessage) error { 250 | return x.ServerStream.SendMsg(m) 251 | } 252 | 253 | func (x *echoClientStreamingEchoServer) Recv() (*EchoMessage, error) { 254 | m := new(EchoMessage) 255 | if err := x.ServerStream.RecvMsg(m); err != nil { 256 | return nil, err 257 | } 258 | return m, nil 259 | } 260 | 261 | func _Echo_ServerStreamingEcho_Handler(srv interface{}, stream grpc.ServerStream) error { 262 | m := new(EchoMessage) 263 | if err := stream.RecvMsg(m); err != nil { 264 | return err 265 | } 266 | return srv.(EchoServer).ServerStreamingEcho(m, &echoServerStreamingEchoServer{stream}) 267 | } 268 | 269 | type Echo_ServerStreamingEchoServer interface { 270 | Send(*EchoMessage) error 271 | grpc.ServerStream 272 | } 273 | 274 | type echoServerStreamingEchoServer struct { 275 | grpc.ServerStream 276 | } 277 | 278 | func (x *echoServerStreamingEchoServer) Send(m *EchoMessage) error { 279 | return x.ServerStream.SendMsg(m) 280 | } 281 | 282 | func _Echo_BidiStreamingBulkEcho_Handler(srv interface{}, stream grpc.ServerStream) error { 283 | return srv.(EchoServer).BidiStreamingBulkEcho(&echoBidiStreamingBulkEchoServer{stream}) 284 | } 285 | 286 | type Echo_BidiStreamingBulkEchoServer interface { 287 | Send(*EchoMessage) error 288 | Recv() (*EchoMessage, error) 289 | grpc.ServerStream 290 | } 291 | 292 | type echoBidiStreamingBulkEchoServer struct { 293 | grpc.ServerStream 294 | } 295 | 296 | func (x *echoBidiStreamingBulkEchoServer) Send(m *EchoMessage) error { 297 | return x.ServerStream.SendMsg(m) 298 | } 299 | 300 | func (x *echoBidiStreamingBulkEchoServer) Recv() (*EchoMessage, error) { 301 | m := new(EchoMessage) 302 | if err := x.ServerStream.RecvMsg(m); err != nil { 303 | return nil, err 304 | } 305 | return m, nil 306 | } 307 | 308 | var _Echo_serviceDesc = grpc.ServiceDesc{ 309 | ServiceName: "grpcurl.test.Echo", 310 | HandlerType: (*EchoServer)(nil), 311 | Methods: []grpc.MethodDesc{ 312 | { 313 | MethodName: "Echo", 314 | Handler: _Echo_Echo_Handler, 315 | }, 316 | }, 317 | Streams: []grpc.StreamDesc{ 318 | { 319 | StreamName: "ClientStreamingEcho", 320 | Handler: _Echo_ClientStreamingEcho_Handler, 321 | ClientStreams: true, 322 | }, 323 | { 324 | StreamName: "ServerStreamingEcho", 325 | Handler: _Echo_ServerStreamingEcho_Handler, 326 | ServerStreams: true, 327 | }, 328 | { 329 | StreamName: "BidiStreamingBulkEcho", 330 | Handler: _Echo_BidiStreamingBulkEcho_Handler, 331 | ServerStreams: true, 332 | ClientStreams: true, 333 | }, 334 | }, 335 | Metadata: "internal/testdata/echo_service.proto", 336 | } 337 | 338 | func init() { proto.RegisterFile("internal/testdata/echo_service.proto", fileDescriptor0) } 339 | 340 | var fileDescriptor0 = []byte{ 341 | // 249 bytes of a gzipped FileDescriptorProto 342 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x91, 0xbf, 0x4b, 0x03, 0x31, 343 | 0x14, 0xc7, 0x4d, 0x51, 0xa1, 0x51, 0x97, 0xa8, 0x50, 0x05, 0xa1, 0x14, 0x87, 0x9b, 0x92, 0xa2, 344 | 0x8b, 0x28, 0x38, 0x5c, 0x71, 0x14, 0xa1, 0xb7, 0xb9, 0x94, 0x34, 0xf7, 0xc8, 0x85, 0xa6, 0x49, 345 | 0x79, 0x79, 0xb9, 0xc1, 0xff, 0xcd, 0xff, 0x4d, 0xae, 0x56, 0x29, 0x88, 0x53, 0x3b, 0xbd, 0xdf, 346 | 0x9f, 0xef, 0x83, 0x2f, 0xbf, 0x75, 0x81, 0x00, 0x83, 0xf6, 0x8a, 0x20, 0x51, 0xad, 0x49, 0x2b, 347 | 0x30, 0x4d, 0x9c, 0x25, 0xc0, 0xd6, 0x19, 0x90, 0x2b, 0x8c, 0x14, 0xc5, 0xa9, 0xc5, 0x95, 0xc9, 348 | 0xe8, 0x65, 0xb7, 0x34, 0x2a, 0xf9, 0xc9, 0x8b, 0x69, 0xe2, 0x2b, 0xa4, 0xa4, 0x2d, 0x88, 0x0b, 349 | 0x7e, 0xd4, 0x6a, 0x9f, 0x61, 0xc0, 0x86, 0xac, 0xe8, 0x4f, 0xbf, 0x0b, 0x71, 0xc3, 0x39, 0x20, 350 | 0x46, 0x9c, 0x99, 0x58, 0xc3, 0xa0, 0x37, 0x64, 0xc5, 0xd9, 0xb4, 0xbf, 0xee, 0x4c, 0x62, 0x0d, 351 | 0x77, 0x9f, 0x3d, 0x7e, 0xd8, 0x41, 0xc4, 0xf3, 0x26, 0x5e, 0xc9, 0x6d, 0x0d, 0xb9, 0x25, 0x70, 352 | 0xfd, 0xff, 0x68, 0x74, 0x20, 0xde, 0xf8, 0xf9, 0xc4, 0x3b, 0x08, 0x54, 0x11, 0x82, 0x5e, 0xba, 353 | 0x60, 0x77, 0xc1, 0x15, 0xac, 0x03, 0x56, 0x80, 0x2d, 0xe0, 0x5e, 0x80, 0x63, 0x26, 0x2a, 0x7e, 354 | 0x59, 0xba, 0xda, 0xfd, 0xe2, 0xca, 0xec, 0x17, 0xbb, 0xfd, 0x38, 0x66, 0xe5, 0xe3, 0xfb, 0x83, 355 | 0x75, 0xd4, 0xe4, 0xb9, 0x34, 0x71, 0xa9, 0x16, 0xfa, 0x03, 0x6c, 0x4e, 0x19, 0x9d, 0xda, 0xdc, 356 | 0xa9, 0x3f, 0xbe, 0x3e, 0xfd, 0x24, 0xf3, 0xe3, 0xb5, 0xa9, 0xf7, 0x5f, 0x01, 0x00, 0x00, 0xff, 357 | 0xff, 0x77, 0x3b, 0x55, 0x03, 0xfc, 0x01, 0x00, 0x00, 358 | } 359 | -------------------------------------------------------------------------------- /internal/testdata/echo_service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpcurl.test; 4 | option go_package = "github.com/kazegusuri/grpcurl/internal/testdata;testdata"; 5 | 6 | message EchoMessage { 7 | string value = 1; 8 | uint32 error_code = 2; 9 | } 10 | 11 | service Echo { 12 | rpc Echo(EchoMessage) returns (EchoMessage) {} 13 | rpc ClientStreamingEcho(stream EchoMessage) returns (EchoMessage) {} 14 | rpc ServerStreamingEcho(EchoMessage) returns (stream EchoMessage) {} 15 | rpc BidiStreamingBulkEcho(stream EchoMessage) returns (stream EchoMessage) {} 16 | } 17 | -------------------------------------------------------------------------------- /internal/testdata/everything.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: internal/testdata/everything.proto 3 | // DO NOT EDIT! 4 | 5 | package testdata 6 | 7 | import proto "github.com/golang/protobuf/proto" 8 | import fmt "fmt" 9 | import math "math" 10 | import google_rpc "google.golang.org/genproto/googleapis/rpc/errdetails" 11 | 12 | import ( 13 | context "golang.org/x/net/context" 14 | grpc "google.golang.org/grpc" 15 | ) 16 | 17 | // Reference imports to suppress errors if they are not otherwise used. 18 | var _ = proto.Marshal 19 | var _ = fmt.Errorf 20 | var _ = math.Inf 21 | 22 | type NumericEnum int32 23 | 24 | const ( 25 | NumericEnum_ZERO NumericEnum = 0 26 | NumericEnum_ONE NumericEnum = 1 27 | NumericEnum_TWO NumericEnum = 2 28 | ) 29 | 30 | var NumericEnum_name = map[int32]string{ 31 | 0: "ZERO", 32 | 1: "ONE", 33 | 2: "TWO", 34 | } 35 | var NumericEnum_value = map[string]int32{ 36 | "ZERO": 0, 37 | "ONE": 1, 38 | "TWO": 2, 39 | } 40 | 41 | func (x NumericEnum) String() string { 42 | return proto.EnumName(NumericEnum_name, int32(x)) 43 | } 44 | func (NumericEnum) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } 45 | 46 | type AliasedEnum int32 47 | 48 | const ( 49 | AliasedEnum_UNKNOWN AliasedEnum = 0 50 | AliasedEnum_STARTED AliasedEnum = 1 51 | AliasedEnum_RUNNING AliasedEnum = 1 52 | ) 53 | 54 | var AliasedEnum_name = map[int32]string{ 55 | 0: "UNKNOWN", 56 | 1: "STARTED", 57 | // Duplicate value: 1: "RUNNING", 58 | } 59 | var AliasedEnum_value = map[string]int32{ 60 | "UNKNOWN": 0, 61 | "STARTED": 1, 62 | "RUNNING": 1, 63 | } 64 | 65 | func (x AliasedEnum) String() string { 66 | return proto.EnumName(AliasedEnum_name, int32(x)) 67 | } 68 | func (AliasedEnum) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } 69 | 70 | type EnumMessage_Nested int32 71 | 72 | const ( 73 | EnumMessage_UNKNOWN EnumMessage_Nested = 0 74 | EnumMessage_PENDING EnumMessage_Nested = 1 75 | EnumMessage_COMPLETED EnumMessage_Nested = 2 76 | ) 77 | 78 | var EnumMessage_Nested_name = map[int32]string{ 79 | 0: "UNKNOWN", 80 | 1: "PENDING", 81 | 2: "COMPLETED", 82 | } 83 | var EnumMessage_Nested_value = map[string]int32{ 84 | "UNKNOWN": 0, 85 | "PENDING": 1, 86 | "COMPLETED": 2, 87 | } 88 | 89 | func (x EnumMessage_Nested) String() string { 90 | return proto.EnumName(EnumMessage_Nested_name, int32(x)) 91 | } 92 | func (EnumMessage_Nested) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{3, 0} } 93 | 94 | type SimpleMessage struct { 95 | StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue" json:"string_value,omitempty"` 96 | BoolValue bool `protobuf:"varint,2,opt,name=bool_value,json=boolValue" json:"bool_value,omitempty"` 97 | } 98 | 99 | func (m *SimpleMessage) Reset() { *m = SimpleMessage{} } 100 | func (m *SimpleMessage) String() string { return proto.CompactTextString(m) } 101 | func (*SimpleMessage) ProtoMessage() {} 102 | func (*SimpleMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } 103 | 104 | func (m *SimpleMessage) GetStringValue() string { 105 | if m != nil { 106 | return m.StringValue 107 | } 108 | return "" 109 | } 110 | 111 | func (m *SimpleMessage) GetBoolValue() bool { 112 | if m != nil { 113 | return m.BoolValue 114 | } 115 | return false 116 | } 117 | 118 | type NumberMessage struct { 119 | FloatValue float32 `protobuf:"fixed32,1,opt,name=float_value,json=floatValue" json:"float_value,omitempty"` 120 | DoubleValue float64 `protobuf:"fixed64,2,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"` 121 | Int32Value int32 `protobuf:"varint,3,opt,name=int32_value,json=int32Value" json:"int32_value,omitempty"` 122 | Int64Value int64 `protobuf:"varint,4,opt,name=int64_value,json=int64Value" json:"int64_value,omitempty"` 123 | Uint32Value uint32 `protobuf:"varint,5,opt,name=uint32_value,json=uint32Value" json:"uint32_value,omitempty"` 124 | Uint64Value uint64 `protobuf:"varint,6,opt,name=uint64_value,json=uint64Value" json:"uint64_value,omitempty"` 125 | Sint32Value int32 `protobuf:"zigzag32,7,opt,name=sint32_value,json=sint32Value" json:"sint32_value,omitempty"` 126 | Sint64Value int64 `protobuf:"zigzag64,8,opt,name=sint64_value,json=sint64Value" json:"sint64_value,omitempty"` 127 | Fixed32Value uint32 `protobuf:"fixed32,9,opt,name=fixed32_value,json=fixed32Value" json:"fixed32_value,omitempty"` 128 | Fixed64Value uint64 `protobuf:"fixed64,10,opt,name=fixed64_value,json=fixed64Value" json:"fixed64_value,omitempty"` 129 | Sfixed32Value int32 `protobuf:"fixed32,11,opt,name=sfixed32_value,json=sfixed32Value" json:"sfixed32_value,omitempty"` 130 | Sfixed64Value int64 `protobuf:"fixed64,12,opt,name=sfixed64_value,json=sfixed64Value" json:"sfixed64_value,omitempty"` 131 | } 132 | 133 | func (m *NumberMessage) Reset() { *m = NumberMessage{} } 134 | func (m *NumberMessage) String() string { return proto.CompactTextString(m) } 135 | func (*NumberMessage) ProtoMessage() {} 136 | func (*NumberMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } 137 | 138 | func (m *NumberMessage) GetFloatValue() float32 { 139 | if m != nil { 140 | return m.FloatValue 141 | } 142 | return 0 143 | } 144 | 145 | func (m *NumberMessage) GetDoubleValue() float64 { 146 | if m != nil { 147 | return m.DoubleValue 148 | } 149 | return 0 150 | } 151 | 152 | func (m *NumberMessage) GetInt32Value() int32 { 153 | if m != nil { 154 | return m.Int32Value 155 | } 156 | return 0 157 | } 158 | 159 | func (m *NumberMessage) GetInt64Value() int64 { 160 | if m != nil { 161 | return m.Int64Value 162 | } 163 | return 0 164 | } 165 | 166 | func (m *NumberMessage) GetUint32Value() uint32 { 167 | if m != nil { 168 | return m.Uint32Value 169 | } 170 | return 0 171 | } 172 | 173 | func (m *NumberMessage) GetUint64Value() uint64 { 174 | if m != nil { 175 | return m.Uint64Value 176 | } 177 | return 0 178 | } 179 | 180 | func (m *NumberMessage) GetSint32Value() int32 { 181 | if m != nil { 182 | return m.Sint32Value 183 | } 184 | return 0 185 | } 186 | 187 | func (m *NumberMessage) GetSint64Value() int64 { 188 | if m != nil { 189 | return m.Sint64Value 190 | } 191 | return 0 192 | } 193 | 194 | func (m *NumberMessage) GetFixed32Value() uint32 { 195 | if m != nil { 196 | return m.Fixed32Value 197 | } 198 | return 0 199 | } 200 | 201 | func (m *NumberMessage) GetFixed64Value() uint64 { 202 | if m != nil { 203 | return m.Fixed64Value 204 | } 205 | return 0 206 | } 207 | 208 | func (m *NumberMessage) GetSfixed32Value() int32 { 209 | if m != nil { 210 | return m.Sfixed32Value 211 | } 212 | return 0 213 | } 214 | 215 | func (m *NumberMessage) GetSfixed64Value() int64 { 216 | if m != nil { 217 | return m.Sfixed64Value 218 | } 219 | return 0 220 | } 221 | 222 | type NestedMessage struct { 223 | NestedValue *NestedMessage_Nested `protobuf:"bytes,1,opt,name=nested_value,json=nestedValue" json:"nested_value,omitempty"` 224 | RepeatedNestedValues []*NestedMessage_Nested `protobuf:"bytes,2,rep,name=repeated_nested_values,json=repeatedNestedValues" json:"repeated_nested_values,omitempty"` 225 | } 226 | 227 | func (m *NestedMessage) Reset() { *m = NestedMessage{} } 228 | func (m *NestedMessage) String() string { return proto.CompactTextString(m) } 229 | func (*NestedMessage) ProtoMessage() {} 230 | func (*NestedMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} } 231 | 232 | func (m *NestedMessage) GetNestedValue() *NestedMessage_Nested { 233 | if m != nil { 234 | return m.NestedValue 235 | } 236 | return nil 237 | } 238 | 239 | func (m *NestedMessage) GetRepeatedNestedValues() []*NestedMessage_Nested { 240 | if m != nil { 241 | return m.RepeatedNestedValues 242 | } 243 | return nil 244 | } 245 | 246 | type NestedMessage_Nested struct { 247 | Int32Value int32 `protobuf:"varint,1,opt,name=int32_value,json=int32Value" json:"int32_value,omitempty"` 248 | StringValue string `protobuf:"bytes,2,opt,name=string_value,json=stringValue" json:"string_value,omitempty"` 249 | } 250 | 251 | func (m *NestedMessage_Nested) Reset() { *m = NestedMessage_Nested{} } 252 | func (m *NestedMessage_Nested) String() string { return proto.CompactTextString(m) } 253 | func (*NestedMessage_Nested) ProtoMessage() {} 254 | func (*NestedMessage_Nested) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2, 0} } 255 | 256 | func (m *NestedMessage_Nested) GetInt32Value() int32 { 257 | if m != nil { 258 | return m.Int32Value 259 | } 260 | return 0 261 | } 262 | 263 | func (m *NestedMessage_Nested) GetStringValue() string { 264 | if m != nil { 265 | return m.StringValue 266 | } 267 | return "" 268 | } 269 | 270 | type EnumMessage struct { 271 | NumericEnumValue NumericEnum `protobuf:"varint,1,opt,name=numeric_enum_value,json=numericEnumValue,enum=grpcurl.test.NumericEnum" json:"numeric_enum_value,omitempty"` 272 | RepeatedNumericEnumValues []NumericEnum `protobuf:"varint,2,rep,packed,name=repeated_numeric_enum_values,json=repeatedNumericEnumValues,enum=grpcurl.test.NumericEnum" json:"repeated_numeric_enum_values,omitempty"` 273 | AliasedEnumValue AliasedEnum `protobuf:"varint,3,opt,name=aliased_enum_value,json=aliasedEnumValue,enum=grpcurl.test.AliasedEnum" json:"aliased_enum_value,omitempty"` 274 | NestedEnumValue EnumMessage_Nested `protobuf:"varint,4,opt,name=nested_enum_value,json=nestedEnumValue,enum=grpcurl.test.EnumMessage_Nested" json:"nested_enum_value,omitempty"` 275 | RepeatedNestedEnumValues []EnumMessage_Nested `protobuf:"varint,5,rep,packed,name=repeated_nested_enum_values,json=repeatedNestedEnumValues,enum=grpcurl.test.EnumMessage_Nested" json:"repeated_nested_enum_values,omitempty"` 276 | } 277 | 278 | func (m *EnumMessage) Reset() { *m = EnumMessage{} } 279 | func (m *EnumMessage) String() string { return proto.CompactTextString(m) } 280 | func (*EnumMessage) ProtoMessage() {} 281 | func (*EnumMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} } 282 | 283 | func (m *EnumMessage) GetNumericEnumValue() NumericEnum { 284 | if m != nil { 285 | return m.NumericEnumValue 286 | } 287 | return NumericEnum_ZERO 288 | } 289 | 290 | func (m *EnumMessage) GetRepeatedNumericEnumValues() []NumericEnum { 291 | if m != nil { 292 | return m.RepeatedNumericEnumValues 293 | } 294 | return nil 295 | } 296 | 297 | func (m *EnumMessage) GetAliasedEnumValue() AliasedEnum { 298 | if m != nil { 299 | return m.AliasedEnumValue 300 | } 301 | return AliasedEnum_UNKNOWN 302 | } 303 | 304 | func (m *EnumMessage) GetNestedEnumValue() EnumMessage_Nested { 305 | if m != nil { 306 | return m.NestedEnumValue 307 | } 308 | return EnumMessage_UNKNOWN 309 | } 310 | 311 | func (m *EnumMessage) GetRepeatedNestedEnumValues() []EnumMessage_Nested { 312 | if m != nil { 313 | return m.RepeatedNestedEnumValues 314 | } 315 | return nil 316 | } 317 | 318 | type Oneof struct { 319 | // Types that are valid to be assigned to OneofValue: 320 | // *Oneof_Int32Value 321 | // *Oneof_StringValue 322 | OneofValue isOneof_OneofValue `protobuf_oneof:"oneof_value"` 323 | } 324 | 325 | func (m *Oneof) Reset() { *m = Oneof{} } 326 | func (m *Oneof) String() string { return proto.CompactTextString(m) } 327 | func (*Oneof) ProtoMessage() {} 328 | func (*Oneof) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} } 329 | 330 | type isOneof_OneofValue interface { 331 | isOneof_OneofValue() 332 | } 333 | 334 | type Oneof_Int32Value struct { 335 | Int32Value int32 `protobuf:"varint,1,opt,name=int32_value,json=int32Value,oneof"` 336 | } 337 | type Oneof_StringValue struct { 338 | StringValue string `protobuf:"bytes,2,opt,name=string_value,json=stringValue,oneof"` 339 | } 340 | 341 | func (*Oneof_Int32Value) isOneof_OneofValue() {} 342 | func (*Oneof_StringValue) isOneof_OneofValue() {} 343 | 344 | func (m *Oneof) GetOneofValue() isOneof_OneofValue { 345 | if m != nil { 346 | return m.OneofValue 347 | } 348 | return nil 349 | } 350 | 351 | func (m *Oneof) GetInt32Value() int32 { 352 | if x, ok := m.GetOneofValue().(*Oneof_Int32Value); ok { 353 | return x.Int32Value 354 | } 355 | return 0 356 | } 357 | 358 | func (m *Oneof) GetStringValue() string { 359 | if x, ok := m.GetOneofValue().(*Oneof_StringValue); ok { 360 | return x.StringValue 361 | } 362 | return "" 363 | } 364 | 365 | // XXX_OneofFuncs is for the internal use of the proto package. 366 | func (*Oneof) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { 367 | return _Oneof_OneofMarshaler, _Oneof_OneofUnmarshaler, _Oneof_OneofSizer, []interface{}{ 368 | (*Oneof_Int32Value)(nil), 369 | (*Oneof_StringValue)(nil), 370 | } 371 | } 372 | 373 | func _Oneof_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { 374 | m := msg.(*Oneof) 375 | // oneof_value 376 | switch x := m.OneofValue.(type) { 377 | case *Oneof_Int32Value: 378 | b.EncodeVarint(1<<3 | proto.WireVarint) 379 | b.EncodeVarint(uint64(x.Int32Value)) 380 | case *Oneof_StringValue: 381 | b.EncodeVarint(2<<3 | proto.WireBytes) 382 | b.EncodeStringBytes(x.StringValue) 383 | case nil: 384 | default: 385 | return fmt.Errorf("Oneof.OneofValue has unexpected type %T", x) 386 | } 387 | return nil 388 | } 389 | 390 | func _Oneof_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { 391 | m := msg.(*Oneof) 392 | switch tag { 393 | case 1: // oneof_value.int32_value 394 | if wire != proto.WireVarint { 395 | return true, proto.ErrInternalBadWireType 396 | } 397 | x, err := b.DecodeVarint() 398 | m.OneofValue = &Oneof_Int32Value{int32(x)} 399 | return true, err 400 | case 2: // oneof_value.string_value 401 | if wire != proto.WireBytes { 402 | return true, proto.ErrInternalBadWireType 403 | } 404 | x, err := b.DecodeStringBytes() 405 | m.OneofValue = &Oneof_StringValue{x} 406 | return true, err 407 | default: 408 | return false, nil 409 | } 410 | } 411 | 412 | func _Oneof_OneofSizer(msg proto.Message) (n int) { 413 | m := msg.(*Oneof) 414 | // oneof_value 415 | switch x := m.OneofValue.(type) { 416 | case *Oneof_Int32Value: 417 | n += proto.SizeVarint(1<<3 | proto.WireVarint) 418 | n += proto.SizeVarint(uint64(x.Int32Value)) 419 | case *Oneof_StringValue: 420 | n += proto.SizeVarint(2<<3 | proto.WireBytes) 421 | n += proto.SizeVarint(uint64(len(x.StringValue))) 422 | n += len(x.StringValue) 423 | case nil: 424 | default: 425 | panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) 426 | } 427 | return n 428 | } 429 | 430 | type OneofMessage struct { 431 | // Types that are valid to be assigned to OneofValue: 432 | // *OneofMessage_Int32Value 433 | // *OneofMessage_StringValue 434 | OneofValue isOneofMessage_OneofValue `protobuf_oneof:"oneof_value"` 435 | RepeatedOneofValues []*Oneof `protobuf:"bytes,3,rep,name=repeated_oneof_values,json=repeatedOneofValues" json:"repeated_oneof_values,omitempty"` 436 | } 437 | 438 | func (m *OneofMessage) Reset() { *m = OneofMessage{} } 439 | func (m *OneofMessage) String() string { return proto.CompactTextString(m) } 440 | func (*OneofMessage) ProtoMessage() {} 441 | func (*OneofMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{5} } 442 | 443 | type isOneofMessage_OneofValue interface { 444 | isOneofMessage_OneofValue() 445 | } 446 | 447 | type OneofMessage_Int32Value struct { 448 | Int32Value int32 `protobuf:"varint,1,opt,name=int32_value,json=int32Value,oneof"` 449 | } 450 | type OneofMessage_StringValue struct { 451 | StringValue string `protobuf:"bytes,2,opt,name=string_value,json=stringValue,oneof"` 452 | } 453 | 454 | func (*OneofMessage_Int32Value) isOneofMessage_OneofValue() {} 455 | func (*OneofMessage_StringValue) isOneofMessage_OneofValue() {} 456 | 457 | func (m *OneofMessage) GetOneofValue() isOneofMessage_OneofValue { 458 | if m != nil { 459 | return m.OneofValue 460 | } 461 | return nil 462 | } 463 | 464 | func (m *OneofMessage) GetInt32Value() int32 { 465 | if x, ok := m.GetOneofValue().(*OneofMessage_Int32Value); ok { 466 | return x.Int32Value 467 | } 468 | return 0 469 | } 470 | 471 | func (m *OneofMessage) GetStringValue() string { 472 | if x, ok := m.GetOneofValue().(*OneofMessage_StringValue); ok { 473 | return x.StringValue 474 | } 475 | return "" 476 | } 477 | 478 | func (m *OneofMessage) GetRepeatedOneofValues() []*Oneof { 479 | if m != nil { 480 | return m.RepeatedOneofValues 481 | } 482 | return nil 483 | } 484 | 485 | // XXX_OneofFuncs is for the internal use of the proto package. 486 | func (*OneofMessage) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { 487 | return _OneofMessage_OneofMarshaler, _OneofMessage_OneofUnmarshaler, _OneofMessage_OneofSizer, []interface{}{ 488 | (*OneofMessage_Int32Value)(nil), 489 | (*OneofMessage_StringValue)(nil), 490 | } 491 | } 492 | 493 | func _OneofMessage_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { 494 | m := msg.(*OneofMessage) 495 | // oneof_value 496 | switch x := m.OneofValue.(type) { 497 | case *OneofMessage_Int32Value: 498 | b.EncodeVarint(1<<3 | proto.WireVarint) 499 | b.EncodeVarint(uint64(x.Int32Value)) 500 | case *OneofMessage_StringValue: 501 | b.EncodeVarint(2<<3 | proto.WireBytes) 502 | b.EncodeStringBytes(x.StringValue) 503 | case nil: 504 | default: 505 | return fmt.Errorf("OneofMessage.OneofValue has unexpected type %T", x) 506 | } 507 | return nil 508 | } 509 | 510 | func _OneofMessage_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { 511 | m := msg.(*OneofMessage) 512 | switch tag { 513 | case 1: // oneof_value.int32_value 514 | if wire != proto.WireVarint { 515 | return true, proto.ErrInternalBadWireType 516 | } 517 | x, err := b.DecodeVarint() 518 | m.OneofValue = &OneofMessage_Int32Value{int32(x)} 519 | return true, err 520 | case 2: // oneof_value.string_value 521 | if wire != proto.WireBytes { 522 | return true, proto.ErrInternalBadWireType 523 | } 524 | x, err := b.DecodeStringBytes() 525 | m.OneofValue = &OneofMessage_StringValue{x} 526 | return true, err 527 | default: 528 | return false, nil 529 | } 530 | } 531 | 532 | func _OneofMessage_OneofSizer(msg proto.Message) (n int) { 533 | m := msg.(*OneofMessage) 534 | // oneof_value 535 | switch x := m.OneofValue.(type) { 536 | case *OneofMessage_Int32Value: 537 | n += proto.SizeVarint(1<<3 | proto.WireVarint) 538 | n += proto.SizeVarint(uint64(x.Int32Value)) 539 | case *OneofMessage_StringValue: 540 | n += proto.SizeVarint(2<<3 | proto.WireBytes) 541 | n += proto.SizeVarint(uint64(len(x.StringValue))) 542 | n += len(x.StringValue) 543 | case nil: 544 | default: 545 | panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) 546 | } 547 | return n 548 | } 549 | 550 | type MapMessage struct { 551 | MappedValue map[string]string `protobuf:"bytes,1,rep,name=mapped_value,json=mappedValue" json:"mapped_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` 552 | MappedEnumValue map[string]NumericEnum `protobuf:"bytes,2,rep,name=mapped_enum_value,json=mappedEnumValue" json:"mapped_enum_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=grpcurl.test.NumericEnum"` 553 | MappedNestedValue map[string]*NestedMessage `protobuf:"bytes,3,rep,name=mapped_nested_value,json=mappedNestedValue" json:"mapped_nested_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` 554 | } 555 | 556 | func (m *MapMessage) Reset() { *m = MapMessage{} } 557 | func (m *MapMessage) String() string { return proto.CompactTextString(m) } 558 | func (*MapMessage) ProtoMessage() {} 559 | func (*MapMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{6} } 560 | 561 | func (m *MapMessage) GetMappedValue() map[string]string { 562 | if m != nil { 563 | return m.MappedValue 564 | } 565 | return nil 566 | } 567 | 568 | func (m *MapMessage) GetMappedEnumValue() map[string]NumericEnum { 569 | if m != nil { 570 | return m.MappedEnumValue 571 | } 572 | return nil 573 | } 574 | 575 | func (m *MapMessage) GetMappedNestedValue() map[string]*NestedMessage { 576 | if m != nil { 577 | return m.MappedNestedValue 578 | } 579 | return nil 580 | } 581 | 582 | type GoogleMessage struct { 583 | Info *google_rpc.RequestInfo `protobuf:"bytes,1,opt,name=info" json:"info,omitempty"` 584 | } 585 | 586 | func (m *GoogleMessage) Reset() { *m = GoogleMessage{} } 587 | func (m *GoogleMessage) String() string { return proto.CompactTextString(m) } 588 | func (*GoogleMessage) ProtoMessage() {} 589 | func (*GoogleMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{7} } 590 | 591 | func (m *GoogleMessage) GetInfo() *google_rpc.RequestInfo { 592 | if m != nil { 593 | return m.Info 594 | } 595 | return nil 596 | } 597 | 598 | func init() { 599 | proto.RegisterType((*SimpleMessage)(nil), "grpcurl.test.SimpleMessage") 600 | proto.RegisterType((*NumberMessage)(nil), "grpcurl.test.NumberMessage") 601 | proto.RegisterType((*NestedMessage)(nil), "grpcurl.test.NestedMessage") 602 | proto.RegisterType((*NestedMessage_Nested)(nil), "grpcurl.test.NestedMessage.Nested") 603 | proto.RegisterType((*EnumMessage)(nil), "grpcurl.test.EnumMessage") 604 | proto.RegisterType((*Oneof)(nil), "grpcurl.test.Oneof") 605 | proto.RegisterType((*OneofMessage)(nil), "grpcurl.test.OneofMessage") 606 | proto.RegisterType((*MapMessage)(nil), "grpcurl.test.MapMessage") 607 | proto.RegisterType((*GoogleMessage)(nil), "grpcurl.test.GoogleMessage") 608 | proto.RegisterEnum("grpcurl.test.NumericEnum", NumericEnum_name, NumericEnum_value) 609 | proto.RegisterEnum("grpcurl.test.AliasedEnum", AliasedEnum_name, AliasedEnum_value) 610 | proto.RegisterEnum("grpcurl.test.EnumMessage_Nested", EnumMessage_Nested_name, EnumMessage_Nested_value) 611 | } 612 | 613 | // Reference imports to suppress errors if they are not otherwise used. 614 | var _ context.Context 615 | var _ grpc.ClientConn 616 | 617 | // This is a compile-time assertion to ensure that this generated file 618 | // is compatible with the grpc package it is being compiled against. 619 | const _ = grpc.SupportPackageIsVersion4 620 | 621 | // Client API for Everything service 622 | 623 | type EverythingClient interface { 624 | Simple(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) 625 | Number(ctx context.Context, in *NumberMessage, opts ...grpc.CallOption) (*NumberMessage, error) 626 | Enum(ctx context.Context, in *EnumMessage, opts ...grpc.CallOption) (*EnumMessage, error) 627 | Oneof(ctx context.Context, in *OneofMessage, opts ...grpc.CallOption) (*OneofMessage, error) 628 | Map(ctx context.Context, in *MapMessage, opts ...grpc.CallOption) (*MapMessage, error) 629 | Google(ctx context.Context, in *GoogleMessage, opts ...grpc.CallOption) (*GoogleMessage, error) 630 | } 631 | 632 | type everythingClient struct { 633 | cc *grpc.ClientConn 634 | } 635 | 636 | func NewEverythingClient(cc *grpc.ClientConn) EverythingClient { 637 | return &everythingClient{cc} 638 | } 639 | 640 | func (c *everythingClient) Simple(ctx context.Context, in *SimpleMessage, opts ...grpc.CallOption) (*SimpleMessage, error) { 641 | out := new(SimpleMessage) 642 | err := grpc.Invoke(ctx, "/grpcurl.test.Everything/Simple", in, out, c.cc, opts...) 643 | if err != nil { 644 | return nil, err 645 | } 646 | return out, nil 647 | } 648 | 649 | func (c *everythingClient) Number(ctx context.Context, in *NumberMessage, opts ...grpc.CallOption) (*NumberMessage, error) { 650 | out := new(NumberMessage) 651 | err := grpc.Invoke(ctx, "/grpcurl.test.Everything/Number", in, out, c.cc, opts...) 652 | if err != nil { 653 | return nil, err 654 | } 655 | return out, nil 656 | } 657 | 658 | func (c *everythingClient) Enum(ctx context.Context, in *EnumMessage, opts ...grpc.CallOption) (*EnumMessage, error) { 659 | out := new(EnumMessage) 660 | err := grpc.Invoke(ctx, "/grpcurl.test.Everything/Enum", in, out, c.cc, opts...) 661 | if err != nil { 662 | return nil, err 663 | } 664 | return out, nil 665 | } 666 | 667 | func (c *everythingClient) Oneof(ctx context.Context, in *OneofMessage, opts ...grpc.CallOption) (*OneofMessage, error) { 668 | out := new(OneofMessage) 669 | err := grpc.Invoke(ctx, "/grpcurl.test.Everything/Oneof", in, out, c.cc, opts...) 670 | if err != nil { 671 | return nil, err 672 | } 673 | return out, nil 674 | } 675 | 676 | func (c *everythingClient) Map(ctx context.Context, in *MapMessage, opts ...grpc.CallOption) (*MapMessage, error) { 677 | out := new(MapMessage) 678 | err := grpc.Invoke(ctx, "/grpcurl.test.Everything/Map", in, out, c.cc, opts...) 679 | if err != nil { 680 | return nil, err 681 | } 682 | return out, nil 683 | } 684 | 685 | func (c *everythingClient) Google(ctx context.Context, in *GoogleMessage, opts ...grpc.CallOption) (*GoogleMessage, error) { 686 | out := new(GoogleMessage) 687 | err := grpc.Invoke(ctx, "/grpcurl.test.Everything/Google", in, out, c.cc, opts...) 688 | if err != nil { 689 | return nil, err 690 | } 691 | return out, nil 692 | } 693 | 694 | // Server API for Everything service 695 | 696 | type EverythingServer interface { 697 | Simple(context.Context, *SimpleMessage) (*SimpleMessage, error) 698 | Number(context.Context, *NumberMessage) (*NumberMessage, error) 699 | Enum(context.Context, *EnumMessage) (*EnumMessage, error) 700 | Oneof(context.Context, *OneofMessage) (*OneofMessage, error) 701 | Map(context.Context, *MapMessage) (*MapMessage, error) 702 | Google(context.Context, *GoogleMessage) (*GoogleMessage, error) 703 | } 704 | 705 | func RegisterEverythingServer(s *grpc.Server, srv EverythingServer) { 706 | s.RegisterService(&_Everything_serviceDesc, srv) 707 | } 708 | 709 | func _Everything_Simple_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 710 | in := new(SimpleMessage) 711 | if err := dec(in); err != nil { 712 | return nil, err 713 | } 714 | if interceptor == nil { 715 | return srv.(EverythingServer).Simple(ctx, in) 716 | } 717 | info := &grpc.UnaryServerInfo{ 718 | Server: srv, 719 | FullMethod: "/grpcurl.test.Everything/Simple", 720 | } 721 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 722 | return srv.(EverythingServer).Simple(ctx, req.(*SimpleMessage)) 723 | } 724 | return interceptor(ctx, in, info, handler) 725 | } 726 | 727 | func _Everything_Number_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 728 | in := new(NumberMessage) 729 | if err := dec(in); err != nil { 730 | return nil, err 731 | } 732 | if interceptor == nil { 733 | return srv.(EverythingServer).Number(ctx, in) 734 | } 735 | info := &grpc.UnaryServerInfo{ 736 | Server: srv, 737 | FullMethod: "/grpcurl.test.Everything/Number", 738 | } 739 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 740 | return srv.(EverythingServer).Number(ctx, req.(*NumberMessage)) 741 | } 742 | return interceptor(ctx, in, info, handler) 743 | } 744 | 745 | func _Everything_Enum_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 746 | in := new(EnumMessage) 747 | if err := dec(in); err != nil { 748 | return nil, err 749 | } 750 | if interceptor == nil { 751 | return srv.(EverythingServer).Enum(ctx, in) 752 | } 753 | info := &grpc.UnaryServerInfo{ 754 | Server: srv, 755 | FullMethod: "/grpcurl.test.Everything/Enum", 756 | } 757 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 758 | return srv.(EverythingServer).Enum(ctx, req.(*EnumMessage)) 759 | } 760 | return interceptor(ctx, in, info, handler) 761 | } 762 | 763 | func _Everything_Oneof_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 764 | in := new(OneofMessage) 765 | if err := dec(in); err != nil { 766 | return nil, err 767 | } 768 | if interceptor == nil { 769 | return srv.(EverythingServer).Oneof(ctx, in) 770 | } 771 | info := &grpc.UnaryServerInfo{ 772 | Server: srv, 773 | FullMethod: "/grpcurl.test.Everything/Oneof", 774 | } 775 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 776 | return srv.(EverythingServer).Oneof(ctx, req.(*OneofMessage)) 777 | } 778 | return interceptor(ctx, in, info, handler) 779 | } 780 | 781 | func _Everything_Map_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 782 | in := new(MapMessage) 783 | if err := dec(in); err != nil { 784 | return nil, err 785 | } 786 | if interceptor == nil { 787 | return srv.(EverythingServer).Map(ctx, in) 788 | } 789 | info := &grpc.UnaryServerInfo{ 790 | Server: srv, 791 | FullMethod: "/grpcurl.test.Everything/Map", 792 | } 793 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 794 | return srv.(EverythingServer).Map(ctx, req.(*MapMessage)) 795 | } 796 | return interceptor(ctx, in, info, handler) 797 | } 798 | 799 | func _Everything_Google_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 800 | in := new(GoogleMessage) 801 | if err := dec(in); err != nil { 802 | return nil, err 803 | } 804 | if interceptor == nil { 805 | return srv.(EverythingServer).Google(ctx, in) 806 | } 807 | info := &grpc.UnaryServerInfo{ 808 | Server: srv, 809 | FullMethod: "/grpcurl.test.Everything/Google", 810 | } 811 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 812 | return srv.(EverythingServer).Google(ctx, req.(*GoogleMessage)) 813 | } 814 | return interceptor(ctx, in, info, handler) 815 | } 816 | 817 | var _Everything_serviceDesc = grpc.ServiceDesc{ 818 | ServiceName: "grpcurl.test.Everything", 819 | HandlerType: (*EverythingServer)(nil), 820 | Methods: []grpc.MethodDesc{ 821 | { 822 | MethodName: "Simple", 823 | Handler: _Everything_Simple_Handler, 824 | }, 825 | { 826 | MethodName: "Number", 827 | Handler: _Everything_Number_Handler, 828 | }, 829 | { 830 | MethodName: "Enum", 831 | Handler: _Everything_Enum_Handler, 832 | }, 833 | { 834 | MethodName: "Oneof", 835 | Handler: _Everything_Oneof_Handler, 836 | }, 837 | { 838 | MethodName: "Map", 839 | Handler: _Everything_Map_Handler, 840 | }, 841 | { 842 | MethodName: "Google", 843 | Handler: _Everything_Google_Handler, 844 | }, 845 | }, 846 | Streams: []grpc.StreamDesc{}, 847 | Metadata: "internal/testdata/everything.proto", 848 | } 849 | 850 | func init() { proto.RegisterFile("internal/testdata/everything.proto", fileDescriptor1) } 851 | 852 | var fileDescriptor1 = []byte{ 853 | // 1010 bytes of a gzipped FileDescriptorProto 854 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0xe1, 0x6e, 0xdb, 0x36, 855 | 0x10, 0xc7, 0x4d, 0xcb, 0x76, 0x92, 0x93, 0xdd, 0x28, 0x4c, 0xd6, 0x39, 0xea, 0xb6, 0x2a, 0x2a, 856 | 0x06, 0xa8, 0x1d, 0x66, 0xa3, 0x6e, 0x51, 0x04, 0xed, 0x50, 0x20, 0x5d, 0x8c, 0xb4, 0x58, 0x22, 857 | 0x77, 0x6c, 0xba, 0x6e, 0x01, 0x36, 0x43, 0xb6, 0x69, 0x57, 0xa8, 0x2c, 0x69, 0xa2, 0x14, 0x2c, 858 | 0x7b, 0x92, 0x7d, 0xda, 0x23, 0xec, 0xfb, 0x1e, 0x66, 0xaf, 0x32, 0x0c, 0x12, 0x25, 0x99, 0x92, 859 | 0x1d, 0x67, 0x1f, 0xfa, 0x4d, 0x3c, 0xfe, 0xf9, 0xe3, 0x1d, 0x79, 0x3c, 0x1d, 0xe8, 0xb6, 0x1b, 860 | 0xd2, 0xc0, 0xb5, 0x9c, 0x6e, 0x48, 0x59, 0x38, 0xb1, 0x42, 0xab, 0x4b, 0x2f, 0x69, 0x70, 0x15, 861 | 0xbe, 0xb7, 0xdd, 0x59, 0xc7, 0x0f, 0xbc, 0xd0, 0xc3, 0xcd, 0x59, 0xe0, 0x8f, 0xa3, 0xc0, 0xe9, 862 | 0xc4, 0x12, 0xf5, 0x8b, 0x99, 0xe7, 0xcd, 0x1c, 0xda, 0x0d, 0xfc, 0x71, 0x97, 0x06, 0x81, 0x17, 863 | 0x0c, 0x27, 0x34, 0xb4, 0x6c, 0x87, 0x71, 0xb5, 0xfe, 0x3d, 0xb4, 0xde, 0xd8, 0x73, 0xdf, 0xa1, 864 | 0x67, 0x94, 0x31, 0x6b, 0x46, 0xf1, 0x01, 0x34, 0x59, 0x18, 0xd8, 0xee, 0x6c, 0x78, 0x69, 0x39, 865 | 0x11, 0x6d, 0x23, 0x0d, 0x19, 0x5b, 0x44, 0xe6, 0xb6, 0x1f, 0x62, 0x13, 0xfe, 0x1c, 0x60, 0xe4, 866 | 0x79, 0x4e, 0x2a, 0xa8, 0x6a, 0xc8, 0xd8, 0x24, 0x5b, 0xb1, 0x25, 0x99, 0xd6, 0xff, 0x96, 0xa0, 867 | 0x65, 0x46, 0xf3, 0x11, 0x0d, 0x32, 0xe6, 0x5d, 0x90, 0xa7, 0x8e, 0x67, 0x85, 0x02, 0xb2, 0x4a, 868 | 0x20, 0x31, 0x71, 0xe2, 0x01, 0x34, 0x27, 0x5e, 0x34, 0x72, 0xa8, 0xc0, 0x44, 0x44, 0xe6, 0x36, 869 | 0x2e, 0xb9, 0x0b, 0xb2, 0xed, 0x86, 0x8f, 0x7a, 0xa9, 0x42, 0xd2, 0x90, 0x51, 0x27, 0x90, 0x98, 870 | 0x44, 0xc1, 0x93, 0xc7, 0xa9, 0xa0, 0xa6, 0x21, 0x43, 0x4a, 0x04, 0x4f, 0x1e, 0xe7, 0x9b, 0x44, 871 | 0x22, 0xa2, 0xae, 0x21, 0xa3, 0x45, 0xe4, 0x48, 0x60, 0xa4, 0x92, 0x1c, 0xd2, 0xd0, 0x90, 0x51, 872 | 0xe3, 0x12, 0x81, 0xc2, 0x44, 0xca, 0x86, 0x86, 0x8c, 0x1d, 0x22, 0xb3, 0x22, 0x85, 0x89, 0x94, 873 | 0x4d, 0x0d, 0x19, 0x98, 0x4b, 0x32, 0xca, 0x3d, 0x68, 0x4d, 0xed, 0xdf, 0xe8, 0x24, 0xc7, 0x6c, 874 | 0x69, 0xc8, 0xd8, 0x20, 0xcd, 0xd4, 0x58, 0x14, 0xe5, 0x20, 0xd0, 0x90, 0xd1, 0x48, 0x45, 0x19, 875 | 0xe9, 0x4b, 0xb8, 0xc5, 0x8a, 0x28, 0x59, 0x43, 0xc6, 0x36, 0x69, 0xb1, 0x02, 0x2b, 0x97, 0xe5, 876 | 0xb0, 0xa6, 0x86, 0x0c, 0x25, 0x93, 0xa5, 0x34, 0xfd, 0x5f, 0x04, 0x2d, 0x93, 0xb2, 0x90, 0x4e, 877 | 0xb2, 0xbb, 0xeb, 0x43, 0xd3, 0x4d, 0x0c, 0xc2, 0xe5, 0xc9, 0x3d, 0xbd, 0x23, 0x66, 0x59, 0xa7, 878 | 0xb0, 0x24, 0x1d, 0x11, 0x99, 0xaf, 0xe3, 0xfb, 0xff, 0x08, 0xb7, 0x03, 0xea, 0x53, 0x2b, 0x06, 879 | 0x89, 0x3c, 0xd6, 0xae, 0x6a, 0xd2, 0xff, 0x04, 0xee, 0x65, 0x04, 0x73, 0x01, 0x66, 0xea, 0x29, 880 | 0x34, 0xf8, 0xb8, 0x9c, 0x22, 0x68, 0x29, 0x45, 0xca, 0xb9, 0x5d, 0x5d, 0xca, 0x6d, 0xfd, 0x1f, 881 | 0x09, 0xe4, 0xbe, 0x1b, 0xcd, 0xb3, 0xf0, 0x4f, 0x00, 0xbb, 0xd1, 0x9c, 0x06, 0xf6, 0x78, 0x48, 882 | 0xdd, 0x68, 0x2e, 0xa0, 0x6f, 0xf5, 0xf6, 0x4b, 0x3e, 0x73, 0x5d, 0xbc, 0x9a, 0x28, 0xee, 0x62, 883 | 0xc0, 0xf7, 0xbe, 0x80, 0xcf, 0x16, 0x07, 0xb0, 0x44, 0xe4, 0xc7, 0xb0, 0x16, 0xb9, 0x9f, 0x47, 884 | 0x5f, 0x42, 0xb3, 0xd8, 0x49, 0xcb, 0xb1, 0x2d, 0x46, 0x27, 0xa2, 0x93, 0xd2, 0x2a, 0x27, 0x8f, 885 | 0xb8, 0x8e, 0x3b, 0x69, 0x2d, 0x06, 0xdc, 0xc9, 0x53, 0xd8, 0x49, 0x2f, 0x47, 0xe0, 0xd4, 0x12, 886 | 0x8e, 0x56, 0xe4, 0x08, 0x67, 0x94, 0x5d, 0xcf, 0x36, 0x5f, 0xba, 0xa0, 0x0d, 0xe1, 0x4e, 0xf9, 887 | 0xce, 0xc5, 0x88, 0xeb, 0x49, 0xc4, 0x37, 0x73, 0xdb, 0xc5, 0x6b, 0x5f, 0xc4, 0xad, 0x3f, 0xcc, 888 | 0xaf, 0x5e, 0x86, 0x8d, 0xb7, 0xe6, 0x77, 0xe6, 0xe0, 0x9d, 0xa9, 0x54, 0xe2, 0xc1, 0xeb, 0xbe, 889 | 0x79, 0xfc, 0xca, 0x3c, 0x51, 0x10, 0x6e, 0xc1, 0xd6, 0xb7, 0x83, 0xb3, 0xd7, 0xa7, 0xfd, 0xf3, 890 | 0xfe, 0xb1, 0x52, 0xd5, 0x7f, 0x81, 0xfa, 0xc0, 0xa5, 0xde, 0x14, 0x1f, 0xac, 0x48, 0x96, 0x97, 891 | 0x95, 0x42, 0xba, 0xdc, 0x5b, 0x95, 0x2e, 0x2f, 0x2b, 0x85, 0x84, 0x79, 0xd1, 0x02, 0xd9, 0x8b, 892 | 0x81, 0x5c, 0xa3, 0xff, 0x85, 0xa0, 0x99, 0x6c, 0xb0, 0xa8, 0xa7, 0x1f, 0x65, 0x1f, 0x7c, 0x02, 893 | 0x9f, 0xe4, 0x87, 0x29, 0x6c, 0xc8, 0xda, 0x52, 0xf2, 0x7e, 0x76, 0x8b, 0xc7, 0x98, 0xb8, 0x40, 894 | 0x76, 0xb3, 0x15, 0xc9, 0x90, 0x1f, 0x5a, 0xd9, 0xe1, 0x3f, 0x6a, 0x00, 0x67, 0x96, 0x9f, 0xb9, 895 | 0x7b, 0x0a, 0xcd, 0xb9, 0xe5, 0xfb, 0xc2, 0x73, 0x8f, 0xe9, 0xf7, 0x8b, 0xf4, 0x85, 0x3e, 0xfe, 896 | 0xf4, 0xd3, 0xa7, 0xd8, 0x77, 0xc3, 0xe0, 0x8a, 0xc8, 0xf3, 0x85, 0x05, 0xff, 0x04, 0x3b, 0x29, 897 | 0x4d, 0xc8, 0x27, 0xfe, 0xe0, 0xbf, 0xbe, 0x01, 0x99, 0x5f, 0x33, 0xc7, 0x6e, 0xcf, 0x8b, 0x56, 898 | 0x3c, 0x84, 0xdd, 0x14, 0x5d, 0x28, 0x4f, 0xfc, 0x34, 0xba, 0x37, 0xc0, 0x85, 0x02, 0xc2, 0xf1, 899 | 0xa9, 0x9b, 0x82, 0x5d, 0x7d, 0x0e, 0x4a, 0x39, 0x38, 0xac, 0x80, 0xf4, 0x81, 0x5e, 0xa5, 0xff, 900 | 0xc4, 0xf8, 0x13, 0xef, 0x41, 0x5d, 0xac, 0x25, 0x7c, 0xf0, 0xb4, 0x7a, 0x88, 0xd4, 0x9f, 0x61, 901 | 0x6f, 0x55, 0x24, 0x2b, 0x18, 0x5d, 0x91, 0xb1, 0xb6, 0x06, 0x08, 0x78, 0x0b, 0x6e, 0xaf, 0x8e, 902 | 0x65, 0xc5, 0x06, 0x0f, 0xc5, 0x0d, 0xe4, 0xde, 0x9d, 0x35, 0xb5, 0x56, 0xd8, 0x42, 0xff, 0x06, 903 | 0x5a, 0x27, 0x49, 0xf7, 0x90, 0x25, 0xc7, 0x57, 0x50, 0xb3, 0xdd, 0xa9, 0x97, 0xfe, 0x03, 0x3e, 904 | 0xed, 0xf0, 0xde, 0xa2, 0x13, 0xf8, 0xe3, 0x0e, 0xa1, 0xbf, 0x46, 0x94, 0x85, 0xaf, 0xdc, 0xa9, 905 | 0x47, 0x12, 0xd1, 0x83, 0xfb, 0x20, 0x0b, 0xae, 0xe3, 0x4d, 0xa8, 0x5d, 0xf4, 0xc9, 0x40, 0xa9, 906 | 0xe0, 0x0d, 0x90, 0x06, 0x66, 0x5f, 0x41, 0xf1, 0xc7, 0xf9, 0xbb, 0x81, 0x52, 0x7d, 0x70, 0x08, 907 | 0xb2, 0x50, 0x97, 0x96, 0x1e, 0xf3, 0x9b, 0xf3, 0x23, 0x12, 0xbf, 0x5e, 0x14, 0x0f, 0xc8, 0x5b, 908 | 0xd3, 0x4c, 0x5e, 0xb6, 0x5a, 0x55, 0x50, 0xef, 0x4f, 0x09, 0xa0, 0x9f, 0x77, 0x40, 0xf8, 0x18, 909 | 0x1a, 0xbc, 0x9b, 0xc1, 0xa5, 0x18, 0x0b, 0x3d, 0x8e, 0xba, 0x6e, 0x52, 0xaf, 0xc4, 0x14, 0xde, 910 | 0xbf, 0x94, 0x29, 0x85, 0xae, 0x46, 0x5d, 0x37, 0xa9, 0x57, 0xf0, 0x73, 0xa8, 0x25, 0xd1, 0xec, 911 | 0x5f, 0x5b, 0xe0, 0xd4, 0xeb, 0xa7, 0xf4, 0x0a, 0x3e, 0xca, 0x2a, 0x95, 0xba, 0xe2, 0x69, 0x67, 912 | 0x84, 0x35, 0x73, 0x7a, 0x05, 0x3f, 0x03, 0xe9, 0xcc, 0xf2, 0x71, 0xfb, 0xba, 0xd7, 0xa0, 0x5e, 913 | 0x3b, 0xc3, 0x4f, 0x81, 0xdf, 0x7e, 0xf9, 0x14, 0x0a, 0x39, 0xa1, 0xae, 0x9b, 0xd4, 0x2b, 0x2f, 914 | 0x9e, 0x5e, 0x1c, 0xce, 0xec, 0xf0, 0x7d, 0x34, 0xea, 0x8c, 0xbd, 0x79, 0xf7, 0x83, 0xf5, 0x3b, 915 | 0x9d, 0x45, 0x2c, 0x0a, 0xec, 0x6e, 0xba, 0xaa, 0xbb, 0xd4, 0xd1, 0x3e, 0xcb, 0x3e, 0x46, 0x8d, 916 | 0xa4, 0x45, 0x7d, 0xf4, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x32, 0x64, 0x3b, 0x38, 0xf6, 0x0a, 917 | 0x00, 0x00, 918 | } 919 | -------------------------------------------------------------------------------- /internal/testdata/everything.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpcurl.test; 4 | option go_package = "github.com/kazegusuri/grpcurl/internal/testdata;testdata"; 5 | 6 | import "google/rpc/error_details.proto"; 7 | 8 | message SimpleMessage { 9 | string string_value = 1; 10 | bool bool_value = 2; 11 | } 12 | 13 | message NumberMessage { 14 | float float_value = 1; 15 | double double_value = 2; 16 | 17 | int32 int32_value = 3; 18 | int64 int64_value = 4; 19 | uint32 uint32_value = 5; 20 | uint64 uint64_value = 6; 21 | sint32 sint32_value = 7; 22 | sint64 sint64_value = 8; 23 | 24 | fixed32 fixed32_value = 9; 25 | fixed64 fixed64_value = 10; 26 | sfixed32 sfixed32_value = 11; 27 | sfixed64 sfixed64_value = 12; 28 | } 29 | 30 | message NestedMessage { 31 | message Nested { 32 | int32 int32_value = 1; 33 | string string_value = 2; 34 | } 35 | Nested nested_value = 1; 36 | repeated Nested repeated_nested_values = 2; 37 | } 38 | 39 | message EnumMessage { 40 | NumericEnum numeric_enum_value = 1; 41 | repeated NumericEnum repeated_numeric_enum_values = 2; 42 | 43 | AliasedEnum aliased_enum_value = 3; 44 | 45 | enum Nested { 46 | UNKNOWN = 0; 47 | PENDING = 1; 48 | COMPLETED = 2; 49 | } 50 | Nested nested_enum_value = 4; 51 | repeated Nested repeated_nested_enum_values = 5; 52 | } 53 | 54 | enum NumericEnum { 55 | ZERO = 0; 56 | ONE = 1; 57 | TWO = 2; 58 | } 59 | 60 | enum AliasedEnum { 61 | option allow_alias = true; 62 | UNKNOWN = 0; 63 | STARTED = 1; 64 | RUNNING = 1; 65 | } 66 | 67 | message Oneof { 68 | oneof oneof_value { 69 | int32 int32_value = 1; 70 | string string_value = 2; 71 | } 72 | } 73 | 74 | message OneofMessage { 75 | oneof oneof_value { 76 | int32 int32_value = 1; 77 | string string_value = 2; 78 | } 79 | 80 | repeated Oneof repeated_oneof_values = 3; 81 | } 82 | 83 | message MapMessage { 84 | map mapped_value = 1; 85 | map mapped_enum_value = 2; 86 | map mapped_nested_value = 3; 87 | } 88 | 89 | message GoogleMessage { 90 | google.rpc.RequestInfo info = 1; 91 | } 92 | 93 | service Everything { 94 | rpc Simple(SimpleMessage) returns (SimpleMessage) {} 95 | rpc Number(NumberMessage) returns (NumberMessage) {} 96 | rpc Enum(EnumMessage) returns (EnumMessage) {} 97 | rpc Oneof(OneofMessage) returns (OneofMessage) {} 98 | rpc Map(MapMessage) returns (MapMessage) {} 99 | rpc Google(GoogleMessage) returns (GoogleMessage) {} 100 | } 101 | -------------------------------------------------------------------------------- /internal/testdata/v2/v2.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: internal/testdata/v2/v2.proto 3 | // DO NOT EDIT! 4 | 5 | /* 6 | Package v2 is a generated protocol buffer package. 7 | 8 | It is generated from these files: 9 | internal/testdata/v2/v2.proto 10 | 11 | It has these top-level messages: 12 | */ 13 | package v2 14 | 15 | import proto "github.com/golang/protobuf/proto" 16 | import fmt "fmt" 17 | import math "math" 18 | import grpcurl_test "github.com/kazegusuri/grpcurl/internal/testdata" 19 | 20 | import ( 21 | context "golang.org/x/net/context" 22 | grpc "google.golang.org/grpc" 23 | ) 24 | 25 | // Reference imports to suppress errors if they are not otherwise used. 26 | var _ = proto.Marshal 27 | var _ = fmt.Errorf 28 | var _ = math.Inf 29 | 30 | // This is a compile-time assertion to ensure that this generated file 31 | // is compatible with the proto package it is being compiled against. 32 | // A compilation error at this line likely means your copy of the 33 | // proto package needs to be updated. 34 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 35 | 36 | // Reference imports to suppress errors if they are not otherwise used. 37 | var _ context.Context 38 | var _ grpc.ClientConn 39 | 40 | // This is a compile-time assertion to ensure that this generated file 41 | // is compatible with the grpc package it is being compiled against. 42 | const _ = grpc.SupportPackageIsVersion4 43 | 44 | // Client API for Echo service 45 | 46 | type EchoClient interface { 47 | Echo(ctx context.Context, in *grpcurl_test.EchoMessage, opts ...grpc.CallOption) (*grpcurl_test.EchoMessage, error) 48 | } 49 | 50 | type echoClient struct { 51 | cc *grpc.ClientConn 52 | } 53 | 54 | func NewEchoClient(cc *grpc.ClientConn) EchoClient { 55 | return &echoClient{cc} 56 | } 57 | 58 | func (c *echoClient) Echo(ctx context.Context, in *grpcurl_test.EchoMessage, opts ...grpc.CallOption) (*grpcurl_test.EchoMessage, error) { 59 | out := new(grpcurl_test.EchoMessage) 60 | err := grpc.Invoke(ctx, "/grpcurl.test.v2.Echo/Echo", in, out, c.cc, opts...) 61 | if err != nil { 62 | return nil, err 63 | } 64 | return out, nil 65 | } 66 | 67 | // Server API for Echo service 68 | 69 | type EchoServer interface { 70 | Echo(context.Context, *grpcurl_test.EchoMessage) (*grpcurl_test.EchoMessage, error) 71 | } 72 | 73 | func RegisterEchoServer(s *grpc.Server, srv EchoServer) { 74 | s.RegisterService(&_Echo_serviceDesc, srv) 75 | } 76 | 77 | func _Echo_Echo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 78 | in := new(grpcurl_test.EchoMessage) 79 | if err := dec(in); err != nil { 80 | return nil, err 81 | } 82 | if interceptor == nil { 83 | return srv.(EchoServer).Echo(ctx, in) 84 | } 85 | info := &grpc.UnaryServerInfo{ 86 | Server: srv, 87 | FullMethod: "/grpcurl.test.v2.Echo/Echo", 88 | } 89 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 90 | return srv.(EchoServer).Echo(ctx, req.(*grpcurl_test.EchoMessage)) 91 | } 92 | return interceptor(ctx, in, info, handler) 93 | } 94 | 95 | var _Echo_serviceDesc = grpc.ServiceDesc{ 96 | ServiceName: "grpcurl.test.v2.Echo", 97 | HandlerType: (*EchoServer)(nil), 98 | Methods: []grpc.MethodDesc{ 99 | { 100 | MethodName: "Echo", 101 | Handler: _Echo_Echo_Handler, 102 | }, 103 | }, 104 | Streams: []grpc.StreamDesc{}, 105 | Metadata: "internal/testdata/v2/v2.proto", 106 | } 107 | 108 | func init() { proto.RegisterFile("internal/testdata/v2/v2.proto", fileDescriptor0) } 109 | 110 | var fileDescriptor0 = []byte{ 111 | // 158 bytes of a gzipped FileDescriptorProto 112 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcd, 0xcc, 0x2b, 0x49, 113 | 0x2d, 0xca, 0x4b, 0xcc, 0xd1, 0x2f, 0x49, 0x2d, 0x2e, 0x49, 0x49, 0x2c, 0x49, 0xd4, 0x2f, 0x33, 114 | 0xd2, 0x2f, 0x33, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4f, 0x2f, 0x2a, 0x48, 0x2e, 115 | 0x2d, 0xca, 0xd1, 0x03, 0xc9, 0xea, 0x95, 0x19, 0x49, 0xa9, 0x60, 0xaa, 0x4f, 0x4d, 0xce, 0xc8, 116 | 0x8f, 0x2f, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0x85, 0x68, 0x33, 0x72, 0xe3, 0x62, 0x71, 0x4d, 117 | 0xce, 0xc8, 0x17, 0xb2, 0x83, 0xd2, 0x92, 0x7a, 0x28, 0xe6, 0x80, 0xc4, 0x7c, 0x53, 0x8b, 0x8b, 118 | 0x13, 0xd3, 0x53, 0xa5, 0x70, 0x4b, 0x29, 0x31, 0x38, 0x99, 0x47, 0x99, 0xa6, 0x67, 0x96, 0x64, 119 | 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x67, 0x27, 0x56, 0xa5, 0xa6, 0x97, 0x16, 0x97, 0x16, 120 | 0x65, 0xea, 0x43, 0xf5, 0xe8, 0x63, 0x73, 0xbd, 0x75, 0x99, 0x51, 0x12, 0x1b, 0xd8, 0x1d, 0xc6, 121 | 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5f, 0xc2, 0xdf, 0x70, 0xdf, 0x00, 0x00, 0x00, 122 | } 123 | -------------------------------------------------------------------------------- /internal/testdata/v2/v2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpcurl.test.v2; 4 | option go_package = "github.com/kazegusuri/grpcurl/internal/testdata/v2;v2"; 5 | 6 | import "internal/testdata/echo_service.proto"; 7 | 8 | service Echo { 9 | rpc Echo(grpcurl.test.EchoMessage) returns (grpcurl.test.EchoMessage) {} 10 | } 11 | -------------------------------------------------------------------------------- /list_services.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/jhump/protoreflect/grpcreflect" 8 | "github.com/spf13/cobra" 9 | ) 10 | 11 | type ListServicesCommand struct { 12 | cmd *cobra.Command 13 | opts *GlobalOptions 14 | addr string 15 | rcli *grpcreflect.Client 16 | long bool 17 | full bool 18 | } 19 | 20 | func NewListServicesCommand(opts *GlobalOptions) *ListServicesCommand { 21 | c := &ListServicesCommand{ 22 | cmd: &cobra.Command{ 23 | Use: "list_services ADDR [FULL_SERVICE_NAME]", 24 | Short: "List services and methods provided by gRPC server", 25 | Example: ` 26 | * List services 27 | grpcurl ls localhost:8888 28 | 29 | * List methods of the service 30 | grpcurl ls localhost:8888 test.TestService 31 | `, 32 | Aliases: []string{"ls"}, 33 | Args: cobra.RangeArgs(1, 2), 34 | SilenceUsage: true, 35 | }, 36 | opts: opts, 37 | } 38 | c.cmd.RunE = c.Run 39 | c.cmd.Flags().BoolVarP(&c.long, "long", "l", false, "list long") 40 | c.cmd.Flags().BoolVarP(&c.full, "full", "F", false, "fully qualified") 41 | return c 42 | } 43 | 44 | func (c *ListServicesCommand) Command() *cobra.Command { 45 | return c.cmd 46 | } 47 | 48 | func (c *ListServicesCommand) Run(cmd *cobra.Command, args []string) error { 49 | nargs := len(args) 50 | ctx := context.Background() 51 | 52 | c.addr = args[0] 53 | conn, err := NewGRPCConnection(ctx, c.addr, c.opts.Insecure) 54 | if err != nil { 55 | return err 56 | } 57 | defer conn.Close() 58 | c.rcli = NewServerReflectionClient(ctx, conn) 59 | 60 | if nargs == 1 { 61 | return c.listServices(ctx) 62 | } else if len(args) == 2 { 63 | return c.listMethods(ctx, args[1]) 64 | } 65 | 66 | return nil 67 | } 68 | 69 | func (c *ListServicesCommand) listServices(ctx context.Context) error { 70 | svcs, err := c.rcli.ListServices() 71 | if err != nil { 72 | return err 73 | } 74 | 75 | for i := range svcs { 76 | fmt.Fprintf(c.opts.Output, "%s\n", svcs[i]) 77 | } 78 | 79 | return nil 80 | } 81 | 82 | func (c *ListServicesCommand) listMethods(ctx context.Context, serviceName string) error { 83 | sdesc, err := c.rcli.ResolveService(serviceName) 84 | if err != nil { 85 | return err 86 | } 87 | 88 | for _, mdesc := range sdesc.GetMethods() { 89 | if c.long { 90 | inType := mdesc.GetInputType() 91 | outType := mdesc.GetOutputType() 92 | inRPCType := "" 93 | outRPCType := "" 94 | if mdesc.IsClientStreaming() { 95 | inRPCType = "streaming " 96 | } 97 | if mdesc.IsServerStreaming() { 98 | outRPCType = "streaming " 99 | } 100 | fmt.Fprintf(c.opts.Output, "%s(%s%s) return (%s%s)\n", 101 | mdesc.GetFullyQualifiedName(), 102 | inRPCType, inType.GetFullyQualifiedName(), 103 | outRPCType, outType.GetFullyQualifiedName()) 104 | } else { 105 | fmt.Fprintf(c.opts.Output, "%s\n", mdesc.GetFullyQualifiedName()) 106 | } 107 | } 108 | 109 | return nil 110 | } 111 | -------------------------------------------------------------------------------- /list_services_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | ) 7 | 8 | func ExampleListServices() { 9 | cmd := NewRootCommand(strings.NewReader(""), os.Stdout) 10 | cmd.Command().SetArgs([]string{"-k", "list_services", addr}) 11 | cmd.Command().Execute() 12 | // Unordered Output: 13 | // grpc.reflection.v1alpha.ServerReflection 14 | // grpcurl.test.Echo 15 | // grpcurl.test.Everything 16 | // grpcurl.test.v2.Echo 17 | } 18 | 19 | func ExampleListServicesMethod() { 20 | cmd := NewRootCommand(strings.NewReader(""), os.Stdout) 21 | cmd.Command().SetArgs([]string{"-k", "list_services", addr, "grpcurl.test.Echo"}) 22 | cmd.Command().Execute() 23 | // Unordered Output: 24 | // grpcurl.test.Echo.Echo 25 | // grpcurl.test.Echo.ClientStreamingEcho 26 | // grpcurl.test.Echo.ServerStreamingEcho 27 | // grpcurl.test.Echo.BidiStreamingBulkEcho 28 | } 29 | 30 | func ExampleListServicesMethodLong() { 31 | cmd := NewRootCommand(strings.NewReader(""), os.Stdout) 32 | cmd.Command().SetArgs([]string{"-k", "list_services", addr, "-l", "grpcurl.test.Echo"}) 33 | cmd.Command().Execute() 34 | // Unordered Output: 35 | // grpcurl.test.Echo.Echo(grpcurl.test.EchoMessage) return (grpcurl.test.EchoMessage) 36 | // grpcurl.test.Echo.ClientStreamingEcho(streaming grpcurl.test.EchoMessage) return (grpcurl.test.EchoMessage) 37 | // grpcurl.test.Echo.ServerStreamingEcho(grpcurl.test.EchoMessage) return (streaming grpcurl.test.EchoMessage) 38 | // grpcurl.test.Echo.BidiStreamingBulkEcho(streaming grpcurl.test.EchoMessage) return (streaming grpcurl.test.EchoMessage) 39 | } 40 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | func main() { 8 | if err := NewRootCommand(os.Stdin, os.Stdout).Command().Execute(); err != nil { 9 | os.Exit(1) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /root.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | type GlobalOptions struct { 10 | Verbose bool 11 | Insecure bool 12 | Input io.Reader 13 | Output io.Writer 14 | } 15 | 16 | type RootCommand struct { 17 | cmd *cobra.Command 18 | opts *GlobalOptions 19 | } 20 | 21 | func NewRootCommand(r io.Reader, w io.Writer) *RootCommand { 22 | c := &RootCommand{ 23 | cmd: &cobra.Command{ 24 | Use: "grpcurl", 25 | Short: "A handy and universal gRPC command line client", 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | return cmd.Help() 28 | }, 29 | }, 30 | opts: &GlobalOptions{ 31 | Input: r, 32 | Output: w, 33 | }, 34 | } 35 | c.cmd.PersistentFlags().BoolVarP(&c.opts.Verbose, "verbose", "v", false, "verbose output") 36 | c.cmd.PersistentFlags().BoolVarP(&c.opts.Insecure, "insecure", "k", false, "with insecure") 37 | c.cmd.AddCommand(NewListServicesCommand(c.opts).Command()) 38 | c.cmd.AddCommand(NewCallCommand(c.opts).Command()) 39 | return c 40 | } 41 | 42 | func (c *RootCommand) Command() *cobra.Command { 43 | return c.cmd 44 | } 45 | --------------------------------------------------------------------------------