Committing vendored dependencies and generated protos
Change-Id: I349c149b513d9de7d9f60bde2c954a939da2fc54
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt b/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt
new file mode 100644
index 0000000..3645162
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt
@@ -0,0 +1,27 @@
+Copyright (c) 2015, Gengo, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Gengo, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/codegenerator/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/codegenerator/BUILD.bazel
new file mode 100644
index 0000000..651177f
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/codegenerator/BUILD.bazel
@@ -0,0 +1,26 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//:generators"])
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "doc.go",
+ "parse_req.go",
+ ],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/codegenerator",
+ deps = [
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ ],
+)
+
+go_test(
+ name = "go_default_test",
+ srcs = ["parse_req_test.go"],
+ embed = [":go_default_library"],
+ deps = [
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ ],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/codegenerator/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/codegenerator/doc.go
new file mode 100644
index 0000000..3645317
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/codegenerator/doc.go
@@ -0,0 +1,4 @@
+/*
+Package codegenerator contains reusable functions used by the code generators.
+*/
+package codegenerator
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/codegenerator/parse_req.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/codegenerator/parse_req.go
new file mode 100644
index 0000000..e74575b
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/codegenerator/parse_req.go
@@ -0,0 +1,23 @@
+package codegenerator
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+
+ "github.com/golang/protobuf/proto"
+ plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
+)
+
+// ParseRequest parses a code generator request from a proto Message.
+func ParseRequest(r io.Reader) (*plugin.CodeGeneratorRequest, error) {
+ input, err := ioutil.ReadAll(r)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read code generator request: %v", err)
+ }
+ req := new(plugin.CodeGeneratorRequest)
+ if err = proto.Unmarshal(input, req); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal code generator request: %v", err)
+ }
+ return req, nil
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel
new file mode 100644
index 0000000..76cafe6
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel
@@ -0,0 +1,22 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+package(default_visibility = ["//visibility:public"])
+
+proto_library(
+ name = "internal_proto",
+ srcs = ["stream_chunk.proto"],
+ deps = ["@com_google_protobuf//:any_proto"],
+)
+
+go_proto_library(
+ name = "internal_go_proto",
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/internal",
+ proto = ":internal_proto",
+)
+
+go_library(
+ name = "go_default_library",
+ embed = [":internal_go_proto"],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/internal",
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.pb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.pb.go
new file mode 100644
index 0000000..8858f06
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.pb.go
@@ -0,0 +1,118 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: internal/stream_chunk.proto
+
+package internal
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import any "github.com/golang/protobuf/ptypes/any"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+// StreamError is a response type which is returned when
+// streaming rpc returns an error.
+type StreamError struct {
+ GrpcCode int32 `protobuf:"varint,1,opt,name=grpc_code,json=grpcCode,proto3" json:"grpc_code,omitempty"`
+ HttpCode int32 `protobuf:"varint,2,opt,name=http_code,json=httpCode,proto3" json:"http_code,omitempty"`
+ Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
+ HttpStatus string `protobuf:"bytes,4,opt,name=http_status,json=httpStatus,proto3" json:"http_status,omitempty"`
+ Details []*any.Any `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *StreamError) Reset() { *m = StreamError{} }
+func (m *StreamError) String() string { return proto.CompactTextString(m) }
+func (*StreamError) ProtoMessage() {}
+func (*StreamError) Descriptor() ([]byte, []int) {
+ return fileDescriptor_stream_chunk_a2afb657504565d7, []int{0}
+}
+func (m *StreamError) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_StreamError.Unmarshal(m, b)
+}
+func (m *StreamError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_StreamError.Marshal(b, m, deterministic)
+}
+func (dst *StreamError) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_StreamError.Merge(dst, src)
+}
+func (m *StreamError) XXX_Size() int {
+ return xxx_messageInfo_StreamError.Size(m)
+}
+func (m *StreamError) XXX_DiscardUnknown() {
+ xxx_messageInfo_StreamError.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_StreamError proto.InternalMessageInfo
+
+func (m *StreamError) GetGrpcCode() int32 {
+ if m != nil {
+ return m.GrpcCode
+ }
+ return 0
+}
+
+func (m *StreamError) GetHttpCode() int32 {
+ if m != nil {
+ return m.HttpCode
+ }
+ return 0
+}
+
+func (m *StreamError) GetMessage() string {
+ if m != nil {
+ return m.Message
+ }
+ return ""
+}
+
+func (m *StreamError) GetHttpStatus() string {
+ if m != nil {
+ return m.HttpStatus
+ }
+ return ""
+}
+
+func (m *StreamError) GetDetails() []*any.Any {
+ if m != nil {
+ return m.Details
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*StreamError)(nil), "grpc.gateway.runtime.StreamError")
+}
+
+func init() {
+ proto.RegisterFile("internal/stream_chunk.proto", fileDescriptor_stream_chunk_a2afb657504565d7)
+}
+
+var fileDescriptor_stream_chunk_a2afb657504565d7 = []byte{
+ // 223 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x34, 0x90, 0x41, 0x4e, 0xc3, 0x30,
+ 0x10, 0x45, 0x15, 0x4a, 0x69, 0x3b, 0xd9, 0x45, 0x5d, 0x18, 0xba, 0x20, 0x62, 0x95, 0x95, 0x23,
+ 0xc1, 0x09, 0x00, 0x71, 0x81, 0x74, 0xc7, 0xa6, 0x9a, 0x26, 0x83, 0x13, 0x91, 0xd8, 0xd1, 0x78,
+ 0x22, 0x94, 0x6b, 0x71, 0xc2, 0xca, 0x8e, 0xb2, 0xf4, 0x7b, 0x7f, 0xbe, 0xbe, 0x0c, 0xa7, 0xce,
+ 0x0a, 0xb1, 0xc5, 0xbe, 0xf4, 0xc2, 0x84, 0xc3, 0xa5, 0x6e, 0x27, 0xfb, 0xab, 0x47, 0x76, 0xe2,
+ 0xb2, 0xa3, 0xe1, 0xb1, 0xd6, 0x06, 0x85, 0xfe, 0x70, 0xd6, 0x3c, 0x59, 0xe9, 0x06, 0x7a, 0x7a,
+ 0x34, 0xce, 0x99, 0x9e, 0xca, 0x98, 0xb9, 0x4e, 0x3f, 0x25, 0xda, 0x79, 0x39, 0x78, 0xf9, 0x4f,
+ 0x20, 0x3d, 0xc7, 0x9e, 0x2f, 0x66, 0xc7, 0xd9, 0x09, 0x0e, 0xa1, 0xe2, 0x52, 0xbb, 0x86, 0x54,
+ 0x92, 0x27, 0xc5, 0xb6, 0xda, 0x07, 0xf0, 0xe9, 0x1a, 0x0a, 0xb2, 0x15, 0x19, 0x17, 0x79, 0xb7,
+ 0xc8, 0x00, 0xa2, 0x54, 0xb0, 0x1b, 0xc8, 0x7b, 0x34, 0xa4, 0x36, 0x79, 0x52, 0x1c, 0xaa, 0xf5,
+ 0x99, 0x3d, 0x43, 0x1a, 0xcf, 0xbc, 0xa0, 0x4c, 0x5e, 0xdd, 0x47, 0x0b, 0x01, 0x9d, 0x23, 0xc9,
+ 0x34, 0xec, 0x1a, 0x12, 0xec, 0x7a, 0xaf, 0xb6, 0xf9, 0xa6, 0x48, 0x5f, 0x8f, 0x7a, 0x59, 0xac,
+ 0xd7, 0xc5, 0xfa, 0xdd, 0xce, 0xd5, 0x1a, 0xfa, 0x80, 0xef, 0xfd, 0xfa, 0x09, 0xd7, 0x87, 0x18,
+ 0x79, 0xbb, 0x05, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x7d, 0xa5, 0x18, 0x17, 0x01, 0x00, 0x00,
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.proto b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.proto
new file mode 100644
index 0000000..55f42ce
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.proto
@@ -0,0 +1,15 @@
+syntax = "proto3";
+package grpc.gateway.runtime;
+option go_package = "internal";
+
+import "google/protobuf/any.proto";
+
+// StreamError is a response type which is returned when
+// streaming rpc returns an error.
+message StreamError {
+ int32 grpc_code = 1;
+ int32 http_code = 2;
+ string message = 3;
+ string http_status = 4;
+ repeated google.protobuf.Any details = 5;
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/BUILD.bazel
new file mode 100644
index 0000000..cb772ef
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/BUILD.bazel
@@ -0,0 +1,45 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+load("@io_bazel_rules_go//proto:compiler.bzl", "go_proto_compiler")
+
+package(default_visibility = ["//visibility:private"])
+
+go_library(
+ name = "go_default_library",
+ srcs = ["main.go"],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway",
+ deps = [
+ "//codegenerator:go_default_library",
+ "//protoc-gen-grpc-gateway/descriptor:go_default_library",
+ "//protoc-gen-grpc-gateway/gengateway:go_default_library",
+ "@com_github_golang_glog//:go_default_library",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ ],
+)
+
+go_binary(
+ name = "protoc-gen-grpc-gateway",
+ embed = [":go_default_library"],
+ visibility = ["//visibility:public"],
+)
+
+go_proto_compiler(
+ name = "go_gen_grpc_gateway",
+ options = [
+ "logtostderr=true",
+ "allow_repeated_fields_in_body=true",
+ ],
+ plugin = ":protoc-gen-grpc-gateway",
+ suffix = ".pb.gw.go",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//runtime:go_default_library",
+ "//utilities:go_default_library",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@org_golang_google_grpc//:go_default_library",
+ "@org_golang_google_grpc//codes:go_default_library",
+ "@org_golang_google_grpc//grpclog:go_default_library",
+ "@org_golang_google_grpc//status:go_default_library",
+ "@org_golang_x_net//context:go_default_library",
+ ],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/BUILD.bazel
new file mode 100644
index 0000000..cfbdc27
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/BUILD.bazel
@@ -0,0 +1,44 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//:generators"])
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "grpc_api_configuration.go",
+ "grpc_api_service.go",
+ "registry.go",
+ "services.go",
+ "types.go",
+ ],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor",
+ deps = [
+ "//protoc-gen-grpc-gateway/httprule:go_default_library",
+ "@com_github_ghodss_yaml//:go_default_library",
+ "@com_github_golang_glog//:go_default_library",
+ "@com_github_golang_protobuf//jsonpb:go_default_library_gen",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@com_github_golang_protobuf//protoc-gen-go/generator:go_default_library_gen",
+ "@go_googleapis//google/api:annotations_go_proto",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
+ ],
+)
+
+go_test(
+ name = "go_default_test",
+ size = "small",
+ srcs = [
+ "grpc_api_configuration_test.go",
+ "registry_test.go",
+ "services_test.go",
+ "types_test.go",
+ ],
+ embed = [":go_default_library"],
+ deps = [
+ "//protoc-gen-grpc-gateway/httprule:go_default_library",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
+ ],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_configuration.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_configuration.go
new file mode 100644
index 0000000..ca68ed7
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_configuration.go
@@ -0,0 +1,71 @@
+package descriptor
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "strings"
+
+ "github.com/ghodss/yaml"
+ "github.com/golang/protobuf/jsonpb"
+)
+
+func loadGrpcAPIServiceFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*GrpcAPIService, error) {
+ jsonContents, err := yaml.YAMLToJSON(yamlFileContents)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to convert gRPC API Configuration from YAML in '%v' to JSON: %v", yamlSourceLogName, err)
+ }
+
+ // As our GrpcAPIService is incomplete accept unkown fields.
+ unmarshaler := jsonpb.Unmarshaler{
+ AllowUnknownFields: true,
+ }
+
+ serviceConfiguration := GrpcAPIService{}
+ if err := unmarshaler.Unmarshal(bytes.NewReader(jsonContents), &serviceConfiguration); err != nil {
+ return nil, fmt.Errorf("Failed to parse gRPC API Configuration from YAML in '%v': %v", yamlSourceLogName, err)
+ }
+
+ return &serviceConfiguration, nil
+}
+
+func registerHTTPRulesFromGrpcAPIService(registry *Registry, service *GrpcAPIService, sourceLogName string) error {
+ if service.HTTP == nil {
+ // Nothing to do
+ return nil
+ }
+
+ for _, rule := range service.HTTP.GetRules() {
+ selector := "." + strings.Trim(rule.GetSelector(), " ")
+ if strings.ContainsAny(selector, "*, ") {
+ return fmt.Errorf("Selector '%v' in %v must specify a single service method without wildcards", rule.GetSelector(), sourceLogName)
+ }
+
+ registry.AddExternalHTTPRule(selector, rule)
+ }
+
+ return nil
+}
+
+// LoadGrpcAPIServiceFromYAML loads a gRPC API Configuration from the given YAML file
+// and registers the HttpRule descriptions contained in it as externalHTTPRules in
+// the given registry. This must be done before loading the proto file.
+//
+// You can learn more about gRPC API Service descriptions from google's documentation
+// at https://cloud.google.com/endpoints/docs/grpc/grpc-service-config
+//
+// Note that for the purposes of the gateway generator we only consider a subset of all
+// available features google supports in their service descriptions.
+func (r *Registry) LoadGrpcAPIServiceFromYAML(yamlFile string) error {
+ yamlFileContents, err := ioutil.ReadFile(yamlFile)
+ if err != nil {
+ return fmt.Errorf("Failed to read gRPC API Configuration description from '%v': %v", yamlFile, err)
+ }
+
+ service, err := loadGrpcAPIServiceFromYAML(yamlFileContents, yamlFile)
+ if err != nil {
+ return err
+ }
+
+ return registerHTTPRulesFromGrpcAPIService(r, service, yamlFile)
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_service.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_service.go
new file mode 100644
index 0000000..75b8240
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/grpc_api_service.go
@@ -0,0 +1,31 @@
+package descriptor
+
+import (
+ "github.com/golang/protobuf/proto"
+ "google.golang.org/genproto/googleapis/api/annotations"
+)
+
+// GrpcAPIService represents a stripped down version of google.api.Service .
+// Compare to https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
+// The original imports 23 other protobuf files we are not interested in. If a significant
+// subset (>50%) of these start being reproduced in this file we should swap to using the
+// full generated version instead.
+//
+// For the purposes of the gateway generator we only consider a small subset of all
+// available features google supports in their service descriptions. Thanks to backwards
+// compatibility guarantees by protobuf it is safe for us to remove the other fields.
+// We also only implement the absolute minimum of protobuf generator boilerplate to use
+// our simplified version. These should be pretty stable too.
+type GrpcAPIService struct {
+ // Http Rule. Named Http in the actual proto. Changed to suppress linter warning.
+ HTTP *annotations.Http `protobuf:"bytes,9,opt,name=http" json:"http,omitempty"`
+}
+
+// ProtoMessage returns an empty GrpcAPIService element
+func (*GrpcAPIService) ProtoMessage() {}
+
+// Reset resets the GrpcAPIService
+func (m *GrpcAPIService) Reset() { *m = GrpcAPIService{} }
+
+// String returns the string representation of the GrpcAPIService
+func (m *GrpcAPIService) String() string { return proto.CompactTextString(m) }
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/registry.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/registry.go
new file mode 100644
index 0000000..2f05636
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/registry.go
@@ -0,0 +1,498 @@
+package descriptor
+
+import (
+ "fmt"
+ "path"
+ "path/filepath"
+ "strings"
+
+ "github.com/golang/glog"
+ descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
+ "google.golang.org/genproto/googleapis/api/annotations"
+)
+
+// Registry is a registry of information extracted from plugin.CodeGeneratorRequest.
+type Registry struct {
+ // msgs is a mapping from fully-qualified message name to descriptor
+ msgs map[string]*Message
+
+ // enums is a mapping from fully-qualified enum name to descriptor
+ enums map[string]*Enum
+
+ // files is a mapping from file path to descriptor
+ files map[string]*File
+
+ // prefix is a prefix to be inserted to golang package paths generated from proto package names.
+ prefix string
+
+ // importPath is used as the package if no input files declare go_package. If it contains slashes, everything up to the rightmost slash is ignored.
+ importPath string
+
+ // pkgMap is a user-specified mapping from file path to proto package.
+ pkgMap map[string]string
+
+ // pkgAliases is a mapping from package aliases to package paths in go which are already taken.
+ pkgAliases map[string]string
+
+ // allowDeleteBody permits http delete methods to have a body
+ allowDeleteBody bool
+
+ // externalHttpRules is a mapping from fully qualified service method names to additional HttpRules applicable besides the ones found in annotations.
+ externalHTTPRules map[string][]*annotations.HttpRule
+
+ // allowMerge generation one swagger file out of multiple protos
+ allowMerge bool
+
+ // mergeFileName target swagger file name after merge
+ mergeFileName string
+
+ // allowRepeatedFieldsInBody permits repeated field in body field path of `google.api.http` annotation option
+ allowRepeatedFieldsInBody bool
+
+ // includePackageInTags controls whether the package name defined in the `package` directive
+ // in the proto file can be prepended to the gRPC service name in the `Tags` field of every operation.
+ includePackageInTags bool
+
+ // repeatedPathParamSeparator specifies how path parameter repeated fields are separated
+ repeatedPathParamSeparator repeatedFieldSeparator
+
+ // useJSONNamesForFields if true json tag name is used for generating fields in swagger definitions,
+ // otherwise the original proto name is used. It's helpful for synchronizing the swagger definition
+ // with grpc-gateway response, if it uses json tags for marshaling.
+ useJSONNamesForFields bool
+
+ // useFQNForSwaggerName if true swagger names will use the full qualified name (FQN) from proto definition,
+ // and generate a dot-separated swagger name concatenating all elements from the proto FQN.
+ // If false, the default behavior is to concat the last 2 elements of the FQN if they are unique, otherwise concat
+ // all the elements of the FQN without any separator
+ useFQNForSwaggerName bool
+
+ // allowColonFinalSegments determines whether colons are permitted
+ // in the final segment of a path.
+ allowColonFinalSegments bool
+}
+
+type repeatedFieldSeparator struct {
+ name string
+ sep rune
+}
+
+// NewRegistry returns a new Registry.
+func NewRegistry() *Registry {
+ return &Registry{
+ msgs: make(map[string]*Message),
+ enums: make(map[string]*Enum),
+ files: make(map[string]*File),
+ pkgMap: make(map[string]string),
+ pkgAliases: make(map[string]string),
+ externalHTTPRules: make(map[string][]*annotations.HttpRule),
+ repeatedPathParamSeparator: repeatedFieldSeparator{
+ name: "csv",
+ sep: ',',
+ },
+ }
+}
+
+// Load loads definitions of services, methods, messages, enumerations and fields from "req".
+func (r *Registry) Load(req *plugin.CodeGeneratorRequest) error {
+ for _, file := range req.GetProtoFile() {
+ r.loadFile(file)
+ }
+
+ var targetPkg string
+ for _, name := range req.FileToGenerate {
+ target := r.files[name]
+ if target == nil {
+ return fmt.Errorf("no such file: %s", name)
+ }
+ name := r.packageIdentityName(target.FileDescriptorProto)
+ if targetPkg == "" {
+ targetPkg = name
+ } else {
+ if targetPkg != name {
+ return fmt.Errorf("inconsistent package names: %s %s", targetPkg, name)
+ }
+ }
+
+ if err := r.loadServices(target); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// loadFile loads messages, enumerations and fields from "file".
+// It does not loads services and methods in "file". You need to call
+// loadServices after loadFiles is called for all files to load services and methods.
+func (r *Registry) loadFile(file *descriptor.FileDescriptorProto) {
+ pkg := GoPackage{
+ Path: r.goPackagePath(file),
+ Name: r.defaultGoPackageName(file),
+ }
+ if err := r.ReserveGoPackageAlias(pkg.Name, pkg.Path); err != nil {
+ for i := 0; ; i++ {
+ alias := fmt.Sprintf("%s_%d", pkg.Name, i)
+ if err := r.ReserveGoPackageAlias(alias, pkg.Path); err == nil {
+ pkg.Alias = alias
+ break
+ }
+ }
+ }
+ f := &File{
+ FileDescriptorProto: file,
+ GoPkg: pkg,
+ }
+
+ r.files[file.GetName()] = f
+ r.registerMsg(f, nil, file.GetMessageType())
+ r.registerEnum(f, nil, file.GetEnumType())
+}
+
+func (r *Registry) registerMsg(file *File, outerPath []string, msgs []*descriptor.DescriptorProto) {
+ for i, md := range msgs {
+ m := &Message{
+ File: file,
+ Outers: outerPath,
+ DescriptorProto: md,
+ Index: i,
+ }
+ for _, fd := range md.GetField() {
+ m.Fields = append(m.Fields, &Field{
+ Message: m,
+ FieldDescriptorProto: fd,
+ })
+ }
+ file.Messages = append(file.Messages, m)
+ r.msgs[m.FQMN()] = m
+ glog.V(1).Infof("register name: %s", m.FQMN())
+
+ var outers []string
+ outers = append(outers, outerPath...)
+ outers = append(outers, m.GetName())
+ r.registerMsg(file, outers, m.GetNestedType())
+ r.registerEnum(file, outers, m.GetEnumType())
+ }
+}
+
+func (r *Registry) registerEnum(file *File, outerPath []string, enums []*descriptor.EnumDescriptorProto) {
+ for i, ed := range enums {
+ e := &Enum{
+ File: file,
+ Outers: outerPath,
+ EnumDescriptorProto: ed,
+ Index: i,
+ }
+ file.Enums = append(file.Enums, e)
+ r.enums[e.FQEN()] = e
+ glog.V(1).Infof("register enum name: %s", e.FQEN())
+ }
+}
+
+// LookupMsg looks up a message type by "name".
+// It tries to resolve "name" from "location" if "name" is a relative message name.
+func (r *Registry) LookupMsg(location, name string) (*Message, error) {
+ glog.V(1).Infof("lookup %s from %s", name, location)
+ if strings.HasPrefix(name, ".") {
+ m, ok := r.msgs[name]
+ if !ok {
+ return nil, fmt.Errorf("no message found: %s", name)
+ }
+ return m, nil
+ }
+
+ if !strings.HasPrefix(location, ".") {
+ location = fmt.Sprintf(".%s", location)
+ }
+ components := strings.Split(location, ".")
+ for len(components) > 0 {
+ fqmn := strings.Join(append(components, name), ".")
+ if m, ok := r.msgs[fqmn]; ok {
+ return m, nil
+ }
+ components = components[:len(components)-1]
+ }
+ return nil, fmt.Errorf("no message found: %s", name)
+}
+
+// LookupEnum looks up a enum type by "name".
+// It tries to resolve "name" from "location" if "name" is a relative enum name.
+func (r *Registry) LookupEnum(location, name string) (*Enum, error) {
+ glog.V(1).Infof("lookup enum %s from %s", name, location)
+ if strings.HasPrefix(name, ".") {
+ e, ok := r.enums[name]
+ if !ok {
+ return nil, fmt.Errorf("no enum found: %s", name)
+ }
+ return e, nil
+ }
+
+ if !strings.HasPrefix(location, ".") {
+ location = fmt.Sprintf(".%s", location)
+ }
+ components := strings.Split(location, ".")
+ for len(components) > 0 {
+ fqen := strings.Join(append(components, name), ".")
+ if e, ok := r.enums[fqen]; ok {
+ return e, nil
+ }
+ components = components[:len(components)-1]
+ }
+ return nil, fmt.Errorf("no enum found: %s", name)
+}
+
+// LookupFile looks up a file by name.
+func (r *Registry) LookupFile(name string) (*File, error) {
+ f, ok := r.files[name]
+ if !ok {
+ return nil, fmt.Errorf("no such file given: %s", name)
+ }
+ return f, nil
+}
+
+// LookupExternalHTTPRules looks up external http rules by fully qualified service method name
+func (r *Registry) LookupExternalHTTPRules(qualifiedMethodName string) []*annotations.HttpRule {
+ return r.externalHTTPRules[qualifiedMethodName]
+}
+
+// AddExternalHTTPRule adds an external http rule for the given fully qualified service method name
+func (r *Registry) AddExternalHTTPRule(qualifiedMethodName string, rule *annotations.HttpRule) {
+ r.externalHTTPRules[qualifiedMethodName] = append(r.externalHTTPRules[qualifiedMethodName], rule)
+}
+
+// AddPkgMap adds a mapping from a .proto file to proto package name.
+func (r *Registry) AddPkgMap(file, protoPkg string) {
+ r.pkgMap[file] = protoPkg
+}
+
+// SetPrefix registers the prefix to be added to go package paths generated from proto package names.
+func (r *Registry) SetPrefix(prefix string) {
+ r.prefix = prefix
+}
+
+// SetImportPath registers the importPath which is used as the package if no
+// input files declare go_package. If it contains slashes, everything up to the
+// rightmost slash is ignored.
+func (r *Registry) SetImportPath(importPath string) {
+ r.importPath = importPath
+}
+
+// ReserveGoPackageAlias reserves the unique alias of go package.
+// If succeeded, the alias will be never used for other packages in generated go files.
+// If failed, the alias is already taken by another package, so you need to use another
+// alias for the package in your go files.
+func (r *Registry) ReserveGoPackageAlias(alias, pkgpath string) error {
+ if taken, ok := r.pkgAliases[alias]; ok {
+ if taken == pkgpath {
+ return nil
+ }
+ return fmt.Errorf("package name %s is already taken. Use another alias", alias)
+ }
+ r.pkgAliases[alias] = pkgpath
+ return nil
+}
+
+// goPackagePath returns the go package path which go files generated from "f" should have.
+// It respects the mapping registered by AddPkgMap if exists. Or use go_package as import path
+// if it includes a slash, Otherwide, it generates a path from the file name of "f".
+func (r *Registry) goPackagePath(f *descriptor.FileDescriptorProto) string {
+ name := f.GetName()
+ if pkg, ok := r.pkgMap[name]; ok {
+ return path.Join(r.prefix, pkg)
+ }
+
+ gopkg := f.Options.GetGoPackage()
+ idx := strings.LastIndex(gopkg, "/")
+ if idx >= 0 {
+ if sc := strings.LastIndex(gopkg, ";"); sc > 0 {
+ gopkg = gopkg[:sc+1-1]
+ }
+ return gopkg
+ }
+
+ return path.Join(r.prefix, path.Dir(name))
+}
+
+// GetAllFQMNs returns a list of all FQMNs
+func (r *Registry) GetAllFQMNs() []string {
+ var keys []string
+ for k := range r.msgs {
+ keys = append(keys, k)
+ }
+ return keys
+}
+
+// GetAllFQENs returns a list of all FQENs
+func (r *Registry) GetAllFQENs() []string {
+ var keys []string
+ for k := range r.enums {
+ keys = append(keys, k)
+ }
+ return keys
+}
+
+// SetAllowDeleteBody controls whether http delete methods may have a
+// body or fail loading if encountered.
+func (r *Registry) SetAllowDeleteBody(allow bool) {
+ r.allowDeleteBody = allow
+}
+
+// SetAllowMerge controls whether generation one swagger file out of multiple protos
+func (r *Registry) SetAllowMerge(allow bool) {
+ r.allowMerge = allow
+}
+
+// IsAllowMerge whether generation one swagger file out of multiple protos
+func (r *Registry) IsAllowMerge() bool {
+ return r.allowMerge
+}
+
+// SetMergeFileName controls the target swagger file name out of multiple protos
+func (r *Registry) SetMergeFileName(mergeFileName string) {
+ r.mergeFileName = mergeFileName
+}
+
+// SetAllowRepeatedFieldsInBody controls whether repeated field can be used
+// in `body` and `response_body` (`google.api.http` annotation option) field path or not
+func (r *Registry) SetAllowRepeatedFieldsInBody(allow bool) {
+ r.allowRepeatedFieldsInBody = allow
+}
+
+// IsAllowRepeatedFieldsInBody checks if repeated field can be used
+// in `body` and `response_body` (`google.api.http` annotation option) field path or not
+func (r *Registry) IsAllowRepeatedFieldsInBody() bool {
+ return r.allowRepeatedFieldsInBody
+}
+
+// SetIncludePackageInTags controls whether the package name defined in the `package` directive
+// in the proto file can be prepended to the gRPC service name in the `Tags` field of every operation.
+func (r *Registry) SetIncludePackageInTags(allow bool) {
+ r.includePackageInTags = allow
+}
+
+// IsIncludePackageInTags checks whether the package name defined in the `package` directive
+// in the proto file can be prepended to the gRPC service name in the `Tags` field of every operation.
+func (r *Registry) IsIncludePackageInTags() bool {
+ return r.includePackageInTags
+}
+
+// GetRepeatedPathParamSeparator returns a rune spcifying how
+// path parameter repeated fields are separated.
+func (r *Registry) GetRepeatedPathParamSeparator() rune {
+ return r.repeatedPathParamSeparator.sep
+}
+
+// GetRepeatedPathParamSeparatorName returns the name path parameter repeated
+// fields repeatedFieldSeparator. I.e. 'csv', 'pipe', 'ssv' or 'tsv'
+func (r *Registry) GetRepeatedPathParamSeparatorName() string {
+ return r.repeatedPathParamSeparator.name
+}
+
+// SetRepeatedPathParamSeparator sets how path parameter repeated fields are
+// separated. Allowed names are 'csv', 'pipe', 'ssv' and 'tsv'.
+func (r *Registry) SetRepeatedPathParamSeparator(name string) error {
+ var sep rune
+ switch name {
+ case "csv":
+ sep = ','
+ case "pipes":
+ sep = '|'
+ case "ssv":
+ sep = ' '
+ case "tsv":
+ sep = '\t'
+ default:
+ return fmt.Errorf("unknown repeated path parameter separator: %s", name)
+ }
+ r.repeatedPathParamSeparator = repeatedFieldSeparator{
+ name: name,
+ sep: sep,
+ }
+ return nil
+}
+
+// SetUseJSONNamesForFields sets useJSONNamesForFields
+func (r *Registry) SetUseJSONNamesForFields(use bool) {
+ r.useJSONNamesForFields = use
+}
+
+// GetUseJSONNamesForFields returns useJSONNamesForFields
+func (r *Registry) GetUseJSONNamesForFields() bool {
+ return r.useJSONNamesForFields
+}
+
+// SetUseFQNForSwaggerName sets useFQNForSwaggerName
+func (r *Registry) SetUseFQNForSwaggerName(use bool) {
+ r.useFQNForSwaggerName = use
+}
+
+// GetAllowColonFinalSegments returns allowColonFinalSegments
+func (r *Registry) GetAllowColonFinalSegments() bool {
+ return r.allowColonFinalSegments
+}
+
+// SetAllowColonFinalSegments sets allowColonFinalSegments
+func (r *Registry) SetAllowColonFinalSegments(use bool) {
+ r.allowColonFinalSegments = use
+}
+
+// GetUseFQNForSwaggerName returns useFQNForSwaggerName
+func (r *Registry) GetUseFQNForSwaggerName() bool {
+ return r.useFQNForSwaggerName
+}
+
+// GetMergeFileName return the target merge swagger file name
+func (r *Registry) GetMergeFileName() string {
+ return r.mergeFileName
+}
+
+// sanitizePackageName replaces unallowed character in package name
+// with allowed character.
+func sanitizePackageName(pkgName string) string {
+ pkgName = strings.Replace(pkgName, ".", "_", -1)
+ pkgName = strings.Replace(pkgName, "-", "_", -1)
+ return pkgName
+}
+
+// defaultGoPackageName returns the default go package name to be used for go files generated from "f".
+// You might need to use an unique alias for the package when you import it. Use ReserveGoPackageAlias to get a unique alias.
+func (r *Registry) defaultGoPackageName(f *descriptor.FileDescriptorProto) string {
+ name := r.packageIdentityName(f)
+ return sanitizePackageName(name)
+}
+
+// packageIdentityName returns the identity of packages.
+// protoc-gen-grpc-gateway rejects CodeGenerationRequests which contains more than one packages
+// as protoc-gen-go does.
+func (r *Registry) packageIdentityName(f *descriptor.FileDescriptorProto) string {
+ if f.Options != nil && f.Options.GoPackage != nil {
+ gopkg := f.Options.GetGoPackage()
+ idx := strings.LastIndex(gopkg, "/")
+ if idx < 0 {
+ gopkg = gopkg[idx+1:]
+ }
+
+ gopkg = gopkg[idx+1:]
+ // package name is overrided with the string after the
+ // ';' character
+ sc := strings.IndexByte(gopkg, ';')
+ if sc < 0 {
+ return sanitizePackageName(gopkg)
+
+ }
+ return sanitizePackageName(gopkg[sc+1:])
+ }
+ if p := r.importPath; len(p) != 0 {
+ if i := strings.LastIndex(p, "/"); i >= 0 {
+ p = p[i+1:]
+ }
+ return p
+ }
+
+ if f.Package == nil {
+ base := filepath.Base(f.GetName())
+ ext := filepath.Ext(base)
+ return strings.TrimSuffix(base, ext)
+ }
+ return f.GetPackage()
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/services.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/services.go
new file mode 100644
index 0000000..8916d31
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/services.go
@@ -0,0 +1,304 @@
+package descriptor
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/golang/glog"
+ "github.com/golang/protobuf/proto"
+ descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule"
+ options "google.golang.org/genproto/googleapis/api/annotations"
+)
+
+// loadServices registers services and their methods from "targetFile" to "r".
+// It must be called after loadFile is called for all files so that loadServices
+// can resolve names of message types and their fields.
+func (r *Registry) loadServices(file *File) error {
+ glog.V(1).Infof("Loading services from %s", file.GetName())
+ var svcs []*Service
+ for _, sd := range file.GetService() {
+ glog.V(2).Infof("Registering %s", sd.GetName())
+ svc := &Service{
+ File: file,
+ ServiceDescriptorProto: sd,
+ }
+ for _, md := range sd.GetMethod() {
+ glog.V(2).Infof("Processing %s.%s", sd.GetName(), md.GetName())
+ opts, err := extractAPIOptions(md)
+ if err != nil {
+ glog.Errorf("Failed to extract HttpRule from %s.%s: %v", svc.GetName(), md.GetName(), err)
+ return err
+ }
+ optsList := r.LookupExternalHTTPRules((&Method{Service: svc, MethodDescriptorProto: md}).FQMN())
+ if opts != nil {
+ optsList = append(optsList, opts)
+ }
+ if len(optsList) == 0 {
+ glog.V(1).Infof("Found non-target method: %s.%s", svc.GetName(), md.GetName())
+ }
+ meth, err := r.newMethod(svc, md, optsList)
+ if err != nil {
+ return err
+ }
+ svc.Methods = append(svc.Methods, meth)
+ }
+ if len(svc.Methods) == 0 {
+ continue
+ }
+ glog.V(2).Infof("Registered %s with %d method(s)", svc.GetName(), len(svc.Methods))
+ svcs = append(svcs, svc)
+ }
+ file.Services = svcs
+ return nil
+}
+
+func (r *Registry) newMethod(svc *Service, md *descriptor.MethodDescriptorProto, optsList []*options.HttpRule) (*Method, error) {
+ requestType, err := r.LookupMsg(svc.File.GetPackage(), md.GetInputType())
+ if err != nil {
+ return nil, err
+ }
+ responseType, err := r.LookupMsg(svc.File.GetPackage(), md.GetOutputType())
+ if err != nil {
+ return nil, err
+ }
+ meth := &Method{
+ Service: svc,
+ MethodDescriptorProto: md,
+ RequestType: requestType,
+ ResponseType: responseType,
+ }
+
+ newBinding := func(opts *options.HttpRule, idx int) (*Binding, error) {
+ var (
+ httpMethod string
+ pathTemplate string
+ )
+ switch {
+ case opts.GetGet() != "":
+ httpMethod = "GET"
+ pathTemplate = opts.GetGet()
+ if opts.Body != "" {
+ return nil, fmt.Errorf("must not set request body when http method is GET: %s", md.GetName())
+ }
+
+ case opts.GetPut() != "":
+ httpMethod = "PUT"
+ pathTemplate = opts.GetPut()
+
+ case opts.GetPost() != "":
+ httpMethod = "POST"
+ pathTemplate = opts.GetPost()
+
+ case opts.GetDelete() != "":
+ httpMethod = "DELETE"
+ pathTemplate = opts.GetDelete()
+ if opts.Body != "" && !r.allowDeleteBody {
+ return nil, fmt.Errorf("must not set request body when http method is DELETE except allow_delete_body option is true: %s", md.GetName())
+ }
+
+ case opts.GetPatch() != "":
+ httpMethod = "PATCH"
+ pathTemplate = opts.GetPatch()
+
+ case opts.GetCustom() != nil:
+ custom := opts.GetCustom()
+ httpMethod = custom.Kind
+ pathTemplate = custom.Path
+
+ default:
+ glog.V(1).Infof("No pattern specified in google.api.HttpRule: %s", md.GetName())
+ return nil, nil
+ }
+
+ parsed, err := httprule.Parse(pathTemplate)
+ if err != nil {
+ return nil, err
+ }
+ tmpl := parsed.Compile()
+
+ if md.GetClientStreaming() && len(tmpl.Fields) > 0 {
+ return nil, fmt.Errorf("cannot use path parameter in client streaming")
+ }
+
+ b := &Binding{
+ Method: meth,
+ Index: idx,
+ PathTmpl: tmpl,
+ HTTPMethod: httpMethod,
+ }
+
+ for _, f := range tmpl.Fields {
+ param, err := r.newParam(meth, f)
+ if err != nil {
+ return nil, err
+ }
+ b.PathParams = append(b.PathParams, param)
+ }
+
+ // TODO(yugui) Handle query params
+
+ b.Body, err = r.newBody(meth, opts.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ b.ResponseBody, err = r.newResponse(meth, opts.ResponseBody)
+ if err != nil {
+ return nil, err
+ }
+
+ return b, nil
+ }
+
+ applyOpts := func(opts *options.HttpRule) error {
+ b, err := newBinding(opts, len(meth.Bindings))
+ if err != nil {
+ return err
+ }
+
+ if b != nil {
+ meth.Bindings = append(meth.Bindings, b)
+ }
+ for _, additional := range opts.GetAdditionalBindings() {
+ if len(additional.AdditionalBindings) > 0 {
+ return fmt.Errorf("additional_binding in additional_binding not allowed: %s.%s", svc.GetName(), meth.GetName())
+ }
+ b, err := newBinding(additional, len(meth.Bindings))
+ if err != nil {
+ return err
+ }
+ meth.Bindings = append(meth.Bindings, b)
+ }
+
+ return nil
+ }
+
+ for _, opts := range optsList {
+ if err := applyOpts(opts); err != nil {
+ return nil, err
+ }
+ }
+
+ return meth, nil
+}
+
+func extractAPIOptions(meth *descriptor.MethodDescriptorProto) (*options.HttpRule, error) {
+ if meth.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(meth.Options, options.E_Http) {
+ return nil, nil
+ }
+ ext, err := proto.GetExtension(meth.Options, options.E_Http)
+ if err != nil {
+ return nil, err
+ }
+ opts, ok := ext.(*options.HttpRule)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want an HttpRule", ext)
+ }
+ return opts, nil
+}
+
+func (r *Registry) newParam(meth *Method, path string) (Parameter, error) {
+ msg := meth.RequestType
+ fields, err := r.resolveFieldPath(msg, path, true)
+ if err != nil {
+ return Parameter{}, err
+ }
+ l := len(fields)
+ if l == 0 {
+ return Parameter{}, fmt.Errorf("invalid field access list for %s", path)
+ }
+ target := fields[l-1].Target
+ switch target.GetType() {
+ case descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_GROUP:
+ glog.V(2).Infoln("found aggregate type:", target, target.TypeName)
+ if IsWellKnownType(*target.TypeName) {
+ glog.V(2).Infoln("found well known aggregate type:", target)
+ } else {
+ return Parameter{}, fmt.Errorf("aggregate type %s in parameter of %s.%s: %s", target.Type, meth.Service.GetName(), meth.GetName(), path)
+ }
+ }
+ return Parameter{
+ FieldPath: FieldPath(fields),
+ Method: meth,
+ Target: fields[l-1].Target,
+ }, nil
+}
+
+func (r *Registry) newBody(meth *Method, path string) (*Body, error) {
+ msg := meth.RequestType
+ switch path {
+ case "":
+ return nil, nil
+ case "*":
+ return &Body{FieldPath: nil}, nil
+ }
+ fields, err := r.resolveFieldPath(msg, path, false)
+ if err != nil {
+ return nil, err
+ }
+ return &Body{FieldPath: FieldPath(fields)}, nil
+}
+
+func (r *Registry) newResponse(meth *Method, path string) (*Body, error) {
+ msg := meth.ResponseType
+ switch path {
+ case "", "*":
+ return nil, nil
+ }
+ fields, err := r.resolveFieldPath(msg, path, false)
+ if err != nil {
+ return nil, err
+ }
+ return &Body{FieldPath: FieldPath(fields)}, nil
+}
+
+// lookupField looks up a field named "name" within "msg".
+// It returns nil if no such field found.
+func lookupField(msg *Message, name string) *Field {
+ for _, f := range msg.Fields {
+ if f.GetName() == name {
+ return f
+ }
+ }
+ return nil
+}
+
+// resolveFieldPath resolves "path" into a list of fieldDescriptor, starting from "msg".
+func (r *Registry) resolveFieldPath(msg *Message, path string, isPathParam bool) ([]FieldPathComponent, error) {
+ if path == "" {
+ return nil, nil
+ }
+
+ root := msg
+ var result []FieldPathComponent
+ for i, c := range strings.Split(path, ".") {
+ if i > 0 {
+ f := result[i-1].Target
+ switch f.GetType() {
+ case descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_GROUP:
+ var err error
+ msg, err = r.LookupMsg(msg.FQMN(), f.GetTypeName())
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, fmt.Errorf("not an aggregate type: %s in %s", f.GetName(), path)
+ }
+ }
+
+ glog.V(2).Infof("Lookup %s in %s", c, msg.FQMN())
+ f := lookupField(msg, c)
+ if f == nil {
+ return nil, fmt.Errorf("no field %q found in %s", path, root.GetName())
+ }
+ if !(isPathParam || r.allowRepeatedFieldsInBody) && f.GetLabel() == descriptor.FieldDescriptorProto_LABEL_REPEATED {
+ return nil, fmt.Errorf("repeated field not allowed in field path: %s in %s", f.GetName(), path)
+ }
+ result = append(result, FieldPathComponent{Name: c, Target: f})
+ }
+ return result, nil
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/types.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/types.go
new file mode 100644
index 0000000..4aa75f8
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/types.go
@@ -0,0 +1,466 @@
+package descriptor
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ gogen "github.com/golang/protobuf/protoc-gen-go/generator"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule"
+)
+
+// IsWellKnownType returns true if the provided fully qualified type name is considered 'well-known'.
+func IsWellKnownType(typeName string) bool {
+ _, ok := wellKnownTypeConv[typeName]
+ return ok
+}
+
+// GoPackage represents a golang package
+type GoPackage struct {
+ // Path is the package path to the package.
+ Path string
+ // Name is the package name of the package
+ Name string
+ // Alias is an alias of the package unique within the current invokation of grpc-gateway generator.
+ Alias string
+}
+
+// Standard returns whether the import is a golang standard package.
+func (p GoPackage) Standard() bool {
+ return !strings.Contains(p.Path, ".")
+}
+
+// String returns a string representation of this package in the form of import line in golang.
+func (p GoPackage) String() string {
+ if p.Alias == "" {
+ return fmt.Sprintf("%q", p.Path)
+ }
+ return fmt.Sprintf("%s %q", p.Alias, p.Path)
+}
+
+// File wraps descriptor.FileDescriptorProto for richer features.
+type File struct {
+ *descriptor.FileDescriptorProto
+ // GoPkg is the go package of the go file generated from this file..
+ GoPkg GoPackage
+ // Messages is the list of messages defined in this file.
+ Messages []*Message
+ // Enums is the list of enums defined in this file.
+ Enums []*Enum
+ // Services is the list of services defined in this file.
+ Services []*Service
+}
+
+// proto2 determines if the syntax of the file is proto2.
+func (f *File) proto2() bool {
+ return f.Syntax == nil || f.GetSyntax() == "proto2"
+}
+
+// Message describes a protocol buffer message types
+type Message struct {
+ // File is the file where the message is defined
+ File *File
+ // Outers is a list of outer messages if this message is a nested type.
+ Outers []string
+ *descriptor.DescriptorProto
+ Fields []*Field
+
+ // Index is proto path index of this message in File.
+ Index int
+}
+
+// FQMN returns a fully qualified message name of this message.
+func (m *Message) FQMN() string {
+ components := []string{""}
+ if m.File.Package != nil {
+ components = append(components, m.File.GetPackage())
+ }
+ components = append(components, m.Outers...)
+ components = append(components, m.GetName())
+ return strings.Join(components, ".")
+}
+
+// GoType returns a go type name for the message type.
+// It prefixes the type name with the package alias if
+// its belonging package is not "currentPackage".
+func (m *Message) GoType(currentPackage string) string {
+ var components []string
+ components = append(components, m.Outers...)
+ components = append(components, m.GetName())
+
+ name := strings.Join(components, "_")
+ if m.File.GoPkg.Path == currentPackage {
+ return name
+ }
+ pkg := m.File.GoPkg.Name
+ if alias := m.File.GoPkg.Alias; alias != "" {
+ pkg = alias
+ }
+ return fmt.Sprintf("%s.%s", pkg, name)
+}
+
+// Enum describes a protocol buffer enum types
+type Enum struct {
+ // File is the file where the enum is defined
+ File *File
+ // Outers is a list of outer messages if this enum is a nested type.
+ Outers []string
+ *descriptor.EnumDescriptorProto
+
+ Index int
+}
+
+// FQEN returns a fully qualified enum name of this enum.
+func (e *Enum) FQEN() string {
+ components := []string{""}
+ if e.File.Package != nil {
+ components = append(components, e.File.GetPackage())
+ }
+ components = append(components, e.Outers...)
+ components = append(components, e.GetName())
+ return strings.Join(components, ".")
+}
+
+// GoType returns a go type name for the enum type.
+// It prefixes the type name with the package alias if
+// its belonging package is not "currentPackage".
+func (e *Enum) GoType(currentPackage string) string {
+ var components []string
+ components = append(components, e.Outers...)
+ components = append(components, e.GetName())
+
+ name := strings.Join(components, "_")
+ if e.File.GoPkg.Path == currentPackage {
+ return name
+ }
+ pkg := e.File.GoPkg.Name
+ if alias := e.File.GoPkg.Alias; alias != "" {
+ pkg = alias
+ }
+ return fmt.Sprintf("%s.%s", pkg, name)
+}
+
+// Service wraps descriptor.ServiceDescriptorProto for richer features.
+type Service struct {
+ // File is the file where this service is defined.
+ File *File
+ *descriptor.ServiceDescriptorProto
+ // Methods is the list of methods defined in this service.
+ Methods []*Method
+}
+
+// FQSN returns the fully qualified service name of this service.
+func (s *Service) FQSN() string {
+ components := []string{""}
+ if s.File.Package != nil {
+ components = append(components, s.File.GetPackage())
+ }
+ components = append(components, s.GetName())
+ return strings.Join(components, ".")
+}
+
+// Method wraps descriptor.MethodDescriptorProto for richer features.
+type Method struct {
+ // Service is the service which this method belongs to.
+ Service *Service
+ *descriptor.MethodDescriptorProto
+
+ // RequestType is the message type of requests to this method.
+ RequestType *Message
+ // ResponseType is the message type of responses from this method.
+ ResponseType *Message
+ Bindings []*Binding
+}
+
+// FQMN returns a fully qualified rpc method name of this method.
+func (m *Method) FQMN() string {
+ components := []string{}
+ components = append(components, m.Service.FQSN())
+ components = append(components, m.GetName())
+ return strings.Join(components, ".")
+}
+
+// Binding describes how an HTTP endpoint is bound to a gRPC method.
+type Binding struct {
+ // Method is the method which the endpoint is bound to.
+ Method *Method
+ // Index is a zero-origin index of the binding in the target method
+ Index int
+ // PathTmpl is path template where this method is mapped to.
+ PathTmpl httprule.Template
+ // HTTPMethod is the HTTP method which this method is mapped to.
+ HTTPMethod string
+ // PathParams is the list of parameters provided in HTTP request paths.
+ PathParams []Parameter
+ // Body describes parameters provided in HTTP request body.
+ Body *Body
+ // ResponseBody describes field in response struct to marshal in HTTP response body.
+ ResponseBody *Body
+}
+
+// ExplicitParams returns a list of explicitly bound parameters of "b",
+// i.e. a union of field path for body and field paths for path parameters.
+func (b *Binding) ExplicitParams() []string {
+ var result []string
+ if b.Body != nil {
+ result = append(result, b.Body.FieldPath.String())
+ }
+ for _, p := range b.PathParams {
+ result = append(result, p.FieldPath.String())
+ }
+ return result
+}
+
+// Field wraps descriptor.FieldDescriptorProto for richer features.
+type Field struct {
+ // Message is the message type which this field belongs to.
+ Message *Message
+ // FieldMessage is the message type of the field.
+ FieldMessage *Message
+ *descriptor.FieldDescriptorProto
+}
+
+// Parameter is a parameter provided in http requests
+type Parameter struct {
+ // FieldPath is a path to a proto field which this parameter is mapped to.
+ FieldPath
+ // Target is the proto field which this parameter is mapped to.
+ Target *Field
+ // Method is the method which this parameter is used for.
+ Method *Method
+}
+
+// ConvertFuncExpr returns a go expression of a converter function.
+// The converter function converts a string into a value for the parameter.
+func (p Parameter) ConvertFuncExpr() (string, error) {
+ tbl := proto3ConvertFuncs
+ if !p.IsProto2() && p.IsRepeated() {
+ tbl = proto3RepeatedConvertFuncs
+ } else if p.IsProto2() && !p.IsRepeated() {
+ tbl = proto2ConvertFuncs
+ } else if p.IsProto2() && p.IsRepeated() {
+ tbl = proto2RepeatedConvertFuncs
+ }
+ typ := p.Target.GetType()
+ conv, ok := tbl[typ]
+ if !ok {
+ conv, ok = wellKnownTypeConv[p.Target.GetTypeName()]
+ }
+ if !ok {
+ return "", fmt.Errorf("unsupported field type %s of parameter %s in %s.%s", typ, p.FieldPath, p.Method.Service.GetName(), p.Method.GetName())
+ }
+ return conv, nil
+}
+
+// IsEnum returns true if the field is an enum type, otherwise false is returned.
+func (p Parameter) IsEnum() bool {
+ return p.Target.GetType() == descriptor.FieldDescriptorProto_TYPE_ENUM
+}
+
+// IsRepeated returns true if the field is repeated, otherwise false is returned.
+func (p Parameter) IsRepeated() bool {
+ return p.Target.GetLabel() == descriptor.FieldDescriptorProto_LABEL_REPEATED
+}
+
+// IsProto2 returns true if the field is proto2, otherwise false is returned.
+func (p Parameter) IsProto2() bool {
+ return p.Target.Message.File.proto2()
+}
+
+// Body describes a http (request|response) body to be sent to the (method|client).
+// This is used in body and response_body options in google.api.HttpRule
+type Body struct {
+ // FieldPath is a path to a proto field which the (request|response) body is mapped to.
+ // The (request|response) body is mapped to the (request|response) type itself if FieldPath is empty.
+ FieldPath FieldPath
+}
+
+// AssignableExpr returns an assignable expression in Go to be used to initialize method request object.
+// It starts with "msgExpr", which is the go expression of the method request object.
+func (b Body) AssignableExpr(msgExpr string) string {
+ return b.FieldPath.AssignableExpr(msgExpr)
+}
+
+// FieldPath is a path to a field from a request message.
+type FieldPath []FieldPathComponent
+
+// String returns a string representation of the field path.
+func (p FieldPath) String() string {
+ var components []string
+ for _, c := range p {
+ components = append(components, c.Name)
+ }
+ return strings.Join(components, ".")
+}
+
+// IsNestedProto3 indicates whether the FieldPath is a nested Proto3 path.
+func (p FieldPath) IsNestedProto3() bool {
+ if len(p) > 1 && !p[0].Target.Message.File.proto2() {
+ return true
+ }
+ return false
+}
+
+// AssignableExpr is an assignable expression in Go to be used to assign a value to the target field.
+// It starts with "msgExpr", which is the go expression of the method request object.
+func (p FieldPath) AssignableExpr(msgExpr string) string {
+ l := len(p)
+ if l == 0 {
+ return msgExpr
+ }
+
+ var preparations []string
+ components := msgExpr
+ for i, c := range p {
+ // Check if it is a oneOf field.
+ if c.Target.OneofIndex != nil {
+ index := c.Target.OneofIndex
+ msg := c.Target.Message
+ oneOfName := gogen.CamelCase(msg.GetOneofDecl()[*index].GetName())
+ oneofFieldName := msg.GetName() + "_" + c.AssignableExpr()
+
+ components = components + "." + oneOfName
+ s := `if %s == nil {
+ %s =&%s{}
+ } else if _, ok := %s.(*%s); !ok {
+ return nil, metadata, grpc.Errorf(codes.InvalidArgument, "expect type: *%s, but: %%t\n",%s)
+ }`
+
+ preparations = append(preparations, fmt.Sprintf(s, components, components, oneofFieldName, components, oneofFieldName, oneofFieldName, components))
+ components = components + ".(*" + oneofFieldName + ")"
+ }
+
+ if i == l-1 {
+ components = components + "." + c.AssignableExpr()
+ continue
+ }
+ components = components + "." + c.ValueExpr()
+ }
+
+ preparations = append(preparations, components)
+ return strings.Join(preparations, "\n")
+}
+
+// FieldPathComponent is a path component in FieldPath
+type FieldPathComponent struct {
+ // Name is a name of the proto field which this component corresponds to.
+ // TODO(yugui) is this necessary?
+ Name string
+ // Target is the proto field which this component corresponds to.
+ Target *Field
+}
+
+// AssignableExpr returns an assignable expression in go for this field.
+func (c FieldPathComponent) AssignableExpr() string {
+ return gogen.CamelCase(c.Name)
+}
+
+// ValueExpr returns an expression in go for this field.
+func (c FieldPathComponent) ValueExpr() string {
+ if c.Target.Message.File.proto2() {
+ return fmt.Sprintf("Get%s()", gogen.CamelCase(c.Name))
+ }
+ return gogen.CamelCase(c.Name)
+}
+
+var (
+ proto3ConvertFuncs = map[descriptor.FieldDescriptorProto_Type]string{
+ descriptor.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64",
+ descriptor.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32",
+ descriptor.FieldDescriptorProto_TYPE_INT64: "runtime.Int64",
+ descriptor.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64",
+ descriptor.FieldDescriptorProto_TYPE_INT32: "runtime.Int32",
+ descriptor.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64",
+ descriptor.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32",
+ descriptor.FieldDescriptorProto_TYPE_BOOL: "runtime.Bool",
+ descriptor.FieldDescriptorProto_TYPE_STRING: "runtime.String",
+ // FieldDescriptorProto_TYPE_GROUP
+ // FieldDescriptorProto_TYPE_MESSAGE
+ descriptor.FieldDescriptorProto_TYPE_BYTES: "runtime.Bytes",
+ descriptor.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32",
+ descriptor.FieldDescriptorProto_TYPE_ENUM: "runtime.Enum",
+ descriptor.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32",
+ descriptor.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64",
+ descriptor.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32",
+ descriptor.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64",
+ }
+
+ proto3RepeatedConvertFuncs = map[descriptor.FieldDescriptorProto_Type]string{
+ descriptor.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64Slice",
+ descriptor.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32Slice",
+ descriptor.FieldDescriptorProto_TYPE_INT64: "runtime.Int64Slice",
+ descriptor.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64Slice",
+ descriptor.FieldDescriptorProto_TYPE_INT32: "runtime.Int32Slice",
+ descriptor.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64Slice",
+ descriptor.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32Slice",
+ descriptor.FieldDescriptorProto_TYPE_BOOL: "runtime.BoolSlice",
+ descriptor.FieldDescriptorProto_TYPE_STRING: "runtime.StringSlice",
+ // FieldDescriptorProto_TYPE_GROUP
+ // FieldDescriptorProto_TYPE_MESSAGE
+ descriptor.FieldDescriptorProto_TYPE_BYTES: "runtime.BytesSlice",
+ descriptor.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32Slice",
+ descriptor.FieldDescriptorProto_TYPE_ENUM: "runtime.EnumSlice",
+ descriptor.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32Slice",
+ descriptor.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64Slice",
+ descriptor.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32Slice",
+ descriptor.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64Slice",
+ }
+
+ proto2ConvertFuncs = map[descriptor.FieldDescriptorProto_Type]string{
+ descriptor.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64P",
+ descriptor.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32P",
+ descriptor.FieldDescriptorProto_TYPE_INT64: "runtime.Int64P",
+ descriptor.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64P",
+ descriptor.FieldDescriptorProto_TYPE_INT32: "runtime.Int32P",
+ descriptor.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64P",
+ descriptor.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32P",
+ descriptor.FieldDescriptorProto_TYPE_BOOL: "runtime.BoolP",
+ descriptor.FieldDescriptorProto_TYPE_STRING: "runtime.StringP",
+ // FieldDescriptorProto_TYPE_GROUP
+ // FieldDescriptorProto_TYPE_MESSAGE
+ // FieldDescriptorProto_TYPE_BYTES
+ // TODO(yugui) Handle bytes
+ descriptor.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32P",
+ descriptor.FieldDescriptorProto_TYPE_ENUM: "runtime.EnumP",
+ descriptor.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32P",
+ descriptor.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64P",
+ descriptor.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32P",
+ descriptor.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64P",
+ }
+
+ proto2RepeatedConvertFuncs = map[descriptor.FieldDescriptorProto_Type]string{
+ descriptor.FieldDescriptorProto_TYPE_DOUBLE: "runtime.Float64Slice",
+ descriptor.FieldDescriptorProto_TYPE_FLOAT: "runtime.Float32Slice",
+ descriptor.FieldDescriptorProto_TYPE_INT64: "runtime.Int64Slice",
+ descriptor.FieldDescriptorProto_TYPE_UINT64: "runtime.Uint64Slice",
+ descriptor.FieldDescriptorProto_TYPE_INT32: "runtime.Int32Slice",
+ descriptor.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64Slice",
+ descriptor.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32Slice",
+ descriptor.FieldDescriptorProto_TYPE_BOOL: "runtime.BoolSlice",
+ descriptor.FieldDescriptorProto_TYPE_STRING: "runtime.StringSlice",
+ // FieldDescriptorProto_TYPE_GROUP
+ // FieldDescriptorProto_TYPE_MESSAGE
+ // FieldDescriptorProto_TYPE_BYTES
+ // TODO(maros7) Handle bytes
+ descriptor.FieldDescriptorProto_TYPE_UINT32: "runtime.Uint32Slice",
+ descriptor.FieldDescriptorProto_TYPE_ENUM: "runtime.EnumSlice",
+ descriptor.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32Slice",
+ descriptor.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64Slice",
+ descriptor.FieldDescriptorProto_TYPE_SINT32: "runtime.Int32Slice",
+ descriptor.FieldDescriptorProto_TYPE_SINT64: "runtime.Int64Slice",
+ }
+
+ wellKnownTypeConv = map[string]string{
+ ".google.protobuf.Timestamp": "runtime.Timestamp",
+ ".google.protobuf.Duration": "runtime.Duration",
+ ".google.protobuf.StringValue": "runtime.StringValue",
+ ".google.protobuf.FloatValue": "runtime.FloatValue",
+ ".google.protobuf.DoubleValue": "runtime.DoubleValue",
+ ".google.protobuf.BoolValue": "runtime.BoolValue",
+ ".google.protobuf.BytesValue": "runtime.BytesValue",
+ ".google.protobuf.Int32Value": "runtime.Int32Value",
+ ".google.protobuf.UInt32Value": "runtime.UInt32Value",
+ ".google.protobuf.Int64Value": "runtime.Int64Value",
+ ".google.protobuf.UInt64Value": "runtime.UInt64Value",
+ }
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator/BUILD.bazel
new file mode 100644
index 0000000..6cb2162
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator/BUILD.bazel
@@ -0,0 +1,13 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+package(default_visibility = ["//:generators"])
+
+go_library(
+ name = "go_default_library",
+ srcs = ["generator.go"],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator",
+ deps = [
+ "//protoc-gen-grpc-gateway/descriptor:go_default_library",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ ],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator/generator.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator/generator.go
new file mode 100644
index 0000000..df55da4
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator/generator.go
@@ -0,0 +1,13 @@
+// Package generator provides an abstract interface to code generators.
+package generator
+
+import (
+ plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
+)
+
+// Generator is an abstraction of code generators.
+type Generator interface {
+ // Generate generates output files from input .proto files.
+ Generate(targets []*descriptor.File) ([]*plugin.CodeGeneratorResponse_File, error)
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/BUILD.bazel
new file mode 100644
index 0000000..316010f
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/BUILD.bazel
@@ -0,0 +1,38 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//protoc-gen-grpc-gateway:__subpackages__"])
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "doc.go",
+ "generator.go",
+ "template.go",
+ ],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway",
+ deps = [
+ "//protoc-gen-grpc-gateway/descriptor:go_default_library",
+ "//protoc-gen-grpc-gateway/generator:go_default_library",
+ "//utilities:go_default_library",
+ "@com_github_golang_glog//:go_default_library",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@com_github_golang_protobuf//protoc-gen-go/generator:go_default_library_gen",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ ],
+)
+
+go_test(
+ name = "go_default_test",
+ size = "small",
+ srcs = [
+ "generator_test.go",
+ "template_test.go",
+ ],
+ embed = [":go_default_library"],
+ deps = [
+ "//protoc-gen-grpc-gateway/descriptor:go_default_library",
+ "//protoc-gen-grpc-gateway/httprule:go_default_library",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
+ ],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/doc.go
new file mode 100644
index 0000000..223d810
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/doc.go
@@ -0,0 +1,2 @@
+// Package gengateway provides a code generator for grpc gateway files.
+package gengateway
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/generator.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/generator.go
new file mode 100644
index 0000000..0b6bfbd
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/generator.go
@@ -0,0 +1,171 @@
+package gengateway
+
+import (
+ "errors"
+ "fmt"
+ "go/format"
+ "path"
+ "path/filepath"
+ "strings"
+
+ "github.com/golang/glog"
+ "github.com/golang/protobuf/proto"
+ plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
+ gen "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator"
+)
+
+var (
+ errNoTargetService = errors.New("no target service defined in the file")
+)
+
+type pathType int
+
+const (
+ pathTypeImport pathType = iota
+ pathTypeSourceRelative
+)
+
+type generator struct {
+ reg *descriptor.Registry
+ baseImports []descriptor.GoPackage
+ useRequestContext bool
+ registerFuncSuffix string
+ pathType pathType
+ allowPatchFeature bool
+}
+
+// New returns a new generator which generates grpc gateway files.
+func New(reg *descriptor.Registry, useRequestContext bool, registerFuncSuffix, pathTypeString string, allowPatchFeature bool) gen.Generator {
+ var imports []descriptor.GoPackage
+ for _, pkgpath := range []string{
+ "context",
+ "io",
+ "net/http",
+ "github.com/grpc-ecosystem/grpc-gateway/runtime",
+ "github.com/grpc-ecosystem/grpc-gateway/utilities",
+ "github.com/golang/protobuf/descriptor",
+ "github.com/golang/protobuf/proto",
+ "google.golang.org/grpc",
+ "google.golang.org/grpc/codes",
+ "google.golang.org/grpc/grpclog",
+ "google.golang.org/grpc/status",
+ } {
+ pkg := descriptor.GoPackage{
+ Path: pkgpath,
+ Name: path.Base(pkgpath),
+ }
+ if err := reg.ReserveGoPackageAlias(pkg.Name, pkg.Path); err != nil {
+ for i := 0; ; i++ {
+ alias := fmt.Sprintf("%s_%d", pkg.Name, i)
+ if err := reg.ReserveGoPackageAlias(alias, pkg.Path); err != nil {
+ continue
+ }
+ pkg.Alias = alias
+ break
+ }
+ }
+ imports = append(imports, pkg)
+ }
+
+ var pathType pathType
+ switch pathTypeString {
+ case "", "import":
+ // paths=import is default
+ case "source_relative":
+ pathType = pathTypeSourceRelative
+ default:
+ glog.Fatalf(`Unknown path type %q: want "import" or "source_relative".`, pathTypeString)
+ }
+
+ return &generator{
+ reg: reg,
+ baseImports: imports,
+ useRequestContext: useRequestContext,
+ registerFuncSuffix: registerFuncSuffix,
+ pathType: pathType,
+ allowPatchFeature: allowPatchFeature,
+ }
+}
+
+func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGeneratorResponse_File, error) {
+ var files []*plugin.CodeGeneratorResponse_File
+ for _, file := range targets {
+ glog.V(1).Infof("Processing %s", file.GetName())
+ code, err := g.generate(file)
+ if err == errNoTargetService {
+ glog.V(1).Infof("%s: %v", file.GetName(), err)
+ continue
+ }
+ if err != nil {
+ return nil, err
+ }
+ formatted, err := format.Source([]byte(code))
+ if err != nil {
+ glog.Errorf("%v: %s", err, code)
+ return nil, err
+ }
+ name := file.GetName()
+ if g.pathType == pathTypeImport && file.GoPkg.Path != "" {
+ name = fmt.Sprintf("%s/%s", file.GoPkg.Path, filepath.Base(name))
+ }
+ ext := filepath.Ext(name)
+ base := strings.TrimSuffix(name, ext)
+ output := fmt.Sprintf("%s.pb.gw.go", base)
+ files = append(files, &plugin.CodeGeneratorResponse_File{
+ Name: proto.String(output),
+ Content: proto.String(string(formatted)),
+ })
+ glog.V(1).Infof("Will emit %s", output)
+ }
+ return files, nil
+}
+
+func (g *generator) generate(file *descriptor.File) (string, error) {
+ pkgSeen := make(map[string]bool)
+ var imports []descriptor.GoPackage
+ for _, pkg := range g.baseImports {
+ pkgSeen[pkg.Path] = true
+ imports = append(imports, pkg)
+ }
+ for _, svc := range file.Services {
+ for _, m := range svc.Methods {
+ imports = append(imports, g.addEnumPathParamImports(file, m, pkgSeen)...)
+ pkg := m.RequestType.File.GoPkg
+ if len(m.Bindings) == 0 ||
+ pkg == file.GoPkg || pkgSeen[pkg.Path] {
+ continue
+ }
+ pkgSeen[pkg.Path] = true
+ imports = append(imports, pkg)
+ }
+ }
+ params := param{
+ File: file,
+ Imports: imports,
+ UseRequestContext: g.useRequestContext,
+ RegisterFuncSuffix: g.registerFuncSuffix,
+ AllowPatchFeature: g.allowPatchFeature,
+ }
+ return applyTemplate(params, g.reg)
+}
+
+// addEnumPathParamImports handles adding import of enum path parameter go packages
+func (g *generator) addEnumPathParamImports(file *descriptor.File, m *descriptor.Method, pkgSeen map[string]bool) []descriptor.GoPackage {
+ var imports []descriptor.GoPackage
+ for _, b := range m.Bindings {
+ for _, p := range b.PathParams {
+ e, err := g.reg.LookupEnum("", p.Target.GetTypeName())
+ if err != nil {
+ continue
+ }
+ pkg := e.File.GoPkg
+ if pkg == file.GoPkg || pkgSeen[pkg.Path] {
+ continue
+ }
+ pkgSeen[pkg.Path] = true
+ imports = append(imports, pkg)
+ }
+ }
+ return imports
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/template.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/template.go
new file mode 100644
index 0000000..1d3d3ca
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway/template.go
@@ -0,0 +1,715 @@
+package gengateway
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "strings"
+ "text/template"
+
+ "github.com/golang/glog"
+ generator2 "github.com/golang/protobuf/protoc-gen-go/generator"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
+ "github.com/grpc-ecosystem/grpc-gateway/utilities"
+)
+
+type param struct {
+ *descriptor.File
+ Imports []descriptor.GoPackage
+ UseRequestContext bool
+ RegisterFuncSuffix string
+ AllowPatchFeature bool
+}
+
+type binding struct {
+ *descriptor.Binding
+ Registry *descriptor.Registry
+ AllowPatchFeature bool
+}
+
+// GetBodyFieldPath returns the binding body's fieldpath.
+func (b binding) GetBodyFieldPath() string {
+ if b.Body != nil && len(b.Body.FieldPath) != 0 {
+ return b.Body.FieldPath.String()
+ }
+ return "*"
+}
+
+// GetBodyFieldPath returns the binding body's struct field name.
+func (b binding) GetBodyFieldStructName() (string, error) {
+ if b.Body != nil && len(b.Body.FieldPath) != 0 {
+ return generator2.CamelCase(b.Body.FieldPath.String()), nil
+ }
+ return "", errors.New("No body field found")
+}
+
+// HasQueryParam determines if the binding needs parameters in query string.
+//
+// It sometimes returns true even though actually the binding does not need.
+// But it is not serious because it just results in a small amount of extra codes generated.
+func (b binding) HasQueryParam() bool {
+ if b.Body != nil && len(b.Body.FieldPath) == 0 {
+ return false
+ }
+ fields := make(map[string]bool)
+ for _, f := range b.Method.RequestType.Fields {
+ fields[f.GetName()] = true
+ }
+ if b.Body != nil {
+ delete(fields, b.Body.FieldPath.String())
+ }
+ for _, p := range b.PathParams {
+ delete(fields, p.FieldPath.String())
+ }
+ return len(fields) > 0
+}
+
+func (b binding) QueryParamFilter() queryParamFilter {
+ var seqs [][]string
+ if b.Body != nil {
+ seqs = append(seqs, strings.Split(b.Body.FieldPath.String(), "."))
+ }
+ for _, p := range b.PathParams {
+ seqs = append(seqs, strings.Split(p.FieldPath.String(), "."))
+ }
+ return queryParamFilter{utilities.NewDoubleArray(seqs)}
+}
+
+// HasEnumPathParam returns true if the path parameter slice contains a parameter
+// that maps to an enum proto field that is not repeated, if not false is returned.
+func (b binding) HasEnumPathParam() bool {
+ return b.hasEnumPathParam(false)
+}
+
+// HasRepeatedEnumPathParam returns true if the path parameter slice contains a parameter
+// that maps to a repeated enum proto field, if not false is returned.
+func (b binding) HasRepeatedEnumPathParam() bool {
+ return b.hasEnumPathParam(true)
+}
+
+// hasEnumPathParam returns true if the path parameter slice contains a parameter
+// that maps to a enum proto field and that the enum proto field is or isn't repeated
+// based on the provided 'repeated' parameter.
+func (b binding) hasEnumPathParam(repeated bool) bool {
+ for _, p := range b.PathParams {
+ if p.IsEnum() && p.IsRepeated() == repeated {
+ return true
+ }
+ }
+ return false
+}
+
+// LookupEnum looks up a enum type by path parameter.
+func (b binding) LookupEnum(p descriptor.Parameter) *descriptor.Enum {
+ e, err := b.Registry.LookupEnum("", p.Target.GetTypeName())
+ if err != nil {
+ return nil
+ }
+ return e
+}
+
+// FieldMaskField returns the golang-style name of the variable for a FieldMask, if there is exactly one of that type in
+// the message. Otherwise, it returns an empty string.
+func (b binding) FieldMaskField() string {
+ var fieldMaskField *descriptor.Field
+ for _, f := range b.Method.RequestType.Fields {
+ if f.GetTypeName() == ".google.protobuf.FieldMask" {
+ // if there is more than 1 FieldMask for this request, then return none
+ if fieldMaskField != nil {
+ return ""
+ }
+ fieldMaskField = f
+ }
+ }
+ if fieldMaskField != nil {
+ return generator2.CamelCase(fieldMaskField.GetName())
+ }
+ return ""
+}
+
+// queryParamFilter is a wrapper of utilities.DoubleArray which provides String() to output DoubleArray.Encoding in a stable and predictable format.
+type queryParamFilter struct {
+ *utilities.DoubleArray
+}
+
+func (f queryParamFilter) String() string {
+ encodings := make([]string, len(f.Encoding))
+ for str, enc := range f.Encoding {
+ encodings[enc] = fmt.Sprintf("%q: %d", str, enc)
+ }
+ e := strings.Join(encodings, ", ")
+ return fmt.Sprintf("&utilities.DoubleArray{Encoding: map[string]int{%s}, Base: %#v, Check: %#v}", e, f.Base, f.Check)
+}
+
+type trailerParams struct {
+ Services []*descriptor.Service
+ UseRequestContext bool
+ RegisterFuncSuffix string
+ AssumeColonVerb bool
+}
+
+func applyTemplate(p param, reg *descriptor.Registry) (string, error) {
+ w := bytes.NewBuffer(nil)
+ if err := headerTemplate.Execute(w, p); err != nil {
+ return "", err
+ }
+ var targetServices []*descriptor.Service
+
+ for _, msg := range p.Messages {
+ msgName := generator2.CamelCase(*msg.Name)
+ msg.Name = &msgName
+ }
+ for _, svc := range p.Services {
+ var methodWithBindingsSeen bool
+ svcName := generator2.CamelCase(*svc.Name)
+ svc.Name = &svcName
+ for _, meth := range svc.Methods {
+ glog.V(2).Infof("Processing %s.%s", svc.GetName(), meth.GetName())
+ methName := generator2.CamelCase(*meth.Name)
+ meth.Name = &methName
+ for _, b := range meth.Bindings {
+ methodWithBindingsSeen = true
+ if err := handlerTemplate.Execute(w, binding{
+ Binding: b,
+ Registry: reg,
+ AllowPatchFeature: p.AllowPatchFeature,
+ }); err != nil {
+ return "", err
+ }
+
+ // Local
+ if err := localHandlerTemplate.Execute(w, binding{
+ Binding: b,
+ Registry: reg,
+ AllowPatchFeature: p.AllowPatchFeature,
+ }); err != nil {
+ return "", err
+ }
+ }
+ }
+ if methodWithBindingsSeen {
+ targetServices = append(targetServices, svc)
+ }
+ }
+ if len(targetServices) == 0 {
+ return "", errNoTargetService
+ }
+
+ assumeColonVerb := true
+ if reg != nil {
+ assumeColonVerb = !reg.GetAllowColonFinalSegments()
+ }
+ tp := trailerParams{
+ Services: targetServices,
+ UseRequestContext: p.UseRequestContext,
+ RegisterFuncSuffix: p.RegisterFuncSuffix,
+ AssumeColonVerb: assumeColonVerb,
+ }
+ // Local
+ if err := localTrailerTemplate.Execute(w, tp); err != nil {
+ return "", err
+ }
+
+ if err := trailerTemplate.Execute(w, tp); err != nil {
+ return "", err
+ }
+ return w.String(), nil
+}
+
+var (
+ headerTemplate = template.Must(template.New("header").Parse(`
+// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
+// source: {{.GetName}}
+
+/*
+Package {{.GoPkg.Name}} is a reverse proxy.
+
+It translates gRPC into RESTful JSON APIs.
+*/
+package {{.GoPkg.Name}}
+import (
+ {{range $i := .Imports}}{{if $i.Standard}}{{$i | printf "%s\n"}}{{end}}{{end}}
+
+ {{range $i := .Imports}}{{if not $i.Standard}}{{$i | printf "%s\n"}}{{end}}{{end}}
+)
+
+// Suppress "imported and not used" errors
+var _ codes.Code
+var _ io.Reader
+var _ status.Status
+var _ = runtime.String
+var _ = utilities.NewDoubleArray
+var _ = descriptor.ForMessage
+`))
+
+ handlerTemplate = template.Must(template.New("handler").Parse(`
+{{if and .Method.GetClientStreaming .Method.GetServerStreaming}}
+{{template "bidi-streaming-request-func" .}}
+{{else if .Method.GetClientStreaming}}
+{{template "client-streaming-request-func" .}}
+{{else}}
+{{template "client-rpc-request-func" .}}
+{{end}}
+`))
+
+ _ = template.Must(handlerTemplate.New("request-func-signature").Parse(strings.Replace(`
+{{if .Method.GetServerStreaming}}
+func request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ctx context.Context, marshaler runtime.Marshaler, client {{.Method.Service.GetName}}Client, req *http.Request, pathParams map[string]string) ({{.Method.Service.GetName}}_{{.Method.GetName}}Client, runtime.ServerMetadata, error)
+{{else}}
+func request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ctx context.Context, marshaler runtime.Marshaler, client {{.Method.Service.GetName}}Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error)
+{{end}}`, "\n", "", -1)))
+
+ _ = template.Must(handlerTemplate.New("client-streaming-request-func").Parse(`
+{{template "request-func-signature" .}} {
+ var metadata runtime.ServerMetadata
+ stream, err := client.{{.Method.GetName}}(ctx)
+ if err != nil {
+ grpclog.Infof("Failed to start streaming: %v", err)
+ return nil, metadata, err
+ }
+ dec := marshaler.NewDecoder(req.Body)
+ for {
+ var protoReq {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}}
+ err = dec.Decode(&protoReq)
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ grpclog.Infof("Failed to decode request: %v", err)
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err = stream.Send(&protoReq); err != nil {
+ if err == io.EOF {
+ break
+ }
+ grpclog.Infof("Failed to send request: %v", err)
+ return nil, metadata, err
+ }
+ }
+
+ if err := stream.CloseSend(); err != nil {
+ grpclog.Infof("Failed to terminate client stream: %v", err)
+ return nil, metadata, err
+ }
+ header, err := stream.Header()
+ if err != nil {
+ grpclog.Infof("Failed to get header from client: %v", err)
+ return nil, metadata, err
+ }
+ metadata.HeaderMD = header
+{{if .Method.GetServerStreaming}}
+ return stream, metadata, nil
+{{else}}
+ msg, err := stream.CloseAndRecv()
+ metadata.TrailerMD = stream.Trailer()
+ return msg, metadata, err
+{{end}}
+}
+`))
+
+ _ = template.Must(handlerTemplate.New("client-rpc-request-func").Parse(`
+{{$AllowPatchFeature := .AllowPatchFeature}}
+{{if .HasQueryParam}}
+var (
+ filter_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}} = {{.QueryParamFilter}}
+)
+{{end}}
+{{template "request-func-signature" .}} {
+ var protoReq {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}}
+ var metadata runtime.ServerMetadata
+{{if .Body}}
+ newReader, berr := utilities.IOReaderFactory(req.Body)
+ if berr != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+ }
+ if err := marshaler.NewDecoder(newReader()).Decode(&{{.Body.AssignableExpr "protoReq"}}); err != nil && err != io.EOF {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ {{- if and $AllowPatchFeature (eq (.HTTPMethod) "PATCH") (.FieldMaskField) (not (eq "*" .GetBodyFieldPath)) }}
+ if protoReq.{{.FieldMaskField}} == nil || len(protoReq.{{.FieldMaskField}}.GetPaths()) == 0 {
+ _, md := descriptor.ForMessage(protoReq.{{.GetBodyFieldStructName}})
+ if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), md); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ } else {
+ protoReq.{{.FieldMaskField}} = fieldMask
+ }
+ }
+ {{end}}
+{{end}}
+{{if .PathParams}}
+ var (
+ val string
+{{- if .HasEnumPathParam}}
+ e int32
+{{- end}}
+{{- if .HasRepeatedEnumPathParam}}
+ es []int32
+{{- end}}
+ ok bool
+ err error
+ _ = err
+ )
+ {{$binding := .}}
+ {{range $param := .PathParams}}
+ {{$enum := $binding.LookupEnum $param}}
+ val, ok = pathParams[{{$param | printf "%q"}}]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", {{$param | printf "%q"}})
+ }
+{{if $param.IsNestedProto3}}
+ err = runtime.PopulateFieldFromPath(&protoReq, {{$param | printf "%q"}}, val)
+ {{if $enum}}
+ e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}_value)
+ {{end}}
+{{else if $enum}}
+ e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}_value)
+{{else}}
+ {{$param.AssignableExpr "protoReq"}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}})
+{{end}}
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
+ }
+{{if and $enum $param.IsRepeated}}
+ s := make([]{{$enum.GoType $param.Target.Message.File.GoPkg.Path}}, len(es))
+ for i, v := range es {
+ s[i] = {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}(v)
+ }
+ {{$param.AssignableExpr "protoReq"}} = s
+{{else if $enum}}
+ {{$param.AssignableExpr "protoReq"}} = {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}(e)
+{{end}}
+ {{end}}
+{{end}}
+{{if .HasQueryParam}}
+ if err := req.ParseForm(); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+{{end}}
+{{if .Method.GetServerStreaming}}
+ stream, err := client.{{.Method.GetName}}(ctx, &protoReq)
+ if err != nil {
+ return nil, metadata, err
+ }
+ header, err := stream.Header()
+ if err != nil {
+ return nil, metadata, err
+ }
+ metadata.HeaderMD = header
+ return stream, metadata, nil
+{{else}}
+ msg, err := client.{{.Method.GetName}}(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ return msg, metadata, err
+{{end}}
+}`))
+
+ _ = template.Must(handlerTemplate.New("bidi-streaming-request-func").Parse(`
+{{template "request-func-signature" .}} {
+ var metadata runtime.ServerMetadata
+ stream, err := client.{{.Method.GetName}}(ctx)
+ if err != nil {
+ grpclog.Infof("Failed to start streaming: %v", err)
+ return nil, metadata, err
+ }
+ dec := marshaler.NewDecoder(req.Body)
+ handleSend := func() error {
+ var protoReq {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}}
+ err := dec.Decode(&protoReq)
+ if err == io.EOF {
+ return err
+ }
+ if err != nil {
+ grpclog.Infof("Failed to decode request: %v", err)
+ return err
+ }
+ if err := stream.Send(&protoReq); err != nil {
+ grpclog.Infof("Failed to send request: %v", err)
+ return err
+ }
+ return nil
+ }
+ if err := handleSend(); err != nil {
+ if cerr := stream.CloseSend(); cerr != nil {
+ grpclog.Infof("Failed to terminate client stream: %v", cerr)
+ }
+ if err == io.EOF {
+ return stream, metadata, nil
+ }
+ return nil, metadata, err
+ }
+ go func() {
+ for {
+ if err := handleSend(); err != nil {
+ break
+ }
+ }
+ if err := stream.CloseSend(); err != nil {
+ grpclog.Infof("Failed to terminate client stream: %v", err)
+ }
+ }()
+ header, err := stream.Header()
+ if err != nil {
+ grpclog.Infof("Failed to get header from client: %v", err)
+ return nil, metadata, err
+ }
+ metadata.HeaderMD = header
+ return stream, metadata, nil
+}
+`))
+
+ localHandlerTemplate = template.Must(template.New("local-handler").Parse(`
+{{if and .Method.GetClientStreaming .Method.GetServerStreaming}}
+{{else if .Method.GetClientStreaming}}
+{{else if .Method.GetServerStreaming}}
+{{else}}
+{{template "local-client-rpc-request-func" .}}
+{{end}}
+`))
+
+ _ = template.Must(localHandlerTemplate.New("local-request-func-signature").Parse(strings.Replace(`
+{{if .Method.GetServerStreaming}}
+{{else}}
+func local_request_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}(ctx context.Context, marshaler runtime.Marshaler, server {{.Method.Service.GetName}}Server, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error)
+{{end}}`, "\n", "", -1)))
+
+ _ = template.Must(localHandlerTemplate.New("local-client-rpc-request-func").Parse(`
+{{$AllowPatchFeature := .AllowPatchFeature}}
+{{template "local-request-func-signature" .}} {
+ var protoReq {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}}
+ var metadata runtime.ServerMetadata
+{{if .Body}}
+ newReader, berr := utilities.IOReaderFactory(req.Body)
+ if berr != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+ }
+ if err := marshaler.NewDecoder(newReader()).Decode(&{{.Body.AssignableExpr "protoReq"}}); err != nil && err != io.EOF {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+ {{- if and $AllowPatchFeature (eq (.HTTPMethod) "PATCH") (.FieldMaskField) (not (eq "*" .GetBodyFieldPath)) }}
+ if protoReq.{{.FieldMaskField}} == nil || len(protoReq.{{.FieldMaskField}}.GetPaths()) == 0 {
+ _, md := descriptor.ForMessage(protoReq.{{.GetBodyFieldStructName}})
+ if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), md); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ } else {
+ protoReq.{{.FieldMaskField}} = fieldMask
+ }
+ }
+ {{end}}
+{{end}}
+{{if .PathParams}}
+ var (
+ val string
+{{- if .HasEnumPathParam}}
+ e int32
+{{- end}}
+{{- if .HasRepeatedEnumPathParam}}
+ es []int32
+{{- end}}
+ ok bool
+ err error
+ _ = err
+ )
+ {{$binding := .}}
+ {{range $param := .PathParams}}
+ {{$enum := $binding.LookupEnum $param}}
+ val, ok = pathParams[{{$param | printf "%q"}}]
+ if !ok {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", {{$param | printf "%q"}})
+ }
+{{if $param.IsNestedProto3}}
+ err = runtime.PopulateFieldFromPath(&protoReq, {{$param | printf "%q"}}, val)
+ {{if $enum}}
+ e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}_value)
+ {{end}}
+{{else if $enum}}
+ e{{if $param.IsRepeated}}s{{end}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}}, {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}_value)
+{{else}}
+ {{$param.AssignableExpr "protoReq"}}, err = {{$param.ConvertFuncExpr}}(val{{if $param.IsRepeated}}, {{$binding.Registry.GetRepeatedPathParamSeparator | printf "%c" | printf "%q"}}{{end}})
+{{end}}
+ if err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
+ }
+{{if and $enum $param.IsRepeated}}
+ s := make([]{{$enum.GoType $param.Target.Message.File.GoPkg.Path}}, len(es))
+ for i, v := range es {
+ s[i] = {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}(v)
+ }
+ {{$param.AssignableExpr "protoReq"}} = s
+{{else if $enum}}
+ {{$param.AssignableExpr "protoReq"}} = {{$enum.GoType $param.Target.Message.File.GoPkg.Path}}(e)
+{{end}}
+ {{end}}
+{{end}}
+{{if .HasQueryParam}}
+ if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_{{.Method.Service.GetName}}_{{.Method.GetName}}_{{.Index}}); err != nil {
+ return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+ }
+{{end}}
+{{if .Method.GetServerStreaming}}
+ // TODO
+{{else}}
+ msg, err := server.{{.Method.GetName}}(ctx, &protoReq)
+ return msg, metadata, err
+{{end}}
+}`))
+
+ localTrailerTemplate = template.Must(template.New("local-trailer").Parse(`
+{{$UseRequestContext := .UseRequestContext}}
+{{range $svc := .Services}}
+// Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Server registers the http handlers for service {{$svc.GetName}} to "mux".
+// UnaryRPC :call {{$svc.GetName}}Server directly.
+// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
+func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Server(ctx context.Context, mux *runtime.ServeMux, server {{$svc.GetName}}Server) error {
+ {{range $m := $svc.Methods}}
+ {{range $b := $m.Bindings}}
+ {{if or $m.GetClientStreaming $m.GetServerStreaming}}
+ mux.Handle({{$b.HTTPMethod | printf "%q"}}, pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport")
+ _, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ })
+ {{else}}
+ mux.Handle({{$b.HTTPMethod | printf "%q"}}, pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ {{- if $UseRequestContext }}
+ ctx, cancel := context.WithCancel(req.Context())
+ {{- else -}}
+ ctx, cancel := context.WithCancel(ctx)
+ {{- end }}
+ defer cancel()
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(rctx, inboundMarshaler, server, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ {{ if $b.ResponseBody }}
+ forward_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, mux, outboundMarshaler, w, req, response_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}{resp}, mux.GetForwardResponseOptions()...)
+ {{ else }}
+ forward_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+ {{end}}
+ })
+ {{end}}
+ {{end}}
+ {{end}}
+ return nil
+}
+{{end}}`))
+
+ trailerTemplate = template.Must(template.New("trailer").Parse(`
+{{$UseRequestContext := .UseRequestContext}}
+{{range $svc := .Services}}
+// Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}FromEndpoint is same as Register{{$svc.GetName}}{{$.RegisterFuncSuffix}} but
+// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
+func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}FromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
+ conn, err := grpc.Dial(endpoint, opts...)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if err != nil {
+ if cerr := conn.Close(); cerr != nil {
+ grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+ }
+ return
+ }
+ go func() {
+ <-ctx.Done()
+ if cerr := conn.Close(); cerr != nil {
+ grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
+ }
+ }()
+ }()
+
+ return Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}(ctx, mux, conn)
+}
+
+// Register{{$svc.GetName}}{{$.RegisterFuncSuffix}} registers the http handlers for service {{$svc.GetName}} to "mux".
+// The handlers forward requests to the grpc endpoint over "conn".
+func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
+ return Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client(ctx, mux, New{{$svc.GetName}}Client(conn))
+}
+
+// Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client registers the http handlers for service {{$svc.GetName}}
+// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "{{$svc.GetName}}Client".
+// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "{{$svc.GetName}}Client"
+// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
+// "{{$svc.GetName}}Client" to call the correct interceptors.
+func Register{{$svc.GetName}}{{$.RegisterFuncSuffix}}Client(ctx context.Context, mux *runtime.ServeMux, client {{$svc.GetName}}Client) error {
+ {{range $m := $svc.Methods}}
+ {{range $b := $m.Bindings}}
+ mux.Handle({{$b.HTTPMethod | printf "%q"}}, pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ {{- if $UseRequestContext }}
+ ctx, cancel := context.WithCancel(req.Context())
+ {{- else -}}
+ ctx, cancel := context.WithCancel(ctx)
+ {{- end }}
+ defer cancel()
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ rctx, err := runtime.AnnotateContext(ctx, mux, req)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(rctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ {{if $m.GetServerStreaming}}
+ forward_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
+ {{else}}
+ {{ if $b.ResponseBody }}
+ forward_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, mux, outboundMarshaler, w, req, response_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}{resp}, mux.GetForwardResponseOptions()...)
+ {{ else }}
+ forward_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+ {{end}}
+ {{end}}
+ })
+ {{end}}
+ {{end}}
+ return nil
+}
+
+{{range $m := $svc.Methods}}
+{{range $b := $m.Bindings}}
+{{if $b.ResponseBody}}
+type response_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}} struct {
+ proto.Message
+}
+
+func (m response_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}}) XXX_ResponseBody() interface{} {
+ response := m.Message.(*{{$m.ResponseType.GoType $m.Service.File.GoPkg.Path}})
+ return {{$b.ResponseBody.AssignableExpr "response"}}
+}
+{{end}}
+{{end}}
+{{end}}
+
+var (
+ {{range $m := $svc.Methods}}
+ {{range $b := $m.Bindings}}
+ pattern_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}} = runtime.MustPattern(runtime.NewPattern({{$b.PathTmpl.Version}}, {{$b.PathTmpl.OpCodes | printf "%#v"}}, {{$b.PathTmpl.Pool | printf "%#v"}}, {{$b.PathTmpl.Verb | printf "%q"}}, runtime.AssumeColonVerbOpt({{$.AssumeColonVerb}})))
+ {{end}}
+ {{end}}
+)
+
+var (
+ {{range $m := $svc.Methods}}
+ {{range $b := $m.Bindings}}
+ forward_{{$svc.GetName}}_{{$m.GetName}}_{{$b.Index}} = {{if $m.GetServerStreaming}}runtime.ForwardResponseStream{{else}}runtime.ForwardResponseMessage{{end}}
+ {{end}}
+ {{end}}
+)
+{{end}}`))
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/BUILD.bazel
new file mode 100644
index 0000000..89f94a1
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/BUILD.bazel
@@ -0,0 +1,32 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//:generators"])
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "compile.go",
+ "parse.go",
+ "types.go",
+ ],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule",
+ deps = [
+ "//utilities:go_default_library",
+ "@com_github_golang_glog//:go_default_library",
+ ],
+)
+
+go_test(
+ name = "go_default_test",
+ size = "small",
+ srcs = [
+ "compile_test.go",
+ "parse_test.go",
+ "types_test.go",
+ ],
+ embed = [":go_default_library"],
+ deps = [
+ "//utilities:go_default_library",
+ "@com_github_golang_glog//:go_default_library",
+ ],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/compile.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/compile.go
new file mode 100644
index 0000000..437039a
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/compile.go
@@ -0,0 +1,117 @@
+package httprule
+
+import (
+ "github.com/grpc-ecosystem/grpc-gateway/utilities"
+)
+
+const (
+ opcodeVersion = 1
+)
+
+// Template is a compiled representation of path templates.
+type Template struct {
+ // Version is the version number of the format.
+ Version int
+ // OpCodes is a sequence of operations.
+ OpCodes []int
+ // Pool is a constant pool
+ Pool []string
+ // Verb is a VERB part in the template.
+ Verb string
+ // Fields is a list of field paths bound in this template.
+ Fields []string
+ // Original template (example: /v1/a_bit_of_everything)
+ Template string
+}
+
+// Compiler compiles utilities representation of path templates into marshallable operations.
+// They can be unmarshalled by runtime.NewPattern.
+type Compiler interface {
+ Compile() Template
+}
+
+type op struct {
+ // code is the opcode of the operation
+ code utilities.OpCode
+
+ // str is a string operand of the code.
+ // num is ignored if str is not empty.
+ str string
+
+ // num is a numeric operand of the code.
+ num int
+}
+
+func (w wildcard) compile() []op {
+ return []op{
+ {code: utilities.OpPush},
+ }
+}
+
+func (w deepWildcard) compile() []op {
+ return []op{
+ {code: utilities.OpPushM},
+ }
+}
+
+func (l literal) compile() []op {
+ return []op{
+ {
+ code: utilities.OpLitPush,
+ str: string(l),
+ },
+ }
+}
+
+func (v variable) compile() []op {
+ var ops []op
+ for _, s := range v.segments {
+ ops = append(ops, s.compile()...)
+ }
+ ops = append(ops, op{
+ code: utilities.OpConcatN,
+ num: len(v.segments),
+ }, op{
+ code: utilities.OpCapture,
+ str: v.path,
+ })
+
+ return ops
+}
+
+func (t template) Compile() Template {
+ var rawOps []op
+ for _, s := range t.segments {
+ rawOps = append(rawOps, s.compile()...)
+ }
+
+ var (
+ ops []int
+ pool []string
+ fields []string
+ )
+ consts := make(map[string]int)
+ for _, op := range rawOps {
+ ops = append(ops, int(op.code))
+ if op.str == "" {
+ ops = append(ops, op.num)
+ } else {
+ if _, ok := consts[op.str]; !ok {
+ consts[op.str] = len(pool)
+ pool = append(pool, op.str)
+ }
+ ops = append(ops, consts[op.str])
+ }
+ if op.code == utilities.OpCapture {
+ fields = append(fields, op.str)
+ }
+ }
+ return Template{
+ Version: opcodeVersion,
+ OpCodes: ops,
+ Pool: pool,
+ Verb: t.verb,
+ Fields: fields,
+ Template: t.template,
+ }
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/fuzz.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/fuzz.go
new file mode 100644
index 0000000..138f7c1
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/fuzz.go
@@ -0,0 +1,11 @@
+// +build gofuzz
+
+package httprule
+
+func Fuzz(data []byte) int {
+ _, err := Parse(string(data))
+ if err != nil {
+ return 0
+ }
+ return 0
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/parse.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/parse.go
new file mode 100644
index 0000000..f933cd8
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/parse.go
@@ -0,0 +1,351 @@
+package httprule
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/golang/glog"
+)
+
+// InvalidTemplateError indicates that the path template is not valid.
+type InvalidTemplateError struct {
+ tmpl string
+ msg string
+}
+
+func (e InvalidTemplateError) Error() string {
+ return fmt.Sprintf("%s: %s", e.msg, e.tmpl)
+}
+
+// Parse parses the string representation of path template
+func Parse(tmpl string) (Compiler, error) {
+ if !strings.HasPrefix(tmpl, "/") {
+ return template{}, InvalidTemplateError{tmpl: tmpl, msg: "no leading /"}
+ }
+ tokens, verb := tokenize(tmpl[1:])
+
+ p := parser{tokens: tokens}
+ segs, err := p.topLevelSegments()
+ if err != nil {
+ return template{}, InvalidTemplateError{tmpl: tmpl, msg: err.Error()}
+ }
+
+ return template{
+ segments: segs,
+ verb: verb,
+ template: tmpl,
+ }, nil
+}
+
+func tokenize(path string) (tokens []string, verb string) {
+ if path == "" {
+ return []string{eof}, ""
+ }
+
+ const (
+ init = iota
+ field
+ nested
+ )
+ var (
+ st = init
+ )
+ for path != "" {
+ var idx int
+ switch st {
+ case init:
+ idx = strings.IndexAny(path, "/{")
+ case field:
+ idx = strings.IndexAny(path, ".=}")
+ case nested:
+ idx = strings.IndexAny(path, "/}")
+ }
+ if idx < 0 {
+ tokens = append(tokens, path)
+ break
+ }
+ switch r := path[idx]; r {
+ case '/', '.':
+ case '{':
+ st = field
+ case '=':
+ st = nested
+ case '}':
+ st = init
+ }
+ if idx == 0 {
+ tokens = append(tokens, path[idx:idx+1])
+ } else {
+ tokens = append(tokens, path[:idx], path[idx:idx+1])
+ }
+ path = path[idx+1:]
+ }
+
+ l := len(tokens)
+ t := tokens[l-1]
+ if idx := strings.LastIndex(t, ":"); idx == 0 {
+ tokens, verb = tokens[:l-1], t[1:]
+ } else if idx > 0 {
+ tokens[l-1], verb = t[:idx], t[idx+1:]
+ }
+ tokens = append(tokens, eof)
+ return tokens, verb
+}
+
+// parser is a parser of the template syntax defined in github.com/googleapis/googleapis/google/api/http.proto.
+type parser struct {
+ tokens []string
+ accepted []string
+}
+
+// topLevelSegments is the target of this parser.
+func (p *parser) topLevelSegments() ([]segment, error) {
+ glog.V(1).Infof("Parsing %q", p.tokens)
+ segs, err := p.segments()
+ if err != nil {
+ return nil, err
+ }
+ glog.V(2).Infof("accept segments: %q; %q", p.accepted, p.tokens)
+ if _, err := p.accept(typeEOF); err != nil {
+ return nil, fmt.Errorf("unexpected token %q after segments %q", p.tokens[0], strings.Join(p.accepted, ""))
+ }
+ glog.V(2).Infof("accept eof: %q; %q", p.accepted, p.tokens)
+ return segs, nil
+}
+
+func (p *parser) segments() ([]segment, error) {
+ s, err := p.segment()
+ if err != nil {
+ return nil, err
+ }
+ glog.V(2).Infof("accept segment: %q; %q", p.accepted, p.tokens)
+
+ segs := []segment{s}
+ for {
+ if _, err := p.accept("/"); err != nil {
+ return segs, nil
+ }
+ s, err := p.segment()
+ if err != nil {
+ return segs, err
+ }
+ segs = append(segs, s)
+ glog.V(2).Infof("accept segment: %q; %q", p.accepted, p.tokens)
+ }
+}
+
+func (p *parser) segment() (segment, error) {
+ if _, err := p.accept("*"); err == nil {
+ return wildcard{}, nil
+ }
+ if _, err := p.accept("**"); err == nil {
+ return deepWildcard{}, nil
+ }
+ if l, err := p.literal(); err == nil {
+ return l, nil
+ }
+
+ v, err := p.variable()
+ if err != nil {
+ return nil, fmt.Errorf("segment neither wildcards, literal or variable: %v", err)
+ }
+ return v, err
+}
+
+func (p *parser) literal() (segment, error) {
+ lit, err := p.accept(typeLiteral)
+ if err != nil {
+ return nil, err
+ }
+ return literal(lit), nil
+}
+
+func (p *parser) variable() (segment, error) {
+ if _, err := p.accept("{"); err != nil {
+ return nil, err
+ }
+
+ path, err := p.fieldPath()
+ if err != nil {
+ return nil, err
+ }
+
+ var segs []segment
+ if _, err := p.accept("="); err == nil {
+ segs, err = p.segments()
+ if err != nil {
+ return nil, fmt.Errorf("invalid segment in variable %q: %v", path, err)
+ }
+ } else {
+ segs = []segment{wildcard{}}
+ }
+
+ if _, err := p.accept("}"); err != nil {
+ return nil, fmt.Errorf("unterminated variable segment: %s", path)
+ }
+ return variable{
+ path: path,
+ segments: segs,
+ }, nil
+}
+
+func (p *parser) fieldPath() (string, error) {
+ c, err := p.accept(typeIdent)
+ if err != nil {
+ return "", err
+ }
+ components := []string{c}
+ for {
+ if _, err = p.accept("."); err != nil {
+ return strings.Join(components, "."), nil
+ }
+ c, err := p.accept(typeIdent)
+ if err != nil {
+ return "", fmt.Errorf("invalid field path component: %v", err)
+ }
+ components = append(components, c)
+ }
+}
+
+// A termType is a type of terminal symbols.
+type termType string
+
+// These constants define some of valid values of termType.
+// They improve readability of parse functions.
+//
+// You can also use "/", "*", "**", "." or "=" as valid values.
+const (
+ typeIdent = termType("ident")
+ typeLiteral = termType("literal")
+ typeEOF = termType("$")
+)
+
+const (
+ // eof is the terminal symbol which always appears at the end of token sequence.
+ eof = "\u0000"
+)
+
+// accept tries to accept a token in "p".
+// This function consumes a token and returns it if it matches to the specified "term".
+// If it doesn't match, the function does not consume any tokens and return an error.
+func (p *parser) accept(term termType) (string, error) {
+ t := p.tokens[0]
+ switch term {
+ case "/", "*", "**", ".", "=", "{", "}":
+ if t != string(term) && t != "/" {
+ return "", fmt.Errorf("expected %q but got %q", term, t)
+ }
+ case typeEOF:
+ if t != eof {
+ return "", fmt.Errorf("expected EOF but got %q", t)
+ }
+ case typeIdent:
+ if err := expectIdent(t); err != nil {
+ return "", err
+ }
+ case typeLiteral:
+ if err := expectPChars(t); err != nil {
+ return "", err
+ }
+ default:
+ return "", fmt.Errorf("unknown termType %q", term)
+ }
+ p.tokens = p.tokens[1:]
+ p.accepted = append(p.accepted, t)
+ return t, nil
+}
+
+// expectPChars determines if "t" consists of only pchars defined in RFC3986.
+//
+// https://www.ietf.org/rfc/rfc3986.txt, P.49
+// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
+// / "*" / "+" / "," / ";" / "="
+// pct-encoded = "%" HEXDIG HEXDIG
+func expectPChars(t string) error {
+ const (
+ init = iota
+ pct1
+ pct2
+ )
+ st := init
+ for _, r := range t {
+ if st != init {
+ if !isHexDigit(r) {
+ return fmt.Errorf("invalid hexdigit: %c(%U)", r, r)
+ }
+ switch st {
+ case pct1:
+ st = pct2
+ case pct2:
+ st = init
+ }
+ continue
+ }
+
+ // unreserved
+ switch {
+ case 'A' <= r && r <= 'Z':
+ continue
+ case 'a' <= r && r <= 'z':
+ continue
+ case '0' <= r && r <= '9':
+ continue
+ }
+ switch r {
+ case '-', '.', '_', '~':
+ // unreserved
+ case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=':
+ // sub-delims
+ case ':', '@':
+ // rest of pchar
+ case '%':
+ // pct-encoded
+ st = pct1
+ default:
+ return fmt.Errorf("invalid character in path segment: %q(%U)", r, r)
+ }
+ }
+ if st != init {
+ return fmt.Errorf("invalid percent-encoding in %q", t)
+ }
+ return nil
+}
+
+// expectIdent determines if "ident" is a valid identifier in .proto schema ([[:alpha:]_][[:alphanum:]_]*).
+func expectIdent(ident string) error {
+ if ident == "" {
+ return fmt.Errorf("empty identifier")
+ }
+ for pos, r := range ident {
+ switch {
+ case '0' <= r && r <= '9':
+ if pos == 0 {
+ return fmt.Errorf("identifier starting with digit: %s", ident)
+ }
+ continue
+ case 'A' <= r && r <= 'Z':
+ continue
+ case 'a' <= r && r <= 'z':
+ continue
+ case r == '_':
+ continue
+ default:
+ return fmt.Errorf("invalid character %q(%U) in identifier: %s", r, r, ident)
+ }
+ }
+ return nil
+}
+
+func isHexDigit(r rune) bool {
+ switch {
+ case '0' <= r && r <= '9':
+ return true
+ case 'A' <= r && r <= 'F':
+ return true
+ case 'a' <= r && r <= 'f':
+ return true
+ }
+ return false
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/types.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/types.go
new file mode 100644
index 0000000..5a814a0
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule/types.go
@@ -0,0 +1,60 @@
+package httprule
+
+import (
+ "fmt"
+ "strings"
+)
+
+type template struct {
+ segments []segment
+ verb string
+ template string
+}
+
+type segment interface {
+ fmt.Stringer
+ compile() (ops []op)
+}
+
+type wildcard struct{}
+
+type deepWildcard struct{}
+
+type literal string
+
+type variable struct {
+ path string
+ segments []segment
+}
+
+func (wildcard) String() string {
+ return "*"
+}
+
+func (deepWildcard) String() string {
+ return "**"
+}
+
+func (l literal) String() string {
+ return string(l)
+}
+
+func (v variable) String() string {
+ var segs []string
+ for _, s := range v.segments {
+ segs = append(segs, s.String())
+ }
+ return fmt.Sprintf("{%s=%s}", v.path, strings.Join(segs, "/"))
+}
+
+func (t template) String() string {
+ var segs []string
+ for _, s := range t.segments {
+ segs = append(segs, s.String())
+ }
+ str := strings.Join(segs, "/")
+ if t.verb != "" {
+ str = fmt.Sprintf("%s:%s", str, t.verb)
+ }
+ return "/" + str
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/main.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/main.go
new file mode 100644
index 0000000..291ba7d
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/main.go
@@ -0,0 +1,141 @@
+// Command protoc-gen-grpc-gateway is a plugin for Google protocol buffer
+// compiler to generate a reverse-proxy, which converts incoming RESTful
+// HTTP/1 requests gRPC invocation.
+// You rarely need to run this program directly. Instead, put this program
+// into your $PATH with a name "protoc-gen-grpc-gateway" and run
+// protoc --grpc-gateway_out=output_directory path/to/input.proto
+//
+// See README.md for more details.
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/golang/glog"
+ "github.com/golang/protobuf/proto"
+ plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
+ "github.com/grpc-ecosystem/grpc-gateway/codegenerator"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/gengateway"
+)
+
+var (
+ importPrefix = flag.String("import_prefix", "", "prefix to be added to go package paths for imported proto files")
+ importPath = flag.String("import_path", "", "used as the package if no input files declare go_package. If it contains slashes, everything up to the rightmost slash is ignored.")
+ registerFuncSuffix = flag.String("register_func_suffix", "Handler", "used to construct names of generated Register*<Suffix> methods.")
+ useRequestContext = flag.Bool("request_context", true, "determine whether to use http.Request's context or not")
+ allowDeleteBody = flag.Bool("allow_delete_body", false, "unless set, HTTP DELETE methods may not have a body")
+ grpcAPIConfiguration = flag.String("grpc_api_configuration", "", "path to gRPC API Configuration in YAML format")
+ pathType = flag.String("paths", "", "specifies how the paths of generated files are structured")
+ allowRepeatedFieldsInBody = flag.Bool("allow_repeated_fields_in_body", false, "allows to use repeated field in `body` and `response_body` field of `google.api.http` annotation option")
+ repeatedPathParamSeparator = flag.String("repeated_path_param_separator", "csv", "configures how repeated fields should be split. Allowed values are `csv`, `pipes`, `ssv` and `tsv`.")
+ allowPatchFeature = flag.Bool("allow_patch_feature", true, "determines whether to use PATCH feature involving update masks (using google.protobuf.FieldMask).")
+ allowColonFinalSegments = flag.Bool("allow_colon_final_segments", false, "determines whether colons are permitted in the final segment of a path")
+ versionFlag = flag.Bool("version", false, "print the current verison")
+)
+
+// Variables set by goreleaser at build time
+var (
+ version = "dev"
+ commit = "unknown"
+ date = "unknown"
+)
+
+func main() {
+ flag.Parse()
+ defer glog.Flush()
+
+ if *versionFlag {
+ fmt.Printf("Version %v, commit %v, built at %v\n", version, commit, date)
+ os.Exit(0)
+ }
+
+ reg := descriptor.NewRegistry()
+
+ glog.V(1).Info("Parsing code generator request")
+ req, err := codegenerator.ParseRequest(os.Stdin)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ glog.V(1).Info("Parsed code generator request")
+ if req.Parameter != nil {
+ for _, p := range strings.Split(req.GetParameter(), ",") {
+ spec := strings.SplitN(p, "=", 2)
+ if len(spec) == 1 {
+ if err := flag.CommandLine.Set(spec[0], ""); err != nil {
+ glog.Fatalf("Cannot set flag %s", p)
+ }
+ continue
+ }
+ name, value := spec[0], spec[1]
+ if strings.HasPrefix(name, "M") {
+ reg.AddPkgMap(name[1:], value)
+ continue
+ }
+ if err := flag.CommandLine.Set(name, value); err != nil {
+ glog.Fatalf("Cannot set flag %s", p)
+ }
+ }
+ }
+
+ g := gengateway.New(reg, *useRequestContext, *registerFuncSuffix, *pathType, *allowPatchFeature)
+
+ if *grpcAPIConfiguration != "" {
+ if err := reg.LoadGrpcAPIServiceFromYAML(*grpcAPIConfiguration); err != nil {
+ emitError(err)
+ return
+ }
+ }
+
+ reg.SetPrefix(*importPrefix)
+ reg.SetImportPath(*importPath)
+ reg.SetAllowDeleteBody(*allowDeleteBody)
+ reg.SetAllowRepeatedFieldsInBody(*allowRepeatedFieldsInBody)
+ reg.SetAllowColonFinalSegments(*allowColonFinalSegments)
+ if err := reg.SetRepeatedPathParamSeparator(*repeatedPathParamSeparator); err != nil {
+ emitError(err)
+ return
+ }
+ if err := reg.Load(req); err != nil {
+ emitError(err)
+ return
+ }
+
+ var targets []*descriptor.File
+ for _, target := range req.FileToGenerate {
+ f, err := reg.LookupFile(target)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ targets = append(targets, f)
+ }
+
+ out, err := g.Generate(targets)
+ glog.V(1).Info("Processed code generator request")
+ if err != nil {
+ emitError(err)
+ return
+ }
+ emitFiles(out)
+}
+
+func emitFiles(out []*plugin.CodeGeneratorResponse_File) {
+ emitResp(&plugin.CodeGeneratorResponse{File: out})
+}
+
+func emitError(err error) {
+ emitResp(&plugin.CodeGeneratorResponse{Error: proto.String(err.Error())})
+}
+
+func emitResp(resp *plugin.CodeGeneratorResponse) {
+ buf, err := proto.Marshal(resp)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ if _, err := os.Stdout.Write(buf); err != nil {
+ glog.Fatal(err)
+ }
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/BUILD.bazel
new file mode 100644
index 0000000..d5a1d05
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/BUILD.bazel
@@ -0,0 +1,30 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
+
+package(default_visibility = ["//visibility:private"])
+
+go_library(
+ name = "go_default_library",
+ srcs = ["main.go"],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger",
+ deps = [
+ "//codegenerator:go_default_library",
+ "//protoc-gen-grpc-gateway/descriptor:go_default_library",
+ "//protoc-gen-swagger/genswagger:go_default_library",
+ "@com_github_golang_glog//:go_default_library",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ ],
+)
+
+go_binary(
+ name = "protoc-gen-swagger",
+ embed = [":go_default_library"],
+ visibility = ["//visibility:public"],
+)
+
+go_test(
+ name = "go_default_test",
+ size = "small",
+ srcs = ["main_test.go"],
+ embed = [":go_default_library"],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/defs.bzl b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/defs.bzl
new file mode 100644
index 0000000..4f90807
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/defs.bzl
@@ -0,0 +1,154 @@
+"""Generated an open-api spec for a grpc api spec.
+
+Reads the the api spec in protobuf format and generate an open-api spec.
+Optionally applies settings from the grpc-service configuration.
+"""
+
+def _collect_includes(gen_dir, srcs):
+ """Build an include path mapping.
+
+ It is important to not just collect unique dirnames, to also support
+ proto files of the same name from different packages.
+
+ The implementation below is similar to what bazel does in its
+ ProtoCompileActionBuilder.java
+ """
+ includes = []
+ for src in srcs:
+ ref_path = src.path
+
+ if ref_path.startswith(gen_dir):
+ ref_path = ref_path[len(gen_dir):].lstrip("/")
+
+ if src.owner.workspace_root:
+ workspace_root = src.owner.workspace_root
+ ref_path = ref_path[len(workspace_root):].lstrip("/")
+
+ include = ref_path + "=" + src.path
+ if include not in includes:
+ includes.append(include)
+
+ return includes
+
+def _run_proto_gen_swagger(ctx, direct_proto_srcs, transitive_proto_srcs, actions, protoc, protoc_gen_swagger, grpc_api_configuration, single_output):
+ swagger_files = []
+
+ inputs = direct_proto_srcs + transitive_proto_srcs
+ tools = [protoc_gen_swagger]
+
+ options = ["logtostderr=true", "allow_repeated_fields_in_body=true"]
+ if grpc_api_configuration:
+ options.append("grpc_api_configuration=%s" % grpc_api_configuration.path)
+ inputs.append(grpc_api_configuration)
+
+ includes = _collect_includes(ctx.genfiles_dir.path, direct_proto_srcs + transitive_proto_srcs)
+
+ if single_output:
+ swagger_file = actions.declare_file(
+ "%s.swagger.json" % ctx.attr.name,
+ sibling = direct_proto_srcs[0],
+ )
+ output_dir = ctx.bin_dir.path
+ if direct_proto_srcs[0].owner.workspace_root:
+ output_dir = "/".join([output_dir, direct_proto_srcs[0].owner.workspace_root])
+
+ output_dir = "/".join([output_dir, direct_proto_srcs[0].dirname])
+
+ options.append("allow_merge=true")
+ options.append("merge_file_name=%s" % ctx.attr.name)
+
+ args = actions.args()
+ args.add("--plugin=%s" % protoc_gen_swagger.path)
+ args.add("--swagger_out=%s:%s" % (",".join(options), output_dir))
+ args.add_all(["-I%s" % include for include in includes])
+ args.add_all([src.path for src in direct_proto_srcs])
+
+ actions.run(
+ executable = protoc,
+ inputs = inputs,
+ tools = tools,
+ outputs = [swagger_file],
+ arguments = [args],
+ )
+
+ swagger_files.append(swagger_file)
+ else:
+ for proto in direct_proto_srcs:
+ swagger_file = actions.declare_file(
+ "%s.swagger.json" % proto.basename[:-len(".proto")],
+ sibling = proto,
+ )
+
+ output_dir = ctx.bin_dir.path
+ if proto.owner.workspace_root:
+ output_dir = "/".join([output_dir, proto.owner.workspace_root])
+
+ args = actions.args()
+ args.add("--plugin=%s" % protoc_gen_swagger.path)
+ args.add("--swagger_out=%s:%s" % (",".join(options), output_dir))
+ args.add_all(["-I%s" % include for include in includes])
+ args.add(proto.path)
+
+ actions.run(
+ executable = protoc,
+ inputs = inputs,
+ tools = tools,
+ outputs = [swagger_file],
+ arguments = [args],
+ )
+
+ swagger_files.append(swagger_file)
+
+ return swagger_files
+
+def _proto_gen_swagger_impl(ctx):
+ proto = ctx.attr.proto[ProtoInfo]
+ grpc_api_configuration = ctx.file.grpc_api_configuration
+
+ return [DefaultInfo(
+ files = depset(
+ _run_proto_gen_swagger(
+ ctx,
+ direct_proto_srcs = proto.direct_sources,
+ transitive_proto_srcs = ctx.files._well_known_protos + proto.transitive_sources.to_list(),
+ actions = ctx.actions,
+ protoc = ctx.executable._protoc,
+ protoc_gen_swagger = ctx.executable._protoc_gen_swagger,
+ grpc_api_configuration = grpc_api_configuration,
+ single_output = ctx.attr.single_output,
+ ),
+ ),
+ )]
+
+protoc_gen_swagger = rule(
+ attrs = {
+ "proto": attr.label(
+ allow_rules = ["proto_library"],
+ mandatory = True,
+ providers = ["proto"],
+ ),
+ "grpc_api_configuration": attr.label(
+ allow_single_file = True,
+ mandatory = False,
+ ),
+ "single_output": attr.bool(
+ default = False,
+ mandatory = False,
+ ),
+ "_protoc": attr.label(
+ default = "@com_google_protobuf//:protoc",
+ executable = True,
+ cfg = "host",
+ ),
+ "_well_known_protos": attr.label(
+ default = "@com_google_protobuf//:well_known_protos",
+ allow_files = True,
+ ),
+ "_protoc_gen_swagger": attr.label(
+ default = Label("//protoc-gen-swagger:protoc-gen-swagger"),
+ executable = True,
+ cfg = "host",
+ ),
+ },
+ implementation = _proto_gen_swagger_impl,
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/BUILD.bazel
new file mode 100644
index 0000000..929d0cf
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/BUILD.bazel
@@ -0,0 +1,46 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//protoc-gen-swagger:__subpackages__"])
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "doc.go",
+ "generator.go",
+ "template.go",
+ "types.go",
+ ],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger",
+ deps = [
+ "//internal:go_default_library",
+ "//protoc-gen-grpc-gateway/descriptor:go_default_library",
+ "//protoc-gen-grpc-gateway/generator:go_default_library",
+ "//protoc-gen-swagger/options:go_default_library",
+ "@com_github_golang_glog//:go_default_library",
+ "@com_github_golang_protobuf//descriptor:go_default_library_gen",
+ "@com_github_golang_protobuf//jsonpb:go_default_library_gen",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@com_github_golang_protobuf//protoc-gen-go/generator:go_default_library_gen",
+ "@io_bazel_rules_go//proto/wkt:any_go_proto",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
+ "@io_bazel_rules_go//proto/wkt:struct_go_proto",
+ ],
+)
+
+go_test(
+ name = "go_default_test",
+ size = "small",
+ srcs = ["template_test.go"],
+ embed = [":go_default_library"],
+ deps = [
+ "//protoc-gen-grpc-gateway/descriptor:go_default_library",
+ "//protoc-gen-grpc-gateway/httprule:go_default_library",
+ "//protoc-gen-swagger/options:go_default_library",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@io_bazel_rules_go//proto/wkt:any_go_proto",
+ "@io_bazel_rules_go//proto/wkt:compiler_plugin_go_proto",
+ "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
+ "@io_bazel_rules_go//proto/wkt:struct_go_proto",
+ ],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/doc.go
new file mode 100644
index 0000000..4d28716
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/doc.go
@@ -0,0 +1,2 @@
+// Package genswagger provides a code generator for swagger.
+package genswagger
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/generator.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/generator.go
new file mode 100644
index 0000000..31409ac
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/generator.go
@@ -0,0 +1,247 @@
+package genswagger
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "path/filepath"
+ "reflect"
+ "strings"
+
+ "github.com/golang/glog"
+ pbdescriptor "github.com/golang/protobuf/descriptor"
+ "github.com/golang/protobuf/proto"
+ protocdescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
+ "github.com/golang/protobuf/ptypes/any"
+ "github.com/grpc-ecosystem/grpc-gateway/internal"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
+ gen "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/generator"
+ swagger_options "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
+)
+
+var (
+ errNoTargetService = errors.New("no target service defined in the file")
+)
+
+type generator struct {
+ reg *descriptor.Registry
+}
+
+type wrapper struct {
+ fileName string
+ swagger *swaggerObject
+}
+
+// New returns a new generator which generates grpc gateway files.
+func New(reg *descriptor.Registry) gen.Generator {
+ return &generator{reg: reg}
+}
+
+// Merge a lot of swagger file (wrapper) to single one swagger file
+func mergeTargetFile(targets []*wrapper, mergeFileName string) *wrapper {
+ var mergedTarget *wrapper
+ for _, f := range targets {
+ if mergedTarget == nil {
+ mergedTarget = &wrapper{
+ fileName: mergeFileName,
+ swagger: f.swagger,
+ }
+ } else {
+ for k, v := range f.swagger.Definitions {
+ mergedTarget.swagger.Definitions[k] = v
+ }
+ for k, v := range f.swagger.StreamDefinitions {
+ mergedTarget.swagger.StreamDefinitions[k] = v
+ }
+ for k, v := range f.swagger.Paths {
+ mergedTarget.swagger.Paths[k] = v
+ }
+ for k, v := range f.swagger.SecurityDefinitions {
+ mergedTarget.swagger.SecurityDefinitions[k] = v
+ }
+ mergedTarget.swagger.Security = append(mergedTarget.swagger.Security, f.swagger.Security...)
+ }
+ }
+ return mergedTarget
+}
+
+func fieldName(k string) string {
+ return strings.ReplaceAll(strings.Title(k), "-", "_")
+}
+
+// Q: What's up with the alias types here?
+// A: We don't want to completely override how these structs are marshaled into
+// JSON, we only want to add fields (see below, extensionMarshalJSON).
+// An infinite recursion would happen if we'd call json.Marshal on the struct
+// that has swaggerObject as an embedded field. To avoid that, we'll create
+// type aliases, and those don't have the custom MarshalJSON methods defined
+// on them. See http://choly.ca/post/go-json-marshalling/ (or, if it ever
+// goes away, use
+// https://web.archive.org/web/20190806073003/http://choly.ca/post/go-json-marshalling/.
+func (so swaggerObject) MarshalJSON() ([]byte, error) {
+ type alias swaggerObject
+ return extensionMarshalJSON(alias(so), so.extensions)
+}
+
+func (so swaggerInfoObject) MarshalJSON() ([]byte, error) {
+ type alias swaggerInfoObject
+ return extensionMarshalJSON(alias(so), so.extensions)
+}
+
+func (so swaggerSecuritySchemeObject) MarshalJSON() ([]byte, error) {
+ type alias swaggerSecuritySchemeObject
+ return extensionMarshalJSON(alias(so), so.extensions)
+}
+
+func (so swaggerOperationObject) MarshalJSON() ([]byte, error) {
+ type alias swaggerOperationObject
+ return extensionMarshalJSON(alias(so), so.extensions)
+}
+
+func (so swaggerResponseObject) MarshalJSON() ([]byte, error) {
+ type alias swaggerResponseObject
+ return extensionMarshalJSON(alias(so), so.extensions)
+}
+
+func extensionMarshalJSON(so interface{}, extensions []extension) ([]byte, error) {
+ // To append arbitrary keys to the struct we'll render into json,
+ // we're creating another struct that embeds the original one, and
+ // its extra fields:
+ //
+ // The struct will look like
+ // struct {
+ // *swaggerCore
+ // XGrpcGatewayFoo json.RawMessage `json:"x-grpc-gateway-foo"`
+ // XGrpcGatewayBar json.RawMessage `json:"x-grpc-gateway-bar"`
+ // }
+ // and thus render into what we want -- the JSON of swaggerCore with the
+ // extensions appended.
+ fields := []reflect.StructField{
+ reflect.StructField{ // embedded
+ Name: "Embedded",
+ Type: reflect.TypeOf(so),
+ Anonymous: true,
+ },
+ }
+ for _, ext := range extensions {
+ fields = append(fields, reflect.StructField{
+ Name: fieldName(ext.key),
+ Type: reflect.TypeOf(ext.value),
+ Tag: reflect.StructTag(fmt.Sprintf("json:\"%s\"", ext.key)),
+ })
+ }
+
+ t := reflect.StructOf(fields)
+ s := reflect.New(t).Elem()
+ s.Field(0).Set(reflect.ValueOf(so))
+ for _, ext := range extensions {
+ s.FieldByName(fieldName(ext.key)).Set(reflect.ValueOf(ext.value))
+ }
+ return json.Marshal(s.Interface())
+}
+
+// encodeSwagger converts swagger file obj to plugin.CodeGeneratorResponse_File
+func encodeSwagger(file *wrapper) (*plugin.CodeGeneratorResponse_File, error) {
+ var formatted bytes.Buffer
+ enc := json.NewEncoder(&formatted)
+ enc.SetIndent("", " ")
+ if err := enc.Encode(*file.swagger); err != nil {
+ return nil, err
+ }
+ name := file.fileName
+ ext := filepath.Ext(name)
+ base := strings.TrimSuffix(name, ext)
+ output := fmt.Sprintf("%s.swagger.json", base)
+ return &plugin.CodeGeneratorResponse_File{
+ Name: proto.String(output),
+ Content: proto.String(formatted.String()),
+ }, nil
+}
+
+func (g *generator) Generate(targets []*descriptor.File) ([]*plugin.CodeGeneratorResponse_File, error) {
+ var files []*plugin.CodeGeneratorResponse_File
+ if g.reg.IsAllowMerge() {
+ var mergedTarget *descriptor.File
+ // try to find proto leader
+ for _, f := range targets {
+ if proto.HasExtension(f.Options, swagger_options.E_Openapiv2Swagger) {
+ mergedTarget = f
+ break
+ }
+ }
+ // merge protos to leader
+ for _, f := range targets {
+ if mergedTarget == nil {
+ mergedTarget = f
+ } else {
+ mergedTarget.Enums = append(mergedTarget.Enums, f.Enums...)
+ mergedTarget.Messages = append(mergedTarget.Messages, f.Messages...)
+ mergedTarget.Services = append(mergedTarget.Services, f.Services...)
+ }
+ }
+
+ targets = nil
+ targets = append(targets, mergedTarget)
+ }
+
+ var swaggers []*wrapper
+ for _, file := range targets {
+ glog.V(1).Infof("Processing %s", file.GetName())
+ swagger, err := applyTemplate(param{File: file, reg: g.reg})
+ if err == errNoTargetService {
+ glog.V(1).Infof("%s: %v", file.GetName(), err)
+ continue
+ }
+ if err != nil {
+ return nil, err
+ }
+ swaggers = append(swaggers, &wrapper{
+ fileName: file.GetName(),
+ swagger: swagger,
+ })
+ }
+
+ if g.reg.IsAllowMerge() {
+ targetSwagger := mergeTargetFile(swaggers, g.reg.GetMergeFileName())
+ f, err := encodeSwagger(targetSwagger)
+ if err != nil {
+ return nil, fmt.Errorf("failed to encode swagger for %s: %s", g.reg.GetMergeFileName(), err)
+ }
+ files = append(files, f)
+ glog.V(1).Infof("New swagger file will emit")
+ } else {
+ for _, file := range swaggers {
+ f, err := encodeSwagger(file)
+ if err != nil {
+ return nil, fmt.Errorf("failed to encode swagger for %s: %s", file.fileName, err)
+ }
+ files = append(files, f)
+ glog.V(1).Infof("New swagger file will emit")
+ }
+ }
+ return files, nil
+}
+
+//AddStreamError Adds grpc.gateway.runtime.StreamError and google.protobuf.Any to registry for stream responses
+func AddStreamError(reg *descriptor.Registry) error {
+ //load internal protos
+ any := fileDescriptorProtoForMessage(&any.Any{})
+ streamError := fileDescriptorProtoForMessage(&internal.StreamError{})
+ if err := reg.Load(&plugin.CodeGeneratorRequest{
+ ProtoFile: []*protocdescriptor.FileDescriptorProto{
+ any,
+ streamError,
+ },
+ }); err != nil {
+ return err
+ }
+ return nil
+}
+
+func fileDescriptorProtoForMessage(msg pbdescriptor.Message) *protocdescriptor.FileDescriptorProto {
+ fdp, _ := pbdescriptor.ForMessage(msg)
+ fdp.SourceCodeInfo = &protocdescriptor.SourceCodeInfo{}
+ return fdp
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/template.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/template.go
new file mode 100644
index 0000000..3d97207
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/template.go
@@ -0,0 +1,1764 @@
+package genswagger
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "reflect"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+
+ "github.com/golang/glog"
+ "github.com/golang/protobuf/jsonpb"
+ "github.com/golang/protobuf/proto"
+ structpb "github.com/golang/protobuf/ptypes/struct"
+ pbdescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ gogen "github.com/golang/protobuf/protoc-gen-go/generator"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
+ swagger_options "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
+)
+
+var wktSchemas = map[string]schemaCore{
+ ".google.protobuf.Timestamp": schemaCore{
+ Type: "string",
+ Format: "date-time",
+ },
+ ".google.protobuf.Duration": schemaCore{
+ Type: "string",
+ },
+ ".google.protobuf.StringValue": schemaCore{
+ Type: "string",
+ },
+ ".google.protobuf.BytesValue": schemaCore{
+ Type: "string",
+ Format: "byte",
+ },
+ ".google.protobuf.Int32Value": schemaCore{
+ Type: "integer",
+ Format: "int32",
+ },
+ ".google.protobuf.UInt32Value": schemaCore{
+ Type: "integer",
+ Format: "int64",
+ },
+ ".google.protobuf.Int64Value": schemaCore{
+ Type: "string",
+ Format: "int64",
+ },
+ ".google.protobuf.UInt64Value": schemaCore{
+ Type: "string",
+ Format: "uint64",
+ },
+ ".google.protobuf.FloatValue": schemaCore{
+ Type: "number",
+ Format: "float",
+ },
+ ".google.protobuf.DoubleValue": schemaCore{
+ Type: "number",
+ Format: "double",
+ },
+ ".google.protobuf.BoolValue": schemaCore{
+ Type: "boolean",
+ Format: "boolean",
+ },
+ ".google.protobuf.Empty": schemaCore{},
+ ".google.protobuf.Struct": schemaCore{
+ Type: "object",
+ },
+ ".google.protobuf.Value": schemaCore{
+ Type: "object",
+ },
+ ".google.protobuf.ListValue": schemaCore{
+ Type: "array",
+ Items: (*swaggerItemsObject)(&schemaCore{
+ Type: "object",
+ }),
+ },
+ ".google.protobuf.NullValue": schemaCore{
+ Type: "string",
+ },
+}
+
+func listEnumNames(enum *descriptor.Enum) (names []string) {
+ for _, value := range enum.GetValue() {
+ names = append(names, value.GetName())
+ }
+ return names
+}
+
+func getEnumDefault(enum *descriptor.Enum) string {
+ for _, value := range enum.GetValue() {
+ if value.GetNumber() == 0 {
+ return value.GetName()
+ }
+ }
+ return ""
+}
+
+// messageToQueryParameters converts a message to a list of swagger query parameters.
+func messageToQueryParameters(message *descriptor.Message, reg *descriptor.Registry, pathParams []descriptor.Parameter) (params []swaggerParameterObject, err error) {
+ for _, field := range message.Fields {
+ p, err := queryParams(message, field, "", reg, pathParams)
+ if err != nil {
+ return nil, err
+ }
+ params = append(params, p...)
+ }
+ return params, nil
+}
+
+// queryParams converts a field to a list of swagger query parameters recursively.
+func queryParams(message *descriptor.Message, field *descriptor.Field, prefix string, reg *descriptor.Registry, pathParams []descriptor.Parameter) (params []swaggerParameterObject, err error) {
+ // make sure the parameter is not already listed as a path parameter
+ for _, pathParam := range pathParams {
+ if pathParam.Target == field {
+ return nil, nil
+ }
+ }
+ schema := schemaOfField(field, reg, nil)
+ fieldType := field.GetTypeName()
+ if message.File != nil {
+ comments := fieldProtoComments(reg, message, field)
+ if err := updateSwaggerDataFromComments(&schema, comments, false); err != nil {
+ return nil, err
+ }
+ }
+
+ isEnum := field.GetType() == pbdescriptor.FieldDescriptorProto_TYPE_ENUM
+ items := schema.Items
+ if schema.Type != "" || isEnum {
+ if schema.Type == "object" {
+ return nil, nil // TODO: currently, mapping object in query parameter is not supported
+ }
+ if items != nil && (items.Type == "" || items.Type == "object") && !isEnum {
+ return nil, nil // TODO: currently, mapping object in query parameter is not supported
+ }
+ desc := schema.Description
+ if schema.Title != "" { // merge title because title of parameter object will be ignored
+ desc = strings.TrimSpace(schema.Title + ". " + schema.Description)
+ }
+
+ // verify if the field is required
+ required := false
+ for _, fieldName := range schema.Required {
+ if fieldName == field.GetName() {
+ required = true
+ break
+ }
+ }
+
+ param := swaggerParameterObject{
+ Description: desc,
+ In: "query",
+ Default: schema.Default,
+ Type: schema.Type,
+ Items: schema.Items,
+ Format: schema.Format,
+ Required: required,
+ }
+ if param.Type == "array" {
+ param.CollectionFormat = "multi"
+ }
+
+ if reg.GetUseJSONNamesForFields() {
+ param.Name = prefix + field.GetJsonName()
+ } else {
+ param.Name = prefix + field.GetName()
+ }
+
+ if isEnum {
+ enum, err := reg.LookupEnum("", fieldType)
+ if err != nil {
+ return nil, fmt.Errorf("unknown enum type %s", fieldType)
+ }
+ if items != nil { // array
+ param.Items = &swaggerItemsObject{
+ Type: "string",
+ Enum: listEnumNames(enum),
+ }
+ } else {
+ param.Type = "string"
+ param.Enum = listEnumNames(enum)
+ param.Default = getEnumDefault(enum)
+ }
+ valueComments := enumValueProtoComments(reg, enum)
+ if valueComments != "" {
+ param.Description = strings.TrimLeft(param.Description+"\n\n "+valueComments, "\n")
+ }
+ }
+ return []swaggerParameterObject{param}, nil
+ }
+
+ // nested type, recurse
+ msg, err := reg.LookupMsg("", fieldType)
+ if err != nil {
+ return nil, fmt.Errorf("unknown message type %s", fieldType)
+ }
+ for _, nestedField := range msg.Fields {
+ p, err := queryParams(msg, nestedField, prefix+field.GetName()+".", reg, pathParams)
+ if err != nil {
+ return nil, err
+ }
+ params = append(params, p...)
+ }
+ return params, nil
+}
+
+// findServicesMessagesAndEnumerations discovers all messages and enums defined in the RPC methods of the service.
+func findServicesMessagesAndEnumerations(s []*descriptor.Service, reg *descriptor.Registry, m messageMap, ms messageMap, e enumMap, refs refMap) {
+ for _, svc := range s {
+ for _, meth := range svc.Methods {
+ // Request may be fully included in query
+ if _, ok := refs[fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(meth.RequestType.FQMN(), reg))]; ok {
+ if !skipRenderingRef(meth.RequestType.FQMN()) {
+ m[fullyQualifiedNameToSwaggerName(meth.RequestType.FQMN(), reg)] = meth.RequestType
+ }
+ }
+ findNestedMessagesAndEnumerations(meth.RequestType, reg, m, e)
+
+ if !skipRenderingRef(meth.ResponseType.FQMN()) {
+ m[fullyQualifiedNameToSwaggerName(meth.ResponseType.FQMN(), reg)] = meth.ResponseType
+ if meth.GetServerStreaming() {
+ runtimeStreamError := fullyQualifiedNameToSwaggerName(".grpc.gateway.runtime.StreamError", reg)
+ glog.V(1).Infof("StreamError FQMN: %s", runtimeStreamError)
+ streamError, err := reg.LookupMsg(".grpc.gateway.runtime", "StreamError")
+ if err == nil {
+ glog.V(1).Infof("StreamError: %v", streamError)
+ m[runtimeStreamError] = streamError
+ findNestedMessagesAndEnumerations(streamError, reg, m, e)
+ } else {
+ //just in case there is an error looking up StreamError
+ glog.Error(err)
+ }
+ ms[fullyQualifiedNameToSwaggerName(meth.ResponseType.FQMN(), reg)] = meth.ResponseType
+ }
+ }
+ findNestedMessagesAndEnumerations(meth.ResponseType, reg, m, e)
+ }
+ }
+}
+
+// findNestedMessagesAndEnumerations those can be generated by the services.
+func findNestedMessagesAndEnumerations(message *descriptor.Message, reg *descriptor.Registry, m messageMap, e enumMap) {
+ // Iterate over all the fields that
+ for _, t := range message.Fields {
+ fieldType := t.GetTypeName()
+ // If the type is an empty string then it is a proto primitive
+ if fieldType != "" {
+ if _, ok := m[fieldType]; !ok {
+ msg, err := reg.LookupMsg("", fieldType)
+ if err != nil {
+ enum, err := reg.LookupEnum("", fieldType)
+ if err != nil {
+ panic(err)
+ }
+ e[fieldType] = enum
+ continue
+ }
+ m[fieldType] = msg
+ findNestedMessagesAndEnumerations(msg, reg, m, e)
+ }
+ }
+ }
+}
+
+func skipRenderingRef(refName string) bool {
+ _, ok := wktSchemas[refName]
+ return ok
+}
+
+func renderMessagesAsDefinition(messages messageMap, d swaggerDefinitionsObject, reg *descriptor.Registry, customRefs refMap) {
+ for name, msg := range messages {
+ if skipRenderingRef(name) {
+ continue
+ }
+
+ if opt := msg.GetOptions(); opt != nil && opt.MapEntry != nil && *opt.MapEntry {
+ continue
+ }
+ schema := swaggerSchemaObject{
+ schemaCore: schemaCore{
+ Type: "object",
+ },
+ }
+ msgComments := protoComments(reg, msg.File, msg.Outers, "MessageType", int32(msg.Index))
+ if err := updateSwaggerDataFromComments(&schema, msgComments, false); err != nil {
+ panic(err)
+ }
+ opts, err := extractSchemaOptionFromMessageDescriptor(msg.DescriptorProto)
+ if err != nil {
+ panic(err)
+ }
+ if opts != nil {
+ protoSchema := swaggerSchemaFromProtoSchema(opts, reg, customRefs)
+
+ // Warning: Make sure not to overwrite any fields already set on the schema type.
+ schema.ExternalDocs = protoSchema.ExternalDocs
+ schema.ReadOnly = protoSchema.ReadOnly
+ schema.MultipleOf = protoSchema.MultipleOf
+ schema.Maximum = protoSchema.Maximum
+ schema.ExclusiveMaximum = protoSchema.ExclusiveMaximum
+ schema.Minimum = protoSchema.Minimum
+ schema.ExclusiveMinimum = protoSchema.ExclusiveMinimum
+ schema.MaxLength = protoSchema.MaxLength
+ schema.MinLength = protoSchema.MinLength
+ schema.Pattern = protoSchema.Pattern
+ schema.Default = protoSchema.Default
+ schema.MaxItems = protoSchema.MaxItems
+ schema.MinItems = protoSchema.MinItems
+ schema.UniqueItems = protoSchema.UniqueItems
+ schema.MaxProperties = protoSchema.MaxProperties
+ schema.MinProperties = protoSchema.MinProperties
+ schema.Required = protoSchema.Required
+ if protoSchema.schemaCore.Type != "" || protoSchema.schemaCore.Ref != "" {
+ schema.schemaCore = protoSchema.schemaCore
+ }
+ if protoSchema.Title != "" {
+ schema.Title = protoSchema.Title
+ }
+ if protoSchema.Description != "" {
+ schema.Description = protoSchema.Description
+ }
+ if protoSchema.Example != nil {
+ schema.Example = protoSchema.Example
+ }
+ }
+
+ for _, f := range msg.Fields {
+ fieldValue := schemaOfField(f, reg, customRefs)
+ comments := fieldProtoComments(reg, msg, f)
+ if err := updateSwaggerDataFromComments(&fieldValue, comments, false); err != nil {
+ panic(err)
+ }
+
+ kv := keyVal{Value: fieldValue}
+ if reg.GetUseJSONNamesForFields() {
+ kv.Key = f.GetJsonName()
+ } else {
+ kv.Key = f.GetName()
+ }
+ if schema.Properties == nil {
+ schema.Properties = &swaggerSchemaObjectProperties{}
+ }
+ *schema.Properties = append(*schema.Properties, kv)
+ }
+ d[fullyQualifiedNameToSwaggerName(msg.FQMN(), reg)] = schema
+ }
+}
+
+func renderMessagesAsStreamDefinition(messages messageMap, d swaggerDefinitionsObject, reg *descriptor.Registry) {
+ for name, msg := range messages {
+ if skipRenderingRef(name) {
+ continue
+ }
+
+ if opt := msg.GetOptions(); opt != nil && opt.MapEntry != nil && *opt.MapEntry {
+ continue
+ }
+ d[fullyQualifiedNameToSwaggerName(msg.FQMN(), reg)] = swaggerSchemaObject{
+ schemaCore: schemaCore{
+ Type: "object",
+ },
+ Title: fmt.Sprintf("Stream result of %s", fullyQualifiedNameToSwaggerName(msg.FQMN(), reg)),
+ Properties: &swaggerSchemaObjectProperties{
+ keyVal{
+ Key: "result",
+ Value: swaggerSchemaObject{
+ schemaCore: schemaCore{
+ Ref: fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(msg.FQMN(), reg)),
+ },
+ },
+ },
+ keyVal{
+ Key: "error",
+ Value: swaggerSchemaObject{
+ schemaCore: schemaCore{
+ Ref: fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(".grpc.gateway.runtime.StreamError", reg)),
+ },
+ },
+ },
+ },
+ }
+ }
+}
+
+// schemaOfField returns a swagger Schema Object for a protobuf field.
+func schemaOfField(f *descriptor.Field, reg *descriptor.Registry, refs refMap) swaggerSchemaObject {
+ const (
+ singular = 0
+ array = 1
+ object = 2
+ )
+ var (
+ core schemaCore
+ aggregate int
+ )
+
+ fd := f.FieldDescriptorProto
+ if m, err := reg.LookupMsg("", f.GetTypeName()); err == nil {
+ if opt := m.GetOptions(); opt != nil && opt.MapEntry != nil && *opt.MapEntry {
+ fd = m.GetField()[1]
+ aggregate = object
+ }
+ }
+ if fd.GetLabel() == pbdescriptor.FieldDescriptorProto_LABEL_REPEATED {
+ aggregate = array
+ }
+
+ var props *swaggerSchemaObjectProperties
+
+ switch ft := fd.GetType(); ft {
+ case pbdescriptor.FieldDescriptorProto_TYPE_ENUM, pbdescriptor.FieldDescriptorProto_TYPE_MESSAGE, pbdescriptor.FieldDescriptorProto_TYPE_GROUP:
+ if wktSchema, ok := wktSchemas[fd.GetTypeName()]; ok {
+ core = wktSchema
+
+ if fd.GetTypeName() == ".google.protobuf.Empty" {
+ props = &swaggerSchemaObjectProperties{}
+ }
+ } else {
+ core = schemaCore{
+ Ref: "#/definitions/" + fullyQualifiedNameToSwaggerName(fd.GetTypeName(), reg),
+ }
+ if refs != nil {
+ refs[fd.GetTypeName()] = struct{}{}
+
+ }
+ }
+ default:
+ ftype, format, ok := primitiveSchema(ft)
+ if ok {
+ core = schemaCore{Type: ftype, Format: format}
+ } else {
+ core = schemaCore{Type: ft.String(), Format: "UNKNOWN"}
+ }
+ }
+
+ ret := swaggerSchemaObject{}
+
+ switch aggregate {
+ case array:
+ ret = swaggerSchemaObject{
+ schemaCore: schemaCore{
+ Type: "array",
+ Items: (*swaggerItemsObject)(&core),
+ },
+ }
+ case object:
+ ret = swaggerSchemaObject{
+ schemaCore: schemaCore{
+ Type: "object",
+ },
+ AdditionalProperties: &swaggerSchemaObject{Properties: props, schemaCore: core},
+ }
+ default:
+ ret = swaggerSchemaObject{
+ schemaCore: core,
+ Properties: props,
+ }
+ }
+
+ if j, err := extractJSONSchemaFromFieldDescriptor(fd); err == nil {
+ updateSwaggerObjectFromJSONSchema(&ret, j)
+ }
+
+ return ret
+}
+
+// primitiveSchema returns a pair of "Type" and "Format" in JSON Schema for
+// the given primitive field type.
+// The last return parameter is true iff the field type is actually primitive.
+func primitiveSchema(t pbdescriptor.FieldDescriptorProto_Type) (ftype, format string, ok bool) {
+ switch t {
+ case pbdescriptor.FieldDescriptorProto_TYPE_DOUBLE:
+ return "number", "double", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_FLOAT:
+ return "number", "float", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_INT64:
+ return "string", "int64", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_UINT64:
+ // 64bit integer types are marshaled as string in the default JSONPb marshaler.
+ // TODO(yugui) Add an option to declare 64bit integers as int64.
+ //
+ // NOTE: uint64 is not a predefined format of integer type in Swagger spec.
+ // So we cannot expect that uint64 is commonly supported by swagger processor.
+ return "string", "uint64", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_INT32:
+ return "integer", "int32", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_FIXED64:
+ // Ditto.
+ return "string", "uint64", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_FIXED32:
+ // Ditto.
+ return "integer", "int64", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_BOOL:
+ return "boolean", "boolean", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_STRING:
+ // NOTE: in swagger specifition, format should be empty on string type
+ return "string", "", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_BYTES:
+ return "string", "byte", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_UINT32:
+ // Ditto.
+ return "integer", "int64", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_SFIXED32:
+ return "integer", "int32", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_SFIXED64:
+ return "string", "int64", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_SINT32:
+ return "integer", "int32", true
+ case pbdescriptor.FieldDescriptorProto_TYPE_SINT64:
+ return "string", "int64", true
+ default:
+ return "", "", false
+ }
+}
+
+// renderEnumerationsAsDefinition inserts enums into the definitions object.
+func renderEnumerationsAsDefinition(enums enumMap, d swaggerDefinitionsObject, reg *descriptor.Registry) {
+ for _, enum := range enums {
+ enumComments := protoComments(reg, enum.File, enum.Outers, "EnumType", int32(enum.Index))
+
+ // it may be necessary to sort the result of the GetValue function.
+ enumNames := listEnumNames(enum)
+ defaultValue := getEnumDefault(enum)
+ valueComments := enumValueProtoComments(reg, enum)
+ if valueComments != "" {
+ enumComments = strings.TrimLeft(enumComments+"\n\n "+valueComments, "\n")
+ }
+ enumSchemaObject := swaggerSchemaObject{
+ schemaCore: schemaCore{
+ Type: "string",
+ Enum: enumNames,
+ Default: defaultValue,
+ },
+ }
+ if err := updateSwaggerDataFromComments(&enumSchemaObject, enumComments, false); err != nil {
+ panic(err)
+ }
+
+ d[fullyQualifiedNameToSwaggerName(enum.FQEN(), reg)] = enumSchemaObject
+ }
+}
+
+// Take in a FQMN or FQEN and return a swagger safe version of the FQMN
+func fullyQualifiedNameToSwaggerName(fqn string, reg *descriptor.Registry) string {
+ registriesSeenMutex.Lock()
+ defer registriesSeenMutex.Unlock()
+ if mapping, present := registriesSeen[reg]; present {
+ return mapping[fqn]
+ }
+ mapping := resolveFullyQualifiedNameToSwaggerNames(append(reg.GetAllFQMNs(), reg.GetAllFQENs()...), reg.GetUseFQNForSwaggerName())
+ registriesSeen[reg] = mapping
+ return mapping[fqn]
+}
+
+// registriesSeen is used to memoise calls to resolveFullyQualifiedNameToSwaggerNames so
+// we don't repeat it unnecessarily, since it can take some time.
+var registriesSeen = map[*descriptor.Registry]map[string]string{}
+var registriesSeenMutex sync.Mutex
+
+// Take the names of every proto and "uniq-ify" them. The idea is to produce a
+// set of names that meet a couple of conditions. They must be stable, they
+// must be unique, and they must be shorter than the FQN.
+//
+// This likely could be made better. This will always generate the same names
+// but may not always produce optimal names. This is a reasonably close
+// approximation of what they should look like in most cases.
+func resolveFullyQualifiedNameToSwaggerNames(messages []string, useFQNForSwaggerName bool) map[string]string {
+ packagesByDepth := make(map[int][][]string)
+ uniqueNames := make(map[string]string)
+
+ hierarchy := func(pkg string) []string {
+ return strings.Split(pkg, ".")
+ }
+
+ for _, p := range messages {
+ h := hierarchy(p)
+ for depth := range h {
+ if _, ok := packagesByDepth[depth]; !ok {
+ packagesByDepth[depth] = make([][]string, 0)
+ }
+ packagesByDepth[depth] = append(packagesByDepth[depth], h[len(h)-depth:])
+ }
+ }
+
+ count := func(list [][]string, item []string) int {
+ i := 0
+ for _, element := range list {
+ if reflect.DeepEqual(element, item) {
+ i++
+ }
+ }
+ return i
+ }
+
+ for _, p := range messages {
+ if useFQNForSwaggerName {
+ // strip leading dot from proto fqn
+ uniqueNames[p] = p[1:]
+ } else {
+ h := hierarchy(p)
+ for depth := 0; depth < len(h); depth++ {
+ if count(packagesByDepth[depth], h[len(h)-depth:]) == 1 {
+ uniqueNames[p] = strings.Join(h[len(h)-depth-1:], "")
+ break
+ }
+ if depth == len(h)-1 {
+ uniqueNames[p] = strings.Join(h, "")
+ }
+ }
+ }
+ }
+ return uniqueNames
+}
+
+var canRegexp = regexp.MustCompile("{([a-zA-Z][a-zA-Z0-9_.]*).*}")
+
+// Swagger expects paths of the form /path/{string_value} but grpc-gateway paths are expected to be of the form /path/{string_value=strprefix/*}. This should reformat it correctly.
+func templateToSwaggerPath(path string, reg *descriptor.Registry) string {
+ // It seems like the right thing to do here is to just use
+ // strings.Split(path, "/") but that breaks badly when you hit a url like
+ // /{my_field=prefix/*}/ and end up with 2 sections representing my_field.
+ // Instead do the right thing and write a small pushdown (counter) automata
+ // for it.
+ var parts []string
+ depth := 0
+ buffer := ""
+ jsonBuffer := ""
+ for _, char := range path {
+ switch char {
+ case '{':
+ // Push on the stack
+ depth++
+ buffer += string(char)
+ jsonBuffer = ""
+ jsonBuffer += string(char)
+ break
+ case '}':
+ if depth == 0 {
+ panic("Encountered } without matching { before it.")
+ }
+ // Pop from the stack
+ depth--
+ buffer += string(char)
+ if reg.GetUseJSONNamesForFields() &&
+ len(jsonBuffer) > 1 {
+ jsonSnakeCaseName := string(jsonBuffer[1:])
+ jsonCamelCaseName := string(lowerCamelCase(jsonSnakeCaseName))
+ prev := string(buffer[:len(buffer)-len(jsonSnakeCaseName)-2])
+ buffer = strings.Join([]string{prev, "{", jsonCamelCaseName, "}"}, "")
+ jsonBuffer = ""
+ }
+ case '/':
+ if depth == 0 {
+ parts = append(parts, buffer)
+ buffer = ""
+ // Since the stack was empty when we hit the '/' we are done with this
+ // section.
+ continue
+ }
+ buffer += string(char)
+ jsonBuffer += string(char)
+ default:
+ buffer += string(char)
+ jsonBuffer += string(char)
+ break
+ }
+ }
+
+ // Now append the last element to parts
+ parts = append(parts, buffer)
+
+ // Parts is now an array of segments of the path. Interestingly, since the
+ // syntax for this subsection CAN be handled by a regexp since it has no
+ // memory.
+ for index, part := range parts {
+ // If part is a resource name such as "parent", "name", "user.name", the format info must be retained.
+ prefix := canRegexp.ReplaceAllString(part, "$1")
+ if isResourceName(prefix) {
+ continue
+ }
+ parts[index] = canRegexp.ReplaceAllString(part, "{$1}")
+ }
+
+ return strings.Join(parts, "/")
+}
+
+func isResourceName(prefix string) bool {
+ words := strings.Split(prefix, ".")
+ l := len(words)
+ field := words[l-1]
+ words = strings.Split(field, ":")
+ field = words[0]
+ return field == "parent" || field == "name"
+}
+
+func renderServices(services []*descriptor.Service, paths swaggerPathsObject, reg *descriptor.Registry, requestResponseRefs, customRefs refMap) error {
+ // Correctness of svcIdx and methIdx depends on 'services' containing the services in the same order as the 'file.Service' array.
+ for svcIdx, svc := range services {
+ for methIdx, meth := range svc.Methods {
+ for bIdx, b := range meth.Bindings {
+ // Iterate over all the swagger parameters
+ parameters := swaggerParametersObject{}
+ for _, parameter := range b.PathParams {
+
+ var paramType, paramFormat, desc, collectionFormat, defaultValue string
+ var enumNames []string
+ var items *swaggerItemsObject
+ var minItems *int
+ switch pt := parameter.Target.GetType(); pt {
+ case pbdescriptor.FieldDescriptorProto_TYPE_GROUP, pbdescriptor.FieldDescriptorProto_TYPE_MESSAGE:
+ if descriptor.IsWellKnownType(parameter.Target.GetTypeName()) {
+ if parameter.IsRepeated() {
+ return fmt.Errorf("only primitive and enum types are allowed in repeated path parameters")
+ }
+ schema := schemaOfField(parameter.Target, reg, customRefs)
+ paramType = schema.Type
+ paramFormat = schema.Format
+ desc = schema.Description
+ defaultValue = schema.Default
+ } else {
+ return fmt.Errorf("only primitive and well-known types are allowed in path parameters")
+ }
+ case pbdescriptor.FieldDescriptorProto_TYPE_ENUM:
+ paramType = "string"
+ paramFormat = ""
+ enum, err := reg.LookupEnum("", parameter.Target.GetTypeName())
+ if err != nil {
+ return err
+ }
+ enumNames = listEnumNames(enum)
+ schema := schemaOfField(parameter.Target, reg, customRefs)
+ desc = schema.Description
+ defaultValue = schema.Default
+ default:
+ var ok bool
+ paramType, paramFormat, ok = primitiveSchema(pt)
+ if !ok {
+ return fmt.Errorf("unknown field type %v", pt)
+ }
+
+ schema := schemaOfField(parameter.Target, reg, customRefs)
+ desc = schema.Description
+ defaultValue = schema.Default
+ }
+
+ if parameter.IsRepeated() {
+ core := schemaCore{Type: paramType, Format: paramFormat}
+ if parameter.IsEnum() {
+ var s []string
+ core.Enum = enumNames
+ enumNames = s
+ }
+ items = (*swaggerItemsObject)(&core)
+ paramType = "array"
+ paramFormat = ""
+ collectionFormat = reg.GetRepeatedPathParamSeparatorName()
+ minItems = new(int)
+ *minItems = 1
+ }
+
+ if desc == "" {
+ desc = fieldProtoComments(reg, parameter.Target.Message, parameter.Target)
+ }
+ parameterString := parameter.String()
+ if reg.GetUseJSONNamesForFields() {
+ parameterString = lowerCamelCase(parameterString)
+ }
+ parameters = append(parameters, swaggerParameterObject{
+ Name: parameterString,
+ Description: desc,
+ In: "path",
+ Required: true,
+ Default: defaultValue,
+ // Parameters in gRPC-Gateway can only be strings?
+ Type: paramType,
+ Format: paramFormat,
+ Enum: enumNames,
+ Items: items,
+ CollectionFormat: collectionFormat,
+ MinItems: minItems,
+ })
+ }
+ // Now check if there is a body parameter
+ if b.Body != nil {
+ var schema swaggerSchemaObject
+ desc := ""
+
+ if len(b.Body.FieldPath) == 0 {
+ schema = swaggerSchemaObject{
+ schemaCore: schemaCore{},
+ }
+
+ wknSchemaCore, isWkn := wktSchemas[meth.RequestType.FQMN()]
+ if !isWkn {
+ schema.Ref = fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(meth.RequestType.FQMN(), reg))
+ } else {
+ schema.schemaCore = wknSchemaCore
+
+ // Special workaround for Empty: it's well-known type but wknSchemas only returns schema.schemaCore; but we need to set schema.Properties which is a level higher.
+ if meth.RequestType.FQMN() == ".google.protobuf.Empty" {
+ schema.Properties = &swaggerSchemaObjectProperties{}
+ }
+ }
+ } else {
+ lastField := b.Body.FieldPath[len(b.Body.FieldPath)-1]
+ schema = schemaOfField(lastField.Target, reg, customRefs)
+ if schema.Description != "" {
+ desc = schema.Description
+ } else {
+ desc = fieldProtoComments(reg, lastField.Target.Message, lastField.Target)
+ }
+ }
+
+ if meth.GetClientStreaming() {
+ desc += " (streaming inputs)"
+ }
+ parameters = append(parameters, swaggerParameterObject{
+ Name: "body",
+ Description: desc,
+ In: "body",
+ Required: true,
+ Schema: &schema,
+ })
+ } else if b.HTTPMethod == "GET" || b.HTTPMethod == "DELETE" {
+ // add the parameters to the query string
+ queryParams, err := messageToQueryParameters(meth.RequestType, reg, b.PathParams)
+ if err != nil {
+ return err
+ }
+ parameters = append(parameters, queryParams...)
+ }
+
+ pathItemObject, ok := paths[templateToSwaggerPath(b.PathTmpl.Template, reg)]
+ if !ok {
+ pathItemObject = swaggerPathItemObject{}
+ }
+
+ methProtoPath := protoPathIndex(reflect.TypeOf((*pbdescriptor.ServiceDescriptorProto)(nil)), "Method")
+ desc := "A successful response."
+ var responseSchema swaggerSchemaObject
+
+ if b.ResponseBody == nil || len(b.ResponseBody.FieldPath) == 0 {
+ responseSchema = swaggerSchemaObject{
+ schemaCore: schemaCore{},
+ }
+
+ // Don't link to a full definition for
+ // empty; it's overly verbose.
+ // schema.Properties{} renders it as
+ // well, without a definition
+ wknSchemaCore, isWkn := wktSchemas[meth.ResponseType.FQMN()]
+ if !isWkn {
+ responseSchema.Ref = fmt.Sprintf("#/definitions/%s", fullyQualifiedNameToSwaggerName(meth.ResponseType.FQMN(), reg))
+ } else {
+ responseSchema.schemaCore = wknSchemaCore
+
+ // Special workaround for Empty: it's well-known type but wknSchemas only returns schema.schemaCore; but we need to set schema.Properties which is a level higher.
+ if meth.ResponseType.FQMN() == ".google.protobuf.Empty" {
+ responseSchema.Properties = &swaggerSchemaObjectProperties{}
+ }
+ }
+ } else {
+ // This is resolving the value of response_body in the google.api.HttpRule
+ lastField := b.ResponseBody.FieldPath[len(b.ResponseBody.FieldPath)-1]
+ responseSchema = schemaOfField(lastField.Target, reg, customRefs)
+ if responseSchema.Description != "" {
+ desc = responseSchema.Description
+ } else {
+ desc = fieldProtoComments(reg, lastField.Target.Message, lastField.Target)
+ }
+ }
+ if meth.GetServerStreaming() {
+ desc += "(streaming responses)"
+ // Use the streamdefinition which wraps the message in a "result"
+ responseSchema.Ref = strings.Replace(responseSchema.Ref, `#/definitions/`, `#/x-stream-definitions/`, 1)
+ }
+
+ tag := svc.GetName()
+ if pkg := svc.File.GetPackage(); pkg != "" && reg.IsIncludePackageInTags() {
+ tag = pkg + "." + tag
+ }
+
+ operationObject := &swaggerOperationObject{
+ Tags: []string{tag},
+ Parameters: parameters,
+ Responses: swaggerResponsesObject{
+ "200": swaggerResponseObject{
+ Description: desc,
+ Schema: responseSchema,
+ },
+ },
+ }
+ if bIdx == 0 {
+ operationObject.OperationID = fmt.Sprintf("%s", meth.GetName())
+ } else {
+ // OperationID must be unique in an OpenAPI v2 definition.
+ operationObject.OperationID = fmt.Sprintf("%s%d", meth.GetName(), bIdx+1)
+ }
+
+ // Fill reference map with referenced request messages
+ for _, param := range operationObject.Parameters {
+ if param.Schema != nil && param.Schema.Ref != "" {
+ requestResponseRefs[param.Schema.Ref] = struct{}{}
+ }
+ }
+
+ methComments := protoComments(reg, svc.File, nil, "Method", int32(svcIdx), methProtoPath, int32(methIdx))
+ if err := updateSwaggerDataFromComments(operationObject, methComments, false); err != nil {
+ panic(err)
+ }
+
+ opts, err := extractOperationOptionFromMethodDescriptor(meth.MethodDescriptorProto)
+ if opts != nil {
+ if err != nil {
+ panic(err)
+ }
+ operationObject.ExternalDocs = protoExternalDocumentationToSwaggerExternalDocumentation(opts.ExternalDocs)
+ // TODO(ivucica): this would be better supported by looking whether the method is deprecated in the proto file
+ operationObject.Deprecated = opts.Deprecated
+
+ if opts.Summary != "" {
+ operationObject.Summary = opts.Summary
+ }
+ if opts.Description != "" {
+ operationObject.Description = opts.Description
+ }
+ if len(opts.Tags) > 0 {
+ operationObject.Tags = make([]string, len(opts.Tags))
+ copy(operationObject.Tags, opts.Tags)
+ }
+ if opts.Security != nil {
+ newSecurity := []swaggerSecurityRequirementObject{}
+ if operationObject.Security != nil {
+ newSecurity = *operationObject.Security
+ }
+ for _, secReq := range opts.Security {
+ newSecReq := swaggerSecurityRequirementObject{}
+ for secReqKey, secReqValue := range secReq.SecurityRequirement {
+ if secReqValue == nil {
+ continue
+ }
+
+ newSecReqValue := make([]string, len(secReqValue.Scope))
+ copy(newSecReqValue, secReqValue.Scope)
+ newSecReq[secReqKey] = newSecReqValue
+ }
+
+ if len(newSecReq) > 0 {
+ newSecurity = append(newSecurity, newSecReq)
+ }
+ }
+ operationObject.Security = &newSecurity
+ }
+ if opts.Responses != nil {
+ for name, resp := range opts.Responses {
+ respObj := swaggerResponseObject{
+ Description: resp.Description,
+ Schema: swaggerSchemaFromProtoSchema(resp.Schema, reg, customRefs),
+ }
+ if resp.Extensions != nil {
+ exts, err := processExtensions(resp.Extensions)
+ if err != nil {
+ return err
+ }
+ respObj.extensions = exts
+ }
+ operationObject.Responses[name] = respObj
+ }
+ }
+
+ if opts.Extensions != nil {
+ exts, err := processExtensions(opts.Extensions)
+ if err != nil {
+ return err
+ }
+ operationObject.extensions = exts
+ }
+
+ // TODO(ivucica): add remaining fields of operation object
+ }
+
+ switch b.HTTPMethod {
+ case "DELETE":
+ pathItemObject.Delete = operationObject
+ break
+ case "GET":
+ pathItemObject.Get = operationObject
+ break
+ case "POST":
+ pathItemObject.Post = operationObject
+ break
+ case "PUT":
+ pathItemObject.Put = operationObject
+ break
+ case "PATCH":
+ pathItemObject.Patch = operationObject
+ break
+ }
+ paths[templateToSwaggerPath(b.PathTmpl.Template, reg)] = pathItemObject
+ }
+ }
+ }
+
+ // Success! return nil on the error object
+ return nil
+}
+
+// This function is called with a param which contains the entire definition of a method.
+func applyTemplate(p param) (*swaggerObject, error) {
+ // Create the basic template object. This is the object that everything is
+ // defined off of.
+ s := swaggerObject{
+ // Swagger 2.0 is the version of this document
+ Swagger: "2.0",
+ Schemes: []string{"http", "https"},
+ Consumes: []string{"application/json"},
+ Produces: []string{"application/json"},
+ Paths: make(swaggerPathsObject),
+ Definitions: make(swaggerDefinitionsObject),
+ StreamDefinitions: make(swaggerDefinitionsObject),
+ Info: swaggerInfoObject{
+ Title: *p.File.Name,
+ Version: "version not set",
+ },
+ }
+
+ // Loops through all the services and their exposed GET/POST/PUT/DELETE definitions
+ // and create entries for all of them.
+ // Also adds custom user specified references to second map.
+ requestResponseRefs, customRefs := refMap{}, refMap{}
+ if err := renderServices(p.Services, s.Paths, p.reg, requestResponseRefs, customRefs); err != nil {
+ panic(err)
+ }
+
+ // Find all the service's messages and enumerations that are defined (recursively)
+ // and write request, response and other custom (but referenced) types out as definition objects.
+ m := messageMap{}
+ ms := messageMap{}
+ e := enumMap{}
+ findServicesMessagesAndEnumerations(p.Services, p.reg, m, ms, e, requestResponseRefs)
+ renderMessagesAsDefinition(m, s.Definitions, p.reg, customRefs)
+ renderMessagesAsStreamDefinition(ms, s.StreamDefinitions, p.reg)
+ renderEnumerationsAsDefinition(e, s.Definitions, p.reg)
+
+ // File itself might have some comments and metadata.
+ packageProtoPath := protoPathIndex(reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil)), "Package")
+ packageComments := protoComments(p.reg, p.File, nil, "Package", packageProtoPath)
+ if err := updateSwaggerDataFromComments(&s, packageComments, true); err != nil {
+ panic(err)
+ }
+
+ // There may be additional options in the swagger option in the proto.
+ spb, err := extractSwaggerOptionFromFileDescriptor(p.FileDescriptorProto)
+ if err != nil {
+ panic(err)
+ }
+ if spb != nil {
+ if spb.Swagger != "" {
+ s.Swagger = spb.Swagger
+ }
+ if spb.Info != nil {
+ if spb.Info.Title != "" {
+ s.Info.Title = spb.Info.Title
+ }
+ if spb.Info.Description != "" {
+ s.Info.Description = spb.Info.Description
+ }
+ if spb.Info.TermsOfService != "" {
+ s.Info.TermsOfService = spb.Info.TermsOfService
+ }
+ if spb.Info.Version != "" {
+ s.Info.Version = spb.Info.Version
+ }
+ if spb.Info.Contact != nil {
+ if s.Info.Contact == nil {
+ s.Info.Contact = &swaggerContactObject{}
+ }
+ if spb.Info.Contact.Name != "" {
+ s.Info.Contact.Name = spb.Info.Contact.Name
+ }
+ if spb.Info.Contact.Url != "" {
+ s.Info.Contact.URL = spb.Info.Contact.Url
+ }
+ if spb.Info.Contact.Email != "" {
+ s.Info.Contact.Email = spb.Info.Contact.Email
+ }
+ }
+ if spb.Info.License != nil {
+ if s.Info.License == nil {
+ s.Info.License = &swaggerLicenseObject{}
+ }
+ if spb.Info.License.Name != "" {
+ s.Info.License.Name = spb.Info.License.Name
+ }
+ if spb.Info.License.Url != "" {
+ s.Info.License.URL = spb.Info.License.Url
+ }
+ }
+ if spb.Info.Extensions != nil {
+ exts, err := processExtensions(spb.Info.Extensions)
+ if err != nil {
+ return nil, err
+ }
+ s.Info.extensions = exts
+ }
+ }
+ if spb.Host != "" {
+ s.Host = spb.Host
+ }
+ if spb.BasePath != "" {
+ s.BasePath = spb.BasePath
+ }
+ if len(spb.Schemes) > 0 {
+ s.Schemes = make([]string, len(spb.Schemes))
+ for i, scheme := range spb.Schemes {
+ s.Schemes[i] = strings.ToLower(scheme.String())
+ }
+ }
+ if len(spb.Consumes) > 0 {
+ s.Consumes = make([]string, len(spb.Consumes))
+ copy(s.Consumes, spb.Consumes)
+ }
+ if len(spb.Produces) > 0 {
+ s.Produces = make([]string, len(spb.Produces))
+ copy(s.Produces, spb.Produces)
+ }
+ if spb.SecurityDefinitions != nil && spb.SecurityDefinitions.Security != nil {
+ if s.SecurityDefinitions == nil {
+ s.SecurityDefinitions = swaggerSecurityDefinitionsObject{}
+ }
+ for secDefKey, secDefValue := range spb.SecurityDefinitions.Security {
+ var newSecDefValue swaggerSecuritySchemeObject
+ if oldSecDefValue, ok := s.SecurityDefinitions[secDefKey]; !ok {
+ newSecDefValue = swaggerSecuritySchemeObject{}
+ } else {
+ newSecDefValue = oldSecDefValue
+ }
+ if secDefValue.Type != swagger_options.SecurityScheme_TYPE_INVALID {
+ switch secDefValue.Type {
+ case swagger_options.SecurityScheme_TYPE_BASIC:
+ newSecDefValue.Type = "basic"
+ case swagger_options.SecurityScheme_TYPE_API_KEY:
+ newSecDefValue.Type = "apiKey"
+ case swagger_options.SecurityScheme_TYPE_OAUTH2:
+ newSecDefValue.Type = "oauth2"
+ }
+ }
+ if secDefValue.Description != "" {
+ newSecDefValue.Description = secDefValue.Description
+ }
+ if secDefValue.Name != "" {
+ newSecDefValue.Name = secDefValue.Name
+ }
+ if secDefValue.In != swagger_options.SecurityScheme_IN_INVALID {
+ switch secDefValue.In {
+ case swagger_options.SecurityScheme_IN_QUERY:
+ newSecDefValue.In = "query"
+ case swagger_options.SecurityScheme_IN_HEADER:
+ newSecDefValue.In = "header"
+ }
+ }
+ if secDefValue.Flow != swagger_options.SecurityScheme_FLOW_INVALID {
+ switch secDefValue.Flow {
+ case swagger_options.SecurityScheme_FLOW_IMPLICIT:
+ newSecDefValue.Flow = "implicit"
+ case swagger_options.SecurityScheme_FLOW_PASSWORD:
+ newSecDefValue.Flow = "password"
+ case swagger_options.SecurityScheme_FLOW_APPLICATION:
+ newSecDefValue.Flow = "application"
+ case swagger_options.SecurityScheme_FLOW_ACCESS_CODE:
+ newSecDefValue.Flow = "accessCode"
+ }
+ }
+ if secDefValue.AuthorizationUrl != "" {
+ newSecDefValue.AuthorizationURL = secDefValue.AuthorizationUrl
+ }
+ if secDefValue.TokenUrl != "" {
+ newSecDefValue.TokenURL = secDefValue.TokenUrl
+ }
+ if secDefValue.Scopes != nil {
+ if newSecDefValue.Scopes == nil {
+ newSecDefValue.Scopes = swaggerScopesObject{}
+ }
+ for scopeKey, scopeDesc := range secDefValue.Scopes.Scope {
+ newSecDefValue.Scopes[scopeKey] = scopeDesc
+ }
+ }
+ if secDefValue.Extensions != nil {
+ exts, err := processExtensions(secDefValue.Extensions)
+ if err != nil {
+ return nil, err
+ }
+ newSecDefValue.extensions = exts
+ }
+ s.SecurityDefinitions[secDefKey] = newSecDefValue
+ }
+ }
+ if spb.Security != nil {
+ newSecurity := []swaggerSecurityRequirementObject{}
+ if s.Security == nil {
+ newSecurity = []swaggerSecurityRequirementObject{}
+ } else {
+ newSecurity = s.Security
+ }
+ for _, secReq := range spb.Security {
+ newSecReq := swaggerSecurityRequirementObject{}
+ for secReqKey, secReqValue := range secReq.SecurityRequirement {
+ newSecReqValue := make([]string, len(secReqValue.Scope))
+ copy(newSecReqValue, secReqValue.Scope)
+ newSecReq[secReqKey] = newSecReqValue
+ }
+ newSecurity = append(newSecurity, newSecReq)
+ }
+ s.Security = newSecurity
+ }
+ s.ExternalDocs = protoExternalDocumentationToSwaggerExternalDocumentation(spb.ExternalDocs)
+ // Populate all Paths with Responses set at top level,
+ // preferring Responses already set over those at the top level.
+ if spb.Responses != nil {
+ for _, verbs := range s.Paths {
+ var maps []swaggerResponsesObject
+ if verbs.Delete != nil {
+ maps = append(maps, verbs.Delete.Responses)
+ }
+ if verbs.Get != nil {
+ maps = append(maps, verbs.Get.Responses)
+ }
+ if verbs.Post != nil {
+ maps = append(maps, verbs.Post.Responses)
+ }
+ if verbs.Put != nil {
+ maps = append(maps, verbs.Put.Responses)
+ }
+ if verbs.Patch != nil {
+ maps = append(maps, verbs.Patch.Responses)
+ }
+
+ for k, v := range spb.Responses {
+ for _, respMap := range maps {
+ if _, ok := respMap[k]; ok {
+ // Don't overwrite already existing Responses
+ continue
+ }
+ respMap[k] = swaggerResponseObject{
+ Description: v.Description,
+ Schema: swaggerSchemaFromProtoSchema(v.Schema, p.reg, customRefs),
+ }
+ }
+ }
+ }
+ }
+
+ if spb.Extensions != nil {
+ exts, err := processExtensions(spb.Extensions)
+ if err != nil {
+ return nil, err
+ }
+ s.extensions = exts
+ }
+
+ // Additional fields on the OpenAPI v2 spec's "Swagger" object
+ // should be added here, once supported in the proto.
+ }
+
+ // Finally add any references added by users that aren't
+ // otherwise rendered.
+ addCustomRefs(s.Definitions, p.reg, customRefs)
+
+ return &s, nil
+}
+
+func processExtensions(inputExts map[string]*structpb.Value) ([]extension, error) {
+ exts := []extension{}
+ for k, v := range inputExts {
+ if !strings.HasPrefix(k, "x-") {
+ return nil, fmt.Errorf("Extension keys need to start with \"x-\": %q", k)
+ }
+ ext, err := (&jsonpb.Marshaler{Indent: " "}).MarshalToString(v)
+ if err != nil {
+ return nil, err
+ }
+ exts = append(exts, extension{key: k, value: json.RawMessage(ext)})
+ }
+ sort.Slice(exts, func(i, j int) bool { return exts[i].key < exts[j].key })
+ return exts, nil
+}
+
+// updateSwaggerDataFromComments updates a Swagger object based on a comment
+// from the proto file.
+//
+// First paragraph of a comment is used for summary. Remaining paragraphs of
+// a comment are used for description. If 'Summary' field is not present on
+// the passed swaggerObject, the summary and description are joined by \n\n.
+//
+// If there is a field named 'Info', its 'Summary' and 'Description' fields
+// will be updated instead.
+//
+// If there is no 'Summary', the same behavior will be attempted on 'Title',
+// but only if the last character is not a period.
+func updateSwaggerDataFromComments(swaggerObject interface{}, comment string, isPackageObject bool) error {
+ if len(comment) == 0 {
+ return nil
+ }
+
+ // Figure out what to apply changes to.
+ swaggerObjectValue := reflect.ValueOf(swaggerObject)
+ infoObjectValue := swaggerObjectValue.Elem().FieldByName("Info")
+ if !infoObjectValue.CanSet() {
+ // No such field? Apply summary and description directly to
+ // passed object.
+ infoObjectValue = swaggerObjectValue.Elem()
+ }
+
+ // Figure out which properties to update.
+ summaryValue := infoObjectValue.FieldByName("Summary")
+ descriptionValue := infoObjectValue.FieldByName("Description")
+ readOnlyValue := infoObjectValue.FieldByName("ReadOnly")
+
+ if readOnlyValue.Kind() == reflect.Bool && readOnlyValue.CanSet() && strings.Contains(comment, "Output only.") {
+ readOnlyValue.Set(reflect.ValueOf(true))
+ }
+
+ usingTitle := false
+ if !summaryValue.CanSet() {
+ summaryValue = infoObjectValue.FieldByName("Title")
+ usingTitle = true
+ }
+
+ paragraphs := strings.Split(comment, "\n\n")
+
+ // If there is a summary (or summary-equivalent) and it's empty, use the first
+ // paragraph as summary, and the rest as description.
+ if summaryValue.CanSet() {
+ summary := strings.TrimSpace(paragraphs[0])
+ description := strings.TrimSpace(strings.Join(paragraphs[1:], "\n\n"))
+ if !usingTitle || (len(summary) > 0 && summary[len(summary)-1] != '.') {
+ // overrides the schema value only if it's empty
+ // keep the comment precedence when updating the package definition
+ if summaryValue.Len() == 0 || isPackageObject {
+ summaryValue.Set(reflect.ValueOf(summary))
+ }
+ if len(description) > 0 {
+ if !descriptionValue.CanSet() {
+ return fmt.Errorf("Encountered object type with a summary, but no description")
+ }
+ // overrides the schema value only if it's empty
+ // keep the comment precedence when updating the package definition
+ if descriptionValue.Len() == 0 || isPackageObject {
+ descriptionValue.Set(reflect.ValueOf(description))
+ }
+ }
+ return nil
+ }
+ }
+
+ // There was no summary field on the swaggerObject. Try to apply the
+ // whole comment into description if the swagger object description is empty.
+ if descriptionValue.CanSet() {
+ if descriptionValue.Len() == 0 || isPackageObject {
+ descriptionValue.Set(reflect.ValueOf(strings.Join(paragraphs, "\n\n")))
+ }
+ return nil
+ }
+
+ return fmt.Errorf("no description nor summary property")
+}
+
+func fieldProtoComments(reg *descriptor.Registry, msg *descriptor.Message, field *descriptor.Field) string {
+ protoPath := protoPathIndex(reflect.TypeOf((*pbdescriptor.DescriptorProto)(nil)), "Field")
+ for i, f := range msg.Fields {
+ if f == field {
+ return protoComments(reg, msg.File, msg.Outers, "MessageType", int32(msg.Index), protoPath, int32(i))
+ }
+ }
+ return ""
+}
+
+func enumValueProtoComments(reg *descriptor.Registry, enum *descriptor.Enum) string {
+ protoPath := protoPathIndex(reflect.TypeOf((*pbdescriptor.EnumDescriptorProto)(nil)), "Value")
+ var comments []string
+ for idx, value := range enum.GetValue() {
+ name := value.GetName()
+ str := protoComments(reg, enum.File, enum.Outers, "EnumType", int32(enum.Index), protoPath, int32(idx))
+ if str != "" {
+ comments = append(comments, name+": "+str)
+ }
+ }
+ if len(comments) > 0 {
+ return "- " + strings.Join(comments, "\n - ")
+ }
+ return ""
+}
+
+func protoComments(reg *descriptor.Registry, file *descriptor.File, outers []string, typeName string, typeIndex int32, fieldPaths ...int32) string {
+ if file.SourceCodeInfo == nil {
+ fmt.Fprintln(os.Stderr, "descriptor.File should not contain nil SourceCodeInfo")
+ return ""
+ }
+
+ outerPaths := make([]int32, len(outers))
+ for i := range outers {
+ location := ""
+ if file.Package != nil {
+ location = file.GetPackage()
+ }
+
+ msg, err := reg.LookupMsg(location, strings.Join(outers[:i+1], "."))
+ if err != nil {
+ panic(err)
+ }
+ outerPaths[i] = int32(msg.Index)
+ }
+
+ for _, loc := range file.SourceCodeInfo.Location {
+ if !isProtoPathMatches(loc.Path, outerPaths, typeName, typeIndex, fieldPaths) {
+ continue
+ }
+ comments := ""
+ if loc.LeadingComments != nil {
+ comments = strings.TrimRight(*loc.LeadingComments, "\n")
+ comments = strings.TrimSpace(comments)
+ // TODO(ivucica): this is a hack to fix "// " being interpreted as "//".
+ // perhaps we should:
+ // - split by \n
+ // - determine if every (but first and last) line begins with " "
+ // - trim every line only if that is the case
+ // - join by \n
+ comments = strings.Replace(comments, "\n ", "\n", -1)
+ }
+ return comments
+ }
+ return ""
+}
+
+var messageProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil)), "MessageType")
+var nestedProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.DescriptorProto)(nil)), "NestedType")
+var packageProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil)), "Package")
+var serviceProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil)), "Service")
+var methodProtoPath = protoPathIndex(reflect.TypeOf((*pbdescriptor.ServiceDescriptorProto)(nil)), "Method")
+
+func isProtoPathMatches(paths []int32, outerPaths []int32, typeName string, typeIndex int32, fieldPaths []int32) bool {
+ if typeName == "Package" && typeIndex == packageProtoPath {
+ // path for package comments is just [2], and all the other processing
+ // is too complex for it.
+ if len(paths) == 0 || typeIndex != paths[0] {
+ return false
+ }
+ return true
+ }
+
+ if len(paths) != len(outerPaths)*2+2+len(fieldPaths) {
+ return false
+ }
+
+ if typeName == "Method" {
+ if paths[0] != serviceProtoPath || paths[2] != methodProtoPath {
+ return false
+ }
+ paths = paths[2:]
+ } else {
+ typeNameDescriptor := reflect.TypeOf((*pbdescriptor.FileDescriptorProto)(nil))
+
+ if len(outerPaths) > 0 {
+ if paths[0] != messageProtoPath || paths[1] != outerPaths[0] {
+ return false
+ }
+ paths = paths[2:]
+ outerPaths = outerPaths[1:]
+
+ for i, v := range outerPaths {
+ if paths[i*2] != nestedProtoPath || paths[i*2+1] != v {
+ return false
+ }
+ }
+ paths = paths[len(outerPaths)*2:]
+
+ if typeName == "MessageType" {
+ typeName = "NestedType"
+ }
+ typeNameDescriptor = reflect.TypeOf((*pbdescriptor.DescriptorProto)(nil))
+ }
+
+ if paths[0] != protoPathIndex(typeNameDescriptor, typeName) || paths[1] != typeIndex {
+ return false
+ }
+ paths = paths[2:]
+ }
+
+ for i, v := range fieldPaths {
+ if paths[i] != v {
+ return false
+ }
+ }
+ return true
+}
+
+// protoPathIndex returns a path component for google.protobuf.descriptor.SourceCode_Location.
+//
+// Specifically, it returns an id as generated from descriptor proto which
+// can be used to determine what type the id following it in the path is.
+// For example, if we are trying to locate comments related to a field named
+// `Address` in a message named `Person`, the path will be:
+//
+// [4, a, 2, b]
+//
+// While `a` gets determined by the order in which the messages appear in
+// the proto file, and `b` is the field index specified in the proto
+// file itself, the path actually needs to specify that `a` refers to a
+// message and not, say, a service; and that `b` refers to a field and not
+// an option.
+//
+// protoPathIndex figures out the values 4 and 2 in the above example. Because
+// messages are top level objects, the value of 4 comes from field id for
+// `MessageType` inside `google.protobuf.descriptor.FileDescriptor` message.
+// This field has a message type `google.protobuf.descriptor.DescriptorProto`.
+// And inside message `DescriptorProto`, there is a field named `Field` with id
+// 2.
+//
+// Some code generators seem to be hardcoding these values; this method instead
+// interprets them from `descriptor.proto`-derived Go source as necessary.
+func protoPathIndex(descriptorType reflect.Type, what string) int32 {
+ field, ok := descriptorType.Elem().FieldByName(what)
+ if !ok {
+ panic(fmt.Errorf("could not find protobuf descriptor type id for %s", what))
+ }
+ pbtag := field.Tag.Get("protobuf")
+ if pbtag == "" {
+ panic(fmt.Errorf("no Go tag 'protobuf' on protobuf descriptor for %s", what))
+ }
+ path, err := strconv.Atoi(strings.Split(pbtag, ",")[1])
+ if err != nil {
+ panic(fmt.Errorf("protobuf descriptor id for %s cannot be converted to a number: %s", what, err.Error()))
+ }
+
+ return int32(path)
+}
+
+// extractOperationOptionFromMethodDescriptor extracts the message of type
+// swagger_options.Operation from a given proto method's descriptor.
+func extractOperationOptionFromMethodDescriptor(meth *pbdescriptor.MethodDescriptorProto) (*swagger_options.Operation, error) {
+ if meth.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(meth.Options, swagger_options.E_Openapiv2Operation) {
+ return nil, nil
+ }
+ ext, err := proto.GetExtension(meth.Options, swagger_options.E_Openapiv2Operation)
+ if err != nil {
+ return nil, err
+ }
+ opts, ok := ext.(*swagger_options.Operation)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want an Operation", ext)
+ }
+ return opts, nil
+}
+
+// extractSchemaOptionFromMessageDescriptor extracts the message of type
+// swagger_options.Schema from a given proto message's descriptor.
+func extractSchemaOptionFromMessageDescriptor(msg *pbdescriptor.DescriptorProto) (*swagger_options.Schema, error) {
+ if msg.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(msg.Options, swagger_options.E_Openapiv2Schema) {
+ return nil, nil
+ }
+ ext, err := proto.GetExtension(msg.Options, swagger_options.E_Openapiv2Schema)
+ if err != nil {
+ return nil, err
+ }
+ opts, ok := ext.(*swagger_options.Schema)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want a Schema", ext)
+ }
+ return opts, nil
+}
+
+// extractSwaggerOptionFromFileDescriptor extracts the message of type
+// swagger_options.Swagger from a given proto method's descriptor.
+func extractSwaggerOptionFromFileDescriptor(file *pbdescriptor.FileDescriptorProto) (*swagger_options.Swagger, error) {
+ if file.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(file.Options, swagger_options.E_Openapiv2Swagger) {
+ return nil, nil
+ }
+ ext, err := proto.GetExtension(file.Options, swagger_options.E_Openapiv2Swagger)
+ if err != nil {
+ return nil, err
+ }
+ opts, ok := ext.(*swagger_options.Swagger)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want a Swagger object", ext)
+ }
+ return opts, nil
+}
+
+func extractJSONSchemaFromFieldDescriptor(fd *pbdescriptor.FieldDescriptorProto) (*swagger_options.JSONSchema, error) {
+ if fd.Options == nil {
+ return nil, nil
+ }
+ if !proto.HasExtension(fd.Options, swagger_options.E_Openapiv2Field) {
+ return nil, nil
+ }
+ ext, err := proto.GetExtension(fd.Options, swagger_options.E_Openapiv2Field)
+ if err != nil {
+ return nil, err
+ }
+ opts, ok := ext.(*swagger_options.JSONSchema)
+ if !ok {
+ return nil, fmt.Errorf("extension is %T; want a JSONSchema object", ext)
+ }
+ return opts, nil
+}
+
+func protoJSONSchemaToSwaggerSchemaCore(j *swagger_options.JSONSchema, reg *descriptor.Registry, refs refMap) schemaCore {
+ ret := schemaCore{}
+
+ if j.GetRef() != "" {
+ swaggerName := fullyQualifiedNameToSwaggerName(j.GetRef(), reg)
+ if swaggerName != "" {
+ ret.Ref = "#/definitions/" + swaggerName
+ if refs != nil {
+ refs[j.GetRef()] = struct{}{}
+ }
+ } else {
+ ret.Ref += j.GetRef()
+ }
+ } else {
+ f, t := protoJSONSchemaTypeToFormat(j.GetType())
+ ret.Format = f
+ ret.Type = t
+ }
+
+ return ret
+}
+
+func updateSwaggerObjectFromJSONSchema(s *swaggerSchemaObject, j *swagger_options.JSONSchema) {
+ s.Title = j.GetTitle()
+ s.Description = j.GetDescription()
+ s.ReadOnly = j.GetReadOnly()
+ s.MultipleOf = j.GetMultipleOf()
+ s.Maximum = j.GetMaximum()
+ s.ExclusiveMaximum = j.GetExclusiveMaximum()
+ s.Minimum = j.GetMinimum()
+ s.ExclusiveMinimum = j.GetExclusiveMinimum()
+ s.MaxLength = j.GetMaxLength()
+ s.MinLength = j.GetMinLength()
+ s.Pattern = j.GetPattern()
+ s.Default = j.GetDefault()
+ s.MaxItems = j.GetMaxItems()
+ s.MinItems = j.GetMinItems()
+ s.UniqueItems = j.GetUniqueItems()
+ s.MaxProperties = j.GetMaxProperties()
+ s.MinProperties = j.GetMinProperties()
+ s.Required = j.GetRequired()
+ if overrideType := j.GetType(); len(overrideType) > 0 {
+ s.Type = strings.ToLower(overrideType[0].String())
+ }
+}
+
+func swaggerSchemaFromProtoSchema(s *swagger_options.Schema, reg *descriptor.Registry, refs refMap) swaggerSchemaObject {
+ ret := swaggerSchemaObject{
+ ExternalDocs: protoExternalDocumentationToSwaggerExternalDocumentation(s.GetExternalDocs()),
+ }
+
+ ret.schemaCore = protoJSONSchemaToSwaggerSchemaCore(s.GetJsonSchema(), reg, refs)
+ updateSwaggerObjectFromJSONSchema(&ret, s.GetJsonSchema())
+
+ if s != nil && s.Example != nil {
+ ret.Example = json.RawMessage(s.Example.Value)
+ }
+
+ return ret
+}
+
+func protoJSONSchemaTypeToFormat(in []swagger_options.JSONSchema_JSONSchemaSimpleTypes) (string, string) {
+ if len(in) == 0 {
+ return "", ""
+ }
+
+ // Can't support more than 1 type, just return the first element.
+ // This is due to an inconsistency in the design of the openapiv2 proto
+ // and that used in schemaCore. schemaCore uses the v3 definition of types,
+ // which only allows a single string, while the openapiv2 proto uses the OpenAPI v2
+ // definition, which defers to the JSON schema definition, which allows a string or an array.
+ // Sources:
+ // https://swagger.io/specification/#itemsObject
+ // https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.2
+ switch in[0] {
+ case swagger_options.JSONSchema_UNKNOWN, swagger_options.JSONSchema_NULL:
+ return "", ""
+ case swagger_options.JSONSchema_OBJECT:
+ return "object", ""
+ case swagger_options.JSONSchema_ARRAY:
+ return "array", ""
+ case swagger_options.JSONSchema_BOOLEAN:
+ return "boolean", "boolean"
+ case swagger_options.JSONSchema_INTEGER:
+ return "integer", "int32"
+ case swagger_options.JSONSchema_NUMBER:
+ return "number", "double"
+ case swagger_options.JSONSchema_STRING:
+ // NOTE: in swagger specifition, format should be empty on string type
+ return "string", ""
+ default:
+ // Maybe panic?
+ return "", ""
+ }
+}
+
+func protoExternalDocumentationToSwaggerExternalDocumentation(in *swagger_options.ExternalDocumentation) *swaggerExternalDocumentationObject {
+ if in == nil {
+ return nil
+ }
+
+ return &swaggerExternalDocumentationObject{
+ Description: in.Description,
+ URL: in.Url,
+ }
+}
+
+func addCustomRefs(d swaggerDefinitionsObject, reg *descriptor.Registry, refs refMap) {
+ if len(refs) == 0 {
+ return
+ }
+ msgMap := make(messageMap)
+ enumMap := make(enumMap)
+ for ref := range refs {
+ if _, ok := d[fullyQualifiedNameToSwaggerName(ref, reg)]; ok {
+ // Skip already existing definitions
+ delete(refs, ref)
+ continue
+ }
+ msg, err := reg.LookupMsg("", ref)
+ if err == nil {
+ msgMap[fullyQualifiedNameToSwaggerName(ref, reg)] = msg
+ continue
+ }
+ enum, err := reg.LookupEnum("", ref)
+ if err == nil {
+ enumMap[fullyQualifiedNameToSwaggerName(ref, reg)] = enum
+ continue
+ }
+
+ // ?? Should be either enum or msg
+ }
+ renderMessagesAsDefinition(msgMap, d, reg, refs)
+ renderEnumerationsAsDefinition(enumMap, d, reg)
+
+ // Run again in case any new refs were added
+ addCustomRefs(d, reg, refs)
+}
+
+func lowerCamelCase(parameter string) string {
+ parameterString := gogen.CamelCase(parameter)
+ builder := &strings.Builder{}
+ builder.WriteString(strings.ToLower(string(parameterString[0])))
+ builder.WriteString(parameterString[1:])
+ return builder.String()
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/types.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/types.go
new file mode 100644
index 0000000..77db96d
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/types.go
@@ -0,0 +1,254 @@
+package genswagger
+
+import (
+ "bytes"
+ "encoding/json"
+
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
+)
+
+type param struct {
+ *descriptor.File
+ reg *descriptor.Registry
+}
+
+type binding struct {
+ *descriptor.Binding
+}
+
+// http://swagger.io/specification/#infoObject
+type swaggerInfoObject struct {
+ Title string `json:"title"`
+ Description string `json:"description,omitempty"`
+ TermsOfService string `json:"termsOfService,omitempty"`
+ Version string `json:"version"`
+
+ Contact *swaggerContactObject `json:"contact,omitempty"`
+ License *swaggerLicenseObject `json:"license,omitempty"`
+
+ extensions []extension
+}
+
+// http://swagger.io/specification/#contactObject
+type swaggerContactObject struct {
+ Name string `json:"name,omitempty"`
+ URL string `json:"url,omitempty"`
+ Email string `json:"email,omitempty"`
+}
+
+// http://swagger.io/specification/#licenseObject
+type swaggerLicenseObject struct {
+ Name string `json:"name,omitempty"`
+ URL string `json:"url,omitempty"`
+}
+
+// http://swagger.io/specification/#externalDocumentationObject
+type swaggerExternalDocumentationObject struct {
+ Description string `json:"description,omitempty"`
+ URL string `json:"url,omitempty"`
+}
+
+type extension struct {
+ key string
+ value json.RawMessage
+}
+
+// http://swagger.io/specification/#swaggerObject
+type swaggerObject struct {
+ Swagger string `json:"swagger"`
+ Info swaggerInfoObject `json:"info"`
+ Host string `json:"host,omitempty"`
+ BasePath string `json:"basePath,omitempty"`
+ Schemes []string `json:"schemes"`
+ Consumes []string `json:"consumes"`
+ Produces []string `json:"produces"`
+ Paths swaggerPathsObject `json:"paths"`
+ Definitions swaggerDefinitionsObject `json:"definitions"`
+ StreamDefinitions swaggerDefinitionsObject `json:"x-stream-definitions,omitempty"`
+ SecurityDefinitions swaggerSecurityDefinitionsObject `json:"securityDefinitions,omitempty"`
+ Security []swaggerSecurityRequirementObject `json:"security,omitempty"`
+ ExternalDocs *swaggerExternalDocumentationObject `json:"externalDocs,omitempty"`
+
+ extensions []extension
+}
+
+// http://swagger.io/specification/#securityDefinitionsObject
+type swaggerSecurityDefinitionsObject map[string]swaggerSecuritySchemeObject
+
+// http://swagger.io/specification/#securitySchemeObject
+type swaggerSecuritySchemeObject struct {
+ Type string `json:"type"`
+ Description string `json:"description,omitempty"`
+ Name string `json:"name,omitempty"`
+ In string `json:"in,omitempty"`
+ Flow string `json:"flow,omitempty"`
+ AuthorizationURL string `json:"authorizationUrl,omitempty"`
+ TokenURL string `json:"tokenUrl,omitempty"`
+ Scopes swaggerScopesObject `json:"scopes,omitempty"`
+
+ extensions []extension
+}
+
+// http://swagger.io/specification/#scopesObject
+type swaggerScopesObject map[string]string
+
+// http://swagger.io/specification/#securityRequirementObject
+type swaggerSecurityRequirementObject map[string][]string
+
+// http://swagger.io/specification/#pathsObject
+type swaggerPathsObject map[string]swaggerPathItemObject
+
+// http://swagger.io/specification/#pathItemObject
+type swaggerPathItemObject struct {
+ Get *swaggerOperationObject `json:"get,omitempty"`
+ Delete *swaggerOperationObject `json:"delete,omitempty"`
+ Post *swaggerOperationObject `json:"post,omitempty"`
+ Put *swaggerOperationObject `json:"put,omitempty"`
+ Patch *swaggerOperationObject `json:"patch,omitempty"`
+}
+
+// http://swagger.io/specification/#operationObject
+type swaggerOperationObject struct {
+ Summary string `json:"summary,omitempty"`
+ Description string `json:"description,omitempty"`
+ OperationID string `json:"operationId"`
+ Responses swaggerResponsesObject `json:"responses"`
+ Parameters swaggerParametersObject `json:"parameters,omitempty"`
+ Tags []string `json:"tags,omitempty"`
+ Deprecated bool `json:"deprecated,omitempty"`
+
+ Security *[]swaggerSecurityRequirementObject `json:"security,omitempty"`
+ ExternalDocs *swaggerExternalDocumentationObject `json:"externalDocs,omitempty"`
+
+ extensions []extension
+}
+
+type swaggerParametersObject []swaggerParameterObject
+
+// http://swagger.io/specification/#parameterObject
+type swaggerParameterObject struct {
+ Name string `json:"name"`
+ Description string `json:"description,omitempty"`
+ In string `json:"in,omitempty"`
+ Required bool `json:"required"`
+ Type string `json:"type,omitempty"`
+ Format string `json:"format,omitempty"`
+ Items *swaggerItemsObject `json:"items,omitempty"`
+ Enum []string `json:"enum,omitempty"`
+ CollectionFormat string `json:"collectionFormat,omitempty"`
+ Default string `json:"default,omitempty"`
+ MinItems *int `json:"minItems,omitempty"`
+
+ // Or you can explicitly refer to another type. If this is defined all
+ // other fields should be empty
+ Schema *swaggerSchemaObject `json:"schema,omitempty"`
+}
+
+// core part of schema, which is common to itemsObject and schemaObject.
+// http://swagger.io/specification/#itemsObject
+type schemaCore struct {
+ Type string `json:"type,omitempty"`
+ Format string `json:"format,omitempty"`
+ Ref string `json:"$ref,omitempty"`
+ Example json.RawMessage `json:"example,omitempty"`
+
+ Items *swaggerItemsObject `json:"items,omitempty"`
+
+ // If the item is an enumeration include a list of all the *NAMES* of the
+ // enum values. I'm not sure how well this will work but assuming all enums
+ // start from 0 index it will be great. I don't think that is a good assumption.
+ Enum []string `json:"enum,omitempty"`
+ Default string `json:"default,omitempty"`
+}
+
+type swaggerItemsObject schemaCore
+
+// http://swagger.io/specification/#responsesObject
+type swaggerResponsesObject map[string]swaggerResponseObject
+
+// http://swagger.io/specification/#responseObject
+type swaggerResponseObject struct {
+ Description string `json:"description"`
+ Schema swaggerSchemaObject `json:"schema"`
+
+ extensions []extension
+}
+
+type keyVal struct {
+ Key string
+ Value interface{}
+}
+
+type swaggerSchemaObjectProperties []keyVal
+
+func (op swaggerSchemaObjectProperties) MarshalJSON() ([]byte, error) {
+ var buf bytes.Buffer
+ buf.WriteString("{")
+ for i, kv := range op {
+ if i != 0 {
+ buf.WriteString(",")
+ }
+ key, err := json.Marshal(kv.Key)
+ if err != nil {
+ return nil, err
+ }
+ buf.Write(key)
+ buf.WriteString(":")
+ val, err := json.Marshal(kv.Value)
+ if err != nil {
+ return nil, err
+ }
+ buf.Write(val)
+ }
+
+ buf.WriteString("}")
+ return buf.Bytes(), nil
+}
+
+// http://swagger.io/specification/#schemaObject
+type swaggerSchemaObject struct {
+ schemaCore
+ // Properties can be recursively defined
+ Properties *swaggerSchemaObjectProperties `json:"properties,omitempty"`
+ AdditionalProperties *swaggerSchemaObject `json:"additionalProperties,omitempty"`
+
+ Description string `json:"description,omitempty"`
+ Title string `json:"title,omitempty"`
+
+ ExternalDocs *swaggerExternalDocumentationObject `json:"externalDocs,omitempty"`
+
+ ReadOnly bool `json:"readOnly,omitempty"`
+ MultipleOf float64 `json:"multipleOf,omitempty"`
+ Maximum float64 `json:"maximum,omitempty"`
+ ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"`
+ Minimum float64 `json:"minimum,omitempty"`
+ ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"`
+ MaxLength uint64 `json:"maxLength,omitempty"`
+ MinLength uint64 `json:"minLength,omitempty"`
+ Pattern string `json:"pattern,omitempty"`
+ MaxItems uint64 `json:"maxItems,omitempty"`
+ MinItems uint64 `json:"minItems,omitempty"`
+ UniqueItems bool `json:"uniqueItems,omitempty"`
+ MaxProperties uint64 `json:"maxProperties,omitempty"`
+ MinProperties uint64 `json:"minProperties,omitempty"`
+ Required []string `json:"required,omitempty"`
+}
+
+// http://swagger.io/specification/#referenceObject
+type swaggerReferenceObject struct {
+ Ref string `json:"$ref"`
+}
+
+// http://swagger.io/specification/#definitionsObject
+type swaggerDefinitionsObject map[string]swaggerSchemaObject
+
+// Internal type mapping from FQMN to descriptor.Message. Used as a set by the
+// findServiceMessages function.
+type messageMap map[string]*descriptor.Message
+
+// Internal type mapping from FQEN to descriptor.Enum. Used as a set by the
+// findServiceMessages function.
+type enumMap map[string]*descriptor.Enum
+
+// Internal type to store used references.
+type refMap map[string]struct{}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/main.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/main.go
new file mode 100644
index 0000000..237e460
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/main.go
@@ -0,0 +1,198 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/golang/glog"
+ "github.com/golang/protobuf/proto"
+ plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
+ "github.com/grpc-ecosystem/grpc-gateway/codegenerator"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
+ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger"
+)
+
+var (
+ importPrefix = flag.String("import_prefix", "", "prefix to be added to go package paths for imported proto files")
+ file = flag.String("file", "-", "where to load data from")
+ allowDeleteBody = flag.Bool("allow_delete_body", false, "unless set, HTTP DELETE methods may not have a body")
+ grpcAPIConfiguration = flag.String("grpc_api_configuration", "", "path to gRPC API Configuration in YAML format")
+ allowMerge = flag.Bool("allow_merge", false, "if set, generation one swagger file out of multiple protos")
+ mergeFileName = flag.String("merge_file_name", "apidocs", "target swagger file name prefix after merge")
+ useJSONNamesForFields = flag.Bool("json_names_for_fields", false, "if it sets Field.GetJsonName() will be used for generating swagger definitions, otherwise Field.GetName() will be used")
+ repeatedPathParamSeparator = flag.String("repeated_path_param_separator", "csv", "configures how repeated fields should be split. Allowed values are `csv`, `pipes`, `ssv` and `tsv`.")
+ versionFlag = flag.Bool("version", false, "print the current verison")
+ allowRepeatedFieldsInBody = flag.Bool("allow_repeated_fields_in_body", false, "allows to use repeated field in `body` and `response_body` field of `google.api.http` annotation option")
+ includePackageInTags = flag.Bool("include_package_in_tags", false, "if unset, the gRPC service name is added to the `Tags` field of each operation. if set and the `package` directive is shown in the proto file, the package name will be prepended to the service name")
+ useFQNForSwaggerName = flag.Bool("fqn_for_swagger_name", false, "if set, the object's swagger names will use the fully qualify name from the proto definition (ie my.package.MyMessage.MyInnerMessage")
+)
+
+// Variables set by goreleaser at build time
+var (
+ version = "dev"
+ commit = "unknown"
+ date = "unknown"
+)
+
+func main() {
+ flag.Parse()
+ defer glog.Flush()
+
+ if *versionFlag {
+ fmt.Printf("Version %v, commit %v, built at %v\n", version, commit, date)
+ os.Exit(0)
+ }
+
+ reg := descriptor.NewRegistry()
+
+ glog.V(1).Info("Processing code generator request")
+ f := os.Stdin
+ if *file != "-" {
+ var err error
+ f, err = os.Open(*file)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ }
+ glog.V(1).Info("Parsing code generator request")
+ req, err := codegenerator.ParseRequest(f)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ glog.V(1).Info("Parsed code generator request")
+ pkgMap := make(map[string]string)
+ if req.Parameter != nil {
+ err := parseReqParam(req.GetParameter(), flag.CommandLine, pkgMap)
+ if err != nil {
+ glog.Fatalf("Error parsing flags: %v", err)
+ }
+ }
+
+ reg.SetPrefix(*importPrefix)
+ reg.SetAllowDeleteBody(*allowDeleteBody)
+ reg.SetAllowMerge(*allowMerge)
+ reg.SetMergeFileName(*mergeFileName)
+ reg.SetUseJSONNamesForFields(*useJSONNamesForFields)
+ reg.SetAllowRepeatedFieldsInBody(*allowRepeatedFieldsInBody)
+ reg.SetIncludePackageInTags(*includePackageInTags)
+ reg.SetUseFQNForSwaggerName(*useFQNForSwaggerName)
+ if err := reg.SetRepeatedPathParamSeparator(*repeatedPathParamSeparator); err != nil {
+ emitError(err)
+ return
+ }
+ for k, v := range pkgMap {
+ reg.AddPkgMap(k, v)
+ }
+
+ if *grpcAPIConfiguration != "" {
+ if err := reg.LoadGrpcAPIServiceFromYAML(*grpcAPIConfiguration); err != nil {
+ emitError(err)
+ return
+ }
+ }
+
+ g := genswagger.New(reg)
+
+ if err := genswagger.AddStreamError(reg); err != nil {
+ emitError(err)
+ return
+ }
+
+ if err := reg.Load(req); err != nil {
+ emitError(err)
+ return
+ }
+
+ var targets []*descriptor.File
+ for _, target := range req.FileToGenerate {
+ f, err := reg.LookupFile(target)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ targets = append(targets, f)
+ }
+
+ out, err := g.Generate(targets)
+ glog.V(1).Info("Processed code generator request")
+ if err != nil {
+ emitError(err)
+ return
+ }
+ emitFiles(out)
+}
+
+func emitFiles(out []*plugin.CodeGeneratorResponse_File) {
+ emitResp(&plugin.CodeGeneratorResponse{File: out})
+}
+
+func emitError(err error) {
+ emitResp(&plugin.CodeGeneratorResponse{Error: proto.String(err.Error())})
+}
+
+func emitResp(resp *plugin.CodeGeneratorResponse) {
+ buf, err := proto.Marshal(resp)
+ if err != nil {
+ glog.Fatal(err)
+ }
+ if _, err := os.Stdout.Write(buf); err != nil {
+ glog.Fatal(err)
+ }
+}
+
+// parseReqParam parses a CodeGeneratorRequest parameter and adds the
+// extracted values to the given FlagSet and pkgMap. Returns a non-nil
+// error if setting a flag failed.
+func parseReqParam(param string, f *flag.FlagSet, pkgMap map[string]string) error {
+ if param == "" {
+ return nil
+ }
+ for _, p := range strings.Split(param, ",") {
+ spec := strings.SplitN(p, "=", 2)
+ if len(spec) == 1 {
+ if spec[0] == "allow_delete_body" {
+ err := f.Set(spec[0], "true")
+ if err != nil {
+ return fmt.Errorf("Cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ if spec[0] == "allow_merge" {
+ err := f.Set(spec[0], "true")
+ if err != nil {
+ return fmt.Errorf("Cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ if spec[0] == "allow_repeated_fields_in_body" {
+ err := f.Set(spec[0], "true")
+ if err != nil {
+ return fmt.Errorf("Cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ if spec[0] == "include_package_in_tags" {
+ err := f.Set(spec[0], "true")
+ if err != nil {
+ return fmt.Errorf("Cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ err := f.Set(spec[0], "")
+ if err != nil {
+ return fmt.Errorf("Cannot set flag %s: %v", p, err)
+ }
+ continue
+ }
+ name, value := spec[0], spec[1]
+ if strings.HasPrefix(name, "M") {
+ pkgMap[name[1:]] = value
+ continue
+ }
+ if err := f.Set(name, value); err != nil {
+ return fmt.Errorf("Cannot set flag %s: %v", p, err)
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/BUILD.bazel
new file mode 100644
index 0000000..8dea43d
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/BUILD.bazel
@@ -0,0 +1,38 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+ name = "options_proto_files",
+ srcs = [
+ "annotations.proto",
+ "openapiv2.proto",
+ ],
+)
+
+go_library(
+ name = "go_default_library",
+ embed = [":options_go_proto"],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options",
+)
+
+proto_library(
+ name = "options_proto",
+ srcs = [
+ "annotations.proto",
+ "openapiv2.proto",
+ ],
+ deps = [
+ "@com_google_protobuf//:any_proto",
+ "@com_google_protobuf//:descriptor_proto",
+ "@com_google_protobuf//:struct_proto",
+ ],
+)
+
+go_proto_library(
+ name = "options_go_proto",
+ compilers = ["@io_bazel_rules_go//proto:go_grpc"],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options",
+ proto = ":options_proto",
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/annotations.pb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/annotations.pb.go
new file mode 100644
index 0000000..9fc282b
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/annotations.pb.go
@@ -0,0 +1,103 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: protoc-gen-swagger/options/annotations.proto
+
+package options // import "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+var E_Openapiv2Swagger = &proto.ExtensionDesc{
+ ExtendedType: (*descriptor.FileOptions)(nil),
+ ExtensionType: (*Swagger)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger",
+ Tag: "bytes,1042,opt,name=openapiv2_swagger,json=openapiv2Swagger",
+ Filename: "protoc-gen-swagger/options/annotations.proto",
+}
+
+var E_Openapiv2Operation = &proto.ExtensionDesc{
+ ExtendedType: (*descriptor.MethodOptions)(nil),
+ ExtensionType: (*Operation)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_operation",
+ Tag: "bytes,1042,opt,name=openapiv2_operation,json=openapiv2Operation",
+ Filename: "protoc-gen-swagger/options/annotations.proto",
+}
+
+var E_Openapiv2Schema = &proto.ExtensionDesc{
+ ExtendedType: (*descriptor.MessageOptions)(nil),
+ ExtensionType: (*Schema)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_schema",
+ Tag: "bytes,1042,opt,name=openapiv2_schema,json=openapiv2Schema",
+ Filename: "protoc-gen-swagger/options/annotations.proto",
+}
+
+var E_Openapiv2Tag = &proto.ExtensionDesc{
+ ExtendedType: (*descriptor.ServiceOptions)(nil),
+ ExtensionType: (*Tag)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_tag",
+ Tag: "bytes,1042,opt,name=openapiv2_tag,json=openapiv2Tag",
+ Filename: "protoc-gen-swagger/options/annotations.proto",
+}
+
+var E_Openapiv2Field = &proto.ExtensionDesc{
+ ExtendedType: (*descriptor.FieldOptions)(nil),
+ ExtensionType: (*JSONSchema)(nil),
+ Field: 1042,
+ Name: "grpc.gateway.protoc_gen_swagger.options.openapiv2_field",
+ Tag: "bytes,1042,opt,name=openapiv2_field,json=openapiv2Field",
+ Filename: "protoc-gen-swagger/options/annotations.proto",
+}
+
+func init() {
+ proto.RegisterExtension(E_Openapiv2Swagger)
+ proto.RegisterExtension(E_Openapiv2Operation)
+ proto.RegisterExtension(E_Openapiv2Schema)
+ proto.RegisterExtension(E_Openapiv2Tag)
+ proto.RegisterExtension(E_Openapiv2Field)
+}
+
+func init() {
+ proto.RegisterFile("protoc-gen-swagger/options/annotations.proto", fileDescriptor_annotations_8378bd63c2853a5a)
+}
+
+var fileDescriptor_annotations_8378bd63c2853a5a = []byte{
+ // 346 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x4f, 0x4f, 0xea, 0x40,
+ 0x14, 0xc5, 0xc3, 0xe6, 0xe5, 0xa5, 0xef, 0xa9, 0x58, 0x37, 0x86, 0xf8, 0x87, 0x9d, 0xc6, 0xc0,
+ 0x8c, 0x81, 0x5d, 0x77, 0x6a, 0xe2, 0xc2, 0x44, 0x49, 0x0a, 0x2b, 0x37, 0x64, 0x18, 0x2e, 0x97,
+ 0x49, 0x4a, 0xef, 0x64, 0x66, 0x80, 0x90, 0xb0, 0xf4, 0x13, 0xf8, 0x89, 0x8d, 0xd3, 0xd2, 0x9a,
+ 0x8a, 0xa6, 0xbb, 0xde, 0xdb, 0x39, 0xe7, 0x77, 0x7a, 0x3a, 0x41, 0x47, 0x1b, 0x72, 0x24, 0xbb,
+ 0x08, 0x69, 0xd7, 0xae, 0x05, 0x22, 0x18, 0x4e, 0xda, 0x29, 0x4a, 0x2d, 0x17, 0x69, 0x4a, 0x4e,
+ 0xf8, 0x67, 0xe6, 0x8f, 0x85, 0x57, 0x68, 0xb4, 0x64, 0x28, 0x1c, 0xac, 0xc5, 0x26, 0xdb, 0xc9,
+ 0x31, 0x42, 0x3a, 0xce, 0xa5, 0x2c, 0x97, 0xb6, 0x6e, 0x7e, 0xb1, 0x25, 0x0d, 0xa9, 0xd0, 0x6a,
+ 0xd5, 0xcb, 0x0c, 0x5a, 0x6d, 0x24, 0xc2, 0x04, 0xb8, 0x9f, 0x26, 0xcb, 0x19, 0x9f, 0x82, 0x95,
+ 0x46, 0x69, 0x47, 0x26, 0x3b, 0x11, 0x6d, 0x83, 0xe3, 0x42, 0xb4, 0x43, 0x85, 0x67, 0x2c, 0xd3,
+ 0xb1, 0x9d, 0x8e, 0x3d, 0xaa, 0x04, 0x06, 0x19, 0xe4, 0xf4, 0xfd, 0x6f, 0xbb, 0x71, 0xfd, 0xaf,
+ 0x77, 0xcb, 0x6a, 0x26, 0x66, 0xc3, 0x6c, 0x8e, 0x9b, 0x05, 0x29, 0xdf, 0x44, 0x6f, 0x8d, 0xe0,
+ 0xa4, 0xc4, 0x93, 0x06, 0xe3, 0x3b, 0x09, 0x2f, 0xbe, 0x05, 0x78, 0x06, 0x37, 0xa7, 0x69, 0x25,
+ 0x42, 0xaf, 0x76, 0x84, 0xc1, 0xce, 0x3a, 0x0e, 0x0b, 0x5e, 0xb1, 0x8b, 0xb6, 0x41, 0xf3, 0x4b,
+ 0x09, 0x72, 0x0e, 0x0b, 0x11, 0x5e, 0xee, 0x89, 0x60, 0xad, 0xc0, 0x6a, 0x0d, 0xbc, 0x7e, 0x0d,
+ 0xde, 0x38, 0x3e, 0x2a, 0x5b, 0xf0, 0x8b, 0xc8, 0x06, 0x07, 0x25, 0xdd, 0x09, 0xdc, 0x83, 0x1e,
+ 0x82, 0x59, 0x29, 0x59, 0x45, 0x77, 0x6a, 0xa3, 0x47, 0x02, 0xe3, 0xff, 0x05, 0x64, 0x24, 0x30,
+ 0xda, 0x06, 0x65, 0x8e, 0xf1, 0x4c, 0x41, 0x32, 0x0d, 0xcf, 0xf7, 0xfc, 0x75, 0x48, 0xaa, 0x9d,
+ 0xf7, 0x6b, 0x43, 0x9f, 0x86, 0x83, 0x97, 0xfc, 0x9b, 0x0f, 0x0b, 0x96, 0xb7, 0xbc, 0x7f, 0x78,
+ 0xbd, 0x43, 0xe5, 0xe6, 0xcb, 0x09, 0x93, 0xb4, 0xe0, 0x9f, 0x86, 0x5d, 0x90, 0x64, 0x37, 0xd6,
+ 0x41, 0x3e, 0xe6, 0xfe, 0xfc, 0xe7, 0xcb, 0x3e, 0xf9, 0xe3, 0xdf, 0xf5, 0x3f, 0x02, 0x00, 0x00,
+ 0xff, 0xff, 0x4b, 0xc4, 0x41, 0xfb, 0x68, 0x03, 0x00, 0x00,
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/annotations.proto b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/annotations.proto
new file mode 100644
index 0000000..2c0f594
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/annotations.proto
@@ -0,0 +1,44 @@
+syntax = "proto3";
+
+package grpc.gateway.protoc_gen_swagger.options;
+
+option go_package = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options";
+
+import "protoc-gen-swagger/options/openapiv2.proto";
+import "google/protobuf/descriptor.proto";
+
+extend google.protobuf.FileOptions {
+ // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ //
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
+ // different descriptor messages.
+ Swagger openapiv2_swagger = 1042;
+}
+extend google.protobuf.MethodOptions {
+ // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ //
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
+ // different descriptor messages.
+ Operation openapiv2_operation = 1042;
+}
+extend google.protobuf.MessageOptions {
+ // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ //
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
+ // different descriptor messages.
+ Schema openapiv2_schema = 1042;
+}
+extend google.protobuf.ServiceOptions {
+ // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ //
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
+ // different descriptor messages.
+ Tag openapiv2_tag = 1042;
+}
+extend google.protobuf.FieldOptions {
+ // ID assigned by protobuf-global-extension-registry@google.com for grpc-gateway project.
+ //
+ // All IDs are the same, as assigned. It is okay that they are the same, as they extend
+ // different descriptor messages.
+ JSONSchema openapiv2_field = 1042;
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/openapiv2.pb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/openapiv2.pb.go
new file mode 100644
index 0000000..6720071
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/openapiv2.pb.go
@@ -0,0 +1,1598 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: protoc-gen-swagger/options/openapiv2.proto
+
+package options // import "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options"
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+import any "github.com/golang/protobuf/ptypes/any"
+import _struct "github.com/golang/protobuf/ptypes/struct"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+type Swagger_SwaggerScheme int32
+
+const (
+ Swagger_UNKNOWN Swagger_SwaggerScheme = 0
+ Swagger_HTTP Swagger_SwaggerScheme = 1
+ Swagger_HTTPS Swagger_SwaggerScheme = 2
+ Swagger_WS Swagger_SwaggerScheme = 3
+ Swagger_WSS Swagger_SwaggerScheme = 4
+)
+
+var Swagger_SwaggerScheme_name = map[int32]string{
+ 0: "UNKNOWN",
+ 1: "HTTP",
+ 2: "HTTPS",
+ 3: "WS",
+ 4: "WSS",
+}
+var Swagger_SwaggerScheme_value = map[string]int32{
+ "UNKNOWN": 0,
+ "HTTP": 1,
+ "HTTPS": 2,
+ "WS": 3,
+ "WSS": 4,
+}
+
+func (x Swagger_SwaggerScheme) String() string {
+ return proto.EnumName(Swagger_SwaggerScheme_name, int32(x))
+}
+func (Swagger_SwaggerScheme) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{0, 0}
+}
+
+type JSONSchema_JSONSchemaSimpleTypes int32
+
+const (
+ JSONSchema_UNKNOWN JSONSchema_JSONSchemaSimpleTypes = 0
+ JSONSchema_ARRAY JSONSchema_JSONSchemaSimpleTypes = 1
+ JSONSchema_BOOLEAN JSONSchema_JSONSchemaSimpleTypes = 2
+ JSONSchema_INTEGER JSONSchema_JSONSchemaSimpleTypes = 3
+ JSONSchema_NULL JSONSchema_JSONSchemaSimpleTypes = 4
+ JSONSchema_NUMBER JSONSchema_JSONSchemaSimpleTypes = 5
+ JSONSchema_OBJECT JSONSchema_JSONSchemaSimpleTypes = 6
+ JSONSchema_STRING JSONSchema_JSONSchemaSimpleTypes = 7
+)
+
+var JSONSchema_JSONSchemaSimpleTypes_name = map[int32]string{
+ 0: "UNKNOWN",
+ 1: "ARRAY",
+ 2: "BOOLEAN",
+ 3: "INTEGER",
+ 4: "NULL",
+ 5: "NUMBER",
+ 6: "OBJECT",
+ 7: "STRING",
+}
+var JSONSchema_JSONSchemaSimpleTypes_value = map[string]int32{
+ "UNKNOWN": 0,
+ "ARRAY": 1,
+ "BOOLEAN": 2,
+ "INTEGER": 3,
+ "NULL": 4,
+ "NUMBER": 5,
+ "OBJECT": 6,
+ "STRING": 7,
+}
+
+func (x JSONSchema_JSONSchemaSimpleTypes) String() string {
+ return proto.EnumName(JSONSchema_JSONSchemaSimpleTypes_name, int32(x))
+}
+func (JSONSchema_JSONSchemaSimpleTypes) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{8, 0}
+}
+
+// Required. The type of the security scheme. Valid values are "basic",
+// "apiKey" or "oauth2".
+type SecurityScheme_Type int32
+
+const (
+ SecurityScheme_TYPE_INVALID SecurityScheme_Type = 0
+ SecurityScheme_TYPE_BASIC SecurityScheme_Type = 1
+ SecurityScheme_TYPE_API_KEY SecurityScheme_Type = 2
+ SecurityScheme_TYPE_OAUTH2 SecurityScheme_Type = 3
+)
+
+var SecurityScheme_Type_name = map[int32]string{
+ 0: "TYPE_INVALID",
+ 1: "TYPE_BASIC",
+ 2: "TYPE_API_KEY",
+ 3: "TYPE_OAUTH2",
+}
+var SecurityScheme_Type_value = map[string]int32{
+ "TYPE_INVALID": 0,
+ "TYPE_BASIC": 1,
+ "TYPE_API_KEY": 2,
+ "TYPE_OAUTH2": 3,
+}
+
+func (x SecurityScheme_Type) String() string {
+ return proto.EnumName(SecurityScheme_Type_name, int32(x))
+}
+func (SecurityScheme_Type) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{11, 0}
+}
+
+// Required. The location of the API key. Valid values are "query" or "header".
+type SecurityScheme_In int32
+
+const (
+ SecurityScheme_IN_INVALID SecurityScheme_In = 0
+ SecurityScheme_IN_QUERY SecurityScheme_In = 1
+ SecurityScheme_IN_HEADER SecurityScheme_In = 2
+)
+
+var SecurityScheme_In_name = map[int32]string{
+ 0: "IN_INVALID",
+ 1: "IN_QUERY",
+ 2: "IN_HEADER",
+}
+var SecurityScheme_In_value = map[string]int32{
+ "IN_INVALID": 0,
+ "IN_QUERY": 1,
+ "IN_HEADER": 2,
+}
+
+func (x SecurityScheme_In) String() string {
+ return proto.EnumName(SecurityScheme_In_name, int32(x))
+}
+func (SecurityScheme_In) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{11, 1}
+}
+
+// Required. The flow used by the OAuth2 security scheme. Valid values are
+// "implicit", "password", "application" or "accessCode".
+type SecurityScheme_Flow int32
+
+const (
+ SecurityScheme_FLOW_INVALID SecurityScheme_Flow = 0
+ SecurityScheme_FLOW_IMPLICIT SecurityScheme_Flow = 1
+ SecurityScheme_FLOW_PASSWORD SecurityScheme_Flow = 2
+ SecurityScheme_FLOW_APPLICATION SecurityScheme_Flow = 3
+ SecurityScheme_FLOW_ACCESS_CODE SecurityScheme_Flow = 4
+)
+
+var SecurityScheme_Flow_name = map[int32]string{
+ 0: "FLOW_INVALID",
+ 1: "FLOW_IMPLICIT",
+ 2: "FLOW_PASSWORD",
+ 3: "FLOW_APPLICATION",
+ 4: "FLOW_ACCESS_CODE",
+}
+var SecurityScheme_Flow_value = map[string]int32{
+ "FLOW_INVALID": 0,
+ "FLOW_IMPLICIT": 1,
+ "FLOW_PASSWORD": 2,
+ "FLOW_APPLICATION": 3,
+ "FLOW_ACCESS_CODE": 4,
+}
+
+func (x SecurityScheme_Flow) String() string {
+ return proto.EnumName(SecurityScheme_Flow_name, int32(x))
+}
+func (SecurityScheme_Flow) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{11, 2}
+}
+
+// `Swagger` is a representation of OpenAPI v2 specification's Swagger object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#swaggerObject
+//
+// TODO(ivucica): document fields
+type Swagger struct {
+ Swagger string `protobuf:"bytes,1,opt,name=swagger,proto3" json:"swagger,omitempty"`
+ Info *Info `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"`
+ Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"`
+ // `base_path` is the common prefix path used on all API endpoints (ie. /api, /v1, etc.). By adding this,
+ // it allows you to remove this portion from the path endpoints in your Swagger file making them easier
+ // to read. Note that using `base_path` does not change the endpoint paths that are generated in the resulting
+ // Swagger file. If you wish to use `base_path` with relatively generated Swagger paths, the
+ // `base_path` prefix must be manually removed from your `google.api.http` paths and your code changed to
+ // serve the API from the `base_path`.
+ BasePath string `protobuf:"bytes,4,opt,name=base_path,json=basePath,proto3" json:"base_path,omitempty"`
+ Schemes []Swagger_SwaggerScheme `protobuf:"varint,5,rep,packed,name=schemes,proto3,enum=grpc.gateway.protoc_gen_swagger.options.Swagger_SwaggerScheme" json:"schemes,omitempty"`
+ Consumes []string `protobuf:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"`
+ Produces []string `protobuf:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"`
+ Responses map[string]*Response `protobuf:"bytes,10,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ SecurityDefinitions *SecurityDefinitions `protobuf:"bytes,11,opt,name=security_definitions,json=securityDefinitions,proto3" json:"security_definitions,omitempty"`
+ Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security,proto3" json:"security,omitempty"`
+ ExternalDocs *ExternalDocumentation `protobuf:"bytes,14,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
+ Extensions map[string]*_struct.Value `protobuf:"bytes,15,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Swagger) Reset() { *m = Swagger{} }
+func (m *Swagger) String() string { return proto.CompactTextString(m) }
+func (*Swagger) ProtoMessage() {}
+func (*Swagger) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{0}
+}
+func (m *Swagger) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Swagger.Unmarshal(m, b)
+}
+func (m *Swagger) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Swagger.Marshal(b, m, deterministic)
+}
+func (dst *Swagger) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Swagger.Merge(dst, src)
+}
+func (m *Swagger) XXX_Size() int {
+ return xxx_messageInfo_Swagger.Size(m)
+}
+func (m *Swagger) XXX_DiscardUnknown() {
+ xxx_messageInfo_Swagger.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Swagger proto.InternalMessageInfo
+
+func (m *Swagger) GetSwagger() string {
+ if m != nil {
+ return m.Swagger
+ }
+ return ""
+}
+
+func (m *Swagger) GetInfo() *Info {
+ if m != nil {
+ return m.Info
+ }
+ return nil
+}
+
+func (m *Swagger) GetHost() string {
+ if m != nil {
+ return m.Host
+ }
+ return ""
+}
+
+func (m *Swagger) GetBasePath() string {
+ if m != nil {
+ return m.BasePath
+ }
+ return ""
+}
+
+func (m *Swagger) GetSchemes() []Swagger_SwaggerScheme {
+ if m != nil {
+ return m.Schemes
+ }
+ return nil
+}
+
+func (m *Swagger) GetConsumes() []string {
+ if m != nil {
+ return m.Consumes
+ }
+ return nil
+}
+
+func (m *Swagger) GetProduces() []string {
+ if m != nil {
+ return m.Produces
+ }
+ return nil
+}
+
+func (m *Swagger) GetResponses() map[string]*Response {
+ if m != nil {
+ return m.Responses
+ }
+ return nil
+}
+
+func (m *Swagger) GetSecurityDefinitions() *SecurityDefinitions {
+ if m != nil {
+ return m.SecurityDefinitions
+ }
+ return nil
+}
+
+func (m *Swagger) GetSecurity() []*SecurityRequirement {
+ if m != nil {
+ return m.Security
+ }
+ return nil
+}
+
+func (m *Swagger) GetExternalDocs() *ExternalDocumentation {
+ if m != nil {
+ return m.ExternalDocs
+ }
+ return nil
+}
+
+func (m *Swagger) GetExtensions() map[string]*_struct.Value {
+ if m != nil {
+ return m.Extensions
+ }
+ return nil
+}
+
+// `Operation` is a representation of OpenAPI v2 specification's Operation object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#operationObject
+//
+// TODO(ivucica): document fields
+type Operation struct {
+ Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"`
+ Summary string `protobuf:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"`
+ Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+ ExternalDocs *ExternalDocumentation `protobuf:"bytes,4,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
+ OperationId string `protobuf:"bytes,5,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"`
+ Consumes []string `protobuf:"bytes,6,rep,name=consumes,proto3" json:"consumes,omitempty"`
+ Produces []string `protobuf:"bytes,7,rep,name=produces,proto3" json:"produces,omitempty"`
+ Responses map[string]*Response `protobuf:"bytes,9,rep,name=responses,proto3" json:"responses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Schemes []string `protobuf:"bytes,10,rep,name=schemes,proto3" json:"schemes,omitempty"`
+ Deprecated bool `protobuf:"varint,11,opt,name=deprecated,proto3" json:"deprecated,omitempty"`
+ Security []*SecurityRequirement `protobuf:"bytes,12,rep,name=security,proto3" json:"security,omitempty"`
+ Extensions map[string]*_struct.Value `protobuf:"bytes,13,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Operation) Reset() { *m = Operation{} }
+func (m *Operation) String() string { return proto.CompactTextString(m) }
+func (*Operation) ProtoMessage() {}
+func (*Operation) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{1}
+}
+func (m *Operation) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Operation.Unmarshal(m, b)
+}
+func (m *Operation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Operation.Marshal(b, m, deterministic)
+}
+func (dst *Operation) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Operation.Merge(dst, src)
+}
+func (m *Operation) XXX_Size() int {
+ return xxx_messageInfo_Operation.Size(m)
+}
+func (m *Operation) XXX_DiscardUnknown() {
+ xxx_messageInfo_Operation.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Operation proto.InternalMessageInfo
+
+func (m *Operation) GetTags() []string {
+ if m != nil {
+ return m.Tags
+ }
+ return nil
+}
+
+func (m *Operation) GetSummary() string {
+ if m != nil {
+ return m.Summary
+ }
+ return ""
+}
+
+func (m *Operation) GetDescription() string {
+ if m != nil {
+ return m.Description
+ }
+ return ""
+}
+
+func (m *Operation) GetExternalDocs() *ExternalDocumentation {
+ if m != nil {
+ return m.ExternalDocs
+ }
+ return nil
+}
+
+func (m *Operation) GetOperationId() string {
+ if m != nil {
+ return m.OperationId
+ }
+ return ""
+}
+
+func (m *Operation) GetConsumes() []string {
+ if m != nil {
+ return m.Consumes
+ }
+ return nil
+}
+
+func (m *Operation) GetProduces() []string {
+ if m != nil {
+ return m.Produces
+ }
+ return nil
+}
+
+func (m *Operation) GetResponses() map[string]*Response {
+ if m != nil {
+ return m.Responses
+ }
+ return nil
+}
+
+func (m *Operation) GetSchemes() []string {
+ if m != nil {
+ return m.Schemes
+ }
+ return nil
+}
+
+func (m *Operation) GetDeprecated() bool {
+ if m != nil {
+ return m.Deprecated
+ }
+ return false
+}
+
+func (m *Operation) GetSecurity() []*SecurityRequirement {
+ if m != nil {
+ return m.Security
+ }
+ return nil
+}
+
+func (m *Operation) GetExtensions() map[string]*_struct.Value {
+ if m != nil {
+ return m.Extensions
+ }
+ return nil
+}
+
+// `Response` is a representation of OpenAPI v2 specification's Response object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responseObject
+//
+type Response struct {
+ // `Description` is a short description of the response.
+ // GFM syntax can be used for rich text representation.
+ Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"`
+ // `Schema` optionally defines the structure of the response.
+ // If `Schema` is not provided, it means there is no content to the response.
+ Schema *Schema `protobuf:"bytes,2,opt,name=schema,proto3" json:"schema,omitempty"`
+ Extensions map[string]*_struct.Value `protobuf:"bytes,5,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Response) Reset() { *m = Response{} }
+func (m *Response) String() string { return proto.CompactTextString(m) }
+func (*Response) ProtoMessage() {}
+func (*Response) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{2}
+}
+func (m *Response) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Response.Unmarshal(m, b)
+}
+func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Response.Marshal(b, m, deterministic)
+}
+func (dst *Response) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Response.Merge(dst, src)
+}
+func (m *Response) XXX_Size() int {
+ return xxx_messageInfo_Response.Size(m)
+}
+func (m *Response) XXX_DiscardUnknown() {
+ xxx_messageInfo_Response.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Response proto.InternalMessageInfo
+
+func (m *Response) GetDescription() string {
+ if m != nil {
+ return m.Description
+ }
+ return ""
+}
+
+func (m *Response) GetSchema() *Schema {
+ if m != nil {
+ return m.Schema
+ }
+ return nil
+}
+
+func (m *Response) GetExtensions() map[string]*_struct.Value {
+ if m != nil {
+ return m.Extensions
+ }
+ return nil
+}
+
+// `Info` is a representation of OpenAPI v2 specification's Info object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#infoObject
+//
+// TODO(ivucica): document fields
+type Info struct {
+ Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
+ Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+ TermsOfService string `protobuf:"bytes,3,opt,name=terms_of_service,json=termsOfService,proto3" json:"terms_of_service,omitempty"`
+ Contact *Contact `protobuf:"bytes,4,opt,name=contact,proto3" json:"contact,omitempty"`
+ License *License `protobuf:"bytes,5,opt,name=license,proto3" json:"license,omitempty"`
+ Version string `protobuf:"bytes,6,opt,name=version,proto3" json:"version,omitempty"`
+ Extensions map[string]*_struct.Value `protobuf:"bytes,7,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Info) Reset() { *m = Info{} }
+func (m *Info) String() string { return proto.CompactTextString(m) }
+func (*Info) ProtoMessage() {}
+func (*Info) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{3}
+}
+func (m *Info) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Info.Unmarshal(m, b)
+}
+func (m *Info) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Info.Marshal(b, m, deterministic)
+}
+func (dst *Info) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Info.Merge(dst, src)
+}
+func (m *Info) XXX_Size() int {
+ return xxx_messageInfo_Info.Size(m)
+}
+func (m *Info) XXX_DiscardUnknown() {
+ xxx_messageInfo_Info.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Info proto.InternalMessageInfo
+
+func (m *Info) GetTitle() string {
+ if m != nil {
+ return m.Title
+ }
+ return ""
+}
+
+func (m *Info) GetDescription() string {
+ if m != nil {
+ return m.Description
+ }
+ return ""
+}
+
+func (m *Info) GetTermsOfService() string {
+ if m != nil {
+ return m.TermsOfService
+ }
+ return ""
+}
+
+func (m *Info) GetContact() *Contact {
+ if m != nil {
+ return m.Contact
+ }
+ return nil
+}
+
+func (m *Info) GetLicense() *License {
+ if m != nil {
+ return m.License
+ }
+ return nil
+}
+
+func (m *Info) GetVersion() string {
+ if m != nil {
+ return m.Version
+ }
+ return ""
+}
+
+func (m *Info) GetExtensions() map[string]*_struct.Value {
+ if m != nil {
+ return m.Extensions
+ }
+ return nil
+}
+
+// `Contact` is a representation of OpenAPI v2 specification's Contact object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#contactObject
+//
+// TODO(ivucica): document fields
+type Contact struct {
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
+ Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Contact) Reset() { *m = Contact{} }
+func (m *Contact) String() string { return proto.CompactTextString(m) }
+func (*Contact) ProtoMessage() {}
+func (*Contact) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{4}
+}
+func (m *Contact) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Contact.Unmarshal(m, b)
+}
+func (m *Contact) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Contact.Marshal(b, m, deterministic)
+}
+func (dst *Contact) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Contact.Merge(dst, src)
+}
+func (m *Contact) XXX_Size() int {
+ return xxx_messageInfo_Contact.Size(m)
+}
+func (m *Contact) XXX_DiscardUnknown() {
+ xxx_messageInfo_Contact.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Contact proto.InternalMessageInfo
+
+func (m *Contact) GetName() string {
+ if m != nil {
+ return m.Name
+ }
+ return ""
+}
+
+func (m *Contact) GetUrl() string {
+ if m != nil {
+ return m.Url
+ }
+ return ""
+}
+
+func (m *Contact) GetEmail() string {
+ if m != nil {
+ return m.Email
+ }
+ return ""
+}
+
+// `License` is a representation of OpenAPI v2 specification's License object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#licenseObject
+//
+type License struct {
+ // Required. The license name used for the API.
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ // A URL to the license used for the API.
+ Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *License) Reset() { *m = License{} }
+func (m *License) String() string { return proto.CompactTextString(m) }
+func (*License) ProtoMessage() {}
+func (*License) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{5}
+}
+func (m *License) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_License.Unmarshal(m, b)
+}
+func (m *License) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_License.Marshal(b, m, deterministic)
+}
+func (dst *License) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_License.Merge(dst, src)
+}
+func (m *License) XXX_Size() int {
+ return xxx_messageInfo_License.Size(m)
+}
+func (m *License) XXX_DiscardUnknown() {
+ xxx_messageInfo_License.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_License proto.InternalMessageInfo
+
+func (m *License) GetName() string {
+ if m != nil {
+ return m.Name
+ }
+ return ""
+}
+
+func (m *License) GetUrl() string {
+ if m != nil {
+ return m.Url
+ }
+ return ""
+}
+
+// `ExternalDocumentation` is a representation of OpenAPI v2 specification's
+// ExternalDocumentation object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#externalDocumentationObject
+//
+// TODO(ivucica): document fields
+type ExternalDocumentation struct {
+ Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"`
+ Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *ExternalDocumentation) Reset() { *m = ExternalDocumentation{} }
+func (m *ExternalDocumentation) String() string { return proto.CompactTextString(m) }
+func (*ExternalDocumentation) ProtoMessage() {}
+func (*ExternalDocumentation) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{6}
+}
+func (m *ExternalDocumentation) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_ExternalDocumentation.Unmarshal(m, b)
+}
+func (m *ExternalDocumentation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_ExternalDocumentation.Marshal(b, m, deterministic)
+}
+func (dst *ExternalDocumentation) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ExternalDocumentation.Merge(dst, src)
+}
+func (m *ExternalDocumentation) XXX_Size() int {
+ return xxx_messageInfo_ExternalDocumentation.Size(m)
+}
+func (m *ExternalDocumentation) XXX_DiscardUnknown() {
+ xxx_messageInfo_ExternalDocumentation.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ExternalDocumentation proto.InternalMessageInfo
+
+func (m *ExternalDocumentation) GetDescription() string {
+ if m != nil {
+ return m.Description
+ }
+ return ""
+}
+
+func (m *ExternalDocumentation) GetUrl() string {
+ if m != nil {
+ return m.Url
+ }
+ return ""
+}
+
+// `Schema` is a representation of OpenAPI v2 specification's Schema object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
+//
+// TODO(ivucica): document fields
+type Schema struct {
+ JsonSchema *JSONSchema `protobuf:"bytes,1,opt,name=json_schema,json=jsonSchema,proto3" json:"json_schema,omitempty"`
+ Discriminator string `protobuf:"bytes,2,opt,name=discriminator,proto3" json:"discriminator,omitempty"`
+ ReadOnly bool `protobuf:"varint,3,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"`
+ ExternalDocs *ExternalDocumentation `protobuf:"bytes,5,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
+ Example *any.Any `protobuf:"bytes,6,opt,name=example,proto3" json:"example,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Schema) Reset() { *m = Schema{} }
+func (m *Schema) String() string { return proto.CompactTextString(m) }
+func (*Schema) ProtoMessage() {}
+func (*Schema) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{7}
+}
+func (m *Schema) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Schema.Unmarshal(m, b)
+}
+func (m *Schema) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Schema.Marshal(b, m, deterministic)
+}
+func (dst *Schema) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Schema.Merge(dst, src)
+}
+func (m *Schema) XXX_Size() int {
+ return xxx_messageInfo_Schema.Size(m)
+}
+func (m *Schema) XXX_DiscardUnknown() {
+ xxx_messageInfo_Schema.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Schema proto.InternalMessageInfo
+
+func (m *Schema) GetJsonSchema() *JSONSchema {
+ if m != nil {
+ return m.JsonSchema
+ }
+ return nil
+}
+
+func (m *Schema) GetDiscriminator() string {
+ if m != nil {
+ return m.Discriminator
+ }
+ return ""
+}
+
+func (m *Schema) GetReadOnly() bool {
+ if m != nil {
+ return m.ReadOnly
+ }
+ return false
+}
+
+func (m *Schema) GetExternalDocs() *ExternalDocumentation {
+ if m != nil {
+ return m.ExternalDocs
+ }
+ return nil
+}
+
+func (m *Schema) GetExample() *any.Any {
+ if m != nil {
+ return m.Example
+ }
+ return nil
+}
+
+// `JSONSchema` represents properties from JSON Schema taken, and as used, in
+// the OpenAPI v2 spec.
+//
+// This includes changes made by OpenAPI v2.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
+//
+// See also: https://cswr.github.io/JsonSchema/spec/basic_types/,
+// https://github.com/json-schema-org/json-schema-spec/blob/master/schema.json
+//
+// TODO(ivucica): document fields
+type JSONSchema struct {
+ // Ref is used to define an external reference to include in the message.
+ // This could be a fully qualified proto message reference, and that type must be imported
+ // into the protofile. If no message is identified, the Ref will be used verbatim in
+ // the output.
+ // For example:
+ // `ref: ".google.protobuf.Timestamp"`.
+ Ref string `protobuf:"bytes,3,opt,name=ref,proto3" json:"ref,omitempty"`
+ Title string `protobuf:"bytes,5,opt,name=title,proto3" json:"title,omitempty"`
+ Description string `protobuf:"bytes,6,opt,name=description,proto3" json:"description,omitempty"`
+ Default string `protobuf:"bytes,7,opt,name=default,proto3" json:"default,omitempty"`
+ ReadOnly bool `protobuf:"varint,8,opt,name=read_only,json=readOnly,proto3" json:"read_only,omitempty"`
+ MultipleOf float64 `protobuf:"fixed64,10,opt,name=multiple_of,json=multipleOf,proto3" json:"multiple_of,omitempty"`
+ Maximum float64 `protobuf:"fixed64,11,opt,name=maximum,proto3" json:"maximum,omitempty"`
+ ExclusiveMaximum bool `protobuf:"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3" json:"exclusive_maximum,omitempty"`
+ Minimum float64 `protobuf:"fixed64,13,opt,name=minimum,proto3" json:"minimum,omitempty"`
+ ExclusiveMinimum bool `protobuf:"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3" json:"exclusive_minimum,omitempty"`
+ MaxLength uint64 `protobuf:"varint,15,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"`
+ MinLength uint64 `protobuf:"varint,16,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"`
+ Pattern string `protobuf:"bytes,17,opt,name=pattern,proto3" json:"pattern,omitempty"`
+ MaxItems uint64 `protobuf:"varint,20,opt,name=max_items,json=maxItems,proto3" json:"max_items,omitempty"`
+ MinItems uint64 `protobuf:"varint,21,opt,name=min_items,json=minItems,proto3" json:"min_items,omitempty"`
+ UniqueItems bool `protobuf:"varint,22,opt,name=unique_items,json=uniqueItems,proto3" json:"unique_items,omitempty"`
+ MaxProperties uint64 `protobuf:"varint,24,opt,name=max_properties,json=maxProperties,proto3" json:"max_properties,omitempty"`
+ MinProperties uint64 `protobuf:"varint,25,opt,name=min_properties,json=minProperties,proto3" json:"min_properties,omitempty"`
+ Required []string `protobuf:"bytes,26,rep,name=required,proto3" json:"required,omitempty"`
+ // Items in 'array' must be unique.
+ Array []string `protobuf:"bytes,34,rep,name=array,proto3" json:"array,omitempty"`
+ Type []JSONSchema_JSONSchemaSimpleTypes `protobuf:"varint,35,rep,packed,name=type,proto3,enum=grpc.gateway.protoc_gen_swagger.options.JSONSchema_JSONSchemaSimpleTypes" json:"type,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *JSONSchema) Reset() { *m = JSONSchema{} }
+func (m *JSONSchema) String() string { return proto.CompactTextString(m) }
+func (*JSONSchema) ProtoMessage() {}
+func (*JSONSchema) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{8}
+}
+func (m *JSONSchema) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_JSONSchema.Unmarshal(m, b)
+}
+func (m *JSONSchema) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_JSONSchema.Marshal(b, m, deterministic)
+}
+func (dst *JSONSchema) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_JSONSchema.Merge(dst, src)
+}
+func (m *JSONSchema) XXX_Size() int {
+ return xxx_messageInfo_JSONSchema.Size(m)
+}
+func (m *JSONSchema) XXX_DiscardUnknown() {
+ xxx_messageInfo_JSONSchema.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_JSONSchema proto.InternalMessageInfo
+
+func (m *JSONSchema) GetRef() string {
+ if m != nil {
+ return m.Ref
+ }
+ return ""
+}
+
+func (m *JSONSchema) GetTitle() string {
+ if m != nil {
+ return m.Title
+ }
+ return ""
+}
+
+func (m *JSONSchema) GetDescription() string {
+ if m != nil {
+ return m.Description
+ }
+ return ""
+}
+
+func (m *JSONSchema) GetDefault() string {
+ if m != nil {
+ return m.Default
+ }
+ return ""
+}
+
+func (m *JSONSchema) GetReadOnly() bool {
+ if m != nil {
+ return m.ReadOnly
+ }
+ return false
+}
+
+func (m *JSONSchema) GetMultipleOf() float64 {
+ if m != nil {
+ return m.MultipleOf
+ }
+ return 0
+}
+
+func (m *JSONSchema) GetMaximum() float64 {
+ if m != nil {
+ return m.Maximum
+ }
+ return 0
+}
+
+func (m *JSONSchema) GetExclusiveMaximum() bool {
+ if m != nil {
+ return m.ExclusiveMaximum
+ }
+ return false
+}
+
+func (m *JSONSchema) GetMinimum() float64 {
+ if m != nil {
+ return m.Minimum
+ }
+ return 0
+}
+
+func (m *JSONSchema) GetExclusiveMinimum() bool {
+ if m != nil {
+ return m.ExclusiveMinimum
+ }
+ return false
+}
+
+func (m *JSONSchema) GetMaxLength() uint64 {
+ if m != nil {
+ return m.MaxLength
+ }
+ return 0
+}
+
+func (m *JSONSchema) GetMinLength() uint64 {
+ if m != nil {
+ return m.MinLength
+ }
+ return 0
+}
+
+func (m *JSONSchema) GetPattern() string {
+ if m != nil {
+ return m.Pattern
+ }
+ return ""
+}
+
+func (m *JSONSchema) GetMaxItems() uint64 {
+ if m != nil {
+ return m.MaxItems
+ }
+ return 0
+}
+
+func (m *JSONSchema) GetMinItems() uint64 {
+ if m != nil {
+ return m.MinItems
+ }
+ return 0
+}
+
+func (m *JSONSchema) GetUniqueItems() bool {
+ if m != nil {
+ return m.UniqueItems
+ }
+ return false
+}
+
+func (m *JSONSchema) GetMaxProperties() uint64 {
+ if m != nil {
+ return m.MaxProperties
+ }
+ return 0
+}
+
+func (m *JSONSchema) GetMinProperties() uint64 {
+ if m != nil {
+ return m.MinProperties
+ }
+ return 0
+}
+
+func (m *JSONSchema) GetRequired() []string {
+ if m != nil {
+ return m.Required
+ }
+ return nil
+}
+
+func (m *JSONSchema) GetArray() []string {
+ if m != nil {
+ return m.Array
+ }
+ return nil
+}
+
+func (m *JSONSchema) GetType() []JSONSchema_JSONSchemaSimpleTypes {
+ if m != nil {
+ return m.Type
+ }
+ return nil
+}
+
+// `Tag` is a representation of OpenAPI v2 specification's Tag object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#tagObject
+//
+// TODO(ivucica): document fields
+type Tag struct {
+ // TODO(ivucica): Description should be extracted from comments on the proto
+ // service object.
+ Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+ ExternalDocs *ExternalDocumentation `protobuf:"bytes,3,opt,name=external_docs,json=externalDocs,proto3" json:"external_docs,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Tag) Reset() { *m = Tag{} }
+func (m *Tag) String() string { return proto.CompactTextString(m) }
+func (*Tag) ProtoMessage() {}
+func (*Tag) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{9}
+}
+func (m *Tag) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Tag.Unmarshal(m, b)
+}
+func (m *Tag) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Tag.Marshal(b, m, deterministic)
+}
+func (dst *Tag) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Tag.Merge(dst, src)
+}
+func (m *Tag) XXX_Size() int {
+ return xxx_messageInfo_Tag.Size(m)
+}
+func (m *Tag) XXX_DiscardUnknown() {
+ xxx_messageInfo_Tag.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Tag proto.InternalMessageInfo
+
+func (m *Tag) GetDescription() string {
+ if m != nil {
+ return m.Description
+ }
+ return ""
+}
+
+func (m *Tag) GetExternalDocs() *ExternalDocumentation {
+ if m != nil {
+ return m.ExternalDocs
+ }
+ return nil
+}
+
+// `SecurityDefinitions` is a representation of OpenAPI v2 specification's
+// Security Definitions object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityDefinitionsObject
+//
+// A declaration of the security schemes available to be used in the
+// specification. This does not enforce the security schemes on the operations
+// and only serves to provide the relevant details for each scheme.
+type SecurityDefinitions struct {
+ // A single security scheme definition, mapping a "name" to the scheme it defines.
+ Security map[string]*SecurityScheme `protobuf:"bytes,1,rep,name=security,proto3" json:"security,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *SecurityDefinitions) Reset() { *m = SecurityDefinitions{} }
+func (m *SecurityDefinitions) String() string { return proto.CompactTextString(m) }
+func (*SecurityDefinitions) ProtoMessage() {}
+func (*SecurityDefinitions) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{10}
+}
+func (m *SecurityDefinitions) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_SecurityDefinitions.Unmarshal(m, b)
+}
+func (m *SecurityDefinitions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_SecurityDefinitions.Marshal(b, m, deterministic)
+}
+func (dst *SecurityDefinitions) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SecurityDefinitions.Merge(dst, src)
+}
+func (m *SecurityDefinitions) XXX_Size() int {
+ return xxx_messageInfo_SecurityDefinitions.Size(m)
+}
+func (m *SecurityDefinitions) XXX_DiscardUnknown() {
+ xxx_messageInfo_SecurityDefinitions.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SecurityDefinitions proto.InternalMessageInfo
+
+func (m *SecurityDefinitions) GetSecurity() map[string]*SecurityScheme {
+ if m != nil {
+ return m.Security
+ }
+ return nil
+}
+
+// `SecurityScheme` is a representation of OpenAPI v2 specification's
+// Security Scheme object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securitySchemeObject
+//
+// Allows the definition of a security scheme that can be used by the
+// operations. Supported schemes are basic authentication, an API key (either as
+// a header or as a query parameter) and OAuth2's common flows (implicit,
+// password, application and access code).
+type SecurityScheme struct {
+ // Required. The type of the security scheme. Valid values are "basic",
+ // "apiKey" or "oauth2".
+ Type SecurityScheme_Type `protobuf:"varint,1,opt,name=type,proto3,enum=grpc.gateway.protoc_gen_swagger.options.SecurityScheme_Type" json:"type,omitempty"`
+ // A short description for security scheme.
+ Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+ // Required. The name of the header or query parameter to be used.
+ //
+ // Valid for apiKey.
+ Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
+ // Required. The location of the API key. Valid values are "query" or "header".
+ //
+ // Valid for apiKey.
+ In SecurityScheme_In `protobuf:"varint,4,opt,name=in,proto3,enum=grpc.gateway.protoc_gen_swagger.options.SecurityScheme_In" json:"in,omitempty"`
+ // Required. The flow used by the OAuth2 security scheme. Valid values are
+ // "implicit", "password", "application" or "accessCode".
+ //
+ // Valid for oauth2.
+ Flow SecurityScheme_Flow `protobuf:"varint,5,opt,name=flow,proto3,enum=grpc.gateway.protoc_gen_swagger.options.SecurityScheme_Flow" json:"flow,omitempty"`
+ // Required. The authorization URL to be used for this flow. This SHOULD be in
+ // the form of a URL.
+ //
+ // Valid for oauth2/implicit and oauth2/accessCode.
+ AuthorizationUrl string `protobuf:"bytes,6,opt,name=authorization_url,json=authorizationUrl,proto3" json:"authorization_url,omitempty"`
+ // Required. The token URL to be used for this flow. This SHOULD be in the
+ // form of a URL.
+ //
+ // Valid for oauth2/password, oauth2/application and oauth2/accessCode.
+ TokenUrl string `protobuf:"bytes,7,opt,name=token_url,json=tokenUrl,proto3" json:"token_url,omitempty"`
+ // Required. The available scopes for the OAuth2 security scheme.
+ //
+ // Valid for oauth2.
+ Scopes *Scopes `protobuf:"bytes,8,opt,name=scopes,proto3" json:"scopes,omitempty"`
+ Extensions map[string]*_struct.Value `protobuf:"bytes,9,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *SecurityScheme) Reset() { *m = SecurityScheme{} }
+func (m *SecurityScheme) String() string { return proto.CompactTextString(m) }
+func (*SecurityScheme) ProtoMessage() {}
+func (*SecurityScheme) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{11}
+}
+func (m *SecurityScheme) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_SecurityScheme.Unmarshal(m, b)
+}
+func (m *SecurityScheme) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_SecurityScheme.Marshal(b, m, deterministic)
+}
+func (dst *SecurityScheme) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SecurityScheme.Merge(dst, src)
+}
+func (m *SecurityScheme) XXX_Size() int {
+ return xxx_messageInfo_SecurityScheme.Size(m)
+}
+func (m *SecurityScheme) XXX_DiscardUnknown() {
+ xxx_messageInfo_SecurityScheme.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SecurityScheme proto.InternalMessageInfo
+
+func (m *SecurityScheme) GetType() SecurityScheme_Type {
+ if m != nil {
+ return m.Type
+ }
+ return SecurityScheme_TYPE_INVALID
+}
+
+func (m *SecurityScheme) GetDescription() string {
+ if m != nil {
+ return m.Description
+ }
+ return ""
+}
+
+func (m *SecurityScheme) GetName() string {
+ if m != nil {
+ return m.Name
+ }
+ return ""
+}
+
+func (m *SecurityScheme) GetIn() SecurityScheme_In {
+ if m != nil {
+ return m.In
+ }
+ return SecurityScheme_IN_INVALID
+}
+
+func (m *SecurityScheme) GetFlow() SecurityScheme_Flow {
+ if m != nil {
+ return m.Flow
+ }
+ return SecurityScheme_FLOW_INVALID
+}
+
+func (m *SecurityScheme) GetAuthorizationUrl() string {
+ if m != nil {
+ return m.AuthorizationUrl
+ }
+ return ""
+}
+
+func (m *SecurityScheme) GetTokenUrl() string {
+ if m != nil {
+ return m.TokenUrl
+ }
+ return ""
+}
+
+func (m *SecurityScheme) GetScopes() *Scopes {
+ if m != nil {
+ return m.Scopes
+ }
+ return nil
+}
+
+func (m *SecurityScheme) GetExtensions() map[string]*_struct.Value {
+ if m != nil {
+ return m.Extensions
+ }
+ return nil
+}
+
+// `SecurityRequirement` is a representation of OpenAPI v2 specification's
+// Security Requirement object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityRequirementObject
+//
+// Lists the required security schemes to execute this operation. The object can
+// have multiple security schemes declared in it which are all required (that
+// is, there is a logical AND between the schemes).
+//
+// The name used for each property MUST correspond to a security scheme
+// declared in the Security Definitions.
+type SecurityRequirement struct {
+ // Each name must correspond to a security scheme which is declared in
+ // the Security Definitions. If the security scheme is of type "oauth2",
+ // then the value is a list of scope names required for the execution.
+ // For other security scheme types, the array MUST be empty.
+ SecurityRequirement map[string]*SecurityRequirement_SecurityRequirementValue `protobuf:"bytes,1,rep,name=security_requirement,json=securityRequirement,proto3" json:"security_requirement,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *SecurityRequirement) Reset() { *m = SecurityRequirement{} }
+func (m *SecurityRequirement) String() string { return proto.CompactTextString(m) }
+func (*SecurityRequirement) ProtoMessage() {}
+func (*SecurityRequirement) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{12}
+}
+func (m *SecurityRequirement) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_SecurityRequirement.Unmarshal(m, b)
+}
+func (m *SecurityRequirement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_SecurityRequirement.Marshal(b, m, deterministic)
+}
+func (dst *SecurityRequirement) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SecurityRequirement.Merge(dst, src)
+}
+func (m *SecurityRequirement) XXX_Size() int {
+ return xxx_messageInfo_SecurityRequirement.Size(m)
+}
+func (m *SecurityRequirement) XXX_DiscardUnknown() {
+ xxx_messageInfo_SecurityRequirement.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SecurityRequirement proto.InternalMessageInfo
+
+func (m *SecurityRequirement) GetSecurityRequirement() map[string]*SecurityRequirement_SecurityRequirementValue {
+ if m != nil {
+ return m.SecurityRequirement
+ }
+ return nil
+}
+
+// If the security scheme is of type "oauth2", then the value is a list of
+// scope names required for the execution. For other security scheme types,
+// the array MUST be empty.
+type SecurityRequirement_SecurityRequirementValue struct {
+ Scope []string `protobuf:"bytes,1,rep,name=scope,proto3" json:"scope,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *SecurityRequirement_SecurityRequirementValue) Reset() {
+ *m = SecurityRequirement_SecurityRequirementValue{}
+}
+func (m *SecurityRequirement_SecurityRequirementValue) String() string {
+ return proto.CompactTextString(m)
+}
+func (*SecurityRequirement_SecurityRequirementValue) ProtoMessage() {}
+func (*SecurityRequirement_SecurityRequirementValue) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{12, 0}
+}
+func (m *SecurityRequirement_SecurityRequirementValue) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.Unmarshal(m, b)
+}
+func (m *SecurityRequirement_SecurityRequirementValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.Marshal(b, m, deterministic)
+}
+func (dst *SecurityRequirement_SecurityRequirementValue) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.Merge(dst, src)
+}
+func (m *SecurityRequirement_SecurityRequirementValue) XXX_Size() int {
+ return xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.Size(m)
+}
+func (m *SecurityRequirement_SecurityRequirementValue) XXX_DiscardUnknown() {
+ xxx_messageInfo_SecurityRequirement_SecurityRequirementValue.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SecurityRequirement_SecurityRequirementValue proto.InternalMessageInfo
+
+func (m *SecurityRequirement_SecurityRequirementValue) GetScope() []string {
+ if m != nil {
+ return m.Scope
+ }
+ return nil
+}
+
+// `Scopes` is a representation of OpenAPI v2 specification's Scopes object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#scopesObject
+//
+// Lists the available scopes for an OAuth2 security scheme.
+type Scopes struct {
+ // Maps between a name of a scope to a short description of it (as the value
+ // of the property).
+ Scope map[string]string `protobuf:"bytes,1,rep,name=scope,proto3" json:"scope,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Scopes) Reset() { *m = Scopes{} }
+func (m *Scopes) String() string { return proto.CompactTextString(m) }
+func (*Scopes) ProtoMessage() {}
+func (*Scopes) Descriptor() ([]byte, []int) {
+ return fileDescriptor_openapiv2_7182f700aabb5117, []int{13}
+}
+func (m *Scopes) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Scopes.Unmarshal(m, b)
+}
+func (m *Scopes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Scopes.Marshal(b, m, deterministic)
+}
+func (dst *Scopes) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Scopes.Merge(dst, src)
+}
+func (m *Scopes) XXX_Size() int {
+ return xxx_messageInfo_Scopes.Size(m)
+}
+func (m *Scopes) XXX_DiscardUnknown() {
+ xxx_messageInfo_Scopes.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Scopes proto.InternalMessageInfo
+
+func (m *Scopes) GetScope() map[string]string {
+ if m != nil {
+ return m.Scope
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterType((*Swagger)(nil), "grpc.gateway.protoc_gen_swagger.options.Swagger")
+ proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.Swagger.ExtensionsEntry")
+ proto.RegisterMapType((map[string]*Response)(nil), "grpc.gateway.protoc_gen_swagger.options.Swagger.ResponsesEntry")
+ proto.RegisterType((*Operation)(nil), "grpc.gateway.protoc_gen_swagger.options.Operation")
+ proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.Operation.ExtensionsEntry")
+ proto.RegisterMapType((map[string]*Response)(nil), "grpc.gateway.protoc_gen_swagger.options.Operation.ResponsesEntry")
+ proto.RegisterType((*Response)(nil), "grpc.gateway.protoc_gen_swagger.options.Response")
+ proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.Response.ExtensionsEntry")
+ proto.RegisterType((*Info)(nil), "grpc.gateway.protoc_gen_swagger.options.Info")
+ proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.Info.ExtensionsEntry")
+ proto.RegisterType((*Contact)(nil), "grpc.gateway.protoc_gen_swagger.options.Contact")
+ proto.RegisterType((*License)(nil), "grpc.gateway.protoc_gen_swagger.options.License")
+ proto.RegisterType((*ExternalDocumentation)(nil), "grpc.gateway.protoc_gen_swagger.options.ExternalDocumentation")
+ proto.RegisterType((*Schema)(nil), "grpc.gateway.protoc_gen_swagger.options.Schema")
+ proto.RegisterType((*JSONSchema)(nil), "grpc.gateway.protoc_gen_swagger.options.JSONSchema")
+ proto.RegisterType((*Tag)(nil), "grpc.gateway.protoc_gen_swagger.options.Tag")
+ proto.RegisterType((*SecurityDefinitions)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityDefinitions")
+ proto.RegisterMapType((map[string]*SecurityScheme)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityDefinitions.SecurityEntry")
+ proto.RegisterType((*SecurityScheme)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityScheme")
+ proto.RegisterMapType((map[string]*_struct.Value)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityScheme.ExtensionsEntry")
+ proto.RegisterType((*SecurityRequirement)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityRequirement")
+ proto.RegisterMapType((map[string]*SecurityRequirement_SecurityRequirementValue)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityRequirement.SecurityRequirementEntry")
+ proto.RegisterType((*SecurityRequirement_SecurityRequirementValue)(nil), "grpc.gateway.protoc_gen_swagger.options.SecurityRequirement.SecurityRequirementValue")
+ proto.RegisterType((*Scopes)(nil), "grpc.gateway.protoc_gen_swagger.options.Scopes")
+ proto.RegisterMapType((map[string]string)(nil), "grpc.gateway.protoc_gen_swagger.options.Scopes.ScopeEntry")
+ proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.Swagger_SwaggerScheme", Swagger_SwaggerScheme_name, Swagger_SwaggerScheme_value)
+ proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.JSONSchema_JSONSchemaSimpleTypes", JSONSchema_JSONSchemaSimpleTypes_name, JSONSchema_JSONSchemaSimpleTypes_value)
+ proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.SecurityScheme_Type", SecurityScheme_Type_name, SecurityScheme_Type_value)
+ proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.SecurityScheme_In", SecurityScheme_In_name, SecurityScheme_In_value)
+ proto.RegisterEnum("grpc.gateway.protoc_gen_swagger.options.SecurityScheme_Flow", SecurityScheme_Flow_name, SecurityScheme_Flow_value)
+}
+
+func init() {
+ proto.RegisterFile("protoc-gen-swagger/options/openapiv2.proto", fileDescriptor_openapiv2_7182f700aabb5117)
+}
+
+var fileDescriptor_openapiv2_7182f700aabb5117 = []byte{
+ // 1884 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0x5b, 0x73, 0xdb, 0xc6,
+ 0xf5, 0x0f, 0x48, 0x90, 0x04, 0x0f, 0x45, 0x7a, 0xbd, 0x96, 0xf3, 0x47, 0x18, 0xdb, 0x7f, 0x85,
+ 0x4d, 0xa7, 0x1a, 0xbb, 0xa6, 0x12, 0xe5, 0xa1, 0x99, 0x4c, 0x6f, 0x94, 0xc4, 0xc8, 0x80, 0x65,
+ 0x92, 0x05, 0xa9, 0x28, 0xee, 0x8c, 0x07, 0x85, 0xc0, 0x25, 0x85, 0x18, 0x17, 0x06, 0x17, 0x49,
+ 0xec, 0x27, 0xe8, 0x73, 0xa7, 0xaf, 0xf9, 0x1e, 0x9d, 0x69, 0x9f, 0xfa, 0x09, 0xfa, 0x59, 0xda,
+ 0xe9, 0x7b, 0x67, 0x2f, 0x20, 0x41, 0x91, 0xf1, 0x90, 0x72, 0x3c, 0x79, 0xe8, 0x13, 0xf7, 0xdc,
+ 0x7e, 0xbb, 0x7b, 0xce, 0x9e, 0x0b, 0x08, 0x8f, 0x27, 0x61, 0x10, 0x07, 0xf6, 0xd3, 0x31, 0xf1,
+ 0x9f, 0x46, 0x57, 0xd6, 0x78, 0x4c, 0xc2, 0xbd, 0x60, 0x12, 0x3b, 0x81, 0x1f, 0xed, 0x05, 0x13,
+ 0xe2, 0x5b, 0x13, 0xe7, 0x72, 0xbf, 0xc9, 0x94, 0xf0, 0xcf, 0xc6, 0xe1, 0xc4, 0x6e, 0x8e, 0xad,
+ 0x98, 0x5c, 0x59, 0x53, 0xce, 0xb3, 0xcd, 0x31, 0xf1, 0x4d, 0x61, 0xd8, 0x14, 0x86, 0xf5, 0x0f,
+ 0xc6, 0x41, 0x30, 0x76, 0xc9, 0x1e, 0x53, 0x39, 0x4f, 0x46, 0x7b, 0x96, 0x2f, 0xf4, 0xeb, 0x0f,
+ 0x6e, 0x8a, 0xa2, 0x38, 0x4c, 0xec, 0x98, 0x4b, 0x1b, 0x7f, 0x55, 0xa0, 0xd4, 0xe7, 0x60, 0x58,
+ 0x85, 0x92, 0xc0, 0x55, 0xa5, 0x1d, 0x69, 0xb7, 0x6c, 0xa4, 0x24, 0x6e, 0x81, 0xec, 0xf8, 0xa3,
+ 0x40, 0xcd, 0xed, 0x48, 0xbb, 0x95, 0xfd, 0xa7, 0xcd, 0x35, 0x8f, 0xd5, 0xd4, 0xfc, 0x51, 0x60,
+ 0x30, 0x53, 0x8c, 0x41, 0xbe, 0x08, 0xa2, 0x58, 0xcd, 0x33, 0x64, 0xb6, 0xc6, 0x1f, 0x42, 0xf9,
+ 0xdc, 0x8a, 0x88, 0x39, 0xb1, 0xe2, 0x0b, 0x55, 0x66, 0x02, 0x85, 0x32, 0x7a, 0x56, 0x7c, 0x81,
+ 0xbf, 0x86, 0x52, 0x64, 0x5f, 0x10, 0x8f, 0x44, 0x6a, 0x61, 0x27, 0xbf, 0x5b, 0xdb, 0xff, 0xf5,
+ 0xda, 0xdb, 0x8a, 0x0b, 0xa5, 0xbf, 0x7d, 0x06, 0x63, 0xa4, 0x70, 0xb8, 0x0e, 0x8a, 0x1d, 0xf8,
+ 0x51, 0x42, 0xa1, 0x8b, 0x3b, 0x79, 0xba, 0x6b, 0x4a, 0x53, 0xd9, 0x24, 0x0c, 0x86, 0x89, 0x4d,
+ 0x22, 0xb5, 0xc4, 0x65, 0x29, 0x8d, 0x5f, 0x41, 0x39, 0x24, 0xd1, 0x24, 0xf0, 0x23, 0x12, 0xa9,
+ 0xb0, 0x93, 0xdf, 0xad, 0xec, 0xff, 0x66, 0xe3, 0x33, 0x19, 0x29, 0x42, 0xdb, 0x8f, 0xc3, 0xa9,
+ 0x31, 0x47, 0xc4, 0x01, 0x6c, 0x47, 0xc4, 0x4e, 0x42, 0x27, 0x9e, 0x9a, 0x43, 0x32, 0x72, 0x7c,
+ 0x87, 0x59, 0xaa, 0x15, 0xe6, 0xf4, 0x5f, 0xae, 0xbf, 0x93, 0x00, 0x39, 0x9a, 0x63, 0x18, 0xf7,
+ 0xa2, 0x65, 0x26, 0xfe, 0x1a, 0x94, 0x94, 0xad, 0x6e, 0xb1, 0xeb, 0x6c, 0xbe, 0x89, 0x41, 0xbe,
+ 0x4d, 0x9c, 0x90, 0x78, 0xc4, 0x8f, 0x8d, 0x19, 0x1a, 0xb6, 0xa1, 0x4a, 0xae, 0x63, 0x12, 0xfa,
+ 0x96, 0x6b, 0x0e, 0x03, 0x3b, 0x52, 0x6b, 0xec, 0x0e, 0xeb, 0x47, 0xb0, 0x2d, 0xac, 0x8f, 0x02,
+ 0x3b, 0xa1, 0xd8, 0x16, 0x65, 0x1b, 0x5b, 0x64, 0xce, 0x8e, 0xf0, 0x1f, 0x00, 0x28, 0xed, 0x47,
+ 0xcc, 0x4b, 0x77, 0xd8, 0x05, 0x7e, 0xbb, 0x71, 0x3c, 0xda, 0x33, 0x08, 0x1e, 0x90, 0x0c, 0x66,
+ 0x3d, 0x80, 0xda, 0x62, 0xb8, 0x30, 0x82, 0xfc, 0x6b, 0x32, 0x15, 0xe9, 0x41, 0x97, 0xf8, 0x18,
+ 0x0a, 0x97, 0x96, 0x9b, 0x10, 0x91, 0x1b, 0x9f, 0xae, 0x7d, 0x80, 0x14, 0xd9, 0xe0, 0xf6, 0x5f,
+ 0xe4, 0x3e, 0x97, 0xea, 0xa7, 0x70, 0xe7, 0xc6, 0x79, 0x56, 0xec, 0xf8, 0xf3, 0xc5, 0x1d, 0xdf,
+ 0x6f, 0xf2, 0x04, 0x6f, 0xa6, 0x09, 0xde, 0xfc, 0x8a, 0x4a, 0x33, 0xb0, 0x8d, 0x03, 0xa8, 0x2e,
+ 0xa4, 0x02, 0xae, 0x40, 0xe9, 0xb4, 0xf3, 0xbc, 0xd3, 0x3d, 0xeb, 0xa0, 0xf7, 0xb0, 0x02, 0xf2,
+ 0xb3, 0xc1, 0xa0, 0x87, 0x24, 0x5c, 0x86, 0x02, 0x5d, 0xf5, 0x51, 0x0e, 0x17, 0x21, 0x77, 0xd6,
+ 0x47, 0x79, 0x5c, 0x82, 0xfc, 0x59, 0xbf, 0x8f, 0x64, 0x5d, 0x56, 0x14, 0x54, 0xd6, 0x65, 0xa5,
+ 0x8c, 0x40, 0x97, 0x95, 0x2a, 0xaa, 0x35, 0xfe, 0x51, 0x84, 0x72, 0x77, 0x42, 0x42, 0x16, 0x1b,
+ 0x9a, 0xdf, 0xb1, 0x35, 0x8e, 0x54, 0x89, 0x25, 0x0d, 0x5b, 0xb3, 0x82, 0x92, 0x78, 0x9e, 0x15,
+ 0x4e, 0xd9, 0x59, 0x69, 0x41, 0xe1, 0x24, 0xde, 0x81, 0xca, 0x90, 0x44, 0x76, 0xe8, 0x30, 0x67,
+ 0x88, 0xa2, 0x90, 0x65, 0x2d, 0x3f, 0x21, 0xf9, 0x1d, 0x3c, 0xa1, 0x8f, 0x60, 0x2b, 0x48, 0x6f,
+ 0x60, 0x3a, 0x43, 0xb5, 0xc0, 0xcf, 0x31, 0xe3, 0x69, 0xc3, 0x5b, 0x17, 0x0b, 0x33, 0x5b, 0x2c,
+ 0xca, 0xec, 0x71, 0xb6, 0xd6, 0x3e, 0xfb, 0xcc, 0xad, 0x6f, 0x28, 0x17, 0xea, 0xbc, 0x3e, 0x02,
+ 0xdb, 0x7b, 0x56, 0xdf, 0x1e, 0x01, 0x0c, 0xc9, 0x24, 0x24, 0xb6, 0x15, 0x93, 0x21, 0x2b, 0x1f,
+ 0x8a, 0x91, 0xe1, 0xbc, 0xc3, 0xbc, 0x3f, 0x5f, 0x48, 0xc9, 0x2a, 0xc3, 0x3e, 0xb8, 0xc5, 0xad,
+ 0xff, 0x07, 0x92, 0x92, 0x27, 0x54, 0xe3, 0x6f, 0x39, 0x50, 0xd2, 0x4d, 0x6f, 0x66, 0x85, 0xb4,
+ 0x9c, 0x15, 0xc7, 0x50, 0x64, 0x51, 0xb6, 0xc4, 0x3e, 0x7b, 0xeb, 0x07, 0x8e, 0x99, 0x19, 0xc2,
+ 0x1c, 0x5b, 0x0b, 0x91, 0x2a, 0x6c, 0xf8, 0x3e, 0xd3, 0x13, 0xbf, 0x31, 0x50, 0xef, 0xcc, 0x6f,
+ 0x79, 0x56, 0x8e, 0x64, 0x54, 0x68, 0xfc, 0x33, 0x0f, 0x32, 0x9d, 0x31, 0xf0, 0x36, 0x14, 0x62,
+ 0x27, 0x76, 0x89, 0x80, 0xe6, 0xc4, 0x4d, 0x7f, 0xe6, 0x96, 0xfd, 0xb9, 0x0b, 0x28, 0x26, 0xa1,
+ 0x17, 0x99, 0xc1, 0xc8, 0x8c, 0x48, 0x78, 0xe9, 0xd8, 0x44, 0x14, 0xa3, 0x1a, 0xe3, 0x77, 0x47,
+ 0x7d, 0xce, 0xc5, 0x3a, 0x94, 0xec, 0xc0, 0x8f, 0x2d, 0x3b, 0x16, 0x95, 0xe8, 0x93, 0xb5, 0xbd,
+ 0x75, 0xc8, 0xed, 0x8c, 0x14, 0x80, 0x62, 0xb9, 0x8e, 0x4d, 0xfc, 0x88, 0xb0, 0x8a, 0xb3, 0x09,
+ 0xd6, 0x09, 0xb7, 0x33, 0x52, 0x00, 0x5a, 0x06, 0x2e, 0x49, 0x48, 0x7d, 0xac, 0x16, 0x79, 0x8d,
+ 0x15, 0x24, 0x7e, 0xb5, 0x10, 0xe2, 0x12, 0x0b, 0xf1, 0xaf, 0x36, 0x1a, 0xdd, 0x7e, 0x84, 0xf0,
+ 0x36, 0xda, 0x50, 0x12, 0xfe, 0xa2, 0x2d, 0xc5, 0xb7, 0xbc, 0x34, 0xa6, 0x6c, 0x4d, 0xb7, 0x48,
+ 0x42, 0x57, 0x84, 0x92, 0x2e, 0x69, 0xe8, 0x89, 0x67, 0x39, 0xae, 0x88, 0x1b, 0x27, 0x1a, 0x7b,
+ 0x50, 0x12, 0xae, 0x5a, 0x0f, 0xa6, 0xf1, 0x1c, 0xee, 0xaf, 0xec, 0x18, 0x6b, 0x24, 0xe5, 0x32,
+ 0xd8, 0xdf, 0x73, 0x50, 0xe4, 0x09, 0x87, 0x07, 0x50, 0xf9, 0x26, 0x0a, 0x7c, 0x53, 0xa4, 0xad,
+ 0xc4, 0xfc, 0xf0, 0xd9, 0xda, 0x61, 0xd0, 0xfb, 0xdd, 0x8e, 0x48, 0x5d, 0xa0, 0x38, 0x02, 0xf5,
+ 0x63, 0xa8, 0x0e, 0x1d, 0x7a, 0x02, 0xcf, 0xf1, 0xad, 0x38, 0x08, 0xc5, 0xe6, 0x8b, 0x4c, 0x3a,
+ 0x5f, 0x87, 0xc4, 0x1a, 0x9a, 0x81, 0xef, 0x4e, 0x99, 0x7b, 0x14, 0x43, 0xa1, 0x8c, 0xae, 0xef,
+ 0xae, 0x98, 0xd1, 0x0a, 0xef, 0xa0, 0xc1, 0x36, 0xa1, 0x44, 0xae, 0x2d, 0x6f, 0xe2, 0x12, 0xf6,
+ 0x3a, 0x2b, 0xfb, 0xdb, 0x4b, 0x2f, 0xa0, 0xe5, 0x4f, 0x8d, 0x54, 0x49, 0xa4, 0xf5, 0x77, 0x25,
+ 0x80, 0xf9, 0xc5, 0xa9, 0x7f, 0x43, 0x32, 0x12, 0xf1, 0xa5, 0xcb, 0x79, 0xba, 0x17, 0xde, 0x90,
+ 0xee, 0xc5, 0xe5, 0x48, 0xa9, 0x50, 0x1a, 0x92, 0x91, 0x95, 0xb8, 0xb1, 0x5a, 0xe2, 0xc9, 0x22,
+ 0xc8, 0x45, 0x57, 0x29, 0x37, 0x5c, 0xf5, 0xff, 0x50, 0xf1, 0x12, 0x37, 0x76, 0x26, 0x2e, 0x31,
+ 0x83, 0x91, 0x0a, 0x3b, 0xd2, 0xae, 0x64, 0x40, 0xca, 0xea, 0x8e, 0x28, 0xae, 0x67, 0x5d, 0x3b,
+ 0x5e, 0xe2, 0xb1, 0x76, 0x2b, 0x19, 0x29, 0x89, 0x9f, 0xc0, 0x5d, 0x72, 0x6d, 0xbb, 0x49, 0xe4,
+ 0x5c, 0x12, 0x33, 0xd5, 0xd9, 0x62, 0xf8, 0x68, 0x26, 0x78, 0x21, 0x94, 0x29, 0x8c, 0xe3, 0x33,
+ 0x95, 0xaa, 0x80, 0xe1, 0xe4, 0x0d, 0x18, 0xa1, 0x53, 0xbb, 0x09, 0x23, 0x94, 0x1f, 0x02, 0x78,
+ 0xd6, 0xb5, 0xe9, 0x12, 0x7f, 0x1c, 0x5f, 0xa8, 0x77, 0x76, 0xa4, 0x5d, 0xd9, 0x28, 0x7b, 0xd6,
+ 0xf5, 0x09, 0x63, 0x30, 0xb1, 0xe3, 0xa7, 0x62, 0x24, 0xc4, 0x8e, 0x2f, 0xc4, 0x2a, 0x94, 0x26,
+ 0x56, 0x4c, 0x63, 0xa8, 0xde, 0xe5, 0x3e, 0x12, 0x24, 0xf5, 0x11, 0xc5, 0x75, 0x62, 0xe2, 0x45,
+ 0xea, 0x36, 0xb3, 0x53, 0x3c, 0xeb, 0x5a, 0xa3, 0x34, 0x13, 0x3a, 0xbe, 0x10, 0xde, 0x17, 0x42,
+ 0xc7, 0xe7, 0xc2, 0x8f, 0x60, 0x2b, 0xf1, 0x9d, 0x6f, 0x13, 0x22, 0xe4, 0xef, 0xb3, 0x93, 0x57,
+ 0x38, 0x8f, 0xab, 0xfc, 0x14, 0x6a, 0x14, 0x7c, 0x12, 0xd2, 0xe1, 0x2b, 0x76, 0x48, 0xa4, 0xaa,
+ 0x0c, 0xa4, 0xea, 0x59, 0xd7, 0xbd, 0x19, 0x93, 0xa9, 0x39, 0x7e, 0x56, 0xed, 0x03, 0xa1, 0xe6,
+ 0xf8, 0x19, 0xb5, 0x3a, 0x28, 0x21, 0x9f, 0x50, 0x86, 0x6a, 0x9d, 0x4f, 0x66, 0x29, 0x4d, 0x1f,
+ 0x8f, 0x15, 0x86, 0xd6, 0x54, 0x6d, 0x30, 0x01, 0x27, 0xf0, 0x2b, 0x90, 0xe3, 0xe9, 0x84, 0xa8,
+ 0x3f, 0x61, 0xdf, 0x9a, 0xda, 0x2d, 0x12, 0x34, 0xb3, 0xec, 0x3b, 0xf4, 0x35, 0x0f, 0xa6, 0x13,
+ 0x12, 0x19, 0x0c, 0xb6, 0x71, 0x05, 0xf7, 0x57, 0x8a, 0x17, 0x47, 0xf1, 0x32, 0x14, 0x5a, 0x86,
+ 0xd1, 0x7a, 0x89, 0x24, 0xca, 0x3f, 0xe8, 0x76, 0x4f, 0xda, 0xad, 0x0e, 0xca, 0x51, 0x42, 0xeb,
+ 0x0c, 0xda, 0xc7, 0x6d, 0x03, 0xe5, 0xe9, 0xbc, 0xde, 0x39, 0x3d, 0x39, 0x41, 0x32, 0x06, 0x28,
+ 0x76, 0x4e, 0x5f, 0x1c, 0xb4, 0x0d, 0x54, 0xa0, 0xeb, 0xee, 0x81, 0xde, 0x3e, 0x1c, 0xa0, 0x22,
+ 0x5d, 0xf7, 0x07, 0x86, 0xd6, 0x39, 0x46, 0x25, 0x5d, 0x56, 0x24, 0x94, 0xd3, 0x65, 0x25, 0x87,
+ 0xf2, 0x3c, 0xbb, 0x66, 0x33, 0x3c, 0x46, 0xf7, 0x74, 0x59, 0xb9, 0x87, 0xb6, 0x75, 0x59, 0xf9,
+ 0x3f, 0xa4, 0xea, 0xb2, 0xf2, 0x21, 0x7a, 0xa0, 0xcb, 0xca, 0x03, 0xf4, 0x50, 0x97, 0x95, 0x87,
+ 0xe8, 0x91, 0x2e, 0x2b, 0x8f, 0x50, 0x43, 0x97, 0x95, 0x8f, 0xd1, 0x63, 0x5d, 0x56, 0x1e, 0xa3,
+ 0x27, 0xba, 0xac, 0x3c, 0x41, 0xcd, 0xc6, 0x9f, 0x25, 0xc8, 0x0f, 0xac, 0xf1, 0x1a, 0xfd, 0x75,
+ 0xa9, 0xc8, 0xe4, 0x7f, 0xf8, 0x22, 0xc3, 0xaf, 0xd8, 0xf8, 0xb7, 0x04, 0xf7, 0x56, 0x7c, 0xfa,
+ 0xe2, 0x51, 0x66, 0xda, 0x95, 0x58, 0x13, 0xd4, 0xdf, 0xe6, 0x53, 0x7a, 0xc6, 0xe3, 0x1d, 0x71,
+ 0x86, 0x5d, 0x8f, 0xa1, 0xba, 0x20, 0x5a, 0xd1, 0x0d, 0x5f, 0x2c, 0x76, 0xc3, 0x5f, 0x6c, 0x7c,
+ 0x0e, 0xf1, 0x4f, 0x46, 0xa6, 0x5d, 0xfe, 0xa7, 0x08, 0xb5, 0x45, 0x29, 0xee, 0x89, 0x97, 0x4c,
+ 0x37, 0xae, 0xdd, 0x62, 0xb4, 0xe7, 0x30, 0x4d, 0xfa, 0x3c, 0xf9, 0xe3, 0x5d, 0x23, 0xce, 0x69,
+ 0x8f, 0xcd, 0x67, 0x7a, 0xac, 0x0e, 0x39, 0xc7, 0x67, 0xc3, 0x52, 0x6d, 0xff, 0x8b, 0xdb, 0x9e,
+ 0x42, 0xf3, 0x8d, 0x9c, 0xe3, 0xd3, 0x3b, 0x8d, 0xdc, 0xe0, 0x8a, 0xd5, 0xfb, 0xb7, 0xb8, 0xd3,
+ 0x97, 0x6e, 0x70, 0x65, 0x30, 0x24, 0x5a, 0x51, 0xad, 0x24, 0xbe, 0x08, 0x42, 0xe7, 0x8f, 0xfc,
+ 0xf3, 0x8f, 0xb6, 0x70, 0xde, 0x32, 0xd0, 0x82, 0xe0, 0x34, 0x74, 0x69, 0x71, 0x8b, 0x83, 0xd7,
+ 0x84, 0x2b, 0xf1, 0xce, 0xa1, 0x30, 0x06, 0x15, 0xb2, 0x99, 0x3c, 0x98, 0x90, 0x88, 0xf5, 0x8d,
+ 0xcd, 0x66, 0x72, 0x6a, 0x66, 0x08, 0x73, 0x3c, 0x5e, 0x18, 0xd8, 0xf8, 0x37, 0xe3, 0xf1, 0x6d,
+ 0xaf, 0xfa, 0x23, 0x8c, 0x6e, 0xcf, 0x41, 0xa6, 0x8f, 0x06, 0x23, 0xd8, 0x1a, 0xbc, 0xec, 0xb5,
+ 0x4d, 0xad, 0xf3, 0x55, 0xeb, 0x44, 0x3b, 0x42, 0xef, 0xe1, 0x1a, 0x00, 0xe3, 0x1c, 0xb4, 0xfa,
+ 0xda, 0x21, 0x92, 0x66, 0x1a, 0xad, 0x9e, 0x66, 0x3e, 0x6f, 0xbf, 0x44, 0x39, 0x7c, 0x07, 0x2a,
+ 0x8c, 0xd3, 0x6d, 0x9d, 0x0e, 0x9e, 0xed, 0xa3, 0x7c, 0xe3, 0x53, 0xc8, 0x69, 0x3e, 0x35, 0xd4,
+ 0x3a, 0x19, 0xa0, 0x2d, 0x50, 0xb4, 0x8e, 0xf9, 0xbb, 0xd3, 0xb6, 0x41, 0x6b, 0x64, 0x15, 0xca,
+ 0x5a, 0xc7, 0x7c, 0xd6, 0x6e, 0x1d, 0xb5, 0x0d, 0x94, 0x6b, 0x7c, 0x03, 0x32, 0x0d, 0x30, 0x45,
+ 0xff, 0xf2, 0xa4, 0x7b, 0x96, 0x31, 0xbb, 0x0b, 0x55, 0xce, 0x79, 0xd1, 0x3b, 0xd1, 0x0e, 0xb5,
+ 0x01, 0x92, 0x66, 0xac, 0x5e, 0xab, 0xdf, 0x3f, 0xeb, 0x1a, 0x47, 0x28, 0x87, 0xb7, 0x01, 0x31,
+ 0x56, 0xab, 0x47, 0xb5, 0x5a, 0x03, 0xad, 0xdb, 0x41, 0xf9, 0x39, 0xf7, 0xf0, 0xb0, 0xdd, 0xef,
+ 0x9b, 0x87, 0xdd, 0xa3, 0x36, 0x92, 0x1b, 0xff, 0xca, 0xcd, 0xab, 0x4d, 0xe6, 0x5b, 0x18, 0xff,
+ 0x49, 0xca, 0xfc, 0x8b, 0x17, 0xce, 0x05, 0xa2, 0xf4, 0x9c, 0xbe, 0xcd, 0x87, 0xf6, 0x2a, 0x1e,
+ 0x0f, 0xee, 0xec, 0xef, 0xbd, 0x8c, 0xa4, 0xfe, 0x09, 0xa8, 0x2b, 0x0c, 0x58, 0xd4, 0x68, 0x0f,
+ 0x64, 0x8f, 0x4e, 0xfc, 0x5d, 0xc3, 0x89, 0xfa, 0x77, 0xd2, 0x4a, 0x93, 0xef, 0x7b, 0x21, 0xaf,
+ 0x17, 0x5f, 0xc8, 0x0f, 0x7e, 0xb7, 0xa5, 0x07, 0xf6, 0x17, 0x89, 0x8e, 0xd5, 0x2c, 0x57, 0x7a,
+ 0xd9, 0x0b, 0x54, 0x36, 0xa9, 0x2f, 0xcc, 0x9e, 0xff, 0x70, 0xe7, 0x89, 0xcb, 0x7f, 0x0e, 0x30,
+ 0x67, 0xae, 0xb8, 0xed, 0x76, 0xf6, 0xb6, 0xe5, 0xcc, 0xb1, 0x0e, 0x0e, 0x7f, 0xdf, 0x1a, 0x3b,
+ 0xf1, 0x45, 0x72, 0xde, 0xb4, 0x03, 0x6f, 0x8f, 0x1e, 0xe4, 0x29, 0xb1, 0x83, 0x68, 0x1a, 0xc5,
+ 0x44, 0x90, 0xe2, 0x5c, 0x7b, 0xdf, 0xff, 0xd7, 0xff, 0x79, 0x91, 0xc9, 0x3e, 0xfb, 0x6f, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0x29, 0x5a, 0xd3, 0x93, 0x1f, 0x18, 0x00, 0x00,
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/openapiv2.proto b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/openapiv2.proto
new file mode 100644
index 0000000..83cb564
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options/openapiv2.proto
@@ -0,0 +1,379 @@
+syntax = "proto3";
+
+package grpc.gateway.protoc_gen_swagger.options;
+
+option go_package = "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/struct.proto";
+
+// `Swagger` is a representation of OpenAPI v2 specification's Swagger object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#swaggerObject
+//
+// TODO(ivucica): document fields
+message Swagger {
+ string swagger = 1;
+ Info info = 2;
+ string host = 3;
+ // `base_path` is the common prefix path used on all API endpoints (ie. /api, /v1, etc.). By adding this,
+ // it allows you to remove this portion from the path endpoints in your Swagger file making them easier
+ // to read. Note that using `base_path` does not change the endpoint paths that are generated in the resulting
+ // Swagger file. If you wish to use `base_path` with relatively generated Swagger paths, the
+ // `base_path` prefix must be manually removed from your `google.api.http` paths and your code changed to
+ // serve the API from the `base_path`.
+ string base_path = 4;
+ enum SwaggerScheme {
+ UNKNOWN = 0;
+ HTTP = 1;
+ HTTPS = 2;
+ WS = 3;
+ WSS = 4;
+ }
+ repeated SwaggerScheme schemes = 5;
+ repeated string consumes = 6;
+ repeated string produces = 7;
+ // field 8 is reserved for 'paths'.
+ reserved 8;
+ // field 9 is reserved for 'definitions', which at this time are already
+ // exposed as and customizable as proto messages.
+ reserved 9;
+ map<string, Response> responses = 10;
+ SecurityDefinitions security_definitions = 11;
+ repeated SecurityRequirement security = 12;
+ // field 13 is reserved for 'tags', which are supposed to be exposed as and
+ // customizable as proto services. TODO(ivucica): add processing of proto
+ // service objects into OpenAPI v2 Tag objects.
+ reserved 13;
+ ExternalDocumentation external_docs = 14;
+ map<string, google.protobuf.Value> extensions = 15;
+}
+
+// `Operation` is a representation of OpenAPI v2 specification's Operation object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#operationObject
+//
+// TODO(ivucica): document fields
+message Operation {
+ repeated string tags = 1;
+ string summary = 2;
+ string description = 3;
+ ExternalDocumentation external_docs = 4;
+ string operation_id = 5;
+ repeated string consumes = 6;
+ repeated string produces = 7;
+ // field 8 is reserved for 'parameters'.
+ reserved 8;
+ map<string, Response> responses = 9;
+ repeated string schemes = 10;
+ bool deprecated = 11;
+ repeated SecurityRequirement security = 12;
+ map<string, google.protobuf.Value> extensions = 13;
+}
+
+// `Response` is a representation of OpenAPI v2 specification's Response object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responseObject
+//
+message Response {
+ // `Description` is a short description of the response.
+ // GFM syntax can be used for rich text representation.
+ string description = 1;
+ // `Schema` optionally defines the structure of the response.
+ // If `Schema` is not provided, it means there is no content to the response.
+ Schema schema = 2;
+ // field 3 is reserved for 'headers'.
+ reserved 3;
+ // field 3 is reserved for 'example'.
+ reserved 4;
+ map<string, google.protobuf.Value> extensions = 5;
+}
+
+// `Info` is a representation of OpenAPI v2 specification's Info object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#infoObject
+//
+// TODO(ivucica): document fields
+message Info {
+ string title = 1;
+ string description = 2;
+ string terms_of_service = 3;
+ Contact contact = 4;
+ License license = 5;
+ string version = 6;
+ map<string, google.protobuf.Value> extensions = 7;
+}
+
+// `Contact` is a representation of OpenAPI v2 specification's Contact object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#contactObject
+//
+// TODO(ivucica): document fields
+message Contact {
+ string name = 1;
+ string url = 2;
+ string email = 3;
+}
+
+// `License` is a representation of OpenAPI v2 specification's License object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#licenseObject
+//
+message License {
+ // Required. The license name used for the API.
+ string name = 1;
+ // A URL to the license used for the API.
+ string url = 2;
+}
+
+// `ExternalDocumentation` is a representation of OpenAPI v2 specification's
+// ExternalDocumentation object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#externalDocumentationObject
+//
+// TODO(ivucica): document fields
+message ExternalDocumentation {
+ string description = 1;
+ string url = 2;
+}
+
+// `Schema` is a representation of OpenAPI v2 specification's Schema object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
+//
+// TODO(ivucica): document fields
+message Schema {
+ JSONSchema json_schema = 1;
+ string discriminator = 2;
+ bool read_only = 3;
+ // field 4 is reserved for 'xml'.
+ reserved 4;
+ ExternalDocumentation external_docs = 5;
+ google.protobuf.Any example = 6;
+}
+
+// `JSONSchema` represents properties from JSON Schema taken, and as used, in
+// the OpenAPI v2 spec.
+//
+// This includes changes made by OpenAPI v2.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
+//
+// See also: https://cswr.github.io/JsonSchema/spec/basic_types/,
+// https://github.com/json-schema-org/json-schema-spec/blob/master/schema.json
+//
+// TODO(ivucica): document fields
+message JSONSchema {
+ // field 1 is reserved for '$id', omitted from OpenAPI v2.
+ reserved 1;
+ // field 2 is reserved for '$schema', omitted from OpenAPI v2.
+ reserved 2;
+ // Ref is used to define an external reference to include in the message.
+ // This could be a fully qualified proto message reference, and that type must be imported
+ // into the protofile. If no message is identified, the Ref will be used verbatim in
+ // the output.
+ // For example:
+ // `ref: ".google.protobuf.Timestamp"`.
+ string ref = 3;
+ // field 4 is reserved for '$comment', omitted from OpenAPI v2.
+ reserved 4;
+ string title = 5;
+ string description = 6;
+ string default = 7;
+ bool read_only = 8;
+ // field 9 is reserved for 'examples', which is omitted from OpenAPI v2 in favor of 'example' field.
+ reserved 9;
+ double multiple_of = 10;
+ double maximum = 11;
+ bool exclusive_maximum = 12;
+ double minimum = 13;
+ bool exclusive_minimum = 14;
+ uint64 max_length = 15;
+ uint64 min_length = 16;
+ string pattern = 17;
+ // field 18 is reserved for 'additionalItems', omitted from OpenAPI v2.
+ reserved 18;
+ // field 19 is reserved for 'items', but in OpenAPI-specific way. TODO(ivucica): add 'items'?
+ reserved 19;
+ uint64 max_items = 20;
+ uint64 min_items = 21;
+ bool unique_items = 22;
+ // field 23 is reserved for 'contains', omitted from OpenAPI v2.
+ reserved 23;
+ uint64 max_properties = 24;
+ uint64 min_properties = 25;
+ repeated string required = 26;
+ // field 27 is reserved for 'additionalProperties', but in OpenAPI-specific way. TODO(ivucica): add 'additionalProperties'?
+ reserved 27;
+ // field 28 is reserved for 'definitions', omitted from OpenAPI v2.
+ reserved 28;
+ // field 29 is reserved for 'properties', but in OpenAPI-specific way. TODO(ivucica): add 'additionalProperties'?
+ reserved 29;
+ // following fields are reserved, as the properties have been omitted from OpenAPI v2:
+ // patternProperties, dependencies, propertyNames, const
+ reserved 30 to 33;
+ // Items in 'array' must be unique.
+ repeated string array = 34;
+
+ enum JSONSchemaSimpleTypes {
+ UNKNOWN = 0;
+ ARRAY = 1;
+ BOOLEAN = 2;
+ INTEGER = 3;
+ NULL = 4;
+ NUMBER = 5;
+ OBJECT = 6;
+ STRING = 7;
+ }
+
+ repeated JSONSchemaSimpleTypes type = 35;
+ // following fields are reserved, as the properties have been omitted from OpenAPI v2:
+ // format, contentMediaType, contentEncoding, if, then, else
+ reserved 36 to 41;
+ // field 42 is reserved for 'allOf', but in OpenAPI-specific way. TODO(ivucica): add 'allOf'?
+ reserved 42;
+ // following fields are reserved, as the properties have been omitted from OpenAPI v2:
+ // anyOf, oneOf, not
+ reserved 43 to 45;
+}
+
+// `Tag` is a representation of OpenAPI v2 specification's Tag object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#tagObject
+//
+// TODO(ivucica): document fields
+message Tag {
+ // field 1 is reserved for 'name'. In our generator, this is (to be) extracted
+ // from the name of proto service, and thus not exposed to the user, as
+ // changing tag object's name would break the link to the references to the
+ // tag in individual operation specifications.
+ //
+ // TODO(ivucica): Add 'name' property. Use it to allow override of the name of
+ // global Tag object, then use that name to reference the tag throughout the
+ // Swagger file.
+ reserved 1;
+ // TODO(ivucica): Description should be extracted from comments on the proto
+ // service object.
+ string description = 2;
+ ExternalDocumentation external_docs = 3;
+}
+
+// `SecurityDefinitions` is a representation of OpenAPI v2 specification's
+// Security Definitions object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityDefinitionsObject
+//
+// A declaration of the security schemes available to be used in the
+// specification. This does not enforce the security schemes on the operations
+// and only serves to provide the relevant details for each scheme.
+message SecurityDefinitions {
+ // A single security scheme definition, mapping a "name" to the scheme it defines.
+ map<string, SecurityScheme> security = 1;
+}
+
+// `SecurityScheme` is a representation of OpenAPI v2 specification's
+// Security Scheme object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securitySchemeObject
+//
+// Allows the definition of a security scheme that can be used by the
+// operations. Supported schemes are basic authentication, an API key (either as
+// a header or as a query parameter) and OAuth2's common flows (implicit,
+// password, application and access code).
+message SecurityScheme {
+ // Required. The type of the security scheme. Valid values are "basic",
+ // "apiKey" or "oauth2".
+ enum Type {
+ TYPE_INVALID = 0;
+ TYPE_BASIC = 1;
+ TYPE_API_KEY = 2;
+ TYPE_OAUTH2 = 3;
+ }
+
+ // Required. The location of the API key. Valid values are "query" or "header".
+ enum In {
+ IN_INVALID = 0;
+ IN_QUERY = 1;
+ IN_HEADER = 2;
+ }
+
+ // Required. The flow used by the OAuth2 security scheme. Valid values are
+ // "implicit", "password", "application" or "accessCode".
+ enum Flow {
+ FLOW_INVALID = 0;
+ FLOW_IMPLICIT = 1;
+ FLOW_PASSWORD = 2;
+ FLOW_APPLICATION = 3;
+ FLOW_ACCESS_CODE = 4;
+ }
+
+ // Required. The type of the security scheme. Valid values are "basic",
+ // "apiKey" or "oauth2".
+ Type type = 1;
+ // A short description for security scheme.
+ string description = 2;
+ // Required. The name of the header or query parameter to be used.
+ //
+ // Valid for apiKey.
+ string name = 3;
+ // Required. The location of the API key. Valid values are "query" or "header".
+ //
+ // Valid for apiKey.
+ In in = 4;
+ // Required. The flow used by the OAuth2 security scheme. Valid values are
+ // "implicit", "password", "application" or "accessCode".
+ //
+ // Valid for oauth2.
+ Flow flow = 5;
+ // Required. The authorization URL to be used for this flow. This SHOULD be in
+ // the form of a URL.
+ //
+ // Valid for oauth2/implicit and oauth2/accessCode.
+ string authorization_url = 6;
+ // Required. The token URL to be used for this flow. This SHOULD be in the
+ // form of a URL.
+ //
+ // Valid for oauth2/password, oauth2/application and oauth2/accessCode.
+ string token_url = 7;
+ // Required. The available scopes for the OAuth2 security scheme.
+ //
+ // Valid for oauth2.
+ Scopes scopes = 8;
+ map<string, google.protobuf.Value> extensions = 9;
+}
+
+// `SecurityRequirement` is a representation of OpenAPI v2 specification's
+// Security Requirement object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityRequirementObject
+//
+// Lists the required security schemes to execute this operation. The object can
+// have multiple security schemes declared in it which are all required (that
+// is, there is a logical AND between the schemes).
+//
+// The name used for each property MUST correspond to a security scheme
+// declared in the Security Definitions.
+message SecurityRequirement {
+ // If the security scheme is of type "oauth2", then the value is a list of
+ // scope names required for the execution. For other security scheme types,
+ // the array MUST be empty.
+ message SecurityRequirementValue {
+ repeated string scope = 1;
+ }
+ // Each name must correspond to a security scheme which is declared in
+ // the Security Definitions. If the security scheme is of type "oauth2",
+ // then the value is a list of scope names required for the execution.
+ // For other security scheme types, the array MUST be empty.
+ map<string, SecurityRequirementValue> security_requirement = 1;
+}
+
+// `Scopes` is a representation of OpenAPI v2 specification's Scopes object.
+//
+// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#scopesObject
+//
+// Lists the available scopes for an OAuth2 security scheme.
+message Scopes {
+ // Maps between a name of a scope to a short description of it (as the value
+ // of the property).
+ map<string, string> scope = 1;
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel
new file mode 100644
index 0000000..819c45a
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel
@@ -0,0 +1,86 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//visibility:public"])
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "context.go",
+ "convert.go",
+ "doc.go",
+ "errors.go",
+ "fieldmask.go",
+ "handler.go",
+ "marshal_httpbodyproto.go",
+ "marshal_json.go",
+ "marshal_jsonpb.go",
+ "marshal_proto.go",
+ "marshaler.go",
+ "marshaler_registry.go",
+ "mux.go",
+ "pattern.go",
+ "proto2_convert.go",
+ "proto_errors.go",
+ "query.go",
+ ],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/runtime",
+ deps = [
+ "//internal:go_default_library",
+ "//utilities:go_default_library",
+ "@com_github_golang_protobuf//descriptor:go_default_library_gen",
+ "@com_github_golang_protobuf//jsonpb:go_default_library_gen",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@go_googleapis//google/api:httpbody_go_proto",
+ "@io_bazel_rules_go//proto/wkt:any_go_proto",
+ "@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
+ "@io_bazel_rules_go//proto/wkt:duration_go_proto",
+ "@io_bazel_rules_go//proto/wkt:field_mask_go_proto",
+ "@io_bazel_rules_go//proto/wkt:timestamp_go_proto",
+ "@io_bazel_rules_go//proto/wkt:wrappers_go_proto",
+ "@org_golang_google_grpc//codes:go_default_library",
+ "@org_golang_google_grpc//grpclog:go_default_library",
+ "@org_golang_google_grpc//metadata:go_default_library",
+ "@org_golang_google_grpc//status:go_default_library",
+ ],
+)
+
+go_test(
+ name = "go_default_test",
+ size = "small",
+ srcs = [
+ "context_test.go",
+ "convert_test.go",
+ "errors_test.go",
+ "fieldmask_test.go",
+ "handler_test.go",
+ "marshal_httpbodyproto_test.go",
+ "marshal_json_test.go",
+ "marshal_jsonpb_test.go",
+ "marshal_proto_test.go",
+ "marshaler_registry_test.go",
+ "mux_test.go",
+ "pattern_test.go",
+ "query_test.go",
+ ],
+ embed = [":go_default_library"],
+ deps = [
+ "//examples/proto/examplepb:go_default_library",
+ "//internal:go_default_library",
+ "//utilities:go_default_library",
+ "@com_github_golang_protobuf//jsonpb:go_default_library_gen",
+ "@com_github_golang_protobuf//proto:go_default_library",
+ "@com_github_golang_protobuf//ptypes:go_default_library_gen",
+ "@go_googleapis//google/api:httpbody_go_proto",
+ "@go_googleapis//google/rpc:errdetails_go_proto",
+ "@io_bazel_rules_go//proto/wkt:duration_go_proto",
+ "@io_bazel_rules_go//proto/wkt:empty_go_proto",
+ "@io_bazel_rules_go//proto/wkt:field_mask_go_proto",
+ "@io_bazel_rules_go//proto/wkt:struct_go_proto",
+ "@io_bazel_rules_go//proto/wkt:timestamp_go_proto",
+ "@io_bazel_rules_go//proto/wkt:wrappers_go_proto",
+ "@org_golang_google_grpc//:go_default_library",
+ "@org_golang_google_grpc//codes:go_default_library",
+ "@org_golang_google_grpc//metadata:go_default_library",
+ "@org_golang_google_grpc//status:go_default_library",
+ ],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go
new file mode 100644
index 0000000..f808382
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go
@@ -0,0 +1,236 @@
+package runtime
+
+import (
+ "context"
+ "encoding/base64"
+ "fmt"
+ "net"
+ "net/http"
+ "net/textproto"
+ "strconv"
+ "strings"
+ "time"
+
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/grpclog"
+ "google.golang.org/grpc/metadata"
+ "google.golang.org/grpc/status"
+)
+
+// MetadataHeaderPrefix is the http prefix that represents custom metadata
+// parameters to or from a gRPC call.
+const MetadataHeaderPrefix = "Grpc-Metadata-"
+
+// MetadataPrefix is prepended to permanent HTTP header keys (as specified
+// by the IANA) when added to the gRPC context.
+const MetadataPrefix = "grpcgateway-"
+
+// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to
+// HTTP headers in a response handled by grpc-gateway
+const MetadataTrailerPrefix = "Grpc-Trailer-"
+
+const metadataGrpcTimeout = "Grpc-Timeout"
+const metadataHeaderBinarySuffix = "-Bin"
+
+const xForwardedFor = "X-Forwarded-For"
+const xForwardedHost = "X-Forwarded-Host"
+
+var (
+ // DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound
+ // header isn't present. If the value is 0 the sent `context` will not have a timeout.
+ DefaultContextTimeout = 0 * time.Second
+)
+
+func decodeBinHeader(v string) ([]byte, error) {
+ if len(v)%4 == 0 {
+ // Input was padded, or padding was not necessary.
+ return base64.StdEncoding.DecodeString(v)
+ }
+ return base64.RawStdEncoding.DecodeString(v)
+}
+
+/*
+AnnotateContext adds context information such as metadata from the request.
+
+At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For",
+except that the forwarded destination is not another HTTP service but rather
+a gRPC service.
+*/
+func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) {
+ ctx, md, err := annotateContext(ctx, mux, req)
+ if err != nil {
+ return nil, err
+ }
+ if md == nil {
+ return ctx, nil
+ }
+
+ return metadata.NewOutgoingContext(ctx, md), nil
+}
+
+// AnnotateIncomingContext adds context information such as metadata from the request.
+// Attach metadata as incoming context.
+func AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) {
+ ctx, md, err := annotateContext(ctx, mux, req)
+ if err != nil {
+ return nil, err
+ }
+ if md == nil {
+ return ctx, nil
+ }
+
+ return metadata.NewIncomingContext(ctx, md), nil
+}
+
+func annotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, metadata.MD, error) {
+ var pairs []string
+ timeout := DefaultContextTimeout
+ if tm := req.Header.Get(metadataGrpcTimeout); tm != "" {
+ var err error
+ timeout, err = timeoutDecode(tm)
+ if err != nil {
+ return nil, nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm)
+ }
+ }
+
+ for key, vals := range req.Header {
+ for _, val := range vals {
+ key = textproto.CanonicalMIMEHeaderKey(key)
+ // For backwards-compatibility, pass through 'authorization' header with no prefix.
+ if key == "Authorization" {
+ pairs = append(pairs, "authorization", val)
+ }
+ if h, ok := mux.incomingHeaderMatcher(key); ok {
+ // Handles "-bin" metadata in grpc, since grpc will do another base64
+ // encode before sending to server, we need to decode it first.
+ if strings.HasSuffix(key, metadataHeaderBinarySuffix) {
+ b, err := decodeBinHeader(val)
+ if err != nil {
+ return nil, nil, status.Errorf(codes.InvalidArgument, "invalid binary header %s: %s", key, err)
+ }
+
+ val = string(b)
+ }
+ pairs = append(pairs, h, val)
+ }
+ }
+ }
+ if host := req.Header.Get(xForwardedHost); host != "" {
+ pairs = append(pairs, strings.ToLower(xForwardedHost), host)
+ } else if req.Host != "" {
+ pairs = append(pairs, strings.ToLower(xForwardedHost), req.Host)
+ }
+
+ if addr := req.RemoteAddr; addr != "" {
+ if remoteIP, _, err := net.SplitHostPort(addr); err == nil {
+ if fwd := req.Header.Get(xForwardedFor); fwd == "" {
+ pairs = append(pairs, strings.ToLower(xForwardedFor), remoteIP)
+ } else {
+ pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP))
+ }
+ } else {
+ grpclog.Infof("invalid remote addr: %s", addr)
+ }
+ }
+
+ if timeout != 0 {
+ ctx, _ = context.WithTimeout(ctx, timeout)
+ }
+ if len(pairs) == 0 {
+ return ctx, nil, nil
+ }
+ md := metadata.Pairs(pairs...)
+ for _, mda := range mux.metadataAnnotators {
+ md = metadata.Join(md, mda(ctx, req))
+ }
+ return ctx, md, nil
+}
+
+// ServerMetadata consists of metadata sent from gRPC server.
+type ServerMetadata struct {
+ HeaderMD metadata.MD
+ TrailerMD metadata.MD
+}
+
+type serverMetadataKey struct{}
+
+// NewServerMetadataContext creates a new context with ServerMetadata
+func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context {
+ return context.WithValue(ctx, serverMetadataKey{}, md)
+}
+
+// ServerMetadataFromContext returns the ServerMetadata in ctx
+func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) {
+ md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata)
+ return
+}
+
+func timeoutDecode(s string) (time.Duration, error) {
+ size := len(s)
+ if size < 2 {
+ return 0, fmt.Errorf("timeout string is too short: %q", s)
+ }
+ d, ok := timeoutUnitToDuration(s[size-1])
+ if !ok {
+ return 0, fmt.Errorf("timeout unit is not recognized: %q", s)
+ }
+ t, err := strconv.ParseInt(s[:size-1], 10, 64)
+ if err != nil {
+ return 0, err
+ }
+ return d * time.Duration(t), nil
+}
+
+func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) {
+ switch u {
+ case 'H':
+ return time.Hour, true
+ case 'M':
+ return time.Minute, true
+ case 'S':
+ return time.Second, true
+ case 'm':
+ return time.Millisecond, true
+ case 'u':
+ return time.Microsecond, true
+ case 'n':
+ return time.Nanosecond, true
+ default:
+ }
+ return
+}
+
+// isPermanentHTTPHeader checks whether hdr belongs to the list of
+// permenant request headers maintained by IANA.
+// http://www.iana.org/assignments/message-headers/message-headers.xml
+func isPermanentHTTPHeader(hdr string) bool {
+ switch hdr {
+ case
+ "Accept",
+ "Accept-Charset",
+ "Accept-Language",
+ "Accept-Ranges",
+ "Authorization",
+ "Cache-Control",
+ "Content-Type",
+ "Cookie",
+ "Date",
+ "Expect",
+ "From",
+ "Host",
+ "If-Match",
+ "If-Modified-Since",
+ "If-None-Match",
+ "If-Schedule-Tag-Match",
+ "If-Unmodified-Since",
+ "Max-Forwards",
+ "Origin",
+ "Pragma",
+ "Referer",
+ "User-Agent",
+ "Via",
+ "Warning":
+ return true
+ }
+ return false
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go
new file mode 100644
index 0000000..2c27934
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go
@@ -0,0 +1,318 @@
+package runtime
+
+import (
+ "encoding/base64"
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/golang/protobuf/jsonpb"
+ "github.com/golang/protobuf/ptypes/duration"
+ "github.com/golang/protobuf/ptypes/timestamp"
+ "github.com/golang/protobuf/ptypes/wrappers"
+)
+
+// String just returns the given string.
+// It is just for compatibility to other types.
+func String(val string) (string, error) {
+ return val, nil
+}
+
+// StringSlice converts 'val' where individual strings are separated by
+// 'sep' into a string slice.
+func StringSlice(val, sep string) ([]string, error) {
+ return strings.Split(val, sep), nil
+}
+
+// Bool converts the given string representation of a boolean value into bool.
+func Bool(val string) (bool, error) {
+ return strconv.ParseBool(val)
+}
+
+// BoolSlice converts 'val' where individual booleans are separated by
+// 'sep' into a bool slice.
+func BoolSlice(val, sep string) ([]bool, error) {
+ s := strings.Split(val, sep)
+ values := make([]bool, len(s))
+ for i, v := range s {
+ value, err := Bool(v)
+ if err != nil {
+ return values, err
+ }
+ values[i] = value
+ }
+ return values, nil
+}
+
+// Float64 converts the given string representation into representation of a floating point number into float64.
+func Float64(val string) (float64, error) {
+ return strconv.ParseFloat(val, 64)
+}
+
+// Float64Slice converts 'val' where individual floating point numbers are separated by
+// 'sep' into a float64 slice.
+func Float64Slice(val, sep string) ([]float64, error) {
+ s := strings.Split(val, sep)
+ values := make([]float64, len(s))
+ for i, v := range s {
+ value, err := Float64(v)
+ if err != nil {
+ return values, err
+ }
+ values[i] = value
+ }
+ return values, nil
+}
+
+// Float32 converts the given string representation of a floating point number into float32.
+func Float32(val string) (float32, error) {
+ f, err := strconv.ParseFloat(val, 32)
+ if err != nil {
+ return 0, err
+ }
+ return float32(f), nil
+}
+
+// Float32Slice converts 'val' where individual floating point numbers are separated by
+// 'sep' into a float32 slice.
+func Float32Slice(val, sep string) ([]float32, error) {
+ s := strings.Split(val, sep)
+ values := make([]float32, len(s))
+ for i, v := range s {
+ value, err := Float32(v)
+ if err != nil {
+ return values, err
+ }
+ values[i] = value
+ }
+ return values, nil
+}
+
+// Int64 converts the given string representation of an integer into int64.
+func Int64(val string) (int64, error) {
+ return strconv.ParseInt(val, 0, 64)
+}
+
+// Int64Slice converts 'val' where individual integers are separated by
+// 'sep' into a int64 slice.
+func Int64Slice(val, sep string) ([]int64, error) {
+ s := strings.Split(val, sep)
+ values := make([]int64, len(s))
+ for i, v := range s {
+ value, err := Int64(v)
+ if err != nil {
+ return values, err
+ }
+ values[i] = value
+ }
+ return values, nil
+}
+
+// Int32 converts the given string representation of an integer into int32.
+func Int32(val string) (int32, error) {
+ i, err := strconv.ParseInt(val, 0, 32)
+ if err != nil {
+ return 0, err
+ }
+ return int32(i), nil
+}
+
+// Int32Slice converts 'val' where individual integers are separated by
+// 'sep' into a int32 slice.
+func Int32Slice(val, sep string) ([]int32, error) {
+ s := strings.Split(val, sep)
+ values := make([]int32, len(s))
+ for i, v := range s {
+ value, err := Int32(v)
+ if err != nil {
+ return values, err
+ }
+ values[i] = value
+ }
+ return values, nil
+}
+
+// Uint64 converts the given string representation of an integer into uint64.
+func Uint64(val string) (uint64, error) {
+ return strconv.ParseUint(val, 0, 64)
+}
+
+// Uint64Slice converts 'val' where individual integers are separated by
+// 'sep' into a uint64 slice.
+func Uint64Slice(val, sep string) ([]uint64, error) {
+ s := strings.Split(val, sep)
+ values := make([]uint64, len(s))
+ for i, v := range s {
+ value, err := Uint64(v)
+ if err != nil {
+ return values, err
+ }
+ values[i] = value
+ }
+ return values, nil
+}
+
+// Uint32 converts the given string representation of an integer into uint32.
+func Uint32(val string) (uint32, error) {
+ i, err := strconv.ParseUint(val, 0, 32)
+ if err != nil {
+ return 0, err
+ }
+ return uint32(i), nil
+}
+
+// Uint32Slice converts 'val' where individual integers are separated by
+// 'sep' into a uint32 slice.
+func Uint32Slice(val, sep string) ([]uint32, error) {
+ s := strings.Split(val, sep)
+ values := make([]uint32, len(s))
+ for i, v := range s {
+ value, err := Uint32(v)
+ if err != nil {
+ return values, err
+ }
+ values[i] = value
+ }
+ return values, nil
+}
+
+// Bytes converts the given string representation of a byte sequence into a slice of bytes
+// A bytes sequence is encoded in URL-safe base64 without padding
+func Bytes(val string) ([]byte, error) {
+ b, err := base64.StdEncoding.DecodeString(val)
+ if err != nil {
+ b, err = base64.URLEncoding.DecodeString(val)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return b, nil
+}
+
+// BytesSlice converts 'val' where individual bytes sequences, encoded in URL-safe
+// base64 without padding, are separated by 'sep' into a slice of bytes slices slice.
+func BytesSlice(val, sep string) ([][]byte, error) {
+ s := strings.Split(val, sep)
+ values := make([][]byte, len(s))
+ for i, v := range s {
+ value, err := Bytes(v)
+ if err != nil {
+ return values, err
+ }
+ values[i] = value
+ }
+ return values, nil
+}
+
+// Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp.
+func Timestamp(val string) (*timestamp.Timestamp, error) {
+ var r timestamp.Timestamp
+ err := jsonpb.UnmarshalString(val, &r)
+ if err != nil {
+ return nil, err
+ }
+ return &r, nil
+}
+
+// Duration converts the given string into a timestamp.Duration.
+func Duration(val string) (*duration.Duration, error) {
+ var r duration.Duration
+ err := jsonpb.UnmarshalString(val, &r)
+ if err != nil {
+ return nil, err
+ }
+ return &r, nil
+}
+
+// Enum converts the given string into an int32 that should be type casted into the
+// correct enum proto type.
+func Enum(val string, enumValMap map[string]int32) (int32, error) {
+ e, ok := enumValMap[val]
+ if ok {
+ return e, nil
+ }
+
+ i, err := Int32(val)
+ if err != nil {
+ return 0, fmt.Errorf("%s is not valid", val)
+ }
+ for _, v := range enumValMap {
+ if v == i {
+ return i, nil
+ }
+ }
+ return 0, fmt.Errorf("%s is not valid", val)
+}
+
+// EnumSlice converts 'val' where individual enums are separated by 'sep'
+// into a int32 slice. Each individual int32 should be type casted into the
+// correct enum proto type.
+func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) {
+ s := strings.Split(val, sep)
+ values := make([]int32, len(s))
+ for i, v := range s {
+ value, err := Enum(v, enumValMap)
+ if err != nil {
+ return values, err
+ }
+ values[i] = value
+ }
+ return values, nil
+}
+
+/*
+ Support fot google.protobuf.wrappers on top of primitive types
+*/
+
+// StringValue well-known type support as wrapper around string type
+func StringValue(val string) (*wrappers.StringValue, error) {
+ return &wrappers.StringValue{Value: val}, nil
+}
+
+// FloatValue well-known type support as wrapper around float32 type
+func FloatValue(val string) (*wrappers.FloatValue, error) {
+ parsedVal, err := Float32(val)
+ return &wrappers.FloatValue{Value: parsedVal}, err
+}
+
+// DoubleValue well-known type support as wrapper around float64 type
+func DoubleValue(val string) (*wrappers.DoubleValue, error) {
+ parsedVal, err := Float64(val)
+ return &wrappers.DoubleValue{Value: parsedVal}, err
+}
+
+// BoolValue well-known type support as wrapper around bool type
+func BoolValue(val string) (*wrappers.BoolValue, error) {
+ parsedVal, err := Bool(val)
+ return &wrappers.BoolValue{Value: parsedVal}, err
+}
+
+// Int32Value well-known type support as wrapper around int32 type
+func Int32Value(val string) (*wrappers.Int32Value, error) {
+ parsedVal, err := Int32(val)
+ return &wrappers.Int32Value{Value: parsedVal}, err
+}
+
+// UInt32Value well-known type support as wrapper around uint32 type
+func UInt32Value(val string) (*wrappers.UInt32Value, error) {
+ parsedVal, err := Uint32(val)
+ return &wrappers.UInt32Value{Value: parsedVal}, err
+}
+
+// Int64Value well-known type support as wrapper around int64 type
+func Int64Value(val string) (*wrappers.Int64Value, error) {
+ parsedVal, err := Int64(val)
+ return &wrappers.Int64Value{Value: parsedVal}, err
+}
+
+// UInt64Value well-known type support as wrapper around uint64 type
+func UInt64Value(val string) (*wrappers.UInt64Value, error) {
+ parsedVal, err := Uint64(val)
+ return &wrappers.UInt64Value{Value: parsedVal}, err
+}
+
+// BytesValue well-known type support as wrapper around bytes[] type
+func BytesValue(val string) (*wrappers.BytesValue, error) {
+ parsedVal, err := Bytes(val)
+ return &wrappers.BytesValue{Value: parsedVal}, err
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go
new file mode 100644
index 0000000..b6e5ddf
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go
@@ -0,0 +1,5 @@
+/*
+Package runtime contains runtime helper functions used by
+servers which protoc-gen-grpc-gateway generates.
+*/
+package runtime
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go
new file mode 100644
index 0000000..a360807
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go
@@ -0,0 +1,146 @@
+package runtime
+
+import (
+ "context"
+ "io"
+ "net/http"
+
+ "github.com/golang/protobuf/proto"
+ "github.com/golang/protobuf/ptypes/any"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/grpclog"
+ "google.golang.org/grpc/status"
+)
+
+// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status.
+// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
+func HTTPStatusFromCode(code codes.Code) int {
+ switch code {
+ case codes.OK:
+ return http.StatusOK
+ case codes.Canceled:
+ return http.StatusRequestTimeout
+ case codes.Unknown:
+ return http.StatusInternalServerError
+ case codes.InvalidArgument:
+ return http.StatusBadRequest
+ case codes.DeadlineExceeded:
+ return http.StatusGatewayTimeout
+ case codes.NotFound:
+ return http.StatusNotFound
+ case codes.AlreadyExists:
+ return http.StatusConflict
+ case codes.PermissionDenied:
+ return http.StatusForbidden
+ case codes.Unauthenticated:
+ return http.StatusUnauthorized
+ case codes.ResourceExhausted:
+ return http.StatusTooManyRequests
+ case codes.FailedPrecondition:
+ // Note, this deliberately doesn't translate to the similarly named '412 Precondition Failed' HTTP response status.
+ return http.StatusBadRequest
+ case codes.Aborted:
+ return http.StatusConflict
+ case codes.OutOfRange:
+ return http.StatusBadRequest
+ case codes.Unimplemented:
+ return http.StatusNotImplemented
+ case codes.Internal:
+ return http.StatusInternalServerError
+ case codes.Unavailable:
+ return http.StatusServiceUnavailable
+ case codes.DataLoss:
+ return http.StatusInternalServerError
+ }
+
+ grpclog.Infof("Unknown gRPC error code: %v", code)
+ return http.StatusInternalServerError
+}
+
+var (
+ // HTTPError replies to the request with the error.
+ // You can set a custom function to this variable to customize error format.
+ HTTPError = DefaultHTTPError
+ // OtherErrorHandler handles the following error used by the gateway: StatusMethodNotAllowed StatusNotFound and StatusBadRequest
+ OtherErrorHandler = DefaultOtherErrorHandler
+)
+
+type errorBody struct {
+ Error string `protobuf:"bytes,100,name=error" json:"error"`
+ // This is to make the error more compatible with users that expect errors to be Status objects:
+ // https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto
+ // It should be the exact same message as the Error field.
+ Code int32 `protobuf:"varint,1,name=code" json:"code"`
+ Message string `protobuf:"bytes,2,name=message" json:"message"`
+ Details []*any.Any `protobuf:"bytes,3,rep,name=details" json:"details,omitempty"`
+}
+
+// Make this also conform to proto.Message for builtin JSONPb Marshaler
+func (e *errorBody) Reset() { *e = errorBody{} }
+func (e *errorBody) String() string { return proto.CompactTextString(e) }
+func (*errorBody) ProtoMessage() {}
+
+// DefaultHTTPError is the default implementation of HTTPError.
+// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode.
+// If otherwise, it replies with http.StatusInternalServerError.
+//
+// The response body returned by this function is a JSON object,
+// which contains a member whose key is "error" and whose value is err.Error().
+func DefaultHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
+ const fallback = `{"error": "failed to marshal error message"}`
+
+ s, ok := status.FromError(err)
+ if !ok {
+ s = status.New(codes.Unknown, err.Error())
+ }
+
+ w.Header().Del("Trailer")
+
+ contentType := marshaler.ContentType()
+ // Check marshaler on run time in order to keep backwards compatability
+ // An interface param needs to be added to the ContentType() function on
+ // the Marshal interface to be able to remove this check
+ if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
+ pb := s.Proto()
+ contentType = httpBodyMarshaler.ContentTypeFromMessage(pb)
+ }
+ w.Header().Set("Content-Type", contentType)
+
+ body := &errorBody{
+ Error: s.Message(),
+ Message: s.Message(),
+ Code: int32(s.Code()),
+ Details: s.Proto().GetDetails(),
+ }
+
+ buf, merr := marshaler.Marshal(body)
+ if merr != nil {
+ grpclog.Infof("Failed to marshal error message %q: %v", body, merr)
+ w.WriteHeader(http.StatusInternalServerError)
+ if _, err := io.WriteString(w, fallback); err != nil {
+ grpclog.Infof("Failed to write response: %v", err)
+ }
+ return
+ }
+
+ md, ok := ServerMetadataFromContext(ctx)
+ if !ok {
+ grpclog.Infof("Failed to extract ServerMetadata from context")
+ }
+
+ handleForwardResponseServerMetadata(w, mux, md)
+ handleForwardResponseTrailerHeader(w, md)
+ st := HTTPStatusFromCode(s.Code())
+ w.WriteHeader(st)
+ if _, err := w.Write(buf); err != nil {
+ grpclog.Infof("Failed to write response: %v", err)
+ }
+
+ handleForwardResponseTrailer(w, md)
+}
+
+// DefaultOtherErrorHandler is the default implementation of OtherErrorHandler.
+// It simply writes a string representation of the given error into "w".
+func DefaultOtherErrorHandler(w http.ResponseWriter, _ *http.Request, msg string, code int) {
+ http.Error(w, msg, code)
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go
new file mode 100644
index 0000000..341aad5
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go
@@ -0,0 +1,82 @@
+package runtime
+
+import (
+ "encoding/json"
+ "io"
+ "strings"
+
+ descriptor2 "github.com/golang/protobuf/descriptor"
+ "github.com/golang/protobuf/protoc-gen-go/descriptor"
+ "google.golang.org/genproto/protobuf/field_mask"
+)
+
+func translateName(name string, md *descriptor.DescriptorProto) (string, *descriptor.DescriptorProto) {
+ // TODO - should really gate this with a test that the marshaller has used json names
+ if md != nil {
+ for _, f := range md.Field {
+ if f.JsonName != nil && f.Name != nil && *f.JsonName == name {
+ var subType *descriptor.DescriptorProto
+
+ // If the field has a TypeName then we retrieve the nested type for translating the embedded message names.
+ if f.TypeName != nil {
+ typeSplit := strings.Split(*f.TypeName, ".")
+ typeName := typeSplit[len(typeSplit)-1]
+ for _, t := range md.NestedType {
+ if typeName == *t.Name {
+ subType = t
+ }
+ }
+ }
+ return *f.Name, subType
+ }
+ }
+ }
+ return name, nil
+}
+
+// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body.
+func FieldMaskFromRequestBody(r io.Reader, md *descriptor.DescriptorProto) (*field_mask.FieldMask, error) {
+ fm := &field_mask.FieldMask{}
+ var root interface{}
+ if err := json.NewDecoder(r).Decode(&root); err != nil {
+ if err == io.EOF {
+ return fm, nil
+ }
+ return nil, err
+ }
+
+ queue := []fieldMaskPathItem{{node: root, md: md}}
+ for len(queue) > 0 {
+ // dequeue an item
+ item := queue[0]
+ queue = queue[1:]
+
+ if m, ok := item.node.(map[string]interface{}); ok {
+ // if the item is an object, then enqueue all of its children
+ for k, v := range m {
+ protoName, subMd := translateName(k, item.md)
+ if subMsg, ok := v.(descriptor2.Message); ok {
+ _, subMd = descriptor2.ForMessage(subMsg)
+ }
+ queue = append(queue, fieldMaskPathItem{path: append(item.path, protoName), node: v, md: subMd})
+ }
+ } else if len(item.path) > 0 {
+ // otherwise, it's a leaf node so print its path
+ fm.Paths = append(fm.Paths, strings.Join(item.path, "."))
+ }
+ }
+
+ return fm, nil
+}
+
+// fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask
+type fieldMaskPathItem struct {
+ // the list of prior fields leading up to node
+ path []string
+
+ // a generic decoded json object the current item to inspect for further path extraction
+ node interface{}
+
+ // descriptor for parent message
+ md *descriptor.DescriptorProto
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go
new file mode 100644
index 0000000..2af9006
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go
@@ -0,0 +1,209 @@
+package runtime
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/textproto"
+
+ "context"
+ "github.com/golang/protobuf/proto"
+ "github.com/grpc-ecosystem/grpc-gateway/internal"
+ "google.golang.org/grpc/grpclog"
+)
+
+var errEmptyResponse = errors.New("empty response")
+
+// ForwardResponseStream forwards the stream from gRPC server to REST client.
+func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {
+ f, ok := w.(http.Flusher)
+ if !ok {
+ grpclog.Infof("Flush not supported in %T", w)
+ http.Error(w, "unexpected type of web server", http.StatusInternalServerError)
+ return
+ }
+
+ md, ok := ServerMetadataFromContext(ctx)
+ if !ok {
+ grpclog.Infof("Failed to extract ServerMetadata from context")
+ http.Error(w, "unexpected error", http.StatusInternalServerError)
+ return
+ }
+ handleForwardResponseServerMetadata(w, mux, md)
+
+ w.Header().Set("Transfer-Encoding", "chunked")
+ w.Header().Set("Content-Type", marshaler.ContentType())
+ if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil {
+ HTTPError(ctx, mux, marshaler, w, req, err)
+ return
+ }
+
+ var delimiter []byte
+ if d, ok := marshaler.(Delimited); ok {
+ delimiter = d.Delimiter()
+ } else {
+ delimiter = []byte("\n")
+ }
+
+ var wroteHeader bool
+ for {
+ resp, err := recv()
+ if err == io.EOF {
+ return
+ }
+ if err != nil {
+ handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err)
+ return
+ }
+ if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil {
+ handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err)
+ return
+ }
+
+ buf, err := marshaler.Marshal(streamChunk(ctx, resp, mux.streamErrorHandler))
+ if err != nil {
+ grpclog.Infof("Failed to marshal response chunk: %v", err)
+ handleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err)
+ return
+ }
+ if _, err = w.Write(buf); err != nil {
+ grpclog.Infof("Failed to send response chunk: %v", err)
+ return
+ }
+ wroteHeader = true
+ if _, err = w.Write(delimiter); err != nil {
+ grpclog.Infof("Failed to send delimiter chunk: %v", err)
+ return
+ }
+ f.Flush()
+ }
+}
+
+func handleForwardResponseServerMetadata(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) {
+ for k, vs := range md.HeaderMD {
+ if h, ok := mux.outgoingHeaderMatcher(k); ok {
+ for _, v := range vs {
+ w.Header().Add(h, v)
+ }
+ }
+ }
+}
+
+func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) {
+ for k := range md.TrailerMD {
+ tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", MetadataTrailerPrefix, k))
+ w.Header().Add("Trailer", tKey)
+ }
+}
+
+func handleForwardResponseTrailer(w http.ResponseWriter, md ServerMetadata) {
+ for k, vs := range md.TrailerMD {
+ tKey := fmt.Sprintf("%s%s", MetadataTrailerPrefix, k)
+ for _, v := range vs {
+ w.Header().Add(tKey, v)
+ }
+ }
+}
+
+// responseBody interface contains method for getting field for marshaling to the response body
+// this method is generated for response struct from the value of `response_body` in the `google.api.HttpRule`
+type responseBody interface {
+ XXX_ResponseBody() interface{}
+}
+
+// ForwardResponseMessage forwards the message "resp" from gRPC server to REST client.
+func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {
+ md, ok := ServerMetadataFromContext(ctx)
+ if !ok {
+ grpclog.Infof("Failed to extract ServerMetadata from context")
+ }
+
+ handleForwardResponseServerMetadata(w, mux, md)
+ handleForwardResponseTrailerHeader(w, md)
+
+ contentType := marshaler.ContentType()
+ // Check marshaler on run time in order to keep backwards compatability
+ // An interface param needs to be added to the ContentType() function on
+ // the Marshal interface to be able to remove this check
+ if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
+ contentType = httpBodyMarshaler.ContentTypeFromMessage(resp)
+ }
+ w.Header().Set("Content-Type", contentType)
+
+ if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil {
+ HTTPError(ctx, mux, marshaler, w, req, err)
+ return
+ }
+ var buf []byte
+ var err error
+ if rb, ok := resp.(responseBody); ok {
+ buf, err = marshaler.Marshal(rb.XXX_ResponseBody())
+ } else {
+ buf, err = marshaler.Marshal(resp)
+ }
+ if err != nil {
+ grpclog.Infof("Marshal error: %v", err)
+ HTTPError(ctx, mux, marshaler, w, req, err)
+ return
+ }
+
+ if _, err = w.Write(buf); err != nil {
+ grpclog.Infof("Failed to write response: %v", err)
+ }
+
+ handleForwardResponseTrailer(w, md)
+}
+
+func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error {
+ if len(opts) == 0 {
+ return nil
+ }
+ for _, opt := range opts {
+ if err := opt(ctx, w, resp); err != nil {
+ grpclog.Infof("Error handling ForwardResponseOptions: %v", err)
+ return err
+ }
+ }
+ return nil
+}
+
+func handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error) {
+ serr := streamError(ctx, mux.streamErrorHandler, err)
+ if !wroteHeader {
+ w.WriteHeader(int(serr.HttpCode))
+ }
+ buf, merr := marshaler.Marshal(errorChunk(serr))
+ if merr != nil {
+ grpclog.Infof("Failed to marshal an error: %v", merr)
+ return
+ }
+ if _, werr := w.Write(buf); werr != nil {
+ grpclog.Infof("Failed to notify error to client: %v", werr)
+ return
+ }
+}
+
+// streamChunk returns a chunk in a response stream for the given result. The
+// given errHandler is used to render an error chunk if result is nil.
+func streamChunk(ctx context.Context, result proto.Message, errHandler StreamErrorHandlerFunc) map[string]proto.Message {
+ if result == nil {
+ return errorChunk(streamError(ctx, errHandler, errEmptyResponse))
+ }
+ return map[string]proto.Message{"result": result}
+}
+
+// streamError returns the payload for the final message in a response stream
+// that represents the given err.
+func streamError(ctx context.Context, errHandler StreamErrorHandlerFunc, err error) *StreamError {
+ serr := errHandler(ctx, err)
+ if serr != nil {
+ return serr
+ }
+ // TODO: log about misbehaving stream error handler?
+ return DefaultHTTPStreamErrorHandler(ctx, err)
+}
+
+func errorChunk(err *StreamError) map[string]proto.Message {
+ return map[string]proto.Message{"error": (*internal.StreamError)(err)}
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go
new file mode 100644
index 0000000..f55285b
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go
@@ -0,0 +1,43 @@
+package runtime
+
+import (
+ "google.golang.org/genproto/googleapis/api/httpbody"
+)
+
+// SetHTTPBodyMarshaler overwrite the default marshaler with the HTTPBodyMarshaler
+func SetHTTPBodyMarshaler(serveMux *ServeMux) {
+ serveMux.marshalers.mimeMap[MIMEWildcard] = &HTTPBodyMarshaler{
+ Marshaler: &JSONPb{OrigName: true},
+ }
+}
+
+// HTTPBodyMarshaler is a Marshaler which supports marshaling of a
+// google.api.HttpBody message as the full response body if it is
+// the actual message used as the response. If not, then this will
+// simply fallback to the Marshaler specified as its default Marshaler.
+type HTTPBodyMarshaler struct {
+ Marshaler
+}
+
+// ContentType implementation to keep backwards compatability with marshal interface
+func (h *HTTPBodyMarshaler) ContentType() string {
+ return h.ContentTypeFromMessage(nil)
+}
+
+// ContentTypeFromMessage in case v is a google.api.HttpBody message it returns
+// its specified content type otherwise fall back to the default Marshaler.
+func (h *HTTPBodyMarshaler) ContentTypeFromMessage(v interface{}) string {
+ if httpBody, ok := v.(*httpbody.HttpBody); ok {
+ return httpBody.GetContentType()
+ }
+ return h.Marshaler.ContentType()
+}
+
+// Marshal marshals "v" by returning the body bytes if v is a
+// google.api.HttpBody message, otherwise it falls back to the default Marshaler.
+func (h *HTTPBodyMarshaler) Marshal(v interface{}) ([]byte, error) {
+ if httpBody, ok := v.(*httpbody.HttpBody); ok {
+ return httpBody.Data, nil
+ }
+ return h.Marshaler.Marshal(v)
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go
new file mode 100644
index 0000000..f9d3a58
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go
@@ -0,0 +1,45 @@
+package runtime
+
+import (
+ "encoding/json"
+ "io"
+)
+
+// JSONBuiltin is a Marshaler which marshals/unmarshals into/from JSON
+// with the standard "encoding/json" package of Golang.
+// Although it is generally faster for simple proto messages than JSONPb,
+// it does not support advanced features of protobuf, e.g. map, oneof, ....
+//
+// The NewEncoder and NewDecoder types return *json.Encoder and
+// *json.Decoder respectively.
+type JSONBuiltin struct{}
+
+// ContentType always Returns "application/json".
+func (*JSONBuiltin) ContentType() string {
+ return "application/json"
+}
+
+// Marshal marshals "v" into JSON
+func (j *JSONBuiltin) Marshal(v interface{}) ([]byte, error) {
+ return json.Marshal(v)
+}
+
+// Unmarshal unmarshals JSON data into "v".
+func (j *JSONBuiltin) Unmarshal(data []byte, v interface{}) error {
+ return json.Unmarshal(data, v)
+}
+
+// NewDecoder returns a Decoder which reads JSON stream from "r".
+func (j *JSONBuiltin) NewDecoder(r io.Reader) Decoder {
+ return json.NewDecoder(r)
+}
+
+// NewEncoder returns an Encoder which writes JSON stream into "w".
+func (j *JSONBuiltin) NewEncoder(w io.Writer) Encoder {
+ return json.NewEncoder(w)
+}
+
+// Delimiter for newline encoded JSON streams.
+func (j *JSONBuiltin) Delimiter() []byte {
+ return []byte("\n")
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go
new file mode 100644
index 0000000..f0de351
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go
@@ -0,0 +1,262 @@
+package runtime
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "reflect"
+
+ "github.com/golang/protobuf/jsonpb"
+ "github.com/golang/protobuf/proto"
+)
+
+// JSONPb is a Marshaler which marshals/unmarshals into/from JSON
+// with the "github.com/golang/protobuf/jsonpb".
+// It supports fully functionality of protobuf unlike JSONBuiltin.
+//
+// The NewDecoder method returns a DecoderWrapper, so the underlying
+// *json.Decoder methods can be used.
+type JSONPb jsonpb.Marshaler
+
+// ContentType always returns "application/json".
+func (*JSONPb) ContentType() string {
+ return "application/json"
+}
+
+// Marshal marshals "v" into JSON.
+func (j *JSONPb) Marshal(v interface{}) ([]byte, error) {
+ if _, ok := v.(proto.Message); !ok {
+ return j.marshalNonProtoField(v)
+ }
+
+ var buf bytes.Buffer
+ if err := j.marshalTo(&buf, v); err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {
+ p, ok := v.(proto.Message)
+ if !ok {
+ buf, err := j.marshalNonProtoField(v)
+ if err != nil {
+ return err
+ }
+ _, err = w.Write(buf)
+ return err
+ }
+ return (*jsonpb.Marshaler)(j).Marshal(w, p)
+}
+
+var (
+ // protoMessageType is stored to prevent constant lookup of the same type at runtime.
+ protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem()
+)
+
+// marshalNonProto marshals a non-message field of a protobuf message.
+// This function does not correctly marshals arbitrary data structure into JSON,
+// but it is only capable of marshaling non-message field values of protobuf,
+// i.e. primitive types, enums; pointers to primitives or enums; maps from
+// integer/string types to primitives/enums/pointers to messages.
+func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
+ if v == nil {
+ return []byte("null"), nil
+ }
+ rv := reflect.ValueOf(v)
+ for rv.Kind() == reflect.Ptr {
+ if rv.IsNil() {
+ return []byte("null"), nil
+ }
+ rv = rv.Elem()
+ }
+
+ if rv.Kind() == reflect.Slice {
+ if rv.IsNil() {
+ if j.EmitDefaults {
+ return []byte("[]"), nil
+ }
+ return []byte("null"), nil
+ }
+
+ if rv.Type().Elem().Implements(protoMessageType) {
+ var buf bytes.Buffer
+ err := buf.WriteByte('[')
+ if err != nil {
+ return nil, err
+ }
+ for i := 0; i < rv.Len(); i++ {
+ if i != 0 {
+ err = buf.WriteByte(',')
+ if err != nil {
+ return nil, err
+ }
+ }
+ if err = (*jsonpb.Marshaler)(j).Marshal(&buf, rv.Index(i).Interface().(proto.Message)); err != nil {
+ return nil, err
+ }
+ }
+ err = buf.WriteByte(']')
+ if err != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+ }
+ }
+
+ if rv.Kind() == reflect.Map {
+ m := make(map[string]*json.RawMessage)
+ for _, k := range rv.MapKeys() {
+ buf, err := j.Marshal(rv.MapIndex(k).Interface())
+ if err != nil {
+ return nil, err
+ }
+ m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf)
+ }
+ if j.Indent != "" {
+ return json.MarshalIndent(m, "", j.Indent)
+ }
+ return json.Marshal(m)
+ }
+ if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts {
+ return json.Marshal(enum.String())
+ }
+ return json.Marshal(rv.Interface())
+}
+
+// Unmarshal unmarshals JSON "data" into "v"
+func (j *JSONPb) Unmarshal(data []byte, v interface{}) error {
+ return unmarshalJSONPb(data, v)
+}
+
+// NewDecoder returns a Decoder which reads JSON stream from "r".
+func (j *JSONPb) NewDecoder(r io.Reader) Decoder {
+ d := json.NewDecoder(r)
+ return DecoderWrapper{Decoder: d}
+}
+
+// DecoderWrapper is a wrapper around a *json.Decoder that adds
+// support for protos to the Decode method.
+type DecoderWrapper struct {
+ *json.Decoder
+}
+
+// Decode wraps the embedded decoder's Decode method to support
+// protos using a jsonpb.Unmarshaler.
+func (d DecoderWrapper) Decode(v interface{}) error {
+ return decodeJSONPb(d.Decoder, v)
+}
+
+// NewEncoder returns an Encoder which writes JSON stream into "w".
+func (j *JSONPb) NewEncoder(w io.Writer) Encoder {
+ return EncoderFunc(func(v interface{}) error {
+ if err := j.marshalTo(w, v); err != nil {
+ return err
+ }
+ // mimic json.Encoder by adding a newline (makes output
+ // easier to read when it contains multiple encoded items)
+ _, err := w.Write(j.Delimiter())
+ return err
+ })
+}
+
+func unmarshalJSONPb(data []byte, v interface{}) error {
+ d := json.NewDecoder(bytes.NewReader(data))
+ return decodeJSONPb(d, v)
+}
+
+func decodeJSONPb(d *json.Decoder, v interface{}) error {
+ p, ok := v.(proto.Message)
+ if !ok {
+ return decodeNonProtoField(d, v)
+ }
+ unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields}
+ return unmarshaler.UnmarshalNext(d, p)
+}
+
+func decodeNonProtoField(d *json.Decoder, v interface{}) error {
+ rv := reflect.ValueOf(v)
+ if rv.Kind() != reflect.Ptr {
+ return fmt.Errorf("%T is not a pointer", v)
+ }
+ for rv.Kind() == reflect.Ptr {
+ if rv.IsNil() {
+ rv.Set(reflect.New(rv.Type().Elem()))
+ }
+ if rv.Type().ConvertibleTo(typeProtoMessage) {
+ unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: allowUnknownFields}
+ return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message))
+ }
+ rv = rv.Elem()
+ }
+ if rv.Kind() == reflect.Map {
+ if rv.IsNil() {
+ rv.Set(reflect.MakeMap(rv.Type()))
+ }
+ conv, ok := convFromType[rv.Type().Key().Kind()]
+ if !ok {
+ return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key())
+ }
+
+ m := make(map[string]*json.RawMessage)
+ if err := d.Decode(&m); err != nil {
+ return err
+ }
+ for k, v := range m {
+ result := conv.Call([]reflect.Value{reflect.ValueOf(k)})
+ if err := result[1].Interface(); err != nil {
+ return err.(error)
+ }
+ bk := result[0]
+ bv := reflect.New(rv.Type().Elem())
+ if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil {
+ return err
+ }
+ rv.SetMapIndex(bk, bv.Elem())
+ }
+ return nil
+ }
+ if _, ok := rv.Interface().(protoEnum); ok {
+ var repr interface{}
+ if err := d.Decode(&repr); err != nil {
+ return err
+ }
+ switch repr.(type) {
+ case string:
+ // TODO(yugui) Should use proto.StructProperties?
+ return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface())
+ case float64:
+ rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type()))
+ return nil
+ default:
+ return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface())
+ }
+ }
+ return d.Decode(v)
+}
+
+type protoEnum interface {
+ fmt.Stringer
+ EnumDescriptor() ([]byte, []int)
+}
+
+var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
+
+// Delimiter for newline encoded JSON streams.
+func (j *JSONPb) Delimiter() []byte {
+ return []byte("\n")
+}
+
+// allowUnknownFields helps not to return an error when the destination
+// is a struct and the input contains object keys which do not match any
+// non-ignored, exported fields in the destination.
+var allowUnknownFields = true
+
+// DisallowUnknownFields enables option in decoder (unmarshaller) to
+// return an error when it finds an unknown field. This function must be
+// called before using the JSON marshaller.
+func DisallowUnknownFields() {
+ allowUnknownFields = false
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go
new file mode 100644
index 0000000..f65d1a2
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go
@@ -0,0 +1,62 @@
+package runtime
+
+import (
+ "io"
+
+ "errors"
+ "github.com/golang/protobuf/proto"
+ "io/ioutil"
+)
+
+// ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes
+type ProtoMarshaller struct{}
+
+// ContentType always returns "application/octet-stream".
+func (*ProtoMarshaller) ContentType() string {
+ return "application/octet-stream"
+}
+
+// Marshal marshals "value" into Proto
+func (*ProtoMarshaller) Marshal(value interface{}) ([]byte, error) {
+ message, ok := value.(proto.Message)
+ if !ok {
+ return nil, errors.New("unable to marshal non proto field")
+ }
+ return proto.Marshal(message)
+}
+
+// Unmarshal unmarshals proto "data" into "value"
+func (*ProtoMarshaller) Unmarshal(data []byte, value interface{}) error {
+ message, ok := value.(proto.Message)
+ if !ok {
+ return errors.New("unable to unmarshal non proto field")
+ }
+ return proto.Unmarshal(data, message)
+}
+
+// NewDecoder returns a Decoder which reads proto stream from "reader".
+func (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder {
+ return DecoderFunc(func(value interface{}) error {
+ buffer, err := ioutil.ReadAll(reader)
+ if err != nil {
+ return err
+ }
+ return marshaller.Unmarshal(buffer, value)
+ })
+}
+
+// NewEncoder returns an Encoder which writes proto stream into "writer".
+func (marshaller *ProtoMarshaller) NewEncoder(writer io.Writer) Encoder {
+ return EncoderFunc(func(value interface{}) error {
+ buffer, err := marshaller.Marshal(value)
+ if err != nil {
+ return err
+ }
+ _, err = writer.Write(buffer)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ })
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go
new file mode 100644
index 0000000..98fe6e8
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go
@@ -0,0 +1,48 @@
+package runtime
+
+import (
+ "io"
+)
+
+// Marshaler defines a conversion between byte sequence and gRPC payloads / fields.
+type Marshaler interface {
+ // Marshal marshals "v" into byte sequence.
+ Marshal(v interface{}) ([]byte, error)
+ // Unmarshal unmarshals "data" into "v".
+ // "v" must be a pointer value.
+ Unmarshal(data []byte, v interface{}) error
+ // NewDecoder returns a Decoder which reads byte sequence from "r".
+ NewDecoder(r io.Reader) Decoder
+ // NewEncoder returns an Encoder which writes bytes sequence into "w".
+ NewEncoder(w io.Writer) Encoder
+ // ContentType returns the Content-Type which this marshaler is responsible for.
+ ContentType() string
+}
+
+// Decoder decodes a byte sequence
+type Decoder interface {
+ Decode(v interface{}) error
+}
+
+// Encoder encodes gRPC payloads / fields into byte sequence.
+type Encoder interface {
+ Encode(v interface{}) error
+}
+
+// DecoderFunc adapts an decoder function into Decoder.
+type DecoderFunc func(v interface{}) error
+
+// Decode delegates invocations to the underlying function itself.
+func (f DecoderFunc) Decode(v interface{}) error { return f(v) }
+
+// EncoderFunc adapts an encoder function into Encoder
+type EncoderFunc func(v interface{}) error
+
+// Encode delegates invocations to the underlying function itself.
+func (f EncoderFunc) Encode(v interface{}) error { return f(v) }
+
+// Delimited defines the streaming delimiter.
+type Delimited interface {
+ // Delimiter returns the record seperator for the stream.
+ Delimiter() []byte
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go
new file mode 100644
index 0000000..5cc53ae
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go
@@ -0,0 +1,91 @@
+package runtime
+
+import (
+ "errors"
+ "net/http"
+)
+
+// MIMEWildcard is the fallback MIME type used for requests which do not match
+// a registered MIME type.
+const MIMEWildcard = "*"
+
+var (
+ acceptHeader = http.CanonicalHeaderKey("Accept")
+ contentTypeHeader = http.CanonicalHeaderKey("Content-Type")
+
+ defaultMarshaler = &JSONPb{OrigName: true}
+)
+
+// MarshalerForRequest returns the inbound/outbound marshalers for this request.
+// It checks the registry on the ServeMux for the MIME type set by the Content-Type header.
+// If it isn't set (or the request Content-Type is empty), checks for "*".
+// If there are multiple Content-Type headers set, choose the first one that it can
+// exactly match in the registry.
+// Otherwise, it follows the above logic for "*"/InboundMarshaler/OutboundMarshaler.
+func MarshalerForRequest(mux *ServeMux, r *http.Request) (inbound Marshaler, outbound Marshaler) {
+ for _, acceptVal := range r.Header[acceptHeader] {
+ if m, ok := mux.marshalers.mimeMap[acceptVal]; ok {
+ outbound = m
+ break
+ }
+ }
+
+ for _, contentTypeVal := range r.Header[contentTypeHeader] {
+ if m, ok := mux.marshalers.mimeMap[contentTypeVal]; ok {
+ inbound = m
+ break
+ }
+ }
+
+ if inbound == nil {
+ inbound = mux.marshalers.mimeMap[MIMEWildcard]
+ }
+ if outbound == nil {
+ outbound = inbound
+ }
+
+ return inbound, outbound
+}
+
+// marshalerRegistry is a mapping from MIME types to Marshalers.
+type marshalerRegistry struct {
+ mimeMap map[string]Marshaler
+}
+
+// add adds a marshaler for a case-sensitive MIME type string ("*" to match any
+// MIME type).
+func (m marshalerRegistry) add(mime string, marshaler Marshaler) error {
+ if len(mime) == 0 {
+ return errors.New("empty MIME type")
+ }
+
+ m.mimeMap[mime] = marshaler
+
+ return nil
+}
+
+// makeMarshalerMIMERegistry returns a new registry of marshalers.
+// It allows for a mapping of case-sensitive Content-Type MIME type string to runtime.Marshaler interfaces.
+//
+// For example, you could allow the client to specify the use of the runtime.JSONPb marshaler
+// with a "application/jsonpb" Content-Type and the use of the runtime.JSONBuiltin marshaler
+// with a "application/json" Content-Type.
+// "*" can be used to match any Content-Type.
+// This can be attached to a ServerMux with the marshaler option.
+func makeMarshalerMIMERegistry() marshalerRegistry {
+ return marshalerRegistry{
+ mimeMap: map[string]Marshaler{
+ MIMEWildcard: defaultMarshaler,
+ },
+ }
+}
+
+// WithMarshalerOption returns a ServeMuxOption which associates inbound and outbound
+// Marshalers to a MIME type in mux.
+func WithMarshalerOption(mime string, marshaler Marshaler) ServeMuxOption {
+ return func(mux *ServeMux) {
+ if err := mux.marshalers.add(mime, marshaler); err != nil {
+ panic(err)
+ }
+ }
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go
new file mode 100644
index 0000000..1da3a58
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go
@@ -0,0 +1,303 @@
+package runtime
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "net/textproto"
+ "strings"
+
+ "github.com/golang/protobuf/proto"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/metadata"
+ "google.golang.org/grpc/status"
+)
+
+// A HandlerFunc handles a specific pair of path pattern and HTTP method.
+type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string)
+
+// ErrUnknownURI is the error supplied to a custom ProtoErrorHandlerFunc when
+// a request is received with a URI path that does not match any registered
+// service method.
+//
+// Since gRPC servers return an "Unimplemented" code for requests with an
+// unrecognized URI path, this error also has a gRPC "Unimplemented" code.
+var ErrUnknownURI = status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented))
+
+// ServeMux is a request multiplexer for grpc-gateway.
+// It matches http requests to patterns and invokes the corresponding handler.
+type ServeMux struct {
+ // handlers maps HTTP method to a list of handlers.
+ handlers map[string][]handler
+ forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error
+ marshalers marshalerRegistry
+ incomingHeaderMatcher HeaderMatcherFunc
+ outgoingHeaderMatcher HeaderMatcherFunc
+ metadataAnnotators []func(context.Context, *http.Request) metadata.MD
+ streamErrorHandler StreamErrorHandlerFunc
+ protoErrorHandler ProtoErrorHandlerFunc
+ disablePathLengthFallback bool
+ lastMatchWins bool
+}
+
+// ServeMuxOption is an option that can be given to a ServeMux on construction.
+type ServeMuxOption func(*ServeMux)
+
+// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption.
+//
+// forwardResponseOption is an option that will be called on the relevant context.Context,
+// http.ResponseWriter, and proto.Message before every forwarded response.
+//
+// The message may be nil in the case where just a header is being sent.
+func WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption {
+ return func(serveMux *ServeMux) {
+ serveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption)
+ }
+}
+
+// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context.
+type HeaderMatcherFunc func(string) (string, bool)
+
+// DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header
+// keys (as specified by the IANA) to gRPC context with grpcgateway- prefix. HTTP headers that start with
+// 'Grpc-Metadata-' are mapped to gRPC metadata after removing prefix 'Grpc-Metadata-'.
+func DefaultHeaderMatcher(key string) (string, bool) {
+ key = textproto.CanonicalMIMEHeaderKey(key)
+ if isPermanentHTTPHeader(key) {
+ return MetadataPrefix + key, true
+ } else if strings.HasPrefix(key, MetadataHeaderPrefix) {
+ return key[len(MetadataHeaderPrefix):], true
+ }
+ return "", false
+}
+
+// WithIncomingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for incoming request to gateway.
+//
+// This matcher will be called with each header in http.Request. If matcher returns true, that header will be
+// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header.
+func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption {
+ return func(mux *ServeMux) {
+ mux.incomingHeaderMatcher = fn
+ }
+}
+
+// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway.
+//
+// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be
+// passed to http response returned from gateway. To transform the header before passing to response,
+// matcher should return modified header.
+func WithOutgoingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption {
+ return func(mux *ServeMux) {
+ mux.outgoingHeaderMatcher = fn
+ }
+}
+
+// WithMetadata returns a ServeMuxOption for passing metadata to a gRPC context.
+//
+// This can be used by services that need to read from http.Request and modify gRPC context. A common use case
+// is reading token from cookie and adding it in gRPC context.
+func WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) ServeMuxOption {
+ return func(serveMux *ServeMux) {
+ serveMux.metadataAnnotators = append(serveMux.metadataAnnotators, annotator)
+ }
+}
+
+// WithProtoErrorHandler returns a ServeMuxOption for passing metadata to a gRPC context.
+//
+// This can be used to handle an error as general proto message defined by gRPC.
+// The response including body and status is not backward compatible with the default error handler.
+// When this option is used, HTTPError and OtherErrorHandler are overwritten on initialization.
+func WithProtoErrorHandler(fn ProtoErrorHandlerFunc) ServeMuxOption {
+ return func(serveMux *ServeMux) {
+ serveMux.protoErrorHandler = fn
+ }
+}
+
+// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback.
+func WithDisablePathLengthFallback() ServeMuxOption {
+ return func(serveMux *ServeMux) {
+ serveMux.disablePathLengthFallback = true
+ }
+}
+
+// WithStreamErrorHandler returns a ServeMuxOption that will use the given custom stream
+// error handler, which allows for customizing the error trailer for server-streaming
+// calls.
+//
+// For stream errors that occur before any response has been written, the mux's
+// ProtoErrorHandler will be invoked. However, once data has been written, the errors must
+// be handled differently: they must be included in the response body. The response body's
+// final message will include the error details returned by the stream error handler.
+func WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption {
+ return func(serveMux *ServeMux) {
+ serveMux.streamErrorHandler = fn
+ }
+}
+
+// WithLastMatchWins returns a ServeMuxOption that will enable "last
+// match wins" behavior, where if multiple path patterns match a
+// request path, the last one defined in the .proto file will be used.
+func WithLastMatchWins() ServeMuxOption {
+ return func(serveMux *ServeMux) {
+ serveMux.lastMatchWins = true
+ }
+}
+
+// NewServeMux returns a new ServeMux whose internal mapping is empty.
+func NewServeMux(opts ...ServeMuxOption) *ServeMux {
+ serveMux := &ServeMux{
+ handlers: make(map[string][]handler),
+ forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0),
+ marshalers: makeMarshalerMIMERegistry(),
+ streamErrorHandler: DefaultHTTPStreamErrorHandler,
+ }
+
+ for _, opt := range opts {
+ opt(serveMux)
+ }
+
+ if serveMux.protoErrorHandler != nil {
+ HTTPError = serveMux.protoErrorHandler
+ // OtherErrorHandler is no longer used when protoErrorHandler is set.
+ // Overwritten by a special error handler to return Unknown.
+ OtherErrorHandler = func(w http.ResponseWriter, r *http.Request, _ string, _ int) {
+ ctx := context.Background()
+ _, outboundMarshaler := MarshalerForRequest(serveMux, r)
+ sterr := status.Error(codes.Unknown, "unexpected use of OtherErrorHandler")
+ serveMux.protoErrorHandler(ctx, serveMux, outboundMarshaler, w, r, sterr)
+ }
+ }
+
+ if serveMux.incomingHeaderMatcher == nil {
+ serveMux.incomingHeaderMatcher = DefaultHeaderMatcher
+ }
+
+ if serveMux.outgoingHeaderMatcher == nil {
+ serveMux.outgoingHeaderMatcher = func(key string) (string, bool) {
+ return fmt.Sprintf("%s%s", MetadataHeaderPrefix, key), true
+ }
+ }
+
+ return serveMux
+}
+
+// Handle associates "h" to the pair of HTTP method and path pattern.
+func (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) {
+ if s.lastMatchWins {
+ s.handlers[meth] = append([]handler{handler{pat: pat, h: h}}, s.handlers[meth]...)
+ } else {
+ s.handlers[meth] = append(s.handlers[meth], handler{pat: pat, h: h})
+ }
+}
+
+// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path.
+func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ ctx := r.Context()
+
+ path := r.URL.Path
+ if !strings.HasPrefix(path, "/") {
+ if s.protoErrorHandler != nil {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ sterr := status.Error(codes.InvalidArgument, http.StatusText(http.StatusBadRequest))
+ s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
+ } else {
+ OtherErrorHandler(w, r, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
+ }
+ return
+ }
+
+ components := strings.Split(path[1:], "/")
+ l := len(components)
+ var verb string
+ if idx := strings.LastIndex(components[l-1], ":"); idx == 0 {
+ if s.protoErrorHandler != nil {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI)
+ } else {
+ OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound)
+ }
+ return
+ } else if idx > 0 {
+ c := components[l-1]
+ components[l-1], verb = c[:idx], c[idx+1:]
+ }
+
+ if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) {
+ r.Method = strings.ToUpper(override)
+ if err := r.ParseForm(); err != nil {
+ if s.protoErrorHandler != nil {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ sterr := status.Error(codes.InvalidArgument, err.Error())
+ s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
+ } else {
+ OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest)
+ }
+ return
+ }
+ }
+ for _, h := range s.handlers[r.Method] {
+ pathParams, err := h.pat.Match(components, verb)
+ if err != nil {
+ continue
+ }
+ h.h(w, r, pathParams)
+ return
+ }
+
+ // lookup other methods to handle fallback from GET to POST and
+ // to determine if it is MethodNotAllowed or NotFound.
+ for m, handlers := range s.handlers {
+ if m == r.Method {
+ continue
+ }
+ for _, h := range handlers {
+ pathParams, err := h.pat.Match(components, verb)
+ if err != nil {
+ continue
+ }
+ // X-HTTP-Method-Override is optional. Always allow fallback to POST.
+ if s.isPathLengthFallback(r) {
+ if err := r.ParseForm(); err != nil {
+ if s.protoErrorHandler != nil {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ sterr := status.Error(codes.InvalidArgument, err.Error())
+ s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr)
+ } else {
+ OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest)
+ }
+ return
+ }
+ h.h(w, r, pathParams)
+ return
+ }
+ if s.protoErrorHandler != nil {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI)
+ } else {
+ OtherErrorHandler(w, r, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
+ }
+ return
+ }
+ }
+
+ if s.protoErrorHandler != nil {
+ _, outboundMarshaler := MarshalerForRequest(s, r)
+ s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, ErrUnknownURI)
+ } else {
+ OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound)
+ }
+}
+
+// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux.
+func (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error {
+ return s.forwardResponseOptions
+}
+
+func (s *ServeMux) isPathLengthFallback(r *http.Request) bool {
+ return !s.disablePathLengthFallback && r.Method == "POST" && r.Header.Get("Content-Type") == "application/x-www-form-urlencoded"
+}
+
+type handler struct {
+ pat Pattern
+ h HandlerFunc
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go
new file mode 100644
index 0000000..0905369
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go
@@ -0,0 +1,262 @@
+package runtime
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ "github.com/grpc-ecosystem/grpc-gateway/utilities"
+ "google.golang.org/grpc/grpclog"
+)
+
+var (
+ // ErrNotMatch indicates that the given HTTP request path does not match to the pattern.
+ ErrNotMatch = errors.New("not match to the path pattern")
+ // ErrInvalidPattern indicates that the given definition of Pattern is not valid.
+ ErrInvalidPattern = errors.New("invalid pattern")
+)
+
+type op struct {
+ code utilities.OpCode
+ operand int
+}
+
+// Pattern is a template pattern of http request paths defined in github.com/googleapis/googleapis/google/api/http.proto.
+type Pattern struct {
+ // ops is a list of operations
+ ops []op
+ // pool is a constant pool indexed by the operands or vars.
+ pool []string
+ // vars is a list of variables names to be bound by this pattern
+ vars []string
+ // stacksize is the max depth of the stack
+ stacksize int
+ // tailLen is the length of the fixed-size segments after a deep wildcard
+ tailLen int
+ // verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part.
+ verb string
+ // assumeColonVerb indicates whether a path suffix after a final
+ // colon may only be interpreted as a verb.
+ assumeColonVerb bool
+}
+
+type patternOptions struct {
+ assumeColonVerb bool
+}
+
+// PatternOpt is an option for creating Patterns.
+type PatternOpt func(*patternOptions)
+
+// NewPattern returns a new Pattern from the given definition values.
+// "ops" is a sequence of op codes. "pool" is a constant pool.
+// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part.
+// "version" must be 1 for now.
+// It returns an error if the given definition is invalid.
+func NewPattern(version int, ops []int, pool []string, verb string, opts ...PatternOpt) (Pattern, error) {
+ options := patternOptions{
+ assumeColonVerb: true,
+ }
+ for _, o := range opts {
+ o(&options)
+ }
+
+ if version != 1 {
+ grpclog.Infof("unsupported version: %d", version)
+ return Pattern{}, ErrInvalidPattern
+ }
+
+ l := len(ops)
+ if l%2 != 0 {
+ grpclog.Infof("odd number of ops codes: %d", l)
+ return Pattern{}, ErrInvalidPattern
+ }
+
+ var (
+ typedOps []op
+ stack, maxstack int
+ tailLen int
+ pushMSeen bool
+ vars []string
+ )
+ for i := 0; i < l; i += 2 {
+ op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]}
+ switch op.code {
+ case utilities.OpNop:
+ continue
+ case utilities.OpPush:
+ if pushMSeen {
+ tailLen++
+ }
+ stack++
+ case utilities.OpPushM:
+ if pushMSeen {
+ grpclog.Infof("pushM appears twice")
+ return Pattern{}, ErrInvalidPattern
+ }
+ pushMSeen = true
+ stack++
+ case utilities.OpLitPush:
+ if op.operand < 0 || len(pool) <= op.operand {
+ grpclog.Infof("negative literal index: %d", op.operand)
+ return Pattern{}, ErrInvalidPattern
+ }
+ if pushMSeen {
+ tailLen++
+ }
+ stack++
+ case utilities.OpConcatN:
+ if op.operand <= 0 {
+ grpclog.Infof("negative concat size: %d", op.operand)
+ return Pattern{}, ErrInvalidPattern
+ }
+ stack -= op.operand
+ if stack < 0 {
+ grpclog.Print("stack underflow")
+ return Pattern{}, ErrInvalidPattern
+ }
+ stack++
+ case utilities.OpCapture:
+ if op.operand < 0 || len(pool) <= op.operand {
+ grpclog.Infof("variable name index out of bound: %d", op.operand)
+ return Pattern{}, ErrInvalidPattern
+ }
+ v := pool[op.operand]
+ op.operand = len(vars)
+ vars = append(vars, v)
+ stack--
+ if stack < 0 {
+ grpclog.Infof("stack underflow")
+ return Pattern{}, ErrInvalidPattern
+ }
+ default:
+ grpclog.Infof("invalid opcode: %d", op.code)
+ return Pattern{}, ErrInvalidPattern
+ }
+
+ if maxstack < stack {
+ maxstack = stack
+ }
+ typedOps = append(typedOps, op)
+ }
+ return Pattern{
+ ops: typedOps,
+ pool: pool,
+ vars: vars,
+ stacksize: maxstack,
+ tailLen: tailLen,
+ verb: verb,
+ assumeColonVerb: options.assumeColonVerb,
+ }, nil
+}
+
+// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization.
+func MustPattern(p Pattern, err error) Pattern {
+ if err != nil {
+ grpclog.Fatalf("Pattern initialization failed: %v", err)
+ }
+ return p
+}
+
+// Match examines components if it matches to the Pattern.
+// If it matches, the function returns a mapping from field paths to their captured values.
+// If otherwise, the function returns an error.
+func (p Pattern) Match(components []string, verb string) (map[string]string, error) {
+ if p.verb != verb {
+ if p.assumeColonVerb || p.verb != "" {
+ return nil, ErrNotMatch
+ }
+ if len(components) == 0 {
+ components = []string{":" + verb}
+ } else {
+ components = append([]string{}, components...)
+ components[len(components)-1] += ":" + verb
+ }
+ verb = ""
+ }
+
+ var pos int
+ stack := make([]string, 0, p.stacksize)
+ captured := make([]string, len(p.vars))
+ l := len(components)
+ for _, op := range p.ops {
+ switch op.code {
+ case utilities.OpNop:
+ continue
+ case utilities.OpPush, utilities.OpLitPush:
+ if pos >= l {
+ return nil, ErrNotMatch
+ }
+ c := components[pos]
+ if op.code == utilities.OpLitPush {
+ if lit := p.pool[op.operand]; c != lit {
+ return nil, ErrNotMatch
+ }
+ }
+ stack = append(stack, c)
+ pos++
+ case utilities.OpPushM:
+ end := len(components)
+ if end < pos+p.tailLen {
+ return nil, ErrNotMatch
+ }
+ end -= p.tailLen
+ stack = append(stack, strings.Join(components[pos:end], "/"))
+ pos = end
+ case utilities.OpConcatN:
+ n := op.operand
+ l := len(stack) - n
+ stack = append(stack[:l], strings.Join(stack[l:], "/"))
+ case utilities.OpCapture:
+ n := len(stack) - 1
+ captured[op.operand] = stack[n]
+ stack = stack[:n]
+ }
+ }
+ if pos < l {
+ return nil, ErrNotMatch
+ }
+ bindings := make(map[string]string)
+ for i, val := range captured {
+ bindings[p.vars[i]] = val
+ }
+ return bindings, nil
+}
+
+// Verb returns the verb part of the Pattern.
+func (p Pattern) Verb() string { return p.verb }
+
+func (p Pattern) String() string {
+ var stack []string
+ for _, op := range p.ops {
+ switch op.code {
+ case utilities.OpNop:
+ continue
+ case utilities.OpPush:
+ stack = append(stack, "*")
+ case utilities.OpLitPush:
+ stack = append(stack, p.pool[op.operand])
+ case utilities.OpPushM:
+ stack = append(stack, "**")
+ case utilities.OpConcatN:
+ n := op.operand
+ l := len(stack) - n
+ stack = append(stack[:l], strings.Join(stack[l:], "/"))
+ case utilities.OpCapture:
+ n := len(stack) - 1
+ stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n])
+ }
+ }
+ segs := strings.Join(stack, "/")
+ if p.verb != "" {
+ return fmt.Sprintf("/%s:%s", segs, p.verb)
+ }
+ return "/" + segs
+}
+
+// AssumeColonVerbOpt indicates whether a path suffix after a final
+// colon may only be interpreted as a verb.
+func AssumeColonVerbOpt(val bool) PatternOpt {
+ return PatternOpt(func(o *patternOptions) {
+ o.assumeColonVerb = val
+ })
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go
new file mode 100644
index 0000000..a3151e2
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go
@@ -0,0 +1,80 @@
+package runtime
+
+import (
+ "github.com/golang/protobuf/proto"
+)
+
+// StringP returns a pointer to a string whose pointee is same as the given string value.
+func StringP(val string) (*string, error) {
+ return proto.String(val), nil
+}
+
+// BoolP parses the given string representation of a boolean value,
+// and returns a pointer to a bool whose value is same as the parsed value.
+func BoolP(val string) (*bool, error) {
+ b, err := Bool(val)
+ if err != nil {
+ return nil, err
+ }
+ return proto.Bool(b), nil
+}
+
+// Float64P parses the given string representation of a floating point number,
+// and returns a pointer to a float64 whose value is same as the parsed number.
+func Float64P(val string) (*float64, error) {
+ f, err := Float64(val)
+ if err != nil {
+ return nil, err
+ }
+ return proto.Float64(f), nil
+}
+
+// Float32P parses the given string representation of a floating point number,
+// and returns a pointer to a float32 whose value is same as the parsed number.
+func Float32P(val string) (*float32, error) {
+ f, err := Float32(val)
+ if err != nil {
+ return nil, err
+ }
+ return proto.Float32(f), nil
+}
+
+// Int64P parses the given string representation of an integer
+// and returns a pointer to a int64 whose value is same as the parsed integer.
+func Int64P(val string) (*int64, error) {
+ i, err := Int64(val)
+ if err != nil {
+ return nil, err
+ }
+ return proto.Int64(i), nil
+}
+
+// Int32P parses the given string representation of an integer
+// and returns a pointer to a int32 whose value is same as the parsed integer.
+func Int32P(val string) (*int32, error) {
+ i, err := Int32(val)
+ if err != nil {
+ return nil, err
+ }
+ return proto.Int32(i), err
+}
+
+// Uint64P parses the given string representation of an integer
+// and returns a pointer to a uint64 whose value is same as the parsed integer.
+func Uint64P(val string) (*uint64, error) {
+ i, err := Uint64(val)
+ if err != nil {
+ return nil, err
+ }
+ return proto.Uint64(i), err
+}
+
+// Uint32P parses the given string representation of an integer
+// and returns a pointer to a uint32 whose value is same as the parsed integer.
+func Uint32P(val string) (*uint32, error) {
+ i, err := Uint32(val)
+ if err != nil {
+ return nil, err
+ }
+ return proto.Uint32(i), err
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go
new file mode 100644
index 0000000..ca76324
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go
@@ -0,0 +1,106 @@
+package runtime
+
+import (
+ "context"
+ "io"
+ "net/http"
+
+ "github.com/golang/protobuf/ptypes/any"
+ "github.com/grpc-ecosystem/grpc-gateway/internal"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/grpclog"
+ "google.golang.org/grpc/status"
+)
+
+// StreamErrorHandlerFunc accepts an error as a gRPC error generated via status package and translates it into a
+// a proto struct used to represent error at the end of a stream.
+type StreamErrorHandlerFunc func(context.Context, error) *StreamError
+
+// StreamError is the payload for the final message in a server stream in the event that the server returns an
+// error after a response message has already been sent.
+type StreamError internal.StreamError
+
+// ProtoErrorHandlerFunc handles the error as a gRPC error generated via status package and replies to the request.
+type ProtoErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error)
+
+var _ ProtoErrorHandlerFunc = DefaultHTTPProtoErrorHandler
+
+// DefaultHTTPProtoErrorHandler is an implementation of HTTPError.
+// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode.
+// If otherwise, it replies with http.StatusInternalServerError.
+//
+// The response body returned by this function is a Status message marshaled by a Marshaler.
+//
+// Do not set this function to HTTPError variable directly, use WithProtoErrorHandler option instead.
+func DefaultHTTPProtoErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
+ // return Internal when Marshal failed
+ const fallback = `{"code": 13, "message": "failed to marshal error message"}`
+
+ s, ok := status.FromError(err)
+ if !ok {
+ s = status.New(codes.Unknown, err.Error())
+ }
+
+ w.Header().Del("Trailer")
+
+ contentType := marshaler.ContentType()
+ // Check marshaler on run time in order to keep backwards compatability
+ // An interface param needs to be added to the ContentType() function on
+ // the Marshal interface to be able to remove this check
+ if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok {
+ pb := s.Proto()
+ contentType = httpBodyMarshaler.ContentTypeFromMessage(pb)
+ }
+ w.Header().Set("Content-Type", contentType)
+
+ buf, merr := marshaler.Marshal(s.Proto())
+ if merr != nil {
+ grpclog.Infof("Failed to marshal error message %q: %v", s.Proto(), merr)
+ w.WriteHeader(http.StatusInternalServerError)
+ if _, err := io.WriteString(w, fallback); err != nil {
+ grpclog.Infof("Failed to write response: %v", err)
+ }
+ return
+ }
+
+ md, ok := ServerMetadataFromContext(ctx)
+ if !ok {
+ grpclog.Infof("Failed to extract ServerMetadata from context")
+ }
+
+ handleForwardResponseServerMetadata(w, mux, md)
+ handleForwardResponseTrailerHeader(w, md)
+ st := HTTPStatusFromCode(s.Code())
+ w.WriteHeader(st)
+ if _, err := w.Write(buf); err != nil {
+ grpclog.Infof("Failed to write response: %v", err)
+ }
+
+ handleForwardResponseTrailer(w, md)
+}
+
+// DefaultHTTPStreamErrorHandler converts the given err into a *StreamError via
+// default logic.
+//
+// It extracts the gRPC status from err if possible. The fields of the status are
+// used to populate the returned StreamError, and the HTTP status code is derived
+// from the gRPC code via HTTPStatusFromCode. If the given err does not contain a
+// gRPC status, an "Unknown" gRPC code is used and "Internal Server Error" HTTP code.
+func DefaultHTTPStreamErrorHandler(_ context.Context, err error) *StreamError {
+ grpcCode := codes.Unknown
+ grpcMessage := err.Error()
+ var grpcDetails []*any.Any
+ if s, ok := status.FromError(err); ok {
+ grpcCode = s.Code()
+ grpcMessage = s.Message()
+ grpcDetails = s.Proto().GetDetails()
+ }
+ httpCode := HTTPStatusFromCode(grpcCode)
+ return &StreamError{
+ GrpcCode: int32(grpcCode),
+ HttpCode: int32(httpCode),
+ Message: grpcMessage,
+ HttpStatus: http.StatusText(httpCode),
+ Details: grpcDetails,
+ }
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go
new file mode 100644
index 0000000..ee0207e
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go
@@ -0,0 +1,389 @@
+package runtime
+
+import (
+ "encoding/base64"
+ "fmt"
+ "net/url"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/golang/protobuf/proto"
+ "github.com/grpc-ecosystem/grpc-gateway/utilities"
+ "google.golang.org/grpc/grpclog"
+)
+
+var valuesKeyRegexp = regexp.MustCompile("^(.*)\\[(.*)\\]$")
+
+// PopulateQueryParameters populates "values" into "msg".
+// A value is ignored if its key starts with one of the elements in "filter".
+func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error {
+ for key, values := range values {
+ match := valuesKeyRegexp.FindStringSubmatch(key)
+ if len(match) == 3 {
+ key = match[1]
+ values = append([]string{match[2]}, values...)
+ }
+ fieldPath := strings.Split(key, ".")
+ if filter.HasCommonPrefix(fieldPath) {
+ continue
+ }
+ if err := populateFieldValueFromPath(msg, fieldPath, values); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// PopulateFieldFromPath sets a value in a nested Protobuf structure.
+// It instantiates missing protobuf fields as it goes.
+func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error {
+ fieldPath := strings.Split(fieldPathString, ".")
+ return populateFieldValueFromPath(msg, fieldPath, []string{value})
+}
+
+func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values []string) error {
+ m := reflect.ValueOf(msg)
+ if m.Kind() != reflect.Ptr {
+ return fmt.Errorf("unexpected type %T: %v", msg, msg)
+ }
+ var props *proto.Properties
+ m = m.Elem()
+ for i, fieldName := range fieldPath {
+ isLast := i == len(fieldPath)-1
+ if !isLast && m.Kind() != reflect.Struct {
+ return fmt.Errorf("non-aggregate type in the mid of path: %s", strings.Join(fieldPath, "."))
+ }
+ var f reflect.Value
+ var err error
+ f, props, err = fieldByProtoName(m, fieldName)
+ if err != nil {
+ return err
+ } else if !f.IsValid() {
+ grpclog.Infof("field not found in %T: %s", msg, strings.Join(fieldPath, "."))
+ return nil
+ }
+
+ switch f.Kind() {
+ case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64:
+ if !isLast {
+ return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], "."))
+ }
+ m = f
+ case reflect.Slice:
+ if !isLast {
+ return fmt.Errorf("unexpected repeated field in %s", strings.Join(fieldPath, "."))
+ }
+ // Handle []byte
+ if f.Type().Elem().Kind() == reflect.Uint8 {
+ m = f
+ break
+ }
+ return populateRepeatedField(f, values, props)
+ case reflect.Ptr:
+ if f.IsNil() {
+ m = reflect.New(f.Type().Elem())
+ f.Set(m.Convert(f.Type()))
+ }
+ m = f.Elem()
+ continue
+ case reflect.Struct:
+ m = f
+ continue
+ case reflect.Map:
+ if !isLast {
+ return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], "."))
+ }
+ return populateMapField(f, values, props)
+ default:
+ return fmt.Errorf("unexpected type %s in %T", f.Type(), msg)
+ }
+ }
+ switch len(values) {
+ case 0:
+ return fmt.Errorf("no value of field: %s", strings.Join(fieldPath, "."))
+ case 1:
+ default:
+ grpclog.Infof("too many field values: %s", strings.Join(fieldPath, "."))
+ }
+ return populateField(m, values[0], props)
+}
+
+// fieldByProtoName looks up a field whose corresponding protobuf field name is "name".
+// "m" must be a struct value. It returns zero reflect.Value if no such field found.
+func fieldByProtoName(m reflect.Value, name string) (reflect.Value, *proto.Properties, error) {
+ props := proto.GetProperties(m.Type())
+
+ // look up field name in oneof map
+ if op, ok := props.OneofTypes[name]; ok {
+ v := reflect.New(op.Type.Elem())
+ field := m.Field(op.Field)
+ if !field.IsNil() {
+ return reflect.Value{}, nil, fmt.Errorf("field already set for %s oneof", props.Prop[op.Field].OrigName)
+ }
+ field.Set(v)
+ return v.Elem().Field(0), op.Prop, nil
+ }
+
+ for _, p := range props.Prop {
+ if p.OrigName == name {
+ return m.FieldByName(p.Name), p, nil
+ }
+ if p.JSONName == name {
+ return m.FieldByName(p.Name), p, nil
+ }
+ }
+ return reflect.Value{}, nil, nil
+}
+
+func populateMapField(f reflect.Value, values []string, props *proto.Properties) error {
+ if len(values) != 2 {
+ return fmt.Errorf("more than one value provided for key %s in map %s", values[0], props.Name)
+ }
+
+ key, value := values[0], values[1]
+ keyType := f.Type().Key()
+ valueType := f.Type().Elem()
+ if f.IsNil() {
+ f.Set(reflect.MakeMap(f.Type()))
+ }
+
+ keyConv, ok := convFromType[keyType.Kind()]
+ if !ok {
+ return fmt.Errorf("unsupported key type %s in map %s", keyType, props.Name)
+ }
+ valueConv, ok := convFromType[valueType.Kind()]
+ if !ok {
+ return fmt.Errorf("unsupported value type %s in map %s", valueType, props.Name)
+ }
+
+ keyV := keyConv.Call([]reflect.Value{reflect.ValueOf(key)})
+ if err := keyV[1].Interface(); err != nil {
+ return err.(error)
+ }
+ valueV := valueConv.Call([]reflect.Value{reflect.ValueOf(value)})
+ if err := valueV[1].Interface(); err != nil {
+ return err.(error)
+ }
+
+ f.SetMapIndex(keyV[0].Convert(keyType), valueV[0].Convert(valueType))
+
+ return nil
+}
+
+func populateRepeatedField(f reflect.Value, values []string, props *proto.Properties) error {
+ elemType := f.Type().Elem()
+
+ // is the destination field a slice of an enumeration type?
+ if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil {
+ return populateFieldEnumRepeated(f, values, enumValMap)
+ }
+
+ conv, ok := convFromType[elemType.Kind()]
+ if !ok {
+ return fmt.Errorf("unsupported field type %s", elemType)
+ }
+ f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type()))
+ for i, v := range values {
+ result := conv.Call([]reflect.Value{reflect.ValueOf(v)})
+ if err := result[1].Interface(); err != nil {
+ return err.(error)
+ }
+ f.Index(i).Set(result[0].Convert(f.Index(i).Type()))
+ }
+ return nil
+}
+
+func populateField(f reflect.Value, value string, props *proto.Properties) error {
+ i := f.Addr().Interface()
+
+ // Handle protobuf well known types
+ var name string
+ switch m := i.(type) {
+ case interface{ XXX_WellKnownType() string }:
+ name = m.XXX_WellKnownType()
+ case proto.Message:
+ const wktPrefix = "google.protobuf."
+ if fullName := proto.MessageName(m); strings.HasPrefix(fullName, wktPrefix) {
+ name = fullName[len(wktPrefix):]
+ }
+ }
+ switch name {
+ case "Timestamp":
+ if value == "null" {
+ f.FieldByName("Seconds").SetInt(0)
+ f.FieldByName("Nanos").SetInt(0)
+ return nil
+ }
+
+ t, err := time.Parse(time.RFC3339Nano, value)
+ if err != nil {
+ return fmt.Errorf("bad Timestamp: %v", err)
+ }
+ f.FieldByName("Seconds").SetInt(int64(t.Unix()))
+ f.FieldByName("Nanos").SetInt(int64(t.Nanosecond()))
+ return nil
+ case "Duration":
+ if value == "null" {
+ f.FieldByName("Seconds").SetInt(0)
+ f.FieldByName("Nanos").SetInt(0)
+ return nil
+ }
+ d, err := time.ParseDuration(value)
+ if err != nil {
+ return fmt.Errorf("bad Duration: %v", err)
+ }
+
+ ns := d.Nanoseconds()
+ s := ns / 1e9
+ ns %= 1e9
+ f.FieldByName("Seconds").SetInt(s)
+ f.FieldByName("Nanos").SetInt(ns)
+ return nil
+ case "DoubleValue":
+ fallthrough
+ case "FloatValue":
+ float64Val, err := strconv.ParseFloat(value, 64)
+ if err != nil {
+ return fmt.Errorf("bad DoubleValue: %s", value)
+ }
+ f.FieldByName("Value").SetFloat(float64Val)
+ return nil
+ case "Int64Value":
+ fallthrough
+ case "Int32Value":
+ int64Val, err := strconv.ParseInt(value, 10, 64)
+ if err != nil {
+ return fmt.Errorf("bad DoubleValue: %s", value)
+ }
+ f.FieldByName("Value").SetInt(int64Val)
+ return nil
+ case "UInt64Value":
+ fallthrough
+ case "UInt32Value":
+ uint64Val, err := strconv.ParseUint(value, 10, 64)
+ if err != nil {
+ return fmt.Errorf("bad DoubleValue: %s", value)
+ }
+ f.FieldByName("Value").SetUint(uint64Val)
+ return nil
+ case "BoolValue":
+ if value == "true" {
+ f.FieldByName("Value").SetBool(true)
+ } else if value == "false" {
+ f.FieldByName("Value").SetBool(false)
+ } else {
+ return fmt.Errorf("bad BoolValue: %s", value)
+ }
+ return nil
+ case "StringValue":
+ f.FieldByName("Value").SetString(value)
+ return nil
+ case "BytesValue":
+ bytesVal, err := base64.StdEncoding.DecodeString(value)
+ if err != nil {
+ return fmt.Errorf("bad BytesValue: %s", value)
+ }
+ f.FieldByName("Value").SetBytes(bytesVal)
+ return nil
+ case "FieldMask":
+ p := f.FieldByName("Paths")
+ for _, v := range strings.Split(value, ",") {
+ if v != "" {
+ p.Set(reflect.Append(p, reflect.ValueOf(v)))
+ }
+ }
+ return nil
+ }
+
+ // Handle Time and Duration stdlib types
+ switch t := i.(type) {
+ case *time.Time:
+ pt, err := time.Parse(time.RFC3339Nano, value)
+ if err != nil {
+ return fmt.Errorf("bad Timestamp: %v", err)
+ }
+ *t = pt
+ return nil
+ case *time.Duration:
+ d, err := time.ParseDuration(value)
+ if err != nil {
+ return fmt.Errorf("bad Duration: %v", err)
+ }
+ *t = d
+ return nil
+ }
+
+ // is the destination field an enumeration type?
+ if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil {
+ return populateFieldEnum(f, value, enumValMap)
+ }
+
+ conv, ok := convFromType[f.Kind()]
+ if !ok {
+ return fmt.Errorf("field type %T is not supported in query parameters", i)
+ }
+ result := conv.Call([]reflect.Value{reflect.ValueOf(value)})
+ if err := result[1].Interface(); err != nil {
+ return err.(error)
+ }
+ f.Set(result[0].Convert(f.Type()))
+ return nil
+}
+
+func convertEnum(value string, t reflect.Type, enumValMap map[string]int32) (reflect.Value, error) {
+ // see if it's an enumeration string
+ if enumVal, ok := enumValMap[value]; ok {
+ return reflect.ValueOf(enumVal).Convert(t), nil
+ }
+
+ // check for an integer that matches an enumeration value
+ eVal, err := strconv.Atoi(value)
+ if err != nil {
+ return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t)
+ }
+ for _, v := range enumValMap {
+ if v == int32(eVal) {
+ return reflect.ValueOf(eVal).Convert(t), nil
+ }
+ }
+ return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t)
+}
+
+func populateFieldEnum(f reflect.Value, value string, enumValMap map[string]int32) error {
+ cval, err := convertEnum(value, f.Type(), enumValMap)
+ if err != nil {
+ return err
+ }
+ f.Set(cval)
+ return nil
+}
+
+func populateFieldEnumRepeated(f reflect.Value, values []string, enumValMap map[string]int32) error {
+ elemType := f.Type().Elem()
+ f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type()))
+ for i, v := range values {
+ result, err := convertEnum(v, elemType, enumValMap)
+ if err != nil {
+ return err
+ }
+ f.Index(i).Set(result)
+ }
+ return nil
+}
+
+var (
+ convFromType = map[reflect.Kind]reflect.Value{
+ reflect.String: reflect.ValueOf(String),
+ reflect.Bool: reflect.ValueOf(Bool),
+ reflect.Float64: reflect.ValueOf(Float64),
+ reflect.Float32: reflect.ValueOf(Float32),
+ reflect.Int64: reflect.ValueOf(Int64),
+ reflect.Int32: reflect.ValueOf(Int32),
+ reflect.Uint64: reflect.ValueOf(Uint64),
+ reflect.Uint32: reflect.ValueOf(Uint32),
+ reflect.Slice: reflect.ValueOf(Bytes),
+ }
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel
new file mode 100644
index 0000000..7109d79
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel
@@ -0,0 +1,21 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+package(default_visibility = ["//visibility:public"])
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "doc.go",
+ "pattern.go",
+ "readerfactory.go",
+ "trie.go",
+ ],
+ importpath = "github.com/grpc-ecosystem/grpc-gateway/utilities",
+)
+
+go_test(
+ name = "go_default_test",
+ size = "small",
+ srcs = ["trie_test.go"],
+ embed = [":go_default_library"],
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go
new file mode 100644
index 0000000..cf79a4d
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go
@@ -0,0 +1,2 @@
+// Package utilities provides members for internal use in grpc-gateway.
+package utilities
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go
new file mode 100644
index 0000000..dfe7de4
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go
@@ -0,0 +1,22 @@
+package utilities
+
+// An OpCode is a opcode of compiled path patterns.
+type OpCode int
+
+// These constants are the valid values of OpCode.
+const (
+ // OpNop does nothing
+ OpNop = OpCode(iota)
+ // OpPush pushes a component to stack
+ OpPush
+ // OpLitPush pushes a component to stack if it matches to the literal
+ OpLitPush
+ // OpPushM concatenates the remaining components and pushes it to stack
+ OpPushM
+ // OpConcatN pops N items from stack, concatenates them and pushes it back to stack
+ OpConcatN
+ // OpCapture pops an item and binds it to the variable
+ OpCapture
+ // OpEnd is the least positive invalid opcode.
+ OpEnd
+)
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go
new file mode 100644
index 0000000..6dd3854
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go
@@ -0,0 +1,20 @@
+package utilities
+
+import (
+ "bytes"
+ "io"
+ "io/ioutil"
+)
+
+// IOReaderFactory takes in an io.Reader and returns a function that will allow you to create a new reader that begins
+// at the start of the stream
+func IOReaderFactory(r io.Reader) (func() io.Reader, error) {
+ b, err := ioutil.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+
+ return func() io.Reader {
+ return bytes.NewReader(b)
+ }, nil
+}
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go
new file mode 100644
index 0000000..c2b7b30
--- /dev/null
+++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go
@@ -0,0 +1,177 @@
+package utilities
+
+import (
+ "sort"
+)
+
+// DoubleArray is a Double Array implementation of trie on sequences of strings.
+type DoubleArray struct {
+ // Encoding keeps an encoding from string to int
+ Encoding map[string]int
+ // Base is the base array of Double Array
+ Base []int
+ // Check is the check array of Double Array
+ Check []int
+}
+
+// NewDoubleArray builds a DoubleArray from a set of sequences of strings.
+func NewDoubleArray(seqs [][]string) *DoubleArray {
+ da := &DoubleArray{Encoding: make(map[string]int)}
+ if len(seqs) == 0 {
+ return da
+ }
+
+ encoded := registerTokens(da, seqs)
+ sort.Sort(byLex(encoded))
+
+ root := node{row: -1, col: -1, left: 0, right: len(encoded)}
+ addSeqs(da, encoded, 0, root)
+
+ for i := len(da.Base); i > 0; i-- {
+ if da.Check[i-1] != 0 {
+ da.Base = da.Base[:i]
+ da.Check = da.Check[:i]
+ break
+ }
+ }
+ return da
+}
+
+func registerTokens(da *DoubleArray, seqs [][]string) [][]int {
+ var result [][]int
+ for _, seq := range seqs {
+ var encoded []int
+ for _, token := range seq {
+ if _, ok := da.Encoding[token]; !ok {
+ da.Encoding[token] = len(da.Encoding)
+ }
+ encoded = append(encoded, da.Encoding[token])
+ }
+ result = append(result, encoded)
+ }
+ for i := range result {
+ result[i] = append(result[i], len(da.Encoding))
+ }
+ return result
+}
+
+type node struct {
+ row, col int
+ left, right int
+}
+
+func (n node) value(seqs [][]int) int {
+ return seqs[n.row][n.col]
+}
+
+func (n node) children(seqs [][]int) []*node {
+ var result []*node
+ lastVal := int(-1)
+ last := new(node)
+ for i := n.left; i < n.right; i++ {
+ if lastVal == seqs[i][n.col+1] {
+ continue
+ }
+ last.right = i
+ last = &node{
+ row: i,
+ col: n.col + 1,
+ left: i,
+ }
+ result = append(result, last)
+ }
+ last.right = n.right
+ return result
+}
+
+func addSeqs(da *DoubleArray, seqs [][]int, pos int, n node) {
+ ensureSize(da, pos)
+
+ children := n.children(seqs)
+ var i int
+ for i = 1; ; i++ {
+ ok := func() bool {
+ for _, child := range children {
+ code := child.value(seqs)
+ j := i + code
+ ensureSize(da, j)
+ if da.Check[j] != 0 {
+ return false
+ }
+ }
+ return true
+ }()
+ if ok {
+ break
+ }
+ }
+ da.Base[pos] = i
+ for _, child := range children {
+ code := child.value(seqs)
+ j := i + code
+ da.Check[j] = pos + 1
+ }
+ terminator := len(da.Encoding)
+ for _, child := range children {
+ code := child.value(seqs)
+ if code == terminator {
+ continue
+ }
+ j := i + code
+ addSeqs(da, seqs, j, *child)
+ }
+}
+
+func ensureSize(da *DoubleArray, i int) {
+ for i >= len(da.Base) {
+ da.Base = append(da.Base, make([]int, len(da.Base)+1)...)
+ da.Check = append(da.Check, make([]int, len(da.Check)+1)...)
+ }
+}
+
+type byLex [][]int
+
+func (l byLex) Len() int { return len(l) }
+func (l byLex) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
+func (l byLex) Less(i, j int) bool {
+ si := l[i]
+ sj := l[j]
+ var k int
+ for k = 0; k < len(si) && k < len(sj); k++ {
+ if si[k] < sj[k] {
+ return true
+ }
+ if si[k] > sj[k] {
+ return false
+ }
+ }
+ if k < len(sj) {
+ return true
+ }
+ return false
+}
+
+// HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence.
+func (da *DoubleArray) HasCommonPrefix(seq []string) bool {
+ if len(da.Base) == 0 {
+ return false
+ }
+
+ var i int
+ for _, t := range seq {
+ code, ok := da.Encoding[t]
+ if !ok {
+ break
+ }
+ j := da.Base[i] + code
+ if len(da.Check) <= j || da.Check[j] != i+1 {
+ break
+ }
+ i = j
+ }
+ j := da.Base[i] + len(da.Encoding)
+ if len(da.Check) <= j || da.Check[j] != i+1 {
+ return false
+ }
+ return true
+}