Răsfoiți Sursa

refactor: 重构swagger,支持openapi3.0

dcsunny 1 an în urmă
părinte
comite
aa3fef3f0f
87 a modificat fișierele cu 992 adăugiri și 15415 ștergeri
  1. 18 17
      go.mod
  2. 819 40
      go.sum
  3. 9 20
      handler.go
  4. 0 15
      openapiv2/options.go
  5. 0 63
      openapiv2/service.go
  6. 0 1
      openapiv2/swagger_ui/dist/swagger-ui-bundle.js
  7. 0 0
      openapiv2/swagger_ui/dist/swagger-ui-bundle.js.map
  8. 0 1
      openapiv2/swagger_ui/dist/swagger-ui-es-bundle-core.js
  9. 0 0
      openapiv2/swagger_ui/dist/swagger-ui-es-bundle-core.js.map
  10. 0 1
      openapiv2/swagger_ui/dist/swagger-ui-es-bundle.js
  11. 0 0
      openapiv2/swagger_ui/dist/swagger-ui-es-bundle.js.map
  12. 0 1
      openapiv2/swagger_ui/dist/swagger-ui-standalone-preset.js
  13. 0 0
      openapiv2/swagger_ui/dist/swagger-ui-standalone-preset.js.map
  14. 0 1
      openapiv2/swagger_ui/dist/swagger-ui.css
  15. 0 0
      openapiv2/swagger_ui/dist/swagger-ui.css.map
  16. 0 1
      openapiv2/swagger_ui/dist/swagger-ui.js
  17. 0 0
      openapiv2/swagger_ui/dist/swagger-ui.js.map
  18. 0 3
      openapiv2/swagger_ui/generate.go
  19. 0 9
      openapiv2/swagger_ui/statik/statik.go
  20. 0 74
      protoc-gen-openapiv2/generator/generator.go
  21. 0 56
      protoc-gen-openapiv2/generator/generator_test.go
  22. 0 38
      protoc-gen-openapiv2/generator/option.go
  23. BIN
      protoc-gen-openapiv2/generator/req.bin
  24. 0 14
      protoc-gen-openapiv2/internal/casing/BUILD.bazel
  25. 0 28
      protoc-gen-openapiv2/internal/casing/LICENSE.md
  26. 0 5
      protoc-gen-openapiv2/internal/casing/README.md
  27. 0 63
      protoc-gen-openapiv2/internal/casing/camel.go
  28. 0 36
      protoc-gen-openapiv2/internal/codegenerator/BUILD.bazel
  29. 0 4
      protoc-gen-openapiv2/internal/codegenerator/doc.go
  30. 0 23
      protoc-gen-openapiv2/internal/codegenerator/parse_req.go
  31. 0 70
      protoc-gen-openapiv2/internal/codegenerator/parse_req_test.go
  32. 0 24
      protoc-gen-openapiv2/internal/codegenerator/supported_features.go
  33. 0 60
      protoc-gen-openapiv2/internal/descriptor/BUILD.bazel
  34. 0 35
      protoc-gen-openapiv2/internal/descriptor/apiconfig/BUILD.bazel
  35. 0 165
      protoc-gen-openapiv2/internal/descriptor/apiconfig/apiconfig.pb.go
  36. 0 21
      protoc-gen-openapiv2/internal/descriptor/apiconfig/apiconfig.proto
  37. 0 46
      protoc-gen-openapiv2/internal/descriptor/apiconfig/apiconfig.swagger.json
  38. 0 71
      protoc-gen-openapiv2/internal/descriptor/grpc_api_configuration.go
  39. 0 149
      protoc-gen-openapiv2/internal/descriptor/grpc_api_configuration_test.go
  40. 0 58
      protoc-gen-openapiv2/internal/descriptor/openapi_configuration.go
  41. 0 114
      protoc-gen-openapiv2/internal/descriptor/openapi_configuration_test.go
  42. 0 683
      protoc-gen-openapiv2/internal/descriptor/openapiconfig/openapiconfig.pb.go
  43. 0 51
      protoc-gen-openapiv2/internal/descriptor/openapiconfig/openapiconfig.proto
  44. 0 46
      protoc-gen-openapiv2/internal/descriptor/openapiconfig/openapiconfig.swagger.json
  45. 0 702
      protoc-gen-openapiv2/internal/descriptor/registry.go
  46. 0 718
      protoc-gen-openapiv2/internal/descriptor/registry_test.go
  47. 0 347
      protoc-gen-openapiv2/internal/descriptor/services.go
  48. 0 1447
      protoc-gen-openapiv2/internal/descriptor/services_test.go
  49. 0 538
      protoc-gen-openapiv2/internal/descriptor/types.go
  50. 0 269
      protoc-gen-openapiv2/internal/descriptor/types_test.go
  51. 0 12
      protoc-gen-openapiv2/internal/generator/generator.go
  52. 0 41
      protoc-gen-openapiv2/internal/genopenapi/cycle_test.go
  53. 0 2
      protoc-gen-openapiv2/internal/genopenapi/doc.go
  54. 0 247
      protoc-gen-openapiv2/internal/genopenapi/generator.go
  55. 0 10
      protoc-gen-openapiv2/internal/genopenapi/helpers.go
  56. 0 10
      protoc-gen-openapiv2/internal/genopenapi/helpers_go111_old.go
  57. 0 2454
      protoc-gen-openapiv2/internal/genopenapi/template.go
  58. 0 4635
      protoc-gen-openapiv2/internal/genopenapi/template_test.go
  59. 0 282
      protoc-gen-openapiv2/internal/genopenapi/types.go
  60. 0 121
      protoc-gen-openapiv2/internal/httprule/compile.go
  61. 0 129
      protoc-gen-openapiv2/internal/httprule/compile_test.go
  62. 0 12
      protoc-gen-openapiv2/internal/httprule/fuzz.go
  63. 0 369
      protoc-gen-openapiv2/internal/httprule/parse.go
  64. 0 366
      protoc-gen-openapiv2/internal/httprule/parse_test.go
  65. 0 60
      protoc-gen-openapiv2/internal/httprule/types.go
  66. 0 91
      protoc-gen-openapiv2/internal/httprule/types_test.go
  67. 0 228
      protoc-gen-openapiv2/main.go
  68. 0 186
      protoc-gen-openapiv2/main_test.go
  69. 0 0
      q/swagger-ui/favicon-16x16.png
  70. 0 0
      q/swagger-ui/favicon-32x32.png
  71. 16 0
      q/swagger-ui/index.css
  72. 9 26
      q/swagger-ui/index.html
  73. 10 6
      q/swagger-ui/oauth2-redirect.html
  74. 20 0
      q/swagger-ui/swagger-initializer.js
  75. 1 0
      q/swagger-ui/swagger-ui-bundle.js
  76. 0 0
      q/swagger-ui/swagger-ui-bundle.js.map
  77. 1 0
      q/swagger-ui/swagger-ui-es-bundle-core.js
  78. 0 0
      q/swagger-ui/swagger-ui-es-bundle-core.js.map
  79. 1 0
      q/swagger-ui/swagger-ui-es-bundle.js
  80. 0 0
      q/swagger-ui/swagger-ui-es-bundle.js.map
  81. 1 0
      q/swagger-ui/swagger-ui-standalone-preset.js
  82. 0 0
      q/swagger-ui/swagger-ui-standalone-preset.js.map
  83. 0 0
      q/swagger-ui/swagger-ui.css
  84. 0 0
      q/swagger-ui/swagger-ui.css.map
  85. 0 0
      q/swagger-ui/swagger-ui.js
  86. 0 0
      q/swagger-ui/swagger-ui.js.map
  87. 87 0
      service.go

+ 18 - 17
go.mod

@@ -1,27 +1,28 @@
 module git.ikuban.com/server/swagger-api
 
-go 1.19
+go 1.22.1
 
 require (
-	github.com/ghodss/yaml v1.0.0
-	github.com/go-kratos/kratos/v2 v2.5.3
-	github.com/go-kratos/swagger-api v1.0.1
-	github.com/golang/glog v1.0.0
-	github.com/golang/protobuf v1.5.2
-	github.com/google/go-cmp v0.5.9
-	github.com/gorilla/mux v1.8.0
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0
-	github.com/rakyll/statik v0.1.7
-	google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1
-	google.golang.org/grpc v1.50.1
-	google.golang.org/protobuf v1.28.1
+	git.ikuban.com/server/gnostic v0.0.0-20240530012907-80ffc2e6ca93
+	github.com/go-kratos/kratos/v2 v2.7.3
+	github.com/gorilla/mux v1.8.1
+	github.com/xmkuban/utils v0.0.12
+	google.golang.org/grpc v1.64.0
+	google.golang.org/protobuf v1.34.1
 )
 
 require (
+	github.com/go-kratos/aegis v0.2.0 // indirect
 	github.com/go-playground/form/v4 v4.2.0 // indirect
-	golang.org/x/net v0.2.0 // indirect
-	golang.org/x/sys v0.2.0 // indirect
-	golang.org/x/text v0.4.0 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
+	github.com/google/gnostic v0.7.0 // indirect
+	github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/shopspring/decimal v1.2.0 // indirect
+	github.com/spf13/cast v1.5.0 // indirect
+	golang.org/x/net v0.22.0 // indirect
+	golang.org/x/sys v0.18.0 // indirect
+	golang.org/x/text v0.14.0 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )

Fișier diff suprimat deoarece este prea mare
+ 819 - 40
go.sum


+ 9 - 20
openapiv2/handler.go → handler.go

@@ -1,29 +1,22 @@
-package openapiv2
+package swagger_api
 
 import (
+	"embed"
 	"encoding/json"
 	"net/http"
 	"net/url"
 
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/generator"
 	"github.com/go-kratos/kratos/v2/api/metadata"
 	"github.com/go-kratos/kratos/v2/transport/http/binding"
-	_ "github.com/go-kratos/swagger-api/openapiv2/swagger_ui/statik" // import statik static files
 	"github.com/gorilla/mux"
-	"github.com/rakyll/statik/fs"
 )
 
-func NewHandler(servicesList []string, handlerOpts ...HandlerOption) http.Handler {
-	opts := &options{
-		// Compatible with default UseJSONNamesForFields is true
-		generatorOptions: []generator.Option{generator.UseJSONNamesForFields(true)},
-	}
+//go:embed q/swagger-ui/*
+var staticFS embed.FS
 
-	for _, o := range handlerOpts {
-		o(opts)
-	}
+func NewHandler(servicesList []string) http.Handler {
 
-	service := New(nil, opts.generatorOptions...)
+	service := New(nil)
 	r := mux.NewRouter()
 
 	r.HandleFunc("/q/services", func(w http.ResponseWriter, r *http.Request) {
@@ -59,7 +52,6 @@ func NewHandler(servicesList []string, handlerOpts ...HandlerOption) http.Handle
 			w.Write([]byte(err.Error()))
 			return
 		}
-
 		content, err := service.GetServiceOpenAPI(r.Context(), &in, false)
 		if err != nil {
 			w.WriteHeader(500)
@@ -72,12 +64,9 @@ func NewHandler(servicesList []string, handlerOpts ...HandlerOption) http.Handle
 		w.Write([]byte(content))
 	}).Methods("GET")
 
-	statikFS, err := fs.New()
-	if err != nil {
-		panic(err)
-	}
-	staticServer := http.FileServer(statikFS)
-	sh := http.StripPrefix("/q/swagger-ui", staticServer)
+	staticServer := http.FileServer(http.FS(staticFS))
+	sh := http.StripPrefix("", staticServer)
+	//r.Handle("/q/swagger-ui/", sh)
 	r.PathPrefix("/q/swagger-ui").Handler(sh)
 	return r
 }

+ 0 - 15
openapiv2/options.go

@@ -1,15 +0,0 @@
-package openapiv2
-
-import "git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/generator"
-
-type options struct {
-	generatorOptions []generator.Option
-}
-
-type HandlerOption func(opt *options)
-
-func WithGeneratorOptions(opts ...generator.Option) HandlerOption {
-	return func(opt *options) {
-		opt.generatorOptions = opts
-	}
-}

+ 0 - 63
openapiv2/service.go

@@ -1,63 +0,0 @@
-package openapiv2
-
-import (
-	"context"
-	"fmt"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/generator"
-	"github.com/go-kratos/kratos/v2/api/metadata"
-	"google.golang.org/grpc"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-// Service is service
-type Service struct {
-	ser  *metadata.Server
-	opts []generator.Option
-}
-
-// New service
-func New(srv *grpc.Server, opts ...generator.Option) *Service {
-	return &Service{
-		ser:  metadata.NewServer(srv),
-		opts: opts,
-	}
-}
-
-// ListServices list services
-func (s *Service) ListServices(ctx context.Context, in *metadata.ListServicesRequest) (*metadata.ListServicesReply, error) {
-	return s.ser.ListServices(ctx, &metadata.ListServicesRequest{})
-}
-
-// GetServiceOpenAPI get service open api
-func (s *Service) GetServiceOpenAPI(ctx context.Context, in *metadata.GetServiceDescRequest, onlyRPC bool) (string, error) {
-	protoSet, err := s.ser.GetServiceDesc(ctx, in)
-	if err != nil {
-		return "", err
-	}
-	files := protoSet.FileDescSet.File
-	var target string
-	if len(files) == 0 {
-		return "", fmt.Errorf("proto file is empty")
-	}
-	if files[len(files)-1].Name == nil {
-		return "", fmt.Errorf("proto file's name is null")
-	}
-	target = *files[len(files)-1].Name
-
-	req := new(pluginpb.CodeGeneratorRequest)
-	req.FileToGenerate = []string{target}
-	var para = ""
-	req.Parameter = &para
-	req.ProtoFile = files
-
-	g := generator.NewGenerator(s.opts...)
-	resp, err := g.Gen(req, onlyRPC)
-	if err != nil {
-		return "", err
-	}
-	if len(resp.File) == 0 {
-		return "{}", nil
-	}
-	return *resp.File[0].Content, nil
-}

Fișier diff suprimat deoarece este prea mare
+ 0 - 1
openapiv2/swagger_ui/dist/swagger-ui-bundle.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
openapiv2/swagger_ui/dist/swagger-ui-bundle.js.map


Fișier diff suprimat deoarece este prea mare
+ 0 - 1
openapiv2/swagger_ui/dist/swagger-ui-es-bundle-core.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
openapiv2/swagger_ui/dist/swagger-ui-es-bundle-core.js.map


Fișier diff suprimat deoarece este prea mare
+ 0 - 1
openapiv2/swagger_ui/dist/swagger-ui-es-bundle.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
openapiv2/swagger_ui/dist/swagger-ui-es-bundle.js.map


Fișier diff suprimat deoarece este prea mare
+ 0 - 1
openapiv2/swagger_ui/dist/swagger-ui-standalone-preset.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
openapiv2/swagger_ui/dist/swagger-ui-standalone-preset.js.map


Fișier diff suprimat deoarece este prea mare
+ 0 - 1
openapiv2/swagger_ui/dist/swagger-ui.css


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
openapiv2/swagger_ui/dist/swagger-ui.css.map


Fișier diff suprimat deoarece este prea mare
+ 0 - 1
openapiv2/swagger_ui/dist/swagger-ui.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
openapiv2/swagger_ui/dist/swagger-ui.js.map


+ 0 - 3
openapiv2/swagger_ui/generate.go

@@ -1,3 +0,0 @@
-//go:generate statik -m -src=./dist
-
-package swagger_ui

Fișier diff suprimat deoarece este prea mare
+ 0 - 9
openapiv2/swagger_ui/statik/statik.go


+ 0 - 74
protoc-gen-openapiv2/generator/generator.go

@@ -1,74 +0,0 @@
-package generator
-
-import (
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/codegenerator"
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor"
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/genopenapi"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-// Generator is openapi v2 generator
-type Generator struct {
-	reg *descriptor.Registry
-}
-
-// NewGenerator return Generator
-func NewGenerator(options ...Option) *Generator {
-	gen := &Generator{
-		reg: descriptor.NewRegistry(),
-	}
-	gen.reg.SetUseJSONNamesForFields(true)
-	gen.reg.SetRecursiveDepth(1024)
-	gen.reg.SetMergeFileName("apidocs")
-	gen.reg.SetDisableDefaultErrors(true)
-	for _, o := range options {
-		o(gen)
-	}
-	return gen
-}
-
-// Gen generates openapi v2 json content
-func (g *Generator) Gen(req *pluginpb.CodeGeneratorRequest, onlyRPC bool) (*pluginpb.CodeGeneratorResponse, error) {
-	reg := g.reg
-	if reg == nil {
-		reg = NewGenerator().reg
-	}
-	reg.SetGenerateRPCMethods(onlyRPC)
-	if err := reg.SetRepeatedPathParamSeparator("csv"); err != nil {
-		return nil, err
-	}
-
-	gen := genopenapi.New(reg)
-
-	if err := genopenapi.AddErrorDefs(reg); err != nil {
-		return nil, err
-	}
-
-	if err := reg.Load(req); err != nil {
-		return nil, err
-	}
-	var targets []*descriptor.File
-	for _, target := range req.FileToGenerate {
-		f, err := reg.LookupFile(target)
-		if err != nil {
-			return nil, err
-		}
-		targets = append(targets, f)
-	}
-
-	out, err := gen.Generate(targets)
-	if err != nil {
-		return nil, err
-	}
-	return emitFiles(out), nil
-}
-
-func emitFiles(out []*descriptor.ResponseFile) *pluginpb.CodeGeneratorResponse {
-	files := make([]*pluginpb.CodeGeneratorResponse_File, len(out))
-	for idx, item := range out {
-		files[idx] = item.CodeGeneratorResponse_File
-	}
-	resp := &pluginpb.CodeGeneratorResponse{File: files}
-	codegenerator.SetSupportedFeaturesOnCodeGeneratorResponse(resp)
-	return resp
-}

+ 0 - 56
protoc-gen-openapiv2/generator/generator_test.go

@@ -1,56 +0,0 @@
-package generator
-
-import (
-	"fmt"
-	"os"
-	"testing"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/codegenerator"
-)
-
-func Test_Gen(t *testing.T) {
-	var err error
-	f, err := os.Open("./req.bin")
-	if err != nil {
-		t.Fatal(err)
-	}
-	req, err := codegenerator.ParseRequest(f)
-	if err != nil {
-		t.Fatal(err)
-	}
-	var g Generator
-
-	resp, err := g.Gen(req, false)
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, file := range resp.File {
-		fmt.Println(*file.Content)
-	}
-}
-func Test_NewGenerator(t *testing.T) {
-	var err error
-	f, err := os.Open("./req.bin")
-	if err != nil {
-		t.Fatal(err)
-	}
-	req, err := codegenerator.ParseRequest(f)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	g := NewGenerator(
-		DisableDefaultErrors(true),
-		UseJSONNamesForFields(false),
-		EnumsAsInts(true),
-		RecursiveDepth(2048),
-	)
-
-	resp, err := g.Gen(req, false)
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, file := range resp.File {
-		fmt.Println(*file.Content)
-	}
-}

+ 0 - 38
protoc-gen-openapiv2/generator/option.go

@@ -1,38 +0,0 @@
-package generator
-
-type Option func(gen *Generator)
-
-// UseJSONNamesForFields. if disabled, the original proto name will be used for generating OpenAPI definitions
-func UseJSONNamesForFields(b bool) Option {
-	return func(gen *Generator) {
-		gen.reg.SetUseJSONNamesForFields(b)
-	}
-}
-
-// RecursiveDepth. maximum recursion count allowed for a field type
-func RecursiveDepth(depth int) Option {
-	return func(gen *Generator) {
-		gen.reg.SetRecursiveDepth(depth)
-	}
-}
-
-// EnumsAsInts. whether to render enum values as integers, as opposed to string values
-func EnumsAsInts(b bool) Option {
-	return func(gen *Generator) {
-		gen.reg.SetEnumsAsInts(b)
-	}
-}
-
-// MergeFileName. target OpenAPI file name prefix after merge
-func MergeFileName(name string) Option {
-	return func(gen *Generator) {
-		gen.reg.SetMergeFileName(name)
-	}
-}
-
-// DisableDefaultErrors. if set, disables generation of default errors. This is useful if you have defined custom error handling
-func DisableDefaultErrors(b bool) Option {
-	return func(gen *Generator) {
-		gen.reg.SetDisableDefaultErrors(b)
-	}
-}

BIN
protoc-gen-openapiv2/generator/req.bin


+ 0 - 14
protoc-gen-openapiv2/internal/casing/BUILD.bazel

@@ -1,14 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library")
-
-go_library(
-    name = "casing",
-    srcs = ["camel.go"],
-    importpath = "github.com/go-kratos/grpc-gateway/v2/internal/casing",
-    visibility = ["//:__subpackages__"],
-)
-
-alias(
-    name = "go_default_library",
-    actual = ":casing",
-    visibility = ["//:__subpackages__"],
-)

+ 0 - 28
protoc-gen-openapiv2/internal/casing/LICENSE.md

@@ -1,28 +0,0 @@
-Copyright 2010 The Go Authors.  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 Google 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.
-

+ 0 - 5
protoc-gen-openapiv2/internal/casing/README.md

@@ -1,5 +0,0 @@
-# Case conversion
-
-This package contains a single function, copied from the
-`github.com/golang/protobuf/protoc-gen-go/generator` package. That
-modules LICENSE is referenced in its entirety in this package.

+ 0 - 63
protoc-gen-openapiv2/internal/casing/camel.go

@@ -1,63 +0,0 @@
-package casing
-
-// Camel returns the CamelCased name.
-//
-// This was moved from the now deprecated github.com/golang/protobuf/protoc-gen-go/generator package
-//
-// If there is an interior underscore followed by a lower case letter,
-// drop the underscore and convert the letter to upper case.
-// There is a remote possibility of this rewrite causing a name collision,
-// but it's so remote we're prepared to pretend it's nonexistent - since the
-// C++ generator lowercases names, it's extremely unlikely to have two fields
-// with different capitalizations.
-// In short, _my_field_name_2 becomes XMyFieldName_2.
-func Camel(s string) string {
-	if s == "" {
-		return ""
-	}
-	t := make([]byte, 0, 32)
-	i := 0
-	if s[0] == '_' {
-		// Need a capital letter; drop the '_'.
-		t = append(t, 'X')
-		i++
-	}
-	// Invariant: if the next letter is lower case, it must be converted
-	// to upper case.
-	// That is, we process a word at a time, where words are marked by _ or
-	// upper case letter. Digits are treated as words.
-	for ; i < len(s); i++ {
-		c := s[i]
-		if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) {
-			continue // Skip the underscore in s.
-		}
-		if isASCIIDigit(c) {
-			t = append(t, c)
-			continue
-		}
-		// Assume we have a letter now - if not, it's a bogus identifier.
-		// The next word is a sequence of characters that must start upper case.
-		if isASCIILower(c) {
-			c ^= ' ' // Make it a capital letter.
-		}
-		t = append(t, c) // Guaranteed not lower case.
-		// Accept lower case sequence that follows.
-		for i+1 < len(s) && isASCIILower(s[i+1]) {
-			i++
-			t = append(t, s[i])
-		}
-	}
-	return string(t)
-}
-
-// And now lots of helper functions.
-
-// Is c an ASCII lower-case letter?
-func isASCIILower(c byte) bool {
-	return 'a' <= c && c <= 'z'
-}
-
-// Is c an ASCII digit?
-func isASCIIDigit(c byte) bool {
-	return '0' <= c && c <= '9'
-}

+ 0 - 36
protoc-gen-openapiv2/internal/codegenerator/BUILD.bazel

@@ -1,36 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
-    name = "codegenerator",
-    srcs = [
-        "doc.go",
-        "parse_req.go",
-        "supported_features.go",
-    ],
-    importpath = "github.com/go-kratos/grpc-gateway/v2/internal/codegenerator",
-    deps = [
-        "@org_golang_google_protobuf//compiler/protogen",
-        "@org_golang_google_protobuf//proto",
-        "@org_golang_google_protobuf//types/pluginpb",
-    ],
-)
-
-go_test(
-    name = "codegenerator_test",
-    srcs = ["parse_req_test.go"],
-    embed = [":codegenerator"],
-    deps = [
-        "@com_github_google_go_cmp//cmp",
-        "@org_golang_google_protobuf//proto",
-        "@org_golang_google_protobuf//testing/protocmp",
-        "@org_golang_google_protobuf//types/pluginpb",
-    ],
-)
-
-alias(
-    name = "go_default_library",
-    actual = ":codegenerator",
-    visibility = ["//:__subpackages__"],
-)

+ 0 - 4
protoc-gen-openapiv2/internal/codegenerator/doc.go

@@ -1,4 +0,0 @@
-/*
-Package codegenerator contains reusable functions used by the code generators.
-*/
-package codegenerator

+ 0 - 23
protoc-gen-openapiv2/internal/codegenerator/parse_req.go

@@ -1,23 +0,0 @@
-package codegenerator
-
-import (
-	"fmt"
-	"io"
-	"io/ioutil"
-
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-// ParseRequest parses a code generator request from a proto Message.
-func ParseRequest(r io.Reader) (*pluginpb.CodeGeneratorRequest, error) {
-	input, err := ioutil.ReadAll(r)
-	if err != nil {
-		return nil, fmt.Errorf("failed to read code generator request: %v", err)
-	}
-	req := new(pluginpb.CodeGeneratorRequest)
-	if err = proto.Unmarshal(input, req); err != nil {
-		return nil, fmt.Errorf("failed to unmarshal code generator request: %v", err)
-	}
-	return req, nil
-}

+ 0 - 70
protoc-gen-openapiv2/internal/codegenerator/parse_req_test.go

@@ -1,70 +0,0 @@
-package codegenerator_test
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"strings"
-	"testing"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/codegenerator"
-	"github.com/google/go-cmp/cmp"
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/testing/protocmp"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-var parseReqTests = []struct {
-	name      string
-	in        io.Reader
-	out       *pluginpb.CodeGeneratorRequest
-	expectErr bool
-}{
-	{
-		"Empty input should produce empty output",
-		mustGetReader(&pluginpb.CodeGeneratorRequest{}),
-		&pluginpb.CodeGeneratorRequest{},
-		false,
-	},
-	{
-		"Invalid reader should produce error",
-		&invalidReader{},
-		nil,
-		true,
-	},
-	{
-		"Invalid proto message should produce error",
-		strings.NewReader("{}"),
-		nil,
-		true,
-	},
-}
-
-func TestParseRequest(t *testing.T) {
-	for _, tt := range parseReqTests {
-		t.Run(tt.name, func(t *testing.T) {
-			out, err := codegenerator.ParseRequest(tt.in)
-			if tt.expectErr && err == nil {
-				t.Error("did not error as expected")
-			}
-			if diff := cmp.Diff(out, tt.out, protocmp.Transform()); diff != "" {
-				t.Errorf(diff)
-			}
-		})
-	}
-}
-
-func mustGetReader(pb proto.Message) io.Reader {
-	b, err := proto.Marshal(pb)
-	if err != nil {
-		panic(err)
-	}
-	return bytes.NewBuffer(b)
-}
-
-type invalidReader struct {
-}
-
-func (*invalidReader) Read(p []byte) (int, error) {
-	return 0, fmt.Errorf("invalid reader")
-}

+ 0 - 24
protoc-gen-openapiv2/internal/codegenerator/supported_features.go

@@ -1,24 +0,0 @@
-package codegenerator
-
-import (
-	"google.golang.org/protobuf/compiler/protogen"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-func supportedCodeGeneratorFeatures() uint64 {
-	// Enable support for optional keyword in proto3.
-	return uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)
-}
-
-// SetSupportedFeaturesOnPluginGen sets supported proto3 features
-// on protogen.Plugin.
-func SetSupportedFeaturesOnPluginGen(gen *protogen.Plugin) {
-	gen.SupportedFeatures = supportedCodeGeneratorFeatures()
-}
-
-// SetSupportedFeaturesOnCodeGeneratorResponse sets supported proto3 features
-// on pluginpb.CodeGeneratorResponse.
-func SetSupportedFeaturesOnCodeGeneratorResponse(resp *pluginpb.CodeGeneratorResponse) {
-	sf := supportedCodeGeneratorFeatures()
-	resp.SupportedFeatures = &sf
-}

+ 0 - 60
protoc-gen-openapiv2/internal/descriptor/BUILD.bazel

@@ -1,60 +0,0 @@
-load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-
-package(default_visibility = ["//visibility:public"])
-
-go_library(
-    name = "descriptor",
-    srcs = [
-        "grpc_api_configuration.go",
-        "openapi_configuration.go",
-        "registry.go",
-        "services.go",
-        "types.go",
-    ],
-    importpath = "github.com/go-kratos/grpc-gateway/v2/internal/descriptor",
-    deps = [
-        "//internal/casing",
-        "//internal/codegenerator",
-        "//internal/descriptor/apiconfig",
-        "//internal/descriptor/openapiconfig",
-        "//internal/httprule",
-        "//protoc-gen-openapiv2/options",
-        "@com_github_ghodss_yaml//:yaml",
-        "@com_github_golang_glog//:glog",
-        "@go_googleapis//google/api:annotations_go_proto",
-        "@org_golang_google_protobuf//compiler/protogen",
-        "@org_golang_google_protobuf//encoding/protojson",
-        "@org_golang_google_protobuf//proto",
-        "@org_golang_google_protobuf//types/descriptorpb",
-        "@org_golang_google_protobuf//types/pluginpb",
-    ],
-)
-
-go_test(
-    name = "descriptor_test",
-    size = "small",
-    srcs = [
-        "grpc_api_configuration_test.go",
-        "openapi_configuration_test.go",
-        "registry_test.go",
-        "services_test.go",
-        "types_test.go",
-    ],
-    embed = [":descriptor"],
-    deps = [
-        "//internal/descriptor/openapiconfig",
-        "//internal/httprule",
-        "//protoc-gen-openapiv2/options",
-        "@org_golang_google_protobuf//compiler/protogen",
-        "@org_golang_google_protobuf//encoding/prototext",
-        "@org_golang_google_protobuf//proto",
-        "@org_golang_google_protobuf//types/descriptorpb",
-        "@org_golang_google_protobuf//types/pluginpb",
-    ],
-)
-
-alias(
-    name = "go_default_library",
-    actual = ":descriptor",
-    visibility = ["//:__subpackages__"],
-)

+ 0 - 35
protoc-gen-openapiv2/internal/descriptor/apiconfig/BUILD.bazel

@@ -1,35 +0,0 @@
-load("@rules_proto//proto:defs.bzl", "proto_library")
-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 = "apiconfig_proto",
-    srcs = [
-        "apiconfig.proto",
-    ],
-    deps = [
-        "@go_googleapis//google/api:annotations_proto",
-    ],
-)
-
-go_proto_library(
-    name = "apiconfig_go_proto",
-    compilers = ["//:go_apiv2"],
-    importpath = "github.com/go-kratos/grpc-gateway/v2/internal/descriptor/apiconfig",
-    proto = ":apiconfig_proto",
-    deps = ["@go_googleapis//google/api:annotations_go_proto"],
-)
-
-go_library(
-    name = "apiconfig",
-    embed = [":apiconfig_go_proto"],
-    importpath = "github.com/go-kratos/grpc-gateway/v2/internal/descriptor/apiconfig",
-)
-
-alias(
-    name = "go_default_library",
-    actual = ":apiconfig",
-    visibility = ["//:__subpackages__"],
-)

+ 0 - 165
protoc-gen-openapiv2/internal/descriptor/apiconfig/apiconfig.pb.go

@@ -1,165 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.26.0
-// 	protoc        v3.15.2
-// source: internal/descriptor/apiconfig/apiconfig.proto
-
-package apiconfig
-
-import (
-	annotations "google.golang.org/genproto/googleapis/api/annotations"
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// 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.
-type GrpcAPIService struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	// Http Rule.
-	Http *annotations.Http `protobuf:"bytes,1,opt,name=http,proto3" json:"http,omitempty"`
-}
-
-func (x *GrpcAPIService) Reset() {
-	*x = GrpcAPIService{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_descriptor_apiconfig_apiconfig_proto_msgTypes[0]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *GrpcAPIService) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*GrpcAPIService) ProtoMessage() {}
-
-func (x *GrpcAPIService) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_descriptor_apiconfig_apiconfig_proto_msgTypes[0]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use GrpcAPIService.ProtoReflect.Descriptor instead.
-func (*GrpcAPIService) Descriptor() ([]byte, []int) {
-	return file_internal_descriptor_apiconfig_apiconfig_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *GrpcAPIService) GetHttp() *annotations.Http {
-	if x != nil {
-		return x.Http
-	}
-	return nil
-}
-
-var File_internal_descriptor_apiconfig_apiconfig_proto protoreflect.FileDescriptor
-
-var file_internal_descriptor_apiconfig_apiconfig_proto_rawDesc = []byte{
-	0x0a, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72,
-	0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f,
-	0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
-	0x2a, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x69, 0x6e,
-	0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
-	0x72, 0x2e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x15, 0x67, 0x6f, 0x6f,
-	0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x22, 0x36, 0x0a, 0x0e, 0x47, 0x72, 0x70, 0x63, 0x41, 0x50, 0x49, 0x53, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e,
-	0x48, 0x74, 0x74, 0x70, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x42, 0x49, 0x5a, 0x47, 0x67, 0x69,
-	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x65, 0x63,
-	0x6f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x67, 0x61, 0x74,
-	0x65, 0x77, 0x61, 0x79, 0x2f, 0x76, 0x32, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
-	0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
-}
-
-var (
-	file_internal_descriptor_apiconfig_apiconfig_proto_rawDescOnce sync.Once
-	file_internal_descriptor_apiconfig_apiconfig_proto_rawDescData = file_internal_descriptor_apiconfig_apiconfig_proto_rawDesc
-)
-
-func file_internal_descriptor_apiconfig_apiconfig_proto_rawDescGZIP() []byte {
-	file_internal_descriptor_apiconfig_apiconfig_proto_rawDescOnce.Do(func() {
-		file_internal_descriptor_apiconfig_apiconfig_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_descriptor_apiconfig_apiconfig_proto_rawDescData)
-	})
-	return file_internal_descriptor_apiconfig_apiconfig_proto_rawDescData
-}
-
-var file_internal_descriptor_apiconfig_apiconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
-var file_internal_descriptor_apiconfig_apiconfig_proto_goTypes = []interface{}{
-	(*GrpcAPIService)(nil),   // 0: grpc.gateway.internal.descriptor.apiconfig.GrpcAPIService
-	(*annotations.Http)(nil), // 1: google.api.Http
-}
-var file_internal_descriptor_apiconfig_apiconfig_proto_depIdxs = []int32{
-	1, // 0: grpc.gateway.internal.descriptor.apiconfig.GrpcAPIService.http:type_name -> google.api.Http
-	1, // [1:1] is the sub-list for method output_type
-	1, // [1:1] is the sub-list for method input_type
-	1, // [1:1] is the sub-list for extension type_name
-	1, // [1:1] is the sub-list for extension extendee
-	0, // [0:1] is the sub-list for field type_name
-}
-
-func init() { file_internal_descriptor_apiconfig_apiconfig_proto_init() }
-func file_internal_descriptor_apiconfig_apiconfig_proto_init() {
-	if File_internal_descriptor_apiconfig_apiconfig_proto != nil {
-		return
-	}
-	if !protoimpl.UnsafeEnabled {
-		file_internal_descriptor_apiconfig_apiconfig_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*GrpcAPIService); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-	}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_internal_descriptor_apiconfig_apiconfig_proto_rawDesc,
-			NumEnums:      0,
-			NumMessages:   1,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_internal_descriptor_apiconfig_apiconfig_proto_goTypes,
-		DependencyIndexes: file_internal_descriptor_apiconfig_apiconfig_proto_depIdxs,
-		MessageInfos:      file_internal_descriptor_apiconfig_apiconfig_proto_msgTypes,
-	}.Build()
-	File_internal_descriptor_apiconfig_apiconfig_proto = out.File
-	file_internal_descriptor_apiconfig_apiconfig_proto_rawDesc = nil
-	file_internal_descriptor_apiconfig_apiconfig_proto_goTypes = nil
-	file_internal_descriptor_apiconfig_apiconfig_proto_depIdxs = nil
-}

+ 0 - 21
protoc-gen-openapiv2/internal/descriptor/apiconfig/apiconfig.proto

@@ -1,21 +0,0 @@
-syntax = "proto3";
-
-package grpc.gateway.internal.descriptor.apiconfig;
-
-option go_package = "github.com/go-kratos/grpc-gateway/v2/internal/descriptor/apiconfig";
-
-import "google/api/http.proto";
-
-// 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.
-message GrpcAPIService {
-	// Http Rule.
-    google.api.Http http = 1;
-}

+ 0 - 46
protoc-gen-openapiv2/internal/descriptor/apiconfig/apiconfig.swagger.json

@@ -1,46 +0,0 @@
-{
-  "swagger": "2.0",
-  "info": {
-    "title": "internal/descriptor/apiconfig/apiconfig.proto",
-    "version": "version not set"
-  },
-  "consumes": [
-    "application/json"
-  ],
-  "produces": [
-    "application/json"
-  ],
-  "paths": {},
-  "definitions": {
-    "protobufAny": {
-      "type": "object",
-      "properties": {
-        "typeUrl": {
-          "type": "string"
-        },
-        "value": {
-          "type": "string",
-          "format": "byte"
-        }
-      }
-    },
-    "rpcStatus": {
-      "type": "object",
-      "properties": {
-        "code": {
-          "type": "integer",
-          "format": "int32"
-        },
-        "message": {
-          "type": "string"
-        },
-        "details": {
-          "type": "array",
-          "items": {
-            "$ref": "#/definitions/protobufAny"
-          }
-        }
-      }
-    }
-  }
-}

+ 0 - 71
protoc-gen-openapiv2/internal/descriptor/grpc_api_configuration.go

@@ -1,71 +0,0 @@
-package descriptor
-
-import (
-	"fmt"
-	"io/ioutil"
-	"strings"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor/apiconfig"
-	"github.com/ghodss/yaml"
-	"google.golang.org/protobuf/encoding/protojson"
-)
-
-func loadGrpcAPIServiceFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*apiconfig.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 unknown fields.
-	unmarshaler := protojson.UnmarshalOptions{
-		DiscardUnknown: true,
-	}
-
-	serviceConfiguration := apiconfig.GrpcAPIService{}
-	if err := unmarshaler.Unmarshal(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 *apiconfig.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)
-}

+ 0 - 149
protoc-gen-openapiv2/internal/descriptor/grpc_api_configuration_test.go

@@ -1,149 +0,0 @@
-package descriptor
-
-import (
-	"strings"
-	"testing"
-)
-
-func TestLoadGrpcAPIServiceFromYAMLInvalidType(t *testing.T) {
-	// Ideally this would fail but for now this test documents that it doesn't
-	service, err := loadGrpcAPIServiceFromYAML([]byte(`type: not.the.right.type`), "invalidtype")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if service == nil {
-		t.Fatal("No service returned")
-	}
-}
-
-func TestLoadGrpcAPIServiceFromYAMLSingleRule(t *testing.T) {
-	service, err := loadGrpcAPIServiceFromYAML([]byte(`
-type: google.api.Service
-config_version: 3
-
-http:
- rules:
- - selector: grpctest.YourService.Echo
-   post: /v1/myecho
-   body: "*"
-`), "example")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if service.Http == nil {
-		t.Fatal("HTTP is empty")
-	}
-
-	if len(service.Http.GetRules()) != 1 {
-		t.Fatalf("Have %v rules instead of one. Got: %v", len(service.Http.GetRules()), service.Http.GetRules())
-	}
-
-	rule := service.Http.GetRules()[0]
-	if rule.GetSelector() != "grpctest.YourService.Echo" {
-		t.Errorf("Rule has unexpected selector '%v'", rule.GetSelector())
-	}
-	if rule.GetPost() != "/v1/myecho" {
-		t.Errorf("Rule has unexpected post '%v'", rule.GetPost())
-	}
-	if rule.GetBody() != "*" {
-		t.Errorf("Rule has unexpected body '%v'", rule.GetBody())
-	}
-}
-
-func TestLoadGrpcAPIServiceFromYAMLRejectInvalidYAML(t *testing.T) {
-	service, err := loadGrpcAPIServiceFromYAML([]byte(`
-type: google.api.Service
-config_version: 3
-
-http:
- rules:
- - selector: grpctest.YourService.Echo
-   - post: thislinebreakstheselectorblockabovewiththeleadingdash
-   body: "*"
-`), "invalidyaml")
-	if err == nil {
-		t.Fatal(err)
-	}
-
-	if !strings.Contains(err.Error(), "line 7") {
-		t.Errorf("Expected yaml error to be detected in line 7. Got other error: %v", err)
-	}
-
-	if service != nil {
-		t.Fatal("Service returned")
-	}
-}
-
-func TestLoadGrpcAPIServiceFromYAMLMultipleWithAdditionalBindings(t *testing.T) {
-	service, err := loadGrpcAPIServiceFromYAML([]byte(`
-type: google.api.Service
-config_version: 3
-
-http:
- rules:
- - selector: first.selector
-   post: /my/post/path
-   body: "*"
-   additional_bindings:
-   - post: /additional/post/path
-   - put: /additional/put/{value}/path
-   - delete: "{value}"
-   - patch: "/additional/patch/{value}"
- - selector: some.other.service
-   delete: foo
-`), "example")
-	if err != nil {
-		t.Fatalf("Failed to load service description from YAML: %v", err)
-	}
-
-	if service == nil {
-		t.Fatal("No service returned")
-	}
-
-	if service.Http == nil {
-		t.Fatal("HTTP is empty")
-	}
-
-	if len(service.Http.GetRules()) != 2 {
-		t.Fatalf("%v service(s) returned when two were expected. Got: %v", len(service.Http.GetRules()), service.Http)
-	}
-
-	first := service.Http.GetRules()[0]
-	if first.GetSelector() != "first.selector" {
-		t.Errorf("first.selector has unexpected selector '%v'", first.GetSelector())
-	}
-	if first.GetBody() != "*" {
-		t.Errorf("first.selector has unexpected body '%v'", first.GetBody())
-	}
-	if first.GetPost() != "/my/post/path" {
-		t.Errorf("first.selector has unexpected post '%v'", first.GetPost())
-	}
-	if len(first.GetAdditionalBindings()) != 4 {
-		t.Fatalf("first.selector has unexpected number of bindings %v instead of four. Got: %v", len(first.GetAdditionalBindings()), first.GetAdditionalBindings())
-	}
-	if first.GetAdditionalBindings()[0].GetPost() != "/additional/post/path" {
-		t.Errorf("first.selector additional binding 0 has unexpected post '%v'", first.GetAdditionalBindings()[0].GetPost())
-	}
-	if first.GetAdditionalBindings()[1].GetPut() != "/additional/put/{value}/path" {
-		t.Errorf("first.selector additional binding 1 has unexpected put '%v'", first.GetAdditionalBindings()[0].GetPost())
-	}
-	if first.GetAdditionalBindings()[2].GetDelete() != "{value}" {
-		t.Errorf("first.selector additional binding 2 has unexpected delete '%v'", first.GetAdditionalBindings()[0].GetPost())
-	}
-	if first.GetAdditionalBindings()[3].GetPatch() != "/additional/patch/{value}" {
-		t.Errorf("first.selector additional binding 3 has unexpected patch '%v'", first.GetAdditionalBindings()[0].GetPost())
-	}
-
-	second := service.Http.GetRules()[1]
-	if second.GetSelector() != "some.other.service" {
-		t.Errorf("some.other.service has unexpected selector '%v'", second.GetSelector())
-	}
-	if second.GetDelete() != "foo" {
-		t.Errorf("some.other.service has unexpected delete '%v'", second.GetDelete())
-	}
-	if len(second.GetAdditionalBindings()) != 0 {
-		t.Errorf("some.other.service has %v additional bindings when it should not have any. Got: %v", len(second.GetAdditionalBindings()), second.GetAdditionalBindings())
-	}
-}

+ 0 - 58
protoc-gen-openapiv2/internal/descriptor/openapi_configuration.go

@@ -1,58 +0,0 @@
-package descriptor
-
-import (
-	"fmt"
-	"io/ioutil"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor/openapiconfig"
-	"github.com/ghodss/yaml"
-	"google.golang.org/protobuf/encoding/protojson"
-)
-
-func loadOpenAPIConfigFromYAML(yamlFileContents []byte, yamlSourceLogName string) (*openapiconfig.OpenAPIConfig, error) {
-	jsonContents, err := yaml.YAMLToJSON(yamlFileContents)
-	if err != nil {
-		return nil, fmt.Errorf("failed to convert OpenAPI Configuration from YAML in '%v' to JSON: %v", yamlSourceLogName, err)
-	}
-
-	// Reject unknown fields because OpenAPIConfig is only used here
-	unmarshaler := protojson.UnmarshalOptions{
-		DiscardUnknown: false,
-	}
-
-	openapiConfiguration := openapiconfig.OpenAPIConfig{}
-	if err := unmarshaler.Unmarshal(jsonContents, &openapiConfiguration); err != nil {
-		return nil, fmt.Errorf("failed to parse gRPC API Configuration from YAML in '%v': %v", yamlSourceLogName, err)
-	}
-
-	return &openapiConfiguration, nil
-}
-
-func registerOpenAPIOptions(registry *Registry, openAPIConfig *openapiconfig.OpenAPIConfig, yamlSourceLogName string) error {
-	if openAPIConfig.OpenapiOptions == nil {
-		// Nothing to do
-		return nil
-	}
-
-	if err := registry.RegisterOpenAPIOptions(openAPIConfig.OpenapiOptions); err != nil {
-		return fmt.Errorf("failed to register option in %s: %s", yamlSourceLogName, err)
-	}
-	return nil
-}
-
-// LoadOpenAPIConfigFromYAML loads an  OpenAPI Configuration from the given YAML file
-// and registers the OpenAPI options the given registry.
-// This must be done after loading the proto file.
-func (r *Registry) LoadOpenAPIConfigFromYAML(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)
-	}
-
-	config, err := loadOpenAPIConfigFromYAML(yamlFileContents, yamlFile)
-	if err != nil {
-		return err
-	}
-
-	return registerOpenAPIOptions(r, config, yamlFile)
-}

+ 0 - 114
protoc-gen-openapiv2/internal/descriptor/openapi_configuration_test.go

@@ -1,114 +0,0 @@
-package descriptor
-
-import (
-	"strings"
-	"testing"
-
-	"github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
-)
-
-func TestLoadOpenAPIConfigFromYAMLRejectInvalidYAML(t *testing.T) {
-	config, err := loadOpenAPIConfigFromYAML([]byte(`
-openapiOptions:
-file:
-- file: test.proto
-  - option:
-      schemes:
-        - HTTP
-        - HTTPS
-        - WSS
-      securityDefinitions:
-        security:
-          ApiKeyAuth:
-            type: TYPE_API_KEY
-            in: IN_HEADER
-            name: "X-API-Key"
-`), "invalidyaml")
-	if err == nil {
-		t.Fatal(err)
-	}
-
-	if !strings.Contains(err.Error(), "line 4") {
-		t.Errorf("Expected yaml error to be detected in line 4. Got other error: %v", err)
-	}
-
-	if config != nil {
-		t.Fatal("Config returned")
-	}
-}
-
-func TestLoadOpenAPIConfigFromYAML(t *testing.T) {
-	config, err := loadOpenAPIConfigFromYAML([]byte(`
-openapiOptions:
-  file:
-  - file: test.proto
-    option:
-      schemes:
-      - HTTP
-      - HTTPS
-      - WSS
-      securityDefinitions:
-        security:
-          ApiKeyAuth:
-            type: TYPE_API_KEY
-            in: IN_HEADER
-            name: "X-API-Key"
-`), "openapi_options")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if config.OpenapiOptions == nil {
-		t.Fatal("OpenAPIOptions is empty")
-	}
-
-	opts := config.OpenapiOptions
-	if numFileOpts := len(opts.File); numFileOpts != 1 {
-		t.Fatalf("expected 1 file option but got %d", numFileOpts)
-	}
-
-	fileOpt := opts.File[0]
-
-	if fileOpt.File != "test.proto" {
-		t.Fatalf("file option has unexpected binding %s", fileOpt.File)
-	}
-
-	swaggerOpt := fileOpt.Option
-
-	if swaggerOpt == nil {
-		t.Fatal("expected option to be set")
-	}
-
-	if numSchemes := len(swaggerOpt.Schemes); numSchemes != 3 {
-		t.Fatalf("expected 3 schemes but got %d", numSchemes)
-	}
-	if swaggerOpt.Schemes[0] != options.Scheme_HTTP {
-		t.Fatalf("expected first scheme to be HTTP but got %s", swaggerOpt.Schemes[0])
-	}
-	if swaggerOpt.Schemes[1] != options.Scheme_HTTPS {
-		t.Fatalf("expected second scheme to be HTTPS but got %s", swaggerOpt.Schemes[1])
-	}
-	if swaggerOpt.Schemes[2] != options.Scheme_WSS {
-		t.Fatalf("expected third scheme to be WSS but got %s", swaggerOpt.Schemes[2])
-	}
-
-	if swaggerOpt.SecurityDefinitions == nil {
-		t.Fatal("expected securityDefinitions to be set")
-	}
-	if numSecOpts := len(swaggerOpt.SecurityDefinitions.Security); numSecOpts != 1 {
-		t.Fatalf("expected 1 security option but got %d", numSecOpts)
-	}
-	secOpt, ok := swaggerOpt.SecurityDefinitions.Security["ApiKeyAuth"]
-	if !ok {
-		t.Fatal("no SecurityScheme for key \"ApiKeyAuth\"")
-	}
-	if secOpt.Type != options.SecurityScheme_TYPE_API_KEY {
-		t.Fatalf("expected scheme type to be TYPE_API_KEY but got %s", secOpt.Type)
-	}
-	if secOpt.In != options.SecurityScheme_IN_HEADER {
-		t.Fatalf("expected scheme  in to be IN_HEADER but got %s", secOpt.In)
-	}
-	if secOpt.Name != "X-API-Key" {
-		t.Fatalf("expected name to be X-API-Key but got %s", secOpt.Name)
-	}
-}

+ 0 - 683
protoc-gen-openapiv2/internal/descriptor/openapiconfig/openapiconfig.pb.go

@@ -1,683 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.26.0
-// 	protoc        v3.15.2
-// source: internal/descriptor/openapiconfig/openapiconfig.proto
-
-package openapiconfig
-
-import (
-	options "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-// OpenAPIFileOption represents OpenAPI options on a file
-type OpenAPIFileOption struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	File   string           `protobuf:"bytes,1,opt,name=file,proto3" json:"file,omitempty"`
-	Option *options.Swagger `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
-}
-
-func (x *OpenAPIFileOption) Reset() {
-	*x = OpenAPIFileOption{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[0]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *OpenAPIFileOption) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*OpenAPIFileOption) ProtoMessage() {}
-
-func (x *OpenAPIFileOption) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[0]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use OpenAPIFileOption.ProtoReflect.Descriptor instead.
-func (*OpenAPIFileOption) Descriptor() ([]byte, []int) {
-	return file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *OpenAPIFileOption) GetFile() string {
-	if x != nil {
-		return x.File
-	}
-	return ""
-}
-
-func (x *OpenAPIFileOption) GetOption() *options.Swagger {
-	if x != nil {
-		return x.Option
-	}
-	return nil
-}
-
-// OpenAPIMethodOption represents OpenAPI options on a method
-type OpenAPIMethodOption struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Method string             `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"`
-	Option *options.Operation `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
-}
-
-func (x *OpenAPIMethodOption) Reset() {
-	*x = OpenAPIMethodOption{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[1]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *OpenAPIMethodOption) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*OpenAPIMethodOption) ProtoMessage() {}
-
-func (x *OpenAPIMethodOption) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[1]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use OpenAPIMethodOption.ProtoReflect.Descriptor instead.
-func (*OpenAPIMethodOption) Descriptor() ([]byte, []int) {
-	return file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *OpenAPIMethodOption) GetMethod() string {
-	if x != nil {
-		return x.Method
-	}
-	return ""
-}
-
-func (x *OpenAPIMethodOption) GetOption() *options.Operation {
-	if x != nil {
-		return x.Option
-	}
-	return nil
-}
-
-// OpenAPIMessageOption represents OpenAPI options on a message
-type OpenAPIMessageOption struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Message string          `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
-	Option  *options.Schema `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
-}
-
-func (x *OpenAPIMessageOption) Reset() {
-	*x = OpenAPIMessageOption{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[2]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *OpenAPIMessageOption) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*OpenAPIMessageOption) ProtoMessage() {}
-
-func (x *OpenAPIMessageOption) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[2]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use OpenAPIMessageOption.ProtoReflect.Descriptor instead.
-func (*OpenAPIMessageOption) Descriptor() ([]byte, []int) {
-	return file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *OpenAPIMessageOption) GetMessage() string {
-	if x != nil {
-		return x.Message
-	}
-	return ""
-}
-
-func (x *OpenAPIMessageOption) GetOption() *options.Schema {
-	if x != nil {
-		return x.Option
-	}
-	return nil
-}
-
-// OpenAPIServiceOption represents OpenAPI options on a service
-type OpenAPIServiceOption struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Service string       `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` // ex: Service
-	Option  *options.Tag `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
-}
-
-func (x *OpenAPIServiceOption) Reset() {
-	*x = OpenAPIServiceOption{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[3]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *OpenAPIServiceOption) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*OpenAPIServiceOption) ProtoMessage() {}
-
-func (x *OpenAPIServiceOption) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[3]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use OpenAPIServiceOption.ProtoReflect.Descriptor instead.
-func (*OpenAPIServiceOption) Descriptor() ([]byte, []int) {
-	return file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{3}
-}
-
-func (x *OpenAPIServiceOption) GetService() string {
-	if x != nil {
-		return x.Service
-	}
-	return ""
-}
-
-func (x *OpenAPIServiceOption) GetOption() *options.Tag {
-	if x != nil {
-		return x.Option
-	}
-	return nil
-}
-
-// OpenAPIFieldOption represents OpenAPI options on a field
-type OpenAPIFieldOption struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	Field  string              `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"`
-	Option *options.JSONSchema `protobuf:"bytes,2,opt,name=option,proto3" json:"option,omitempty"`
-}
-
-func (x *OpenAPIFieldOption) Reset() {
-	*x = OpenAPIFieldOption{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[4]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *OpenAPIFieldOption) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*OpenAPIFieldOption) ProtoMessage() {}
-
-func (x *OpenAPIFieldOption) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[4]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use OpenAPIFieldOption.ProtoReflect.Descriptor instead.
-func (*OpenAPIFieldOption) Descriptor() ([]byte, []int) {
-	return file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{4}
-}
-
-func (x *OpenAPIFieldOption) GetField() string {
-	if x != nil {
-		return x.Field
-	}
-	return ""
-}
-
-func (x *OpenAPIFieldOption) GetOption() *options.JSONSchema {
-	if x != nil {
-		return x.Option
-	}
-	return nil
-}
-
-// OpenAPIOptions represents OpenAPI protobuf options
-type OpenAPIOptions struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	File    []*OpenAPIFileOption    `protobuf:"bytes,1,rep,name=file,proto3" json:"file,omitempty"`
-	Method  []*OpenAPIMethodOption  `protobuf:"bytes,2,rep,name=method,proto3" json:"method,omitempty"`
-	Message []*OpenAPIMessageOption `protobuf:"bytes,3,rep,name=message,proto3" json:"message,omitempty"`
-	Service []*OpenAPIServiceOption `protobuf:"bytes,4,rep,name=service,proto3" json:"service,omitempty"`
-	Field   []*OpenAPIFieldOption   `protobuf:"bytes,5,rep,name=field,proto3" json:"field,omitempty"`
-}
-
-func (x *OpenAPIOptions) Reset() {
-	*x = OpenAPIOptions{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[5]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *OpenAPIOptions) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*OpenAPIOptions) ProtoMessage() {}
-
-func (x *OpenAPIOptions) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[5]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use OpenAPIOptions.ProtoReflect.Descriptor instead.
-func (*OpenAPIOptions) Descriptor() ([]byte, []int) {
-	return file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{5}
-}
-
-func (x *OpenAPIOptions) GetFile() []*OpenAPIFileOption {
-	if x != nil {
-		return x.File
-	}
-	return nil
-}
-
-func (x *OpenAPIOptions) GetMethod() []*OpenAPIMethodOption {
-	if x != nil {
-		return x.Method
-	}
-	return nil
-}
-
-func (x *OpenAPIOptions) GetMessage() []*OpenAPIMessageOption {
-	if x != nil {
-		return x.Message
-	}
-	return nil
-}
-
-func (x *OpenAPIOptions) GetService() []*OpenAPIServiceOption {
-	if x != nil {
-		return x.Service
-	}
-	return nil
-}
-
-func (x *OpenAPIOptions) GetField() []*OpenAPIFieldOption {
-	if x != nil {
-		return x.Field
-	}
-	return nil
-}
-
-// OpenAPIConfig represents a set of OpenAPI options
-type OpenAPIConfig struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	OpenapiOptions *OpenAPIOptions `protobuf:"bytes,1,opt,name=openapi_options,json=openapiOptions,proto3" json:"openapi_options,omitempty"`
-}
-
-func (x *OpenAPIConfig) Reset() {
-	*x = OpenAPIConfig{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[6]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *OpenAPIConfig) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*OpenAPIConfig) ProtoMessage() {}
-
-func (x *OpenAPIConfig) ProtoReflect() protoreflect.Message {
-	mi := &file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[6]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use OpenAPIConfig.ProtoReflect.Descriptor instead.
-func (*OpenAPIConfig) Descriptor() ([]byte, []int) {
-	return file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP(), []int{6}
-}
-
-func (x *OpenAPIConfig) GetOpenapiOptions() *OpenAPIOptions {
-	if x != nil {
-		return x.OpenapiOptions
-	}
-	return nil
-}
-
-var File_internal_descriptor_openapiconfig_openapiconfig_proto protoreflect.FileDescriptor
-
-var file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDesc = []byte{
-	0x0a, 0x35, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72,
-	0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61,
-	0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64,
-	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,
-	0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x2c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d,
-	0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x73, 0x0a, 0x11, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49,
-	0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69,
-	0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x4a,
-	0x0a, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32,
-	0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,
-	0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x77, 0x61, 0x67, 0x67,
-	0x65, 0x72, 0x52, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7b, 0x0a, 0x13, 0x4f, 0x70,
-	0x65, 0x6e, 0x41, 0x50, 0x49, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f,
-	0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x4c, 0x0a, 0x06, 0x6f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x72, 0x70, 0x63,
-	0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f,
-	0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
-	0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7b, 0x0a, 0x14, 0x4f, 0x70, 0x65, 0x6e, 0x41,
-	0x50, 0x49, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
-	0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x49, 0x0a, 0x06, 0x6f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x72, 0x70, 0x63,
-	0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f,
-	0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x6f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x22, 0x78, 0x0a, 0x14, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x53,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07,
-	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61,
-	0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x5f, 0x67, 0x65, 0x6e,
-	0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f,
-	0x6e, 0x73, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x79,
-	0x0a, 0x12, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x4d, 0x0a, 0x06, 0x6f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x67, 0x72, 0x70,
-	0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
-	0x5f, 0x67, 0x65, 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2e, 0x6f,
-	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x53, 0x63, 0x68, 0x65, 0x6d,
-	0x61, 0x52, 0x06, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xde, 0x03, 0x0a, 0x0e, 0x4f, 0x70,
-	0x65, 0x6e, 0x41, 0x50, 0x49, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x04,
-	0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x67, 0x72, 0x70,
-	0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
-	0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70,
-	0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e,
-	0x41, 0x50, 0x49, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x66,
-	0x69, 0x6c, 0x65, 0x12, 0x5b, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77,
-	0x61, 0x79, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63,
-	0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x4d, 0x65, 0x74, 0x68,
-	0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
-	0x12, 0x5e, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x44, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
-	0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
-	0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
-	0x12, 0x5e, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x44, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
-	0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
-	0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66,
-	0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x12, 0x58, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
-	0x42, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x69,
-	0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
-	0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x78, 0x0a, 0x0d, 0x4f, 0x70,
-	0x65, 0x6e, 0x41, 0x50, 0x49, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x67, 0x0a, 0x0f, 0x6f,
-	0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x61, 0x74, 0x65,
-	0x77, 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x73,
-	0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x4f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x4f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
-	0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x65, 0x63, 0x6f, 0x73, 0x79, 0x73, 0x74, 0x65,
-	0x6d, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2f, 0x76,
-	0x32, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72,
-	0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
-}
-
-var (
-	file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescOnce sync.Once
-	file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescData = file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDesc
-)
-
-func file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescGZIP() []byte {
-	file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescOnce.Do(func() {
-		file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescData)
-	})
-	return file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDescData
-}
-
-var file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
-var file_internal_descriptor_openapiconfig_openapiconfig_proto_goTypes = []interface{}{
-	(*OpenAPIFileOption)(nil),    // 0: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFileOption
-	(*OpenAPIMethodOption)(nil),  // 1: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMethodOption
-	(*OpenAPIMessageOption)(nil), // 2: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMessageOption
-	(*OpenAPIServiceOption)(nil), // 3: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIServiceOption
-	(*OpenAPIFieldOption)(nil),   // 4: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFieldOption
-	(*OpenAPIOptions)(nil),       // 5: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions
-	(*OpenAPIConfig)(nil),        // 6: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIConfig
-	(*options.Swagger)(nil),      // 7: grpc.gateway.protoc_gen_openapiv2.options.Swagger
-	(*options.Operation)(nil),    // 8: grpc.gateway.protoc_gen_openapiv2.options.Operation
-	(*options.Schema)(nil),       // 9: grpc.gateway.protoc_gen_openapiv2.options.Schema
-	(*options.Tag)(nil),          // 10: grpc.gateway.protoc_gen_openapiv2.options.Tag
-	(*options.JSONSchema)(nil),   // 11: grpc.gateway.protoc_gen_openapiv2.options.JSONSchema
-}
-var file_internal_descriptor_openapiconfig_openapiconfig_proto_depIdxs = []int32{
-	7,  // 0: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFileOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Swagger
-	8,  // 1: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMethodOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Operation
-	9,  // 2: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMessageOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Schema
-	10, // 3: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIServiceOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.Tag
-	11, // 4: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFieldOption.option:type_name -> grpc.gateway.protoc_gen_openapiv2.options.JSONSchema
-	0,  // 5: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.file:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFileOption
-	1,  // 6: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.method:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMethodOption
-	2,  // 7: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.message:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIMessageOption
-	3,  // 8: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.service:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIServiceOption
-	4,  // 9: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions.field:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIFieldOption
-	5,  // 10: grpc.gateway.internal.descriptor.openapiconfig.OpenAPIConfig.openapi_options:type_name -> grpc.gateway.internal.descriptor.openapiconfig.OpenAPIOptions
-	11, // [11:11] is the sub-list for method output_type
-	11, // [11:11] is the sub-list for method input_type
-	11, // [11:11] is the sub-list for extension type_name
-	11, // [11:11] is the sub-list for extension extendee
-	0,  // [0:11] is the sub-list for field type_name
-}
-
-func init() { file_internal_descriptor_openapiconfig_openapiconfig_proto_init() }
-func file_internal_descriptor_openapiconfig_openapiconfig_proto_init() {
-	if File_internal_descriptor_openapiconfig_openapiconfig_proto != nil {
-		return
-	}
-	if !protoimpl.UnsafeEnabled {
-		file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*OpenAPIFileOption); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*OpenAPIMethodOption); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*OpenAPIMessageOption); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*OpenAPIServiceOption); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*OpenAPIFieldOption); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*OpenAPIOptions); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*OpenAPIConfig); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-	}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDesc,
-			NumEnums:      0,
-			NumMessages:   7,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_internal_descriptor_openapiconfig_openapiconfig_proto_goTypes,
-		DependencyIndexes: file_internal_descriptor_openapiconfig_openapiconfig_proto_depIdxs,
-		MessageInfos:      file_internal_descriptor_openapiconfig_openapiconfig_proto_msgTypes,
-	}.Build()
-	File_internal_descriptor_openapiconfig_openapiconfig_proto = out.File
-	file_internal_descriptor_openapiconfig_openapiconfig_proto_rawDesc = nil
-	file_internal_descriptor_openapiconfig_openapiconfig_proto_goTypes = nil
-	file_internal_descriptor_openapiconfig_openapiconfig_proto_depIdxs = nil
-}

+ 0 - 51
protoc-gen-openapiv2/internal/descriptor/openapiconfig/openapiconfig.proto

@@ -1,51 +0,0 @@
-syntax = "proto3";
-
-package grpc.gateway.internal.descriptor.openapiconfig;
-
-option go_package = "github.com/go-kratos/grpc-gateway/v2/internal/descriptor/openapiconfig";
-
-import "protoc-gen-openapiv2/options/openapiv2.proto";
-
-// OpenAPIFileOption represents OpenAPI options on a file
-message OpenAPIFileOption {
-    string file = 1;
-    grpc.gateway.protoc_gen_openapiv2.options.Swagger option = 2;
-}
-
-// OpenAPIMethodOption represents OpenAPI options on a method
-message OpenAPIMethodOption {
-    string method = 1;
-    grpc.gateway.protoc_gen_openapiv2.options.Operation option = 2;
-}
-
-// OpenAPIMessageOption represents OpenAPI options on a message
-message OpenAPIMessageOption {
-    string message = 1;
-    grpc.gateway.protoc_gen_openapiv2.options.Schema option = 2;
-}
-
-// OpenAPIServiceOption represents OpenAPI options on a service
-message OpenAPIServiceOption {
-    string service = 1; // ex: Service
-    grpc.gateway.protoc_gen_openapiv2.options.Tag option = 2;
-}
-
-// OpenAPIFieldOption represents OpenAPI options on a field
-message OpenAPIFieldOption {
-    string field = 1;
-    grpc.gateway.protoc_gen_openapiv2.options.JSONSchema option = 2;
-}
-
-// OpenAPIOptions represents OpenAPI protobuf options
-message OpenAPIOptions {
-    repeated OpenAPIFileOption file = 1;
-    repeated OpenAPIMethodOption method = 2;
-    repeated OpenAPIMessageOption message = 3;
-    repeated OpenAPIServiceOption service = 4;
-    repeated OpenAPIFieldOption field = 5;
-}
-
-// OpenAPIConfig represents a set of OpenAPI options
-message OpenAPIConfig {
-    OpenAPIOptions openapi_options = 1;
-}

+ 0 - 46
protoc-gen-openapiv2/internal/descriptor/openapiconfig/openapiconfig.swagger.json

@@ -1,46 +0,0 @@
-{
-  "swagger": "2.0",
-  "info": {
-    "title": "internal/descriptor/openapiconfig/openapiconfig.proto",
-    "version": "version not set"
-  },
-  "consumes": [
-    "application/json"
-  ],
-  "produces": [
-    "application/json"
-  ],
-  "paths": {},
-  "definitions": {
-    "protobufAny": {
-      "type": "object",
-      "properties": {
-        "typeUrl": {
-          "type": "string"
-        },
-        "value": {
-          "type": "string",
-          "format": "byte"
-        }
-      }
-    },
-    "rpcStatus": {
-      "type": "object",
-      "properties": {
-        "code": {
-          "type": "integer",
-          "format": "int32"
-        },
-        "message": {
-          "type": "string"
-        },
-        "details": {
-          "type": "array",
-          "items": {
-            "$ref": "#/definitions/protobufAny"
-          }
-        }
-      }
-    }
-  }
-}

+ 0 - 702
protoc-gen-openapiv2/internal/descriptor/registry.go

@@ -1,702 +0,0 @@
-package descriptor
-
-import (
-	"fmt"
-	"strings"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/codegenerator"
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor/openapiconfig"
-	"github.com/golang/glog"
-	"github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
-	"google.golang.org/genproto/googleapis/api/annotations"
-	"google.golang.org/protobuf/compiler/protogen"
-	"google.golang.org/protobuf/types/descriptorpb"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-// Registry is a registry of information extracted from pluginpb.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
-
-	// 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 OpenAPI file out of multiple protos
-	allowMerge bool
-
-	// mergeFileName target OpenAPI 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 OpenAPI definitions,
-	// otherwise the original proto name is used. It's helpful for synchronizing the OpenAPI definition
-	// with gRPC-Gateway response, if it uses json tags for marshaling.
-	useJSONNamesForFields bool
-
-	// useFQNForOpenAPIName if true OpenAPI names will use the full qualified name (FQN) from proto definition,
-	// and generate a dot-separated OpenAPI 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
-	useFQNForOpenAPIName bool
-
-	// useGoTemplate determines whether you want to use GO templates
-	// in your protofile comments
-	useGoTemplate bool
-
-	// enumsAsInts render enum as integer, as opposed to string
-	enumsAsInts bool
-
-	// disableDefaultErrors disables the generation of the default error types.
-	// This is useful for users who have defined custom error handling.
-	disableDefaultErrors bool
-
-	// simpleOperationIDs removes the service prefix from the generated
-	// operationIDs. This risks generating duplicate operationIDs.
-	simpleOperationIDs bool
-
-	standalone bool
-	// warnOnUnboundMethods causes the registry to emit warning logs if an RPC method
-	// has no HttpRule annotation.
-	warnOnUnboundMethods bool
-
-	// proto3OptionalNullable specifies whether Proto3 Optional fields should be marked as x-nullable.
-	proto3OptionalNullable bool
-
-	// fileOptions is a mapping of file name to additional OpenAPI file options
-	fileOptions map[string]*options.Swagger
-
-	// methodOptions is a mapping of fully-qualified method name to additional OpenAPI method options
-	methodOptions map[string]*options.Operation
-
-	// messageOptions is a mapping of fully-qualified message name to additional OpenAPI message options
-	messageOptions map[string]*options.Schema
-
-	//serviceOptions is a mapping of fully-qualified service name to additional OpenAPI service options
-	serviceOptions map[string]*options.Tag
-
-	// fieldOptions is a mapping of the fully-qualified name of the parent message concat
-	// field name and a period to additional OpenAPI field options
-	fieldOptions map[string]*options.JSONSchema
-
-	// generateUnboundMethods causes the registry to generate proxy methods even for
-	// RPC methods that have no HttpRule annotation.
-	generateUnboundMethods bool
-
-	generateRPCMethods bool
-
-	// omitPackageDoc, if false, causes a package comment to be included in the generated code.
-	omitPackageDoc bool
-
-	// recursiveDepth sets the maximum depth of a field parameter
-	recursiveDepth int
-}
-
-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:  ',',
-		},
-		fileOptions:    make(map[string]*options.Swagger),
-		methodOptions:  make(map[string]*options.Operation),
-		messageOptions: make(map[string]*options.Schema),
-		serviceOptions: make(map[string]*options.Tag),
-		fieldOptions:   make(map[string]*options.JSONSchema),
-		recursiveDepth: 1000,
-	}
-}
-
-// Load loads definitions of services, methods, messages, enumerations and fields from "req".
-func (r *Registry) Load(req *pluginpb.CodeGeneratorRequest) error {
-	var profofiles []*descriptorpb.FileDescriptorProto
-	registry := map[string]struct{}{}
-	for _, f := range req.ProtoFile {
-		if _, ok := registry[f.GetName()]; !ok {
-			registry[f.GetName()] = struct{}{}
-			profofiles = append(profofiles, f)
-		}
-	}
-	req.ProtoFile = profofiles
-	gen, err := protogen.Options{}.New(req)
-	if err != nil {
-		fmt.Println("New err:", err)
-		return err
-	}
-	// Note: keep in mind that this might be not enough because
-	// protogen.Plugin is used only to load files here.
-	// The support for features must be set on the pluginpb.CodeGeneratorResponse.
-	codegenerator.SetSupportedFeaturesOnPluginGen(gen)
-	return r.load(gen)
-}
-
-func (r *Registry) LoadFromPlugin(gen *protogen.Plugin) error {
-	return r.load(gen)
-}
-
-func (r *Registry) load(gen *protogen.Plugin) error {
-	for filePath, f := range gen.FilesByPath {
-		r.loadFile(filePath, f)
-	}
-
-	for filePath, f := range gen.FilesByPath {
-		if !f.Generate {
-			continue
-		}
-		file := r.files[filePath]
-		if err := r.loadServices(file); 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(filePath string, file *protogen.File) {
-	pkg := GoPackage{
-		Path: string(file.GoImportPath),
-		Name: string(file.GoPackageName),
-	}
-	if r.standalone {
-		pkg.Alias = "ext" + strings.Title(pkg.Name)
-	}
-
-	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.Proto,
-		GoPkg:                   pkg,
-		GeneratedFilenamePrefix: file.GeneratedFilenamePrefix,
-	}
-
-	r.files[filePath] = f
-	r.registerMsg(f, nil, file.Proto.MessageType)
-	r.registerEnum(f, nil, file.Proto.EnumType)
-}
-
-func (r *Registry) registerMsg(file *File, outerPath []string, msgs []*descriptorpb.DescriptorProto) {
-	for i, md := range msgs {
-		m := &Message{
-			File:              file,
-			Outers:            outerPath,
-			DescriptorProto:   md,
-			Index:             i,
-			ForcePrefixedName: r.standalone,
-		}
-		for _, fd := range md.GetField() {
-			m.Fields = append(m.Fields, &Field{
-				Message:              m,
-				FieldDescriptorProto: fd,
-				ForcePrefixedName:    r.standalone,
-			})
-		}
-		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 []*descriptorpb.EnumDescriptorProto) {
-	for i, ed := range enums {
-		e := &Enum{
-			File:                file,
-			Outers:              outerPath,
-			EnumDescriptorProto: ed,
-			Index:               i,
-			ForcePrefixedName:   r.standalone,
-		}
-		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)
-}
-
-// UnboundExternalHTTPRules returns the list of External HTTPRules
-// which does not have a matching method in the registry
-func (r *Registry) UnboundExternalHTTPRules() []string {
-	allServiceMethods := make(map[string]struct{})
-	for _, f := range r.files {
-		for _, s := range f.GetService() {
-			svc := &Service{File: f, ServiceDescriptorProto: s}
-			for _, m := range s.GetMethod() {
-				method := &Method{Service: svc, MethodDescriptorProto: m}
-				allServiceMethods[method.FQMN()] = struct{}{}
-			}
-		}
-	}
-
-	var missingMethods []string
-	for httpRuleMethod := range r.externalHTTPRules {
-		if _, ok := allServiceMethods[httpRuleMethod]; !ok {
-			missingMethods = append(missingMethods, httpRuleMethod)
-		}
-	}
-	return missingMethods
-}
-
-// 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
-}
-
-// SetStandalone registers standalone flag to control package prefix
-func (r *Registry) SetStandalone(standalone bool) {
-	r.standalone = standalone
-}
-
-// SetRecursiveDepth records the max recursion count
-func (r *Registry) SetRecursiveDepth(count int) {
-	r.recursiveDepth = count
-}
-
-// GetRecursiveDepth returns the max recursion count
-func (r *Registry) GetRecursiveDepth() int {
-	return r.recursiveDepth
-}
-
-// 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
-}
-
-// 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 OpenAPI file out of multiple protos
-func (r *Registry) SetAllowMerge(allow bool) {
-	r.allowMerge = allow
-}
-
-// IsAllowMerge whether generation one OpenAPI file out of multiple protos
-func (r *Registry) IsAllowMerge() bool {
-	return r.allowMerge
-}
-
-// SetMergeFileName controls the target OpenAPI 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
-}
-
-// SetUseFQNForOpenAPIName sets useFQNForOpenAPIName
-func (r *Registry) SetUseFQNForOpenAPIName(use bool) {
-	r.useFQNForOpenAPIName = use
-}
-
-// GetUseFQNForOpenAPIName returns useFQNForOpenAPIName
-func (r *Registry) GetUseFQNForOpenAPIName() bool {
-	return r.useFQNForOpenAPIName
-}
-
-// GetMergeFileName return the target merge OpenAPI file name
-func (r *Registry) GetMergeFileName() string {
-	return r.mergeFileName
-}
-
-// SetUseGoTemplate sets useGoTemplate
-func (r *Registry) SetUseGoTemplate(use bool) {
-	r.useGoTemplate = use
-}
-
-// GetUseGoTemplate returns useGoTemplate
-func (r *Registry) GetUseGoTemplate() bool {
-	return r.useGoTemplate
-}
-
-// SetEnumsAsInts set enumsAsInts
-func (r *Registry) SetEnumsAsInts(enumsAsInts bool) {
-	r.enumsAsInts = enumsAsInts
-}
-
-// GetEnumsAsInts returns enumsAsInts
-func (r *Registry) GetEnumsAsInts() bool {
-	return r.enumsAsInts
-}
-
-// SetDisableDefaultErrors sets disableDefaultErrors
-func (r *Registry) SetDisableDefaultErrors(use bool) {
-	r.disableDefaultErrors = use
-}
-
-// GetDisableDefaultErrors returns disableDefaultErrors
-func (r *Registry) GetDisableDefaultErrors() bool {
-	return r.disableDefaultErrors
-}
-
-// SetSimpleOperationIDs sets simpleOperationIDs
-func (r *Registry) SetSimpleOperationIDs(use bool) {
-	r.simpleOperationIDs = use
-}
-
-// GetSimpleOperationIDs returns simpleOperationIDs
-func (r *Registry) GetSimpleOperationIDs() bool {
-	return r.simpleOperationIDs
-}
-
-// SetWarnOnUnboundMethods sets warnOnUnboundMethods
-func (r *Registry) SetWarnOnUnboundMethods(warn bool) {
-	r.warnOnUnboundMethods = warn
-}
-
-// SetGenerateUnboundMethods sets generateUnboundMethods
-func (r *Registry) SetGenerateUnboundMethods(generate bool) {
-	r.generateUnboundMethods = generate
-}
-
-// SetGenerateRPCMethods sets generateRPCMethods
-func (r *Registry) SetGenerateRPCMethods(rpc bool) {
-	r.generateRPCMethods = rpc
-}
-
-// SetOmitPackageDoc controls whether the generated code contains a package comment (if set to false, it will contain one)
-func (r *Registry) SetOmitPackageDoc(omit bool) {
-	r.omitPackageDoc = omit
-}
-
-// GetOmitPackageDoc returns whether a package comment will be omitted from the generated code
-func (r *Registry) GetOmitPackageDoc() bool {
-	return r.omitPackageDoc
-}
-
-// SetProto3OptionalNullable set proto3OtionalNullable
-func (r *Registry) SetProto3OptionalNullable(proto3OtionalNullable bool) {
-	r.proto3OptionalNullable = proto3OtionalNullable
-}
-
-// GetProto3OptionalNullable returns proto3OtionalNullable
-func (r *Registry) GetProto3OptionalNullable() bool {
-	return r.proto3OptionalNullable
-}
-
-// RegisterOpenAPIOptions registers OpenAPI options
-func (r *Registry) RegisterOpenAPIOptions(opts *openapiconfig.OpenAPIOptions) error {
-	if opts == nil {
-		return nil
-	}
-
-	for _, opt := range opts.File {
-		if _, ok := r.files[opt.File]; !ok {
-			return fmt.Errorf("no file %s found", opt.File)
-		}
-		r.fileOptions[opt.File] = opt.Option
-	}
-
-	// build map of all registered methods
-	methods := make(map[string]struct{})
-	services := make(map[string]struct{})
-	for _, f := range r.files {
-		for _, s := range f.Services {
-			services[s.FQSN()] = struct{}{}
-			for _, m := range s.Methods {
-				methods[m.FQMN()] = struct{}{}
-			}
-		}
-	}
-
-	for _, opt := range opts.Method {
-		qualifiedMethod := "." + opt.Method
-		if _, ok := methods[qualifiedMethod]; !ok {
-			return fmt.Errorf("no method %s found", opt.Method)
-		}
-		r.methodOptions[qualifiedMethod] = opt.Option
-	}
-
-	for _, opt := range opts.Message {
-		qualifiedMessage := "." + opt.Message
-		if _, ok := r.msgs[qualifiedMessage]; !ok {
-			return fmt.Errorf("no message %s found", opt.Message)
-		}
-		r.messageOptions[qualifiedMessage] = opt.Option
-	}
-
-	for _, opt := range opts.Service {
-		qualifiedService := "." + opt.Service
-		if _, ok := services[qualifiedService]; !ok {
-			return fmt.Errorf("no service %s found", opt.Service)
-		}
-		r.serviceOptions[qualifiedService] = opt.Option
-	}
-
-	// build map of all registered fields
-	fields := make(map[string]struct{})
-	for _, m := range r.msgs {
-		for _, f := range m.Fields {
-			fields[f.FQFN()] = struct{}{}
-		}
-	}
-	for _, opt := range opts.Field {
-		qualifiedField := "." + opt.Field
-		if _, ok := fields[qualifiedField]; !ok {
-			return fmt.Errorf("no field %s found", opt.Field)
-		}
-		r.fieldOptions[qualifiedField] = opt.Option
-	}
-	return nil
-}
-
-// GetOpenAPIFileOption returns a registered OpenAPI option for a file
-func (r *Registry) GetOpenAPIFileOption(file string) (*options.Swagger, bool) {
-	opt, ok := r.fileOptions[file]
-	return opt, ok
-}
-
-// GetOpenAPIMethodOption returns a registered OpenAPI option for a method
-func (r *Registry) GetOpenAPIMethodOption(qualifiedMethod string) (*options.Operation, bool) {
-	opt, ok := r.methodOptions[qualifiedMethod]
-	return opt, ok
-}
-
-// GetOpenAPIMessageOption returns a registered OpenAPI option for a message
-func (r *Registry) GetOpenAPIMessageOption(qualifiedMessage string) (*options.Schema, bool) {
-	opt, ok := r.messageOptions[qualifiedMessage]
-	return opt, ok
-}
-
-// GetOpenAPIServiceOption returns a registered OpenAPI option for a service
-func (r *Registry) GetOpenAPIServiceOption(qualifiedService string) (*options.Tag, bool) {
-	opt, ok := r.serviceOptions[qualifiedService]
-	return opt, ok
-}
-
-// GetOpenAPIFieldOption returns a registered OpenAPI option for a field
-func (r *Registry) GetOpenAPIFieldOption(qualifiedField string) (*options.JSONSchema, bool) {
-	opt, ok := r.fieldOptions[qualifiedField]
-	return opt, ok
-}
-
-func (r *Registry) FieldName(f *Field) string {
-	if r.useJSONNamesForFields {
-		return f.GetJsonName()
-	}
-	return f.GetName()
-}

+ 0 - 718
protoc-gen-openapiv2/internal/descriptor/registry_test.go

@@ -1,718 +0,0 @@
-package descriptor
-
-import (
-	"testing"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor/openapiconfig"
-	"google.golang.org/protobuf/compiler/protogen"
-	"google.golang.org/protobuf/encoding/prototext"
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/types/descriptorpb"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-func newGeneratorFromSources(req *pluginpb.CodeGeneratorRequest, sources ...string) (*protogen.Plugin, error) {
-	for _, src := range sources {
-		var fd descriptorpb.FileDescriptorProto
-		if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-			return nil, err
-		}
-		req.FileToGenerate = append(req.FileToGenerate, fd.GetName())
-		req.ProtoFile = append(req.ProtoFile, &fd)
-	}
-	return protogen.Options{}.New(req)
-}
-
-func loadFileWithCodeGeneratorRequest(t *testing.T, reg *Registry, req *pluginpb.CodeGeneratorRequest, sources ...string) []*descriptorpb.FileDescriptorProto {
-	t.Helper()
-	plugin, err := newGeneratorFromSources(req, sources...)
-	if err != nil {
-		t.Fatalf("failed to create a generator: %v", err)
-	}
-	err = reg.LoadFromPlugin(plugin)
-	if err != nil {
-		t.Fatalf("failed to Registry.LoadFromPlugin(): %v", err)
-	}
-	return plugin.Request.ProtoFile
-}
-
-func loadFile(t *testing.T, reg *Registry, src string) *descriptorpb.FileDescriptorProto {
-	t.Helper()
-	fds := loadFileWithCodeGeneratorRequest(t, reg, &pluginpb.CodeGeneratorRequest{}, src)
-	return fds[0]
-}
-
-func TestLoadFile(t *testing.T) {
-	reg := NewRegistry()
-	fd := loadFile(t, reg, `
-		name: 'example.proto'
-		package: 'example'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-		message_type <
-			name: 'ExampleMessage'
-			field <
-				name: 'str'
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-				number: 1
-			>
-		>
-	`)
-
-	file := reg.files["example.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
-		return
-	}
-	wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example", Name: "example"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-
-	msg, err := reg.LookupMsg("", ".example.ExampleMessage")
-	if err != nil {
-		t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", "", ".example.ExampleMessage", err)
-		return
-	}
-	if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
-		t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", "", ".example.ExampleMessage", got, want)
-	}
-	if got, want := msg.File, file; got != want {
-		t.Errorf("msg.File = %v; want %v", got, want)
-	}
-	if got := msg.Outers; got != nil {
-		t.Errorf("msg.Outers = %v; want %v", got, nil)
-	}
-	if got, want := len(msg.Fields), 1; got != want {
-		t.Errorf("len(msg.Fields) = %d; want %d", got, want)
-	} else if got, want := msg.Fields[0].FieldDescriptorProto, fd.MessageType[0].Field[0]; got != want {
-		t.Errorf("msg.Fields[0].FieldDescriptorProto = %v; want %v", got, want)
-	} else if got, want := msg.Fields[0].Message, msg; got != want {
-		t.Errorf("msg.Fields[0].Message = %v; want %v", got, want)
-	}
-
-	if got, want := len(file.Messages), 1; got != want {
-		t.Errorf("file.Meeesages = %#v; want %#v", file.Messages, []*Message{msg})
-	}
-	if got, want := file.Messages[0], msg; got != want {
-		t.Errorf("file.Meeesages[0] = %v; want %v", got, want)
-	}
-}
-
-func TestLoadFileNestedPackage(t *testing.T) {
-	reg := NewRegistry()
-	loadFile(t, reg, `
-		name: 'example.proto'
-		package: 'example.nested.nested2'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.nested.nested2' >
-	`)
-
-	file := reg.files["example.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
-		return
-	}
-	wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.nested.nested2", Name: "example_nested_nested2"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-}
-
-func TestLoadFileWithDir(t *testing.T) {
-	reg := NewRegistry()
-	loadFile(t, reg, `
-		name: 'path/to/example.proto'
-		package: 'example'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-	`)
-
-	file := reg.files["path/to/example.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
-		return
-	}
-	wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example", Name: "example"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-}
-
-func TestLoadFileWithoutPackage(t *testing.T) {
-	reg := NewRegistry()
-	loadFile(t, reg, `
-		name: 'path/to/example_file.proto'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example_file' >
-	`)
-
-	file := reg.files["path/to/example_file.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
-		return
-	}
-	wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example_file", Name: "example_file"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-}
-
-func TestLoadFileWithMapping(t *testing.T) {
-	reg := NewRegistry()
-	loadFileWithCodeGeneratorRequest(t, reg, &pluginpb.CodeGeneratorRequest{
-		Parameter: proto.String("Mpath/to/example.proto=example.com/proj/example/proto"),
-	}, `
-		name: 'path/to/example.proto'
-		package: 'example'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-	`)
-
-	file := reg.files["path/to/example.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
-		return
-	}
-	wantPkg := GoPackage{Path: "example.com/proj/example/proto", Name: "example"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-}
-
-func TestLoadFileWithPackageNameCollision(t *testing.T) {
-	reg := NewRegistry()
-	loadFile(t, reg, `
-		name: 'path/to/another.proto'
-		package: 'example'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-	`)
-	loadFile(t, reg, `
-		name: 'path/to/example.proto'
-		package: 'example'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-	`)
-	if err := reg.ReserveGoPackageAlias("ioutil", "io/ioutil"); err != nil {
-		t.Fatalf("reg.ReserveGoPackageAlias(%q) failed with %v; want success", "ioutil", err)
-	}
-	loadFile(t, reg, `
-		name: 'path/to/ioutil.proto'
-		package: 'ioutil'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/ioutil' >
-	`)
-
-	file := reg.files["path/to/another.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "path/to/another.proto")
-		return
-	}
-	wantPkg := GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example", Name: "example"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-
-	file = reg.files["path/to/example.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "path/to/example.proto")
-		return
-	}
-	wantPkg = GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example", Name: "example", Alias: ""}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-
-	file = reg.files["path/to/ioutil.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "path/to/ioutil.proto")
-		return
-	}
-	wantPkg = GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway/runtime/internal/ioutil", Name: "ioutil", Alias: "ioutil_0"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-}
-
-func TestLoadFileWithIdenticalGoPkg(t *testing.T) {
-	reg := NewRegistry()
-	loadFileWithCodeGeneratorRequest(t, reg, &pluginpb.CodeGeneratorRequest{
-		Parameter: proto.String("Mpath/to/another.proto=example.com/example,Mpath/to/example.proto=example.com/example"),
-	}, `
-		name: 'path/to/another.proto'
-		package: 'example'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-	`, `
-		name: 'path/to/example.proto'
-		package: 'example'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-	`)
-
-	file := reg.files["path/to/example.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
-		return
-	}
-	wantPkg := GoPackage{Path: "example.com/example", Name: "example"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-
-	file = reg.files["path/to/another.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
-		return
-	}
-	wantPkg = GoPackage{Path: "example.com/example", Name: "example"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-}
-
-// TestLookupMsgWithoutPackage tests a case when there is no "package" directive.
-// In Go, it is required to have a generated package so we rely on
-// google.golang.org/protobuf/compiler/protogen to provide it.
-func TestLookupMsgWithoutPackage(t *testing.T) {
-	reg := NewRegistry()
-	fd := loadFile(t, reg, `
-		name: 'example.proto'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-		message_type <
-			name: 'ExampleMessage'
-			field <
-				name: 'str'
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-				number: 1
-			>
-		>
-	`)
-
-	msg, err := reg.LookupMsg("", ".ExampleMessage")
-	if err != nil {
-		t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", "", ".ExampleMessage", err)
-		return
-	}
-	if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
-		t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", "", ".ExampleMessage", got, want)
-	}
-}
-
-func TestLookupMsgWithNestedPackage(t *testing.T) {
-	reg := NewRegistry()
-	fd := loadFile(t, reg, `
-		name: 'example.proto'
-		package: 'nested.nested2.mypackage'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-		message_type <
-			name: 'ExampleMessage'
-			field <
-				name: 'str'
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-				number: 1
-			>
-		>
-	`)
-
-	for _, name := range []string{
-		"nested.nested2.mypackage.ExampleMessage",
-		"nested2.mypackage.ExampleMessage",
-		"mypackage.ExampleMessage",
-		"ExampleMessage",
-	} {
-		msg, err := reg.LookupMsg("nested.nested2.mypackage", name)
-		if err != nil {
-			t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", ".nested.nested2.mypackage", name, err)
-			return
-		}
-		if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
-			t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", ".nested.nested2.mypackage", name, got, want)
-		}
-	}
-
-	for _, loc := range []string{
-		".nested.nested2.mypackage",
-		"nested.nested2.mypackage",
-		".nested.nested2",
-		"nested.nested2",
-		".nested",
-		"nested",
-		".",
-		"",
-		"somewhere.else",
-	} {
-		name := "nested.nested2.mypackage.ExampleMessage"
-		msg, err := reg.LookupMsg(loc, name)
-		if err != nil {
-			t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", loc, name, err)
-			return
-		}
-		if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
-			t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", loc, name, got, want)
-		}
-	}
-
-	for _, loc := range []string{
-		".nested.nested2.mypackage",
-		"nested.nested2.mypackage",
-		".nested.nested2",
-		"nested.nested2",
-		".nested",
-		"nested",
-	} {
-		name := "nested2.mypackage.ExampleMessage"
-		msg, err := reg.LookupMsg(loc, name)
-		if err != nil {
-			t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", loc, name, err)
-			return
-		}
-		if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
-			t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", loc, name, got, want)
-		}
-	}
-}
-
-func TestLoadWithInconsistentTargetPackage(t *testing.T) {
-	for _, spec := range []struct {
-		req        string
-		consistent bool
-	}{
-		// root package, explicit go package
-		{
-			req: `
-				file_to_generate: 'a.proto'
-				file_to_generate: 'b.proto'
-				proto_file <
-					name: 'a.proto'
-					options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.foo' >
-					message_type < name: 'A' >
-					service <
-						name: "AService"
-						method <
-							name: "Meth"
-							input_type: "A"
-							output_type: "A"
-							options <
-								[google.api.http] < post: "/v1/a" body: "*" >
-							>
-						>
-					>
-				>
-				proto_file <
-					name: 'b.proto'
-					options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.foo' >
-					message_type < name: 'B' >
-					service <
-						name: "BService"
-						method <
-							name: "Meth"
-							input_type: "B"
-							output_type: "B"
-							options <
-								[google.api.http] < post: "/v1/b" body: "*" >
-							>
-						>
-					>
-				>
-			`,
-			consistent: true,
-		},
-		// named package, explicit go package
-		{
-			req: `
-				file_to_generate: 'a.proto'
-				file_to_generate: 'b.proto'
-				proto_file <
-					name: 'a.proto'
-					package: 'example.foo'
-					options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.foo' >
-					message_type < name: 'A' >
-					service <
-						name: "AService"
-						method <
-							name: "Meth"
-							input_type: "A"
-							output_type: "A"
-							options <
-								[google.api.http] < post: "/v1/a" body: "*" >
-							>
-						>
-					>
-				>
-				proto_file <
-					name: 'b.proto'
-					package: 'example.foo'
-					options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example.foo' >
-					message_type < name: 'B' >
-					service <
-						name: "BService"
-						method <
-							name: "Meth"
-							input_type: "B"
-							output_type: "B"
-							options <
-								[google.api.http] < post: "/v1/b" body: "*" >
-							>
-						>
-					>
-				>
-			`,
-			consistent: true,
-		},
-	} {
-		var req pluginpb.CodeGeneratorRequest
-		if err := prototext.Unmarshal([]byte(spec.req), &req); err != nil {
-			t.Fatalf("proto.UnmarshalText(%s, &file) failed with %v; want success", spec.req, err)
-		}
-		_, err := newGeneratorFromSources(&req)
-		if got, want := err == nil, spec.consistent; got != want {
-			if want {
-				t.Errorf("reg.Load(%s) failed with %v; want success", spec.req, err)
-				continue
-			}
-			t.Errorf("reg.Load(%s) succeeded; want an package inconsistency error", spec.req)
-		}
-	}
-}
-
-func TestLoadOverriddenPackageName(t *testing.T) {
-	reg := NewRegistry()
-	loadFile(t, reg, `
-		name: 'example.proto'
-		package: 'example'
-		options < go_package: 'example.com/xyz;pb' >
-	`)
-	file := reg.files["example.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
-		return
-	}
-	wantPkg := GoPackage{Path: "example.com/xyz", Name: "pb"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-}
-
-func TestLoadWithStandalone(t *testing.T) {
-	reg := NewRegistry()
-	reg.SetStandalone(true)
-	loadFile(t, reg, `
-		name: 'example.proto'
-		package: 'example'
-		options < go_package: 'example.com/xyz;pb' >
-	`)
-	file := reg.files["example.proto"]
-	if file == nil {
-		t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
-		return
-	}
-	wantPkg := GoPackage{Path: "example.com/xyz", Name: "pb", Alias: "extPb"}
-	if got, want := file.GoPkg, wantPkg; got != want {
-		t.Errorf("file.GoPkg = %#v; want %#v", got, want)
-	}
-}
-
-func TestUnboundExternalHTTPRules(t *testing.T) {
-	reg := NewRegistry()
-	methodName := ".example.ExampleService.Echo"
-	reg.AddExternalHTTPRule(methodName, nil)
-	assertStringSlice(t, "unbound external HTTP rules", reg.UnboundExternalHTTPRules(), []string{methodName})
-	loadFile(t, reg, `
-		name: "path/to/example.proto",
-		package: "example"
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-		message_type <
-			name: "StringMessage"
-			field <
-				name: "string"
-				number: 1
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-			>
-		>
-		service <
-			name: "ExampleService"
-			method <
-				name: "Echo"
-				input_type: "StringMessage"
-				output_type: "StringMessage"
-			>
-		>
-	`)
-	assertStringSlice(t, "unbound external HTTP rules", reg.UnboundExternalHTTPRules(), []string{})
-}
-
-func TestRegisterOpenAPIOptions(t *testing.T) {
-	codeReqText := `file_to_generate: 'a.proto'
-	proto_file <
-		name: 'a.proto'
-		package: 'example.foo'
-		options < go_package: 'github.com/grpc-ecosystem/grpc-gateway/runtime/internal/example' >
-		message_type <
-			name: 'ExampleMessage'
-			field <
-				name: 'str'
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-				number: 1
-			>
-		>
-		service <
-			name: "AService"
-			method <
-				name: "Meth"
-				input_type: "ExampleMessage"
-				output_type: "ExampleMessage"
-				options <
-					[google.api.http] < post: "/v1/a" body: "*" >
-				>
-			>
-		>
-	>
-	`
-	var codeReq pluginpb.CodeGeneratorRequest
-	if err := prototext.Unmarshal([]byte(codeReqText), &codeReq); err != nil {
-		t.Fatalf("proto.UnmarshalText(%s, &file) failed with %v; want success", codeReqText, err)
-	}
-
-	for _, tcase := range []struct {
-		options   *openapiconfig.OpenAPIOptions
-		shouldErr bool
-		desc      string
-	}{
-		{
-			desc: "handle nil options",
-		},
-		{
-			desc: "successfully add options if referenced entity exists",
-			options: &openapiconfig.OpenAPIOptions{
-				File: []*openapiconfig.OpenAPIFileOption{
-					{
-						File: "a.proto",
-					},
-				},
-				Method: []*openapiconfig.OpenAPIMethodOption{
-					{
-						Method: "example.foo.AService.Meth",
-					},
-				},
-				Message: []*openapiconfig.OpenAPIMessageOption{
-					{
-						Message: "example.foo.ExampleMessage",
-					},
-				},
-				Service: []*openapiconfig.OpenAPIServiceOption{
-					{
-						Service: "example.foo.AService",
-					},
-				},
-				Field: []*openapiconfig.OpenAPIFieldOption{
-					{
-						Field: "example.foo.ExampleMessage.str",
-					},
-				},
-			},
-		},
-		{
-			desc: "reject fully qualified names with leading \".\"",
-			options: &openapiconfig.OpenAPIOptions{
-				File: []*openapiconfig.OpenAPIFileOption{
-					{
-						File: "a.proto",
-					},
-				},
-				Method: []*openapiconfig.OpenAPIMethodOption{
-					{
-						Method: ".example.foo.AService.Meth",
-					},
-				},
-				Message: []*openapiconfig.OpenAPIMessageOption{
-					{
-						Message: ".example.foo.ExampleMessage",
-					},
-				},
-				Service: []*openapiconfig.OpenAPIServiceOption{
-					{
-						Service: ".example.foo.AService",
-					},
-				},
-				Field: []*openapiconfig.OpenAPIFieldOption{
-					{
-						Field: ".example.foo.ExampleMessage.str",
-					},
-				},
-			},
-			shouldErr: true,
-		},
-		{
-			desc: "error if file does not exist",
-			options: &openapiconfig.OpenAPIOptions{
-				File: []*openapiconfig.OpenAPIFileOption{
-					{
-						File: "b.proto",
-					},
-				},
-			},
-			shouldErr: true,
-		},
-		{
-			desc: "error if method does not exist",
-			options: &openapiconfig.OpenAPIOptions{
-				Method: []*openapiconfig.OpenAPIMethodOption{
-					{
-						Method: "example.foo.AService.Meth2",
-					},
-				},
-			},
-			shouldErr: true,
-		},
-		{
-			desc: "error if message does not exist",
-			options: &openapiconfig.OpenAPIOptions{
-				Message: []*openapiconfig.OpenAPIMessageOption{
-					{
-						Message: "example.foo.NonexistentMessage",
-					},
-				},
-			},
-			shouldErr: true,
-		},
-		{
-			desc: "error if service does not exist",
-			options: &openapiconfig.OpenAPIOptions{
-				Service: []*openapiconfig.OpenAPIServiceOption{
-					{
-						Service: "example.foo.AService1",
-					},
-				},
-			},
-			shouldErr: true,
-		},
-		{
-			desc: "error if field does not exist",
-			options: &openapiconfig.OpenAPIOptions{
-				Field: []*openapiconfig.OpenAPIFieldOption{
-					{
-						Field: "example.foo.ExampleMessage.str1",
-					},
-				},
-			},
-			shouldErr: true,
-		},
-	} {
-		t.Run(tcase.desc, func(t *testing.T) {
-			reg := NewRegistry()
-			loadFileWithCodeGeneratorRequest(t, reg, &codeReq)
-			err := reg.RegisterOpenAPIOptions(tcase.options)
-			if (err != nil) != tcase.shouldErr {
-				t.Fatalf("got unexpected error: %s", err)
-			}
-		})
-	}
-}
-
-func assertStringSlice(t *testing.T, message string, got, want []string) {
-	if len(got) != len(want) {
-		t.Errorf("%s = %#v len(%d); want %#v len(%d)", message, got, len(got), want, len(want))
-	}
-	for i := range want {
-		if got[i] != want[i] {
-			t.Errorf("%s[%d] = %#v; want %#v", message, i, got[i], want[i])
-		}
-	}
-}

+ 0 - 347
protoc-gen-openapiv2/internal/descriptor/services.go

@@ -1,347 +0,0 @@
-package descriptor
-
-import (
-	"fmt"
-	"strings"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/httprule"
-	"github.com/golang/glog"
-	options "google.golang.org/genproto/googleapis/api/annotations"
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/types/descriptorpb"
-)
-
-// 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,
-			ForcePrefixedName:      r.standalone,
-		}
-		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
-			}
-			var optsList []*options.HttpRule
-			if r.generateRPCMethods {
-				defaultOpts, err := defaultAPIOptions(svc, md)
-				if err != nil {
-					glog.Errorf("Failed to generate default HttpRule from %s.%s: %v", svc.GetName(), md.GetName(), err)
-					return err
-				}
-				optsList = append(optsList, defaultOpts)
-			} else {
-				optsList = r.LookupExternalHTTPRules((&Method{Service: svc, MethodDescriptorProto: md}).FQMN())
-				if opts != nil {
-					optsList = append(optsList, opts)
-				}
-			}
-			if len(optsList) == 0 {
-				if r.generateUnboundMethods {
-					defaultOpts, err := defaultAPIOptions(svc, md)
-					if err != nil {
-						glog.Errorf("Failed to generate default HttpRule from %s.%s: %v", svc.GetName(), md.GetName(), err)
-						return err
-					}
-					optsList = append(optsList, defaultOpts)
-				} else {
-					logFn := glog.V(1).Infof
-					if r.warnOnUnboundMethods {
-						logFn = glog.Warningf
-					}
-					logFn("No HttpRule found for 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 *descriptorpb.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 *descriptorpb.MethodDescriptorProto) (*options.HttpRule, error) {
-	if meth.Options == nil {
-		return nil, nil
-	}
-	if !proto.HasExtension(meth.Options, options.E_Http) {
-		return nil, nil
-	}
-	ext := proto.GetExtension(meth.Options, options.E_Http)
-	opts, ok := ext.(*options.HttpRule)
-	if !ok {
-		return nil, fmt.Errorf("extension is %T; want an HttpRule", ext)
-	}
-	return opts, nil
-}
-
-func defaultAPIOptions(svc *Service, md *descriptorpb.MethodDescriptorProto) (*options.HttpRule, error) {
-	// FQSN prefixes the service's full name with a '.', e.g.: '.example.ExampleService'
-	fqsn := strings.TrimPrefix(svc.FQSN(), ".")
-
-	// This generates an HttpRule that matches the gRPC mapping to HTTP/2 described in
-	// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
-	// i.e.:
-	//   * method is POST
-	//   * path is "/<service name>/<method name>"
-	//   * body should contain the serialized request message
-	rule := &options.HttpRule{
-		Pattern: &options.HttpRule_Post{
-			Post: fmt.Sprintf("/%s/%s", fqsn, md.GetName()),
-		},
-		Body: "*",
-	}
-	return rule, 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 descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, descriptorpb.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("%s.%s: %s is a protobuf message type. Protobuf message types cannot be used as path parameters, use a scalar value type (such as string) instead", 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 descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, descriptorpb.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() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED {
-			return nil, fmt.Errorf("repeated field not allowed in field path: %s in %s", f.GetName(), path)
-		}
-		if isPathParam && f.GetProto3Optional() {
-			return nil, fmt.Errorf("optional field not allowed in field path: %s in %s", f.GetName(), path)
-		}
-		result = append(result, FieldPathComponent{Name: c, Target: f})
-	}
-	return result, nil
-}

+ 0 - 1447
protoc-gen-openapiv2/internal/descriptor/services_test.go

@@ -1,1447 +0,0 @@
-package descriptor
-
-import (
-	"reflect"
-	"strings"
-	"testing"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/httprule"
-	"google.golang.org/protobuf/compiler/protogen"
-	"google.golang.org/protobuf/encoding/prototext"
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/types/descriptorpb"
-)
-
-func compilePath(t *testing.T, path string) httprule.Template {
-	parsed, err := httprule.Parse(path)
-	if err != nil {
-		t.Fatalf("httprule.Parse(%q) failed with %v; want success", path, err)
-	}
-	return parsed.Compile()
-}
-
-func testExtractServices(t *testing.T, input []*descriptorpb.FileDescriptorProto, target string, wantSvcs []*Service) {
-	testExtractServicesWithRegistry(t, NewRegistry(), input, target, wantSvcs)
-}
-
-func testExtractServicesWithRegistry(t *testing.T, reg *Registry, input []*descriptorpb.FileDescriptorProto, target string, wantSvcs []*Service) {
-	for _, file := range input {
-		reg.loadFile(file.GetName(), &protogen.File{
-			Proto: file,
-		})
-	}
-	err := reg.loadServices(reg.files[target])
-	if err != nil {
-		t.Errorf("loadServices(%q) failed with %v; want success; files=%v", target, err, input)
-	}
-
-	file := reg.files[target]
-	svcs := file.Services
-	var i int
-	for i = 0; i < len(svcs) && i < len(wantSvcs); i++ {
-		svc, wantSvc := svcs[i], wantSvcs[i]
-		if got, want := svc.ServiceDescriptorProto, wantSvc.ServiceDescriptorProto; !proto.Equal(got, want) {
-			t.Errorf("svcs[%d].ServiceDescriptorProto = %v; want %v; input = %v", i, got, want, input)
-			continue
-		}
-		var j int
-		for j = 0; j < len(svc.Methods) && j < len(wantSvc.Methods); j++ {
-			meth, wantMeth := svc.Methods[j], wantSvc.Methods[j]
-			if got, want := meth.MethodDescriptorProto, wantMeth.MethodDescriptorProto; !proto.Equal(got, want) {
-				t.Errorf("svcs[%d].Methods[%d].MethodDescriptorProto = %v; want %v; input = %v", i, j, got, want, input)
-				continue
-			}
-			if got, want := meth.RequestType, wantMeth.RequestType; got.FQMN() != want.FQMN() {
-				t.Errorf("svcs[%d].Methods[%d].RequestType = %s; want %s; input = %v", i, j, got.FQMN(), want.FQMN(), input)
-			}
-			if got, want := meth.ResponseType, wantMeth.ResponseType; got.FQMN() != want.FQMN() {
-				t.Errorf("svcs[%d].Methods[%d].ResponseType = %s; want %s; input = %v", i, j, got.FQMN(), want.FQMN(), input)
-			}
-			var k int
-			for k = 0; k < len(meth.Bindings) && k < len(wantMeth.Bindings); k++ {
-				binding, wantBinding := meth.Bindings[k], wantMeth.Bindings[k]
-				if got, want := binding.Index, wantBinding.Index; got != want {
-					t.Errorf("svcs[%d].Methods[%d].Bindings[%d].Index = %d; want %d; input = %v", i, j, k, got, want, input)
-				}
-				if got, want := binding.PathTmpl, wantBinding.PathTmpl; !reflect.DeepEqual(got, want) {
-					t.Errorf("svcs[%d].Methods[%d].Bindings[%d].PathTmpl = %#v; want %#v; input = %v", i, j, k, got, want, input)
-				}
-				if got, want := binding.HTTPMethod, wantBinding.HTTPMethod; got != want {
-					t.Errorf("svcs[%d].Methods[%d].Bindings[%d].HTTPMethod = %q; want %q; input = %v", i, j, k, got, want, input)
-				}
-
-				var l int
-				for l = 0; l < len(binding.PathParams) && l < len(wantBinding.PathParams); l++ {
-					param, wantParam := binding.PathParams[l], wantBinding.PathParams[l]
-					if got, want := param.FieldPath.String(), wantParam.FieldPath.String(); got != want {
-						t.Errorf("svcs[%d].Methods[%d].Bindings[%d].PathParams[%d].FieldPath.String() = %q; want %q; input = %v", i, j, k, l, got, want, input)
-						continue
-					}
-					for m := 0; m < len(param.FieldPath) && m < len(wantParam.FieldPath); m++ {
-						field, wantField := param.FieldPath[m].Target, wantParam.FieldPath[m].Target
-						if got, want := field.FieldDescriptorProto, wantField.FieldDescriptorProto; !proto.Equal(got, want) {
-							t.Errorf("svcs[%d].Methods[%d].Bindings[%d].PathParams[%d].FieldPath[%d].Target.FieldDescriptorProto = %v; want %v; input = %v", i, j, k, l, m, got, want, input)
-						}
-					}
-				}
-				for ; l < len(binding.PathParams); l++ {
-					got := binding.PathParams[l].FieldPath.String()
-					t.Errorf("svcs[%d].Methods[%d].Bindings[%d].PathParams[%d] = %q; want it to be missing; input = %v", i, j, k, l, got, input)
-				}
-				for ; l < len(wantBinding.PathParams); l++ {
-					want := wantBinding.PathParams[l].FieldPath.String()
-					t.Errorf("svcs[%d].Methods[%d].Bindings[%d].PathParams[%d] missing; want %q; input = %v", i, j, k, l, want, input)
-				}
-
-				if got, want := (binding.Body != nil), (wantBinding.Body != nil); got != want {
-					if got {
-						t.Errorf("svcs[%d].Methods[%d].Bindings[%d].Body = %q; want it to be missing; input = %v", i, j, k, binding.Body.FieldPath.String(), input)
-					} else {
-						t.Errorf("svcs[%d].Methods[%d].Bindings[%d].Body missing; want %q; input = %v", i, j, k, wantBinding.Body.FieldPath.String(), input)
-					}
-				} else if binding.Body != nil {
-					if got, want := binding.Body.FieldPath.String(), wantBinding.Body.FieldPath.String(); got != want {
-						t.Errorf("svcs[%d].Methods[%d].Bindings[%d].Body = %q; want %q; input = %v", i, j, k, got, want, input)
-					}
-				}
-			}
-			for ; k < len(meth.Bindings); k++ {
-				got := meth.Bindings[k]
-				t.Errorf("svcs[%d].Methods[%d].Bindings[%d] = %v; want it to be missing; input = %v", i, j, k, got, input)
-			}
-			for ; k < len(wantMeth.Bindings); k++ {
-				want := wantMeth.Bindings[k]
-				t.Errorf("svcs[%d].Methods[%d].Bindings[%d] missing; want %v; input = %v", i, j, k, want, input)
-			}
-		}
-		for ; j < len(svc.Methods); j++ {
-			got := svc.Methods[j].MethodDescriptorProto
-			t.Errorf("svcs[%d].Methods[%d] = %v; want it to be missing; input = %v", i, j, got, input)
-		}
-		for ; j < len(wantSvc.Methods); j++ {
-			want := wantSvc.Methods[j].MethodDescriptorProto
-			t.Errorf("svcs[%d].Methods[%d] missing; want %v; input = %v", i, j, want, input)
-		}
-	}
-	for ; i < len(svcs); i++ {
-		got := svcs[i].ServiceDescriptorProto
-		t.Errorf("svcs[%d] = %v; want it to be missing; input = %v", i, got, input)
-	}
-	for ; i < len(wantSvcs); i++ {
-		want := wantSvcs[i].ServiceDescriptorProto
-		t.Errorf("svcs[%d] missing; want %v; input = %v", i, want, input)
-	}
-}
-
-func crossLinkFixture(f *File) *File {
-	for _, m := range f.Messages {
-		m.File = f
-		for _, f := range m.Fields {
-			f.Message = m
-		}
-	}
-	for _, svc := range f.Services {
-		svc.File = f
-		for _, m := range svc.Methods {
-			m.Service = svc
-			for _, b := range m.Bindings {
-				b.Method = m
-				for _, param := range b.PathParams {
-					param.Method = m
-				}
-			}
-		}
-	}
-	for _, e := range f.Enums {
-		e.File = f
-	}
-	return f
-}
-
-func TestExtractServicesSimple(t *testing.T) {
-	src := `
-		name: "path/to/example.proto",
-		package: "example"
-		message_type <
-			name: "StringMessage"
-			field <
-				name: "string"
-				number: 1
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-			>
-		>
-		service <
-			name: "ExampleService"
-			method <
-				name: "Echo"
-				input_type: "StringMessage"
-				output_type: "StringMessage"
-				options <
-					[google.api.http] <
-						post: "/v1/example/echo"
-						body: "*"
-					>
-				>
-			>
-		>
-	`
-	var fd descriptorpb.FileDescriptorProto
-	if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-		t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-	}
-	msg := &Message{
-		DescriptorProto: fd.MessageType[0],
-		Fields: []*Field{
-			{
-				FieldDescriptorProto: fd.MessageType[0].Field[0],
-			},
-		},
-	}
-	file := &File{
-		FileDescriptorProto: &fd,
-		GoPkg: GoPackage{
-			Path: "path/to/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*Message{msg},
-		Services: []*Service{
-			{
-				ServiceDescriptorProto: fd.Service[0],
-				Methods: []*Method{
-					{
-						MethodDescriptorProto: fd.Service[0].Method[0],
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*Binding{
-							{
-								PathTmpl:   compilePath(t, "/v1/example/echo"),
-								HTTPMethod: "POST",
-								Body:       &Body{FieldPath: nil},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-
-	crossLinkFixture(file)
-	testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
-}
-
-func TestExtractServicesWithoutAnnotation(t *testing.T) {
-	src := `
-		name: "path/to/example.proto",
-		package: "example"
-		message_type <
-			name: "StringMessage"
-			field <
-				name: "string"
-				number: 1
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-			>
-		>
-		service <
-			name: "ExampleService"
-			method <
-				name: "Echo"
-				input_type: "StringMessage"
-				output_type: "StringMessage"
-			>
-		>
-	`
-	var fd descriptorpb.FileDescriptorProto
-	if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-		t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-	}
-	msg := &Message{
-		DescriptorProto: fd.MessageType[0],
-		Fields: []*Field{
-			{
-				FieldDescriptorProto: fd.MessageType[0].Field[0],
-			},
-		},
-	}
-	file := &File{
-		FileDescriptorProto: &fd,
-		GoPkg: GoPackage{
-			Path: "path/to/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*Message{msg},
-		Services: []*Service{
-			{
-				ServiceDescriptorProto: fd.Service[0],
-				Methods: []*Method{
-					{
-						MethodDescriptorProto: fd.Service[0].Method[0],
-						RequestType:           msg,
-						ResponseType:          msg,
-					},
-				},
-			},
-		},
-	}
-
-	crossLinkFixture(file)
-	testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
-}
-
-func TestExtractServicesGenerateUnboundMethods(t *testing.T) {
-	src := `
-		name: "path/to/example.proto",
-		package: "example"
-		message_type <
-			name: "StringMessage"
-			field <
-				name: "string"
-				number: 1
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-			>
-		>
-		service <
-			name: "ExampleService"
-			method <
-				name: "Echo"
-				input_type: "StringMessage"
-				output_type: "StringMessage"
-			>
-		>
-	`
-	var fd descriptorpb.FileDescriptorProto
-	if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-		t.Fatalf("prototext.Unmarshal (%s, &fd) failed with %v; want success", src, err)
-	}
-	msg := &Message{
-		DescriptorProto: fd.MessageType[0],
-		Fields: []*Field{
-			{
-				FieldDescriptorProto: fd.MessageType[0].Field[0],
-			},
-		},
-	}
-	file := &File{
-		FileDescriptorProto: &fd,
-		GoPkg: GoPackage{
-			Path: "path/to/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*Message{msg},
-		Services: []*Service{
-			{
-				ServiceDescriptorProto: fd.Service[0],
-				Methods: []*Method{
-					{
-						MethodDescriptorProto: fd.Service[0].Method[0],
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*Binding{
-							{
-								PathTmpl:   compilePath(t, "/example.ExampleService/Echo"),
-								HTTPMethod: "POST",
-								Body:       &Body{FieldPath: nil},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-
-	crossLinkFixture(file)
-	reg := NewRegistry()
-	reg.SetGenerateUnboundMethods(true)
-	testExtractServicesWithRegistry(t, reg, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
-}
-
-func TestExtractServicesCrossPackage(t *testing.T) {
-	srcs := []string{
-		`
-			name: "path/to/example.proto",
-			package: "example"
-			message_type <
-				name: "StringMessage"
-				field <
-					name: "string"
-					number: 1
-					label: LABEL_OPTIONAL
-					type: TYPE_STRING
-				>
-			>
-			service <
-				name: "ExampleService"
-				method <
-					name: "ToString"
-					input_type: ".another.example.BoolMessage"
-					output_type: "StringMessage"
-					options <
-						[google.api.http] <
-							post: "/v1/example/to_s"
-							body: "*"
-						>
-					>
-				>
-			>
-		`, `
-			name: "path/to/another/example.proto",
-			package: "another.example"
-			message_type <
-				name: "BoolMessage"
-				field <
-					name: "bool"
-					number: 1
-					label: LABEL_OPTIONAL
-					type: TYPE_BOOL
-				>
-			>
-		`,
-	}
-	var fds []*descriptorpb.FileDescriptorProto
-	for _, src := range srcs {
-		var fd descriptorpb.FileDescriptorProto
-		if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-			t.Fatalf("prototext.Unmarshal(%s, &fd) failed with %v; want success", src, err)
-		}
-		fds = append(fds, &fd)
-	}
-	stringMsg := &Message{
-		DescriptorProto: fds[0].MessageType[0],
-		Fields: []*Field{
-			{
-				FieldDescriptorProto: fds[0].MessageType[0].Field[0],
-			},
-		},
-	}
-	boolMsg := &Message{
-		DescriptorProto: fds[1].MessageType[0],
-		Fields: []*Field{
-			{
-				FieldDescriptorProto: fds[1].MessageType[0].Field[0],
-			},
-		},
-	}
-	files := []*File{
-		{
-			FileDescriptorProto: fds[0],
-			GoPkg: GoPackage{
-				Path: "path/to/example.pb",
-				Name: "example_pb",
-			},
-			Messages: []*Message{stringMsg},
-			Services: []*Service{
-				{
-					ServiceDescriptorProto: fds[0].Service[0],
-					Methods: []*Method{
-						{
-							MethodDescriptorProto: fds[0].Service[0].Method[0],
-							RequestType:           boolMsg,
-							ResponseType:          stringMsg,
-							Bindings: []*Binding{
-								{
-									PathTmpl:   compilePath(t, "/v1/example/to_s"),
-									HTTPMethod: "POST",
-									Body:       &Body{FieldPath: nil},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-		{
-			FileDescriptorProto: fds[1],
-			GoPkg: GoPackage{
-				Path: "path/to/another/example.pb",
-				Name: "example_pb",
-			},
-			Messages: []*Message{boolMsg},
-		},
-	}
-
-	for _, file := range files {
-		crossLinkFixture(file)
-	}
-	testExtractServices(t, fds, "path/to/example.proto", files[0].Services)
-}
-
-func TestExtractServicesWithBodyPath(t *testing.T) {
-	src := `
-		name: "path/to/example.proto",
-		package: "example"
-		message_type <
-			name: "OuterMessage"
-			nested_type <
-				name: "StringMessage"
-				field <
-					name: "string"
-					number: 1
-					label: LABEL_OPTIONAL
-					type: TYPE_STRING
-				>
-			>
-			field <
-				name: "nested"
-				number: 1
-				label: LABEL_OPTIONAL
-				type: TYPE_MESSAGE
-				type_name: "StringMessage"
-			>
-		>
-		service <
-			name: "ExampleService"
-			method <
-				name: "Echo"
-				input_type: "OuterMessage"
-				output_type: "OuterMessage"
-				options <
-					[google.api.http] <
-						post: "/v1/example/echo"
-						body: "nested"
-					>
-				>
-			>
-		>
-	`
-	var fd descriptorpb.FileDescriptorProto
-	if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-		t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-	}
-	msg := &Message{
-		DescriptorProto: fd.MessageType[0],
-		Fields: []*Field{
-			{
-				FieldDescriptorProto: fd.MessageType[0].Field[0],
-			},
-		},
-	}
-	file := &File{
-		FileDescriptorProto: &fd,
-		GoPkg: GoPackage{
-			Path: "path/to/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*Message{msg},
-		Services: []*Service{
-			{
-				ServiceDescriptorProto: fd.Service[0],
-				Methods: []*Method{
-					{
-						MethodDescriptorProto: fd.Service[0].Method[0],
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*Binding{
-							{
-								PathTmpl:   compilePath(t, "/v1/example/echo"),
-								HTTPMethod: "POST",
-								Body: &Body{
-									FieldPath: FieldPath{
-										{
-											Name:   "nested",
-											Target: msg.Fields[0],
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-
-	crossLinkFixture(file)
-	testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
-}
-
-func TestExtractServicesWithPathParam(t *testing.T) {
-	src := `
-		name: "path/to/example.proto",
-		package: "example"
-		message_type <
-			name: "StringMessage"
-			field <
-				name: "string"
-				number: 1
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-			>
-		>
-		service <
-			name: "ExampleService"
-			method <
-				name: "Echo"
-				input_type: "StringMessage"
-				output_type: "StringMessage"
-				options <
-					[google.api.http] <
-						get: "/v1/example/echo/{string=*}"
-					>
-				>
-			>
-		>
-	`
-	var fd descriptorpb.FileDescriptorProto
-	if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-		t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-	}
-	msg := &Message{
-		DescriptorProto: fd.MessageType[0],
-		Fields: []*Field{
-			{
-				FieldDescriptorProto: fd.MessageType[0].Field[0],
-			},
-		},
-	}
-	file := &File{
-		FileDescriptorProto: &fd,
-		GoPkg: GoPackage{
-			Path: "path/to/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*Message{msg},
-		Services: []*Service{
-			{
-				ServiceDescriptorProto: fd.Service[0],
-				Methods: []*Method{
-					{
-						MethodDescriptorProto: fd.Service[0].Method[0],
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*Binding{
-							{
-								PathTmpl:   compilePath(t, "/v1/example/echo/{string=*}"),
-								HTTPMethod: "GET",
-								PathParams: []Parameter{
-									{
-										FieldPath: FieldPath{
-											{
-												Name:   "string",
-												Target: msg.Fields[0],
-											},
-										},
-										Target: msg.Fields[0],
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-
-	crossLinkFixture(file)
-	testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
-}
-
-func TestExtractServicesWithAdditionalBinding(t *testing.T) {
-	src := `
-		name: "path/to/example.proto",
-		package: "example"
-		message_type <
-			name: "StringMessage"
-			field <
-				name: "string"
-				number: 1
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-			>
-		>
-		service <
-			name: "ExampleService"
-			method <
-				name: "Echo"
-				input_type: "StringMessage"
-				output_type: "StringMessage"
-				options <
-					[google.api.http] <
-						post: "/v1/example/echo"
-						body: "*"
-						additional_bindings <
-							get: "/v1/example/echo/{string}"
-						>
-						additional_bindings <
-							post: "/v2/example/echo"
-							body: "string"
-						>
-					>
-				>
-			>
-		>
-	`
-	var fd descriptorpb.FileDescriptorProto
-	if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-		t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-	}
-	msg := &Message{
-		DescriptorProto: fd.MessageType[0],
-		Fields: []*Field{
-			{
-				FieldDescriptorProto: fd.MessageType[0].Field[0],
-			},
-		},
-	}
-	file := &File{
-		FileDescriptorProto: &fd,
-		GoPkg: GoPackage{
-			Path: "path/to/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*Message{msg},
-		Services: []*Service{
-			{
-				ServiceDescriptorProto: fd.Service[0],
-				Methods: []*Method{
-					{
-						MethodDescriptorProto: fd.Service[0].Method[0],
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*Binding{
-							{
-								Index:      0,
-								PathTmpl:   compilePath(t, "/v1/example/echo"),
-								HTTPMethod: "POST",
-								Body:       &Body{FieldPath: nil},
-							},
-							{
-								Index:      1,
-								PathTmpl:   compilePath(t, "/v1/example/echo/{string}"),
-								HTTPMethod: "GET",
-								PathParams: []Parameter{
-									{
-										FieldPath: FieldPath{
-											{
-												Name:   "string",
-												Target: msg.Fields[0],
-											},
-										},
-										Target: msg.Fields[0],
-									},
-								},
-								Body: nil,
-							},
-							{
-								Index:      2,
-								PathTmpl:   compilePath(t, "/v2/example/echo"),
-								HTTPMethod: "POST",
-								Body: &Body{
-									FieldPath: FieldPath{
-										FieldPathComponent{
-											Name:   "string",
-											Target: msg.Fields[0],
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-
-	crossLinkFixture(file)
-	testExtractServices(t, []*descriptorpb.FileDescriptorProto{&fd}, "path/to/example.proto", file.Services)
-}
-
-func TestExtractServicesWithError(t *testing.T) {
-	for _, spec := range []struct {
-		target string
-		srcs   []string
-	}{
-		{
-			target: "path/to/example.proto",
-			srcs: []string{
-				// message not found
-				`
-					name: "path/to/example.proto",
-					package: "example"
-					service <
-						name: "ExampleService"
-						method <
-							name: "Echo"
-							input_type: "StringMessage"
-							output_type: "StringMessage"
-							options <
-								[google.api.http] <
-									post: "/v1/example/echo"
-									body: "*"
-								>
-							>
-						>
-					>
-				`,
-			},
-		},
-		// body field path not resolved
-		{
-			target: "path/to/example.proto",
-			srcs: []string{`
-						name: "path/to/example.proto",
-						package: "example"
-						message_type <
-							name: "StringMessage"
-							field <
-								name: "string"
-								number: 1
-								label: LABEL_OPTIONAL
-								type: TYPE_STRING
-							>
-						>
-						service <
-							name: "ExampleService"
-							method <
-								name: "Echo"
-								input_type: "StringMessage"
-								output_type: "StringMessage"
-								options <
-									[google.api.http] <
-										post: "/v1/example/echo"
-										body: "bool"
-									>
-								>
-							>
-						>`,
-			},
-		},
-		// param field path not resolved
-		{
-			target: "path/to/example.proto",
-			srcs: []string{
-				`
-					name: "path/to/example.proto",
-					package: "example"
-					message_type <
-						name: "StringMessage"
-						field <
-							name: "string"
-							number: 1
-							label: LABEL_OPTIONAL
-							type: TYPE_STRING
-						>
-					>
-					service <
-						name: "ExampleService"
-						method <
-							name: "Echo"
-							input_type: "StringMessage"
-							output_type: "StringMessage"
-							options <
-								[google.api.http] <
-									post: "/v1/example/echo/{bool=*}"
-								>
-							>
-						>
-					>
-				`,
-			},
-		},
-		// non aggregate type on field path
-		{
-			target: "path/to/example.proto",
-			srcs: []string{
-				`
-					name: "path/to/example.proto",
-					package: "example"
-					message_type <
-						name: "OuterMessage"
-						field <
-							name: "mid"
-							number: 1
-							label: LABEL_OPTIONAL
-							type: TYPE_STRING
-						>
-						field <
-							name: "bool"
-							number: 2
-							label: LABEL_OPTIONAL
-							type: TYPE_BOOL
-						>
-					>
-					service <
-						name: "ExampleService"
-						method <
-							name: "Echo"
-							input_type: "OuterMessage"
-							output_type: "OuterMessage"
-							options <
-								[google.api.http] <
-									post: "/v1/example/echo/{mid.bool=*}"
-								>
-							>
-						>
-					>
-				`,
-			},
-		},
-		// path param in client streaming
-		{
-			target: "path/to/example.proto",
-			srcs: []string{
-				`
-					name: "path/to/example.proto",
-					package: "example"
-					message_type <
-						name: "StringMessage"
-						field <
-							name: "string"
-							number: 1
-							label: LABEL_OPTIONAL
-							type: TYPE_STRING
-						>
-					>
-					service <
-						name: "ExampleService"
-						method <
-							name: "Echo"
-							input_type: "StringMessage"
-							output_type: "StringMessage"
-							options <
-								[google.api.http] <
-									post: "/v1/example/echo/{bool=*}"
-								>
-							>
-							client_streaming: true
-						>
-					>
-				`,
-			},
-		},
-		// body for GET
-		{
-			target: "path/to/example.proto",
-			srcs: []string{
-				`
-					name: "path/to/example.proto",
-					package: "example"
-					message_type <
-						name: "StringMessage"
-						field <
-							name: "string"
-							number: 1
-							label: LABEL_OPTIONAL
-							type: TYPE_STRING
-						>
-					>
-					service <
-						name: "ExampleService"
-						method <
-							name: "Echo"
-							input_type: "StringMessage"
-							output_type: "StringMessage"
-							options <
-								[google.api.http] <
-									get: "/v1/example/echo"
-									body: "string"
-								>
-							>
-						>
-					>
-				`,
-			},
-		},
-		// body for DELETE
-		{
-			target: "path/to/example.proto",
-			srcs: []string{
-				`
-					name: "path/to/example.proto",
-					package: "example"
-					message_type <
-						name: "StringMessage"
-						field <
-							name: "string"
-							number: 1
-							label: LABEL_OPTIONAL
-							type: TYPE_STRING
-						>
-					>
-					service <
-						name: "ExampleService"
-						method <
-							name: "RemoveResource"
-							input_type: "StringMessage"
-							output_type: "StringMessage"
-							options <
-								[google.api.http] <
-									delete: "/v1/example/resource"
-									body: "string"
-								>
-							>
-						>
-					>
-				`,
-			},
-		},
-		// no pattern specified
-		{
-			target: "path/to/example.proto",
-			srcs: []string{
-				`
-					name: "path/to/example.proto",
-					package: "example"
-					service <
-						name: "ExampleService"
-						method <
-							name: "RemoveResource"
-							input_type: "StringMessage"
-							output_type: "StringMessage"
-							options <
-								[google.api.http] <
-									body: "string"
-								>
-							>
-						>
-					>
-				`,
-			},
-		},
-		// unsupported path parameter type
-		{
-			target: "path/to/example.proto",
-			srcs: []string{`
-					name: "path/to/example.proto",
-					package: "example"
-					message_type <
-						name: "OuterMessage"
-						nested_type <
-							name: "StringMessage"
-							field <
-								name: "value"
-								number: 1
-								label: LABEL_OPTIONAL
-								type: TYPE_STRING
-							>
-						>
-						field <
-							name: "string"
-							number: 1
-							label: LABEL_OPTIONAL
-							type: TYPE_MESSAGE
-							type_name: "StringMessage"
-						>
-					>
-					service <
-						name: "ExampleService"
-						method <
-							name: "Echo"
-							input_type: "OuterMessage"
-							output_type: "OuterMessage"
-							options <
-								[google.api.http] <
-									get: "/v1/example/echo/{string=*}"
-								>
-							>
-						>
-					>
-				`,
-			},
-		},
-	} {
-		reg := NewRegistry()
-
-		for _, src := range spec.srcs {
-			var fd descriptorpb.FileDescriptorProto
-			if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-				t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-			}
-			reg.loadFile(spec.target, &protogen.File{
-				Proto: &fd,
-			})
-		}
-		err := reg.loadServices(reg.files[spec.target])
-		if err == nil {
-			t.Errorf("loadServices(%q) succeeded; want an error; files=%v", spec.target, spec.srcs)
-		}
-		t.Log(err)
-	}
-}
-
-func TestResolveFieldPath(t *testing.T) {
-	for _, spec := range []struct {
-		src     string
-		path    string
-		wantErr bool
-	}{
-		{
-			src: `
-				name: 'example.proto'
-				package: 'example'
-				message_type <
-					name: 'ExampleMessage'
-					field <
-						name: 'string'
-						type: TYPE_STRING
-						label: LABEL_OPTIONAL
-						number: 1
-					>
-				>
-			`,
-			path:    "string",
-			wantErr: false,
-		},
-		// no such field
-		{
-			src: `
-				name: 'example.proto'
-				package: 'example'
-				message_type <
-					name: 'ExampleMessage'
-					field <
-						name: 'string'
-						type: TYPE_STRING
-						label: LABEL_OPTIONAL
-						number: 1
-					>
-				>
-			`,
-			path:    "something_else",
-			wantErr: true,
-		},
-		// repeated field
-		{
-			src: `
-				name: 'example.proto'
-				package: 'example'
-				message_type <
-					name: 'ExampleMessage'
-					field <
-						name: 'string'
-						type: TYPE_STRING
-						label: LABEL_REPEATED
-						number: 1
-					>
-				>
-			`,
-			path:    "string",
-			wantErr: true,
-		},
-		// nested field
-		{
-			src: `
-				name: 'example.proto'
-				package: 'example'
-				message_type <
-					name: 'ExampleMessage'
-					field <
-						name: 'nested'
-						type: TYPE_MESSAGE
-						type_name: 'AnotherMessage'
-						label: LABEL_OPTIONAL
-						number: 1
-					>
-					field <
-						name: 'terminal'
-						type: TYPE_BOOL
-						label: LABEL_OPTIONAL
-						number: 2
-					>
-				>
-				message_type <
-					name: 'AnotherMessage'
-					field <
-						name: 'nested2'
-						type: TYPE_MESSAGE
-						type_name: 'ExampleMessage'
-						label: LABEL_OPTIONAL
-						number: 1
-					>
-				>
-			`,
-			path:    "nested.nested2.nested.nested2.nested.nested2.terminal",
-			wantErr: false,
-		},
-		// non aggregate field on the path
-		{
-			src: `
-				name: 'example.proto'
-				package: 'example'
-				message_type <
-					name: 'ExampleMessage'
-					field <
-						name: 'nested'
-						type: TYPE_MESSAGE
-						type_name: 'AnotherMessage'
-						label: LABEL_OPTIONAL
-						number: 1
-					>
-					field <
-						name: 'terminal'
-						type: TYPE_BOOL
-						label: LABEL_OPTIONAL
-						number: 2
-					>
-				>
-				message_type <
-					name: 'AnotherMessage'
-					field <
-						name: 'nested2'
-						type: TYPE_MESSAGE
-						type_name: 'ExampleMessage'
-						label: LABEL_OPTIONAL
-						number: 1
-					>
-				>
-			`,
-			path:    "nested.terminal.nested2",
-			wantErr: true,
-		},
-		// repeated field
-		{
-			src: `
-				name: 'example.proto'
-				package: 'example'
-				message_type <
-					name: 'ExampleMessage'
-					field <
-						name: 'nested'
-						type: TYPE_MESSAGE
-						type_name: 'AnotherMessage'
-						label: LABEL_OPTIONAL
-						number: 1
-					>
-					field <
-						name: 'terminal'
-						type: TYPE_BOOL
-						label: LABEL_OPTIONAL
-						number: 2
-					>
-				>
-				message_type <
-					name: 'AnotherMessage'
-					field <
-						name: 'nested2'
-						type: TYPE_MESSAGE
-						type_name: 'ExampleMessage'
-						label: LABEL_REPEATED
-						number: 1
-					>
-				>
-			`,
-			path:    "nested.nested2.terminal",
-			wantErr: true,
-		},
-	} {
-		var file descriptorpb.FileDescriptorProto
-		if err := prototext.Unmarshal([]byte(spec.src), &file); err != nil {
-			t.Fatalf("proto.Unmarshal(%s) failed with %v; want success", spec.src, err)
-		}
-		reg := NewRegistry()
-		reg.loadFile(file.GetName(), &protogen.File{
-			Proto: &file,
-		})
-		f, err := reg.LookupFile(file.GetName())
-		if err != nil {
-			t.Fatalf("reg.LookupFile(%q) failed with %v; want success; on file=%s", file.GetName(), err, spec.src)
-		}
-		_, err = reg.resolveFieldPath(f.Messages[0], spec.path, false)
-		if got, want := err != nil, spec.wantErr; got != want {
-			if want {
-				t.Errorf("reg.resolveFiledPath(%q, %q) succeeded; want an error", f.Messages[0].GetName(), spec.path)
-				continue
-			}
-			t.Errorf("reg.resolveFiledPath(%q, %q) failed with %v; want success", f.Messages[0].GetName(), spec.path, err)
-		}
-	}
-}
-
-func TestExtractServicesWithDeleteBody(t *testing.T) {
-	for _, spec := range []struct {
-		allowDeleteBody bool
-		expectErr       bool
-		target          string
-		srcs            []string
-	}{
-		// body for DELETE, but registry configured to allow it
-		{
-			allowDeleteBody: true,
-			expectErr:       false,
-			target:          "path/to/example.proto",
-			srcs: []string{
-				`
-					name: "path/to/example.proto",
-					package: "example"
-					message_type <
-						name: "StringMessage"
-						field <
-							name: "string"
-							number: 1
-							label: LABEL_OPTIONAL
-							type: TYPE_STRING
-						>
-					>
-					service <
-						name: "ExampleService"
-						method <
-							name: "RemoveResource"
-							input_type: "StringMessage"
-							output_type: "StringMessage"
-							options <
-								[google.api.http] <
-									delete: "/v1/example/resource"
-									body: "string"
-								>
-							>
-						>
-					>
-				`,
-			},
-		},
-		// body for DELETE, registry configured not to allow it
-		{
-			allowDeleteBody: false,
-			expectErr:       true,
-			target:          "path/to/example.proto",
-			srcs: []string{
-				`
-					name: "path/to/example.proto",
-					package: "example"
-					message_type <
-						name: "StringMessage"
-						field <
-							name: "string"
-							number: 1
-							label: LABEL_OPTIONAL
-							type: TYPE_STRING
-						>
-					>
-					service <
-						name: "ExampleService"
-						method <
-							name: "RemoveResource"
-							input_type: "StringMessage"
-							output_type: "StringMessage"
-							options <
-								[google.api.http] <
-									delete: "/v1/example/resource"
-									body: "string"
-								>
-							>
-						>
-					>
-				`,
-			},
-		},
-	} {
-		reg := NewRegistry()
-		reg.SetAllowDeleteBody(spec.allowDeleteBody)
-
-		for _, src := range spec.srcs {
-			var fd descriptorpb.FileDescriptorProto
-			if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-				t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-			}
-			reg.loadFile(fd.GetName(), &protogen.File{
-				Proto: &fd,
-			})
-		}
-		err := reg.loadServices(reg.files[spec.target])
-		if spec.expectErr && err == nil {
-			t.Errorf("loadServices(%q) succeeded; want an error; allowDeleteBody=%v, files=%v", spec.target, spec.allowDeleteBody, spec.srcs)
-		}
-		if !spec.expectErr && err != nil {
-			t.Errorf("loadServices(%q) failed; do not want an error; allowDeleteBody=%v, files=%v", spec.target, spec.allowDeleteBody, spec.srcs)
-		}
-		t.Log(err)
-	}
-}
-
-func TestCauseErrorWithPathParam(t *testing.T) {
-	src := `
-		name: "path/to/example.proto",
-		package: "example"
-		message_type <
-			name: "TypeMessage"
-			field <
-					name: "message"
-					type: TYPE_MESSAGE
-					type_name: 'ExampleMessage'
-					number: 1,
-					label: LABEL_OPTIONAL
-				>
-		>
-		service <
-			name: "ExampleService"
-			method <
-				name: "Echo"
-				input_type: "TypeMessage"
-				output_type: "TypeMessage"
-				options <
-					[google.api.http] <
-						get: "/v1/example/echo/{message=*}"
-					>
-				>
-			>
-		>
-	`
-	var fd descriptorpb.FileDescriptorProto
-	if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-		t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-	}
-	target := "path/to/example.proto"
-	reg := NewRegistry()
-	input := []*descriptorpb.FileDescriptorProto{&fd}
-	reg.loadFile(fd.GetName(), &protogen.File{
-		Proto: &fd,
-	})
-	// switch this field to see the error
-	wantErr := true
-	err := reg.loadServices(reg.files[target])
-	if got, want := err != nil, wantErr; got != want {
-		if want {
-			t.Errorf("loadServices(%q, %q) succeeded; want an error", target, input)
-		}
-		t.Errorf("loadServices(%q, %q) failed with %v; want success", target, input, err)
-	}
-}
-
-func TestOptionalProto3URLPathMappingError(t *testing.T) {
-	src := `
-		name: "path/to/example.proto"
-		package: "example"
-		message_type <
-			name: "StringMessage"
-			field <
-				name: "field1"
-				number: 1
-				type: TYPE_STRING
-				proto3_optional: true
-			>
-		>
-		service <
-			name: "ExampleService"
-			method <
-				name: "Echo"
-				input_type: "StringMessage"
-				output_type: "StringMessage"
-				options <
-					[google.api.http] <
-						get: "/v1/example/echo/{field1=*}"
-					>
-				>
-			>
-		>
-	`
-	var fd descriptorpb.FileDescriptorProto
-	if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-		t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-	}
-	target := "path/to/example.proto"
-	reg := NewRegistry()
-	input := []*descriptorpb.FileDescriptorProto{&fd}
-	reg.loadFile(fd.GetName(), &protogen.File{
-		Proto: &fd,
-	})
-	wantErrMsg := "field not allowed in field path: field1 in field1"
-	err := reg.loadServices(reg.files[target])
-	if err != nil {
-		if !strings.Contains(err.Error(), wantErrMsg) {
-			t.Errorf("loadServices(%q, %q) failed with %v; want %s", target, input, err, wantErrMsg)
-		}
-	} else {
-		t.Errorf("loadServices(%q, %q) expcted an error %s, got nil", target, input, wantErrMsg)
-	}
-}

+ 0 - 538
protoc-gen-openapiv2/internal/descriptor/types.go

@@ -1,538 +0,0 @@
-package descriptor
-
-import (
-	"fmt"
-	"strings"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/casing"
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/httprule"
-	"google.golang.org/protobuf/types/descriptorpb"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-// 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 invocation 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)
-}
-
-// ResponseFile wraps pluginpb.CodeGeneratorResponse_File.
-type ResponseFile struct {
-	*pluginpb.CodeGeneratorResponse_File
-	// GoPkg is the Go package of the generated file.
-	GoPkg GoPackage
-}
-
-// File wraps descriptorpb.FileDescriptorProto for richer features.
-type File struct {
-	*descriptorpb.FileDescriptorProto
-	// GoPkg is the go package of the go file generated from this file.
-	GoPkg GoPackage
-	// GeneratedFilenamePrefix is used to construct filenames for generated
-	// files associated with this source file.
-	//
-	// For example, the source file "dir/foo.proto" might have a filename prefix
-	// of "dir/foo". Appending ".pb.go" produces an output file of "dir/foo.pb.go".
-	GeneratedFilenamePrefix string
-	// 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
-}
-
-// Pkg returns package name or alias if it's present
-func (f *File) Pkg() string {
-	pkg := f.GoPkg.Name
-	if alias := f.GoPkg.Alias; alias != "" {
-		pkg = alias
-	}
-	return pkg
-}
-
-// 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 {
-	*descriptorpb.DescriptorProto
-	// 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
-	// Fields is a list of message fields.
-	Fields []*Field
-	// Index is proto path index of this message in File.
-	Index int
-	// ForcePrefixedName when set to true, prefixes a type with a package prefix.
-	ForcePrefixedName bool
-}
-
-// 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.ForcePrefixedName && m.File.GoPkg.Path == currentPackage {
-		return name
-	}
-	return fmt.Sprintf("%s.%s", m.File.Pkg(), name)
-}
-
-// Enum describes a protocol buffer enum types.
-type Enum struct {
-	*descriptorpb.EnumDescriptorProto
-	// 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
-	// Index is a enum index value.
-	Index int
-	// ForcePrefixedName when set to true, prefixes a type with a package prefix.
-	ForcePrefixedName bool
-}
-
-// 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.ForcePrefixedName && e.File.GoPkg.Path == currentPackage {
-		return name
-	}
-	return fmt.Sprintf("%s.%s", e.File.Pkg(), name)
-}
-
-// Service wraps descriptorpb.ServiceDescriptorProto for richer features.
-type Service struct {
-	*descriptorpb.ServiceDescriptorProto
-	// File is the file where this service is defined.
-	File *File
-	// Methods is the list of methods defined in this service.
-	Methods []*Method
-	// ForcePrefixedName when set to true, prefixes a type with a package prefix.
-	ForcePrefixedName bool
-}
-
-// 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, ".")
-}
-
-// InstanceName returns object name of the service with package prefix if needed
-func (s *Service) InstanceName() string {
-	if !s.ForcePrefixedName {
-		return s.GetName()
-	}
-	return fmt.Sprintf("%s.%s", s.File.Pkg(), s.GetName())
-}
-
-// ClientConstructorName returns name of the Client constructor with package prefix if needed
-func (s *Service) ClientConstructorName() string {
-	constructor := "New" + s.GetName() + "Client"
-	if !s.ForcePrefixedName {
-		return constructor
-	}
-	return fmt.Sprintf("%s.%s", s.File.Pkg(), constructor)
-}
-
-// Method wraps descriptorpb.MethodDescriptorProto for richer features.
-type Method struct {
-	*descriptorpb.MethodDescriptorProto
-	// Service is the service which this method belongs to.
-	Service *Service
-	// 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 {
-	var 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 descriptorpb.FieldDescriptorProto for richer features.
-type Field struct {
-	*descriptorpb.FieldDescriptorProto
-	// Message is the message type which this field belongs to.
-	Message *Message
-	// FieldMessage is the message type of the field.
-	FieldMessage *Message
-	// ForcePrefixedName when set to true, prefixes a type with a package prefix.
-	ForcePrefixedName bool
-}
-
-// FQFN returns a fully qualified field name of this field.
-func (f *Field) FQFN() string {
-	return strings.Join([]string{f.Message.FQMN(), f.GetName()}, ".")
-}
-
-// 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.IsOptionalProto3() {
-		tbl = proto3OptionalConvertFuncs
-	} 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() == descriptorpb.FieldDescriptorProto_TYPE_ENUM
-}
-
-// IsRepeated returns true if the field is repeated, otherwise false is returned.
-func (p Parameter) IsRepeated() bool {
-	return p.Target.GetLabel() == descriptorpb.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
-}
-
-// IsOptionalProto3 indicates whether the FieldPath is a proto3 optional field.
-func (p FieldPath) IsOptionalProto3() bool {
-	if len(p) == 0 {
-		return false
-	}
-	return p[0].Target.GetProto3Optional()
-}
-
-// 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 {
-		// We need to check if the target is not proto3_optional first.
-		// Under the hood, proto3_optional uses oneof to signal to old proto3 clients
-		// that presence is tracked for this field. This oneof is known as a "synthetic" oneof.
-		if !c.Target.GetProto3Optional() && c.Target.OneofIndex != nil {
-			index := c.Target.OneofIndex
-			msg := c.Target.Message
-			oneOfName := casing.Camel(msg.GetOneofDecl()[*index].GetName())
-			oneofFieldName := msg.GetName() + "_" + c.AssignableExpr()
-
-			if c.Target.ForcePrefixedName {
-				oneofFieldName = msg.File.Pkg() + "." + oneofFieldName
-			}
-
-			components = components + "." + oneOfName
-			s := `if %s == nil {
-				%s =&%s{}
-			} else if _, ok := %s.(*%s); !ok {
-				return nil, metadata, status.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 casing.Camel(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()", casing.Camel(c.Name))
-	}
-	return casing.Camel(c.Name)
-}
-
-var (
-	proto3ConvertFuncs = map[descriptorpb.FieldDescriptorProto_Type]string{
-		descriptorpb.FieldDescriptorProto_TYPE_DOUBLE:  "runtime.Float64",
-		descriptorpb.FieldDescriptorProto_TYPE_FLOAT:   "runtime.Float32",
-		descriptorpb.FieldDescriptorProto_TYPE_INT64:   "runtime.Int64",
-		descriptorpb.FieldDescriptorProto_TYPE_UINT64:  "runtime.Uint64",
-		descriptorpb.FieldDescriptorProto_TYPE_INT32:   "runtime.Int32",
-		descriptorpb.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64",
-		descriptorpb.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32",
-		descriptorpb.FieldDescriptorProto_TYPE_BOOL:    "runtime.Bool",
-		descriptorpb.FieldDescriptorProto_TYPE_STRING:  "runtime.String",
-		// FieldDescriptorProto_TYPE_GROUP
-		// FieldDescriptorProto_TYPE_MESSAGE
-		descriptorpb.FieldDescriptorProto_TYPE_BYTES:    "runtime.Bytes",
-		descriptorpb.FieldDescriptorProto_TYPE_UINT32:   "runtime.Uint32",
-		descriptorpb.FieldDescriptorProto_TYPE_ENUM:     "runtime.Enum",
-		descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32",
-		descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64",
-		descriptorpb.FieldDescriptorProto_TYPE_SINT32:   "runtime.Int32",
-		descriptorpb.FieldDescriptorProto_TYPE_SINT64:   "runtime.Int64",
-	}
-
-	proto3OptionalConvertFuncs = func() map[descriptorpb.FieldDescriptorProto_Type]string {
-		result := make(map[descriptorpb.FieldDescriptorProto_Type]string)
-		for typ, converter := range proto3ConvertFuncs {
-			// TODO: this will use convert functions from proto2.
-			//       The converters returning pointers should be moved
-			//       to a more generic file.
-			result[typ] = converter + "P"
-		}
-		return result
-	}()
-
-	// TODO: replace it with a IIFE
-	proto3RepeatedConvertFuncs = map[descriptorpb.FieldDescriptorProto_Type]string{
-		descriptorpb.FieldDescriptorProto_TYPE_DOUBLE:  "runtime.Float64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_FLOAT:   "runtime.Float32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_INT64:   "runtime.Int64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_UINT64:  "runtime.Uint64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_INT32:   "runtime.Int32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_BOOL:    "runtime.BoolSlice",
-		descriptorpb.FieldDescriptorProto_TYPE_STRING:  "runtime.StringSlice",
-		// FieldDescriptorProto_TYPE_GROUP
-		// FieldDescriptorProto_TYPE_MESSAGE
-		descriptorpb.FieldDescriptorProto_TYPE_BYTES:    "runtime.BytesSlice",
-		descriptorpb.FieldDescriptorProto_TYPE_UINT32:   "runtime.Uint32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_ENUM:     "runtime.EnumSlice",
-		descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_SINT32:   "runtime.Int32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_SINT64:   "runtime.Int64Slice",
-	}
-
-	proto2ConvertFuncs = map[descriptorpb.FieldDescriptorProto_Type]string{
-		descriptorpb.FieldDescriptorProto_TYPE_DOUBLE:  "runtime.Float64P",
-		descriptorpb.FieldDescriptorProto_TYPE_FLOAT:   "runtime.Float32P",
-		descriptorpb.FieldDescriptorProto_TYPE_INT64:   "runtime.Int64P",
-		descriptorpb.FieldDescriptorProto_TYPE_UINT64:  "runtime.Uint64P",
-		descriptorpb.FieldDescriptorProto_TYPE_INT32:   "runtime.Int32P",
-		descriptorpb.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64P",
-		descriptorpb.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32P",
-		descriptorpb.FieldDescriptorProto_TYPE_BOOL:    "runtime.BoolP",
-		descriptorpb.FieldDescriptorProto_TYPE_STRING:  "runtime.StringP",
-		// FieldDescriptorProto_TYPE_GROUP
-		// FieldDescriptorProto_TYPE_MESSAGE
-		// FieldDescriptorProto_TYPE_BYTES
-		// TODO(yugui) Handle bytes
-		descriptorpb.FieldDescriptorProto_TYPE_UINT32:   "runtime.Uint32P",
-		descriptorpb.FieldDescriptorProto_TYPE_ENUM:     "runtime.EnumP",
-		descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32P",
-		descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64P",
-		descriptorpb.FieldDescriptorProto_TYPE_SINT32:   "runtime.Int32P",
-		descriptorpb.FieldDescriptorProto_TYPE_SINT64:   "runtime.Int64P",
-	}
-
-	proto2RepeatedConvertFuncs = map[descriptorpb.FieldDescriptorProto_Type]string{
-		descriptorpb.FieldDescriptorProto_TYPE_DOUBLE:  "runtime.Float64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_FLOAT:   "runtime.Float32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_INT64:   "runtime.Int64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_UINT64:  "runtime.Uint64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_INT32:   "runtime.Int32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_FIXED64: "runtime.Uint64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_FIXED32: "runtime.Uint32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_BOOL:    "runtime.BoolSlice",
-		descriptorpb.FieldDescriptorProto_TYPE_STRING:  "runtime.StringSlice",
-		// FieldDescriptorProto_TYPE_GROUP
-		// FieldDescriptorProto_TYPE_MESSAGE
-		// FieldDescriptorProto_TYPE_BYTES
-		// TODO(maros7) Handle bytes
-		descriptorpb.FieldDescriptorProto_TYPE_UINT32:   "runtime.Uint32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_ENUM:     "runtime.EnumSlice",
-		descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: "runtime.Int32Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: "runtime.Int64Slice",
-		descriptorpb.FieldDescriptorProto_TYPE_SINT32:   "runtime.Int32Slice",
-		descriptorpb.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",
-	}
-)

+ 0 - 269
protoc-gen-openapiv2/internal/descriptor/types_test.go

@@ -1,269 +0,0 @@
-package descriptor
-
-import (
-	"testing"
-
-	"google.golang.org/protobuf/encoding/prototext"
-	"google.golang.org/protobuf/types/descriptorpb"
-)
-
-func TestGoPackageStandard(t *testing.T) {
-	for _, spec := range []struct {
-		pkg  GoPackage
-		want bool
-	}{
-		{
-			pkg:  GoPackage{Path: "fmt", Name: "fmt"},
-			want: true,
-		},
-		{
-			pkg:  GoPackage{Path: "encoding/json", Name: "json"},
-			want: true,
-		},
-		{
-			pkg:  GoPackage{Path: "google.golang.org/protobuf/encoding/protojson", Name: "jsonpb"},
-			want: false,
-		},
-		{
-			pkg:  GoPackage{Path: "golang.org/x/net/context", Name: "context"},
-			want: false,
-		},
-		{
-			pkg:  GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway", Name: "main"},
-			want: false,
-		},
-		{
-			pkg:  GoPackage{Path: "github.com/google/googleapis/google/api/http.pb", Name: "http_pb", Alias: "htpb"},
-			want: false,
-		},
-	} {
-		if got, want := spec.pkg.Standard(), spec.want; got != want {
-			t.Errorf("%#v.Standard() = %v; want %v", spec.pkg, got, want)
-		}
-	}
-}
-
-func TestGoPackageString(t *testing.T) {
-	for _, spec := range []struct {
-		pkg  GoPackage
-		want string
-	}{
-		{
-			pkg:  GoPackage{Path: "fmt", Name: "fmt"},
-			want: `"fmt"`,
-		},
-		{
-			pkg:  GoPackage{Path: "encoding/json", Name: "json"},
-			want: `"encoding/json"`,
-		},
-		{
-			pkg:  GoPackage{Path: "google.golang.org/protobuf/encoding/protojson", Name: "jsonpb"},
-			want: `"google.golang.org/protobuf/encoding/protojson"`,
-		},
-		{
-			pkg:  GoPackage{Path: "golang.org/x/net/context", Name: "context"},
-			want: `"golang.org/x/net/context"`,
-		},
-		{
-			pkg:  GoPackage{Path: "github.com/grpc-ecosystem/grpc-gateway", Name: "main"},
-			want: `"github.com/grpc-ecosystem/grpc-gateway"`,
-		},
-		{
-			pkg:  GoPackage{Path: "github.com/google/googleapis/google/api/http.pb", Name: "http_pb", Alias: "htpb"},
-			want: `htpb "github.com/google/googleapis/google/api/http.pb"`,
-		},
-	} {
-		if got, want := spec.pkg.String(), spec.want; got != want {
-			t.Errorf("%#v.String() = %q; want %q", spec.pkg, got, want)
-		}
-	}
-}
-
-func TestFieldPath(t *testing.T) {
-	var fds []*descriptorpb.FileDescriptorProto
-	for _, src := range []string{
-		`
-		name: 'example.proto'
-		package: 'example'
-		message_type <
-			name: 'Nest'
-			field <
-				name: 'nest2_field'
-				label: LABEL_OPTIONAL
-				type: TYPE_MESSAGE
-				type_name: 'Nest2'
-				number: 1
-			>
-			field <
-				name: 'terminal_field'
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-				number: 2
-			>
-		>
-		syntax: "proto3"
-		`, `
-		name: 'another.proto'
-		package: 'example'
-		message_type <
-			name: 'Nest2'
-			field <
-				name: 'nest_field'
-				label: LABEL_OPTIONAL
-				type: TYPE_MESSAGE
-				type_name: 'Nest'
-				number: 1
-			>
-			field <
-				name: 'terminal_field'
-				label: LABEL_OPTIONAL
-				type: TYPE_STRING
-				number: 2
-			>
-		>
-		syntax: "proto2"
-		`,
-	} {
-		var fd descriptorpb.FileDescriptorProto
-		if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-			t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-		}
-		fds = append(fds, &fd)
-	}
-	nest1 := &Message{
-		DescriptorProto: fds[0].MessageType[0],
-		Fields: []*Field{
-			{FieldDescriptorProto: fds[0].MessageType[0].Field[0]},
-			{FieldDescriptorProto: fds[0].MessageType[0].Field[1]},
-		},
-	}
-	nest2 := &Message{
-		DescriptorProto: fds[1].MessageType[0],
-		Fields: []*Field{
-			{FieldDescriptorProto: fds[1].MessageType[0].Field[0]},
-			{FieldDescriptorProto: fds[1].MessageType[0].Field[1]},
-		},
-	}
-	file1 := &File{
-		FileDescriptorProto: fds[0],
-		GoPkg:               GoPackage{Path: "example", Name: "example"},
-		Messages:            []*Message{nest1},
-	}
-	file2 := &File{
-		FileDescriptorProto: fds[1],
-		GoPkg:               GoPackage{Path: "example", Name: "example"},
-		Messages:            []*Message{nest2},
-	}
-	crossLinkFixture(file1)
-	crossLinkFixture(file2)
-
-	c1 := FieldPathComponent{
-		Name:   "nest_field",
-		Target: nest2.Fields[0],
-	}
-	if got, want := c1.ValueExpr(), "GetNestField()"; got != want {
-		t.Errorf("c1.ValueExpr() = %q; want %q", got, want)
-	}
-	if got, want := c1.AssignableExpr(), "NestField"; got != want {
-		t.Errorf("c1.AssignableExpr() = %q; want %q", got, want)
-	}
-
-	c2 := FieldPathComponent{
-		Name:   "nest2_field",
-		Target: nest1.Fields[0],
-	}
-	if got, want := c2.ValueExpr(), "Nest2Field"; got != want {
-		t.Errorf("c2.ValueExpr() = %q; want %q", got, want)
-	}
-	if got, want := c2.ValueExpr(), "Nest2Field"; got != want {
-		t.Errorf("c2.ValueExpr() = %q; want %q", got, want)
-	}
-
-	fp := FieldPath{
-		c1, c2, c1, FieldPathComponent{
-			Name:   "terminal_field",
-			Target: nest1.Fields[1],
-		},
-	}
-	if got, want := fp.AssignableExpr("resp"), "resp.GetNestField().Nest2Field.GetNestField().TerminalField"; got != want {
-		t.Errorf("fp.AssignableExpr(%q) = %q; want %q", "resp", got, want)
-	}
-
-	fp2 := FieldPath{
-		c2, c1, c2, FieldPathComponent{
-			Name:   "terminal_field",
-			Target: nest2.Fields[1],
-		},
-	}
-	if got, want := fp2.AssignableExpr("resp"), "resp.Nest2Field.GetNestField().Nest2Field.TerminalField"; got != want {
-		t.Errorf("fp2.AssignableExpr(%q) = %q; want %q", "resp", got, want)
-	}
-
-	var fpEmpty FieldPath
-	if got, want := fpEmpty.AssignableExpr("resp"), "resp"; got != want {
-		t.Errorf("fpEmpty.AssignableExpr(%q) = %q; want %q", "resp", got, want)
-	}
-}
-
-func TestGoType(t *testing.T) {
-	src := `
-		name: 'example.proto'
-		package: 'example'
-		message_type <
-			name: 'Message'
-			field <
-				name: 'field'
-				type: TYPE_STRING
-				number: 1
-			>
-		>,
-		enum_type <
-			name: 'EnumName'
-		>,
-	`
-
-	var fd descriptorpb.FileDescriptorProto
-	if err := prototext.Unmarshal([]byte(src), &fd); err != nil {
-		t.Fatalf("proto.UnmarshalText(%s, &fd) failed with %v; want success", src, err)
-	}
-
-	msg := &Message{
-		DescriptorProto: fd.MessageType[0],
-		Fields: []*Field{
-			{FieldDescriptorProto: fd.MessageType[0].Field[0]},
-		},
-	}
-	enum := &Enum{
-		EnumDescriptorProto: fd.EnumType[0],
-	}
-	file := &File{
-		FileDescriptorProto: &fd,
-		GoPkg:               GoPackage{Path: "example", Name: "example"},
-		Messages:            []*Message{msg},
-		Enums:               []*Enum{enum},
-	}
-	crossLinkFixture(file)
-
-	if got, want := msg.GoType("example"), "Message"; got != want {
-		t.Errorf("msg.GoType() = %q; want %q", got, want)
-	}
-	if got, want := msg.GoType("extPackage"), "example.Message"; got != want {
-		t.Errorf("msg.GoType() = %q; want %q", got, want)
-	}
-	msg.ForcePrefixedName = true
-	if got, want := msg.GoType("example"), "example.Message"; got != want {
-		t.Errorf("msg.GoType() = %q; want %q", got, want)
-	}
-
-	if got, want := enum.GoType("example"), "EnumName"; got != want {
-		t.Errorf("enum.GoType() = %q; want %q", got, want)
-	}
-	if got, want := enum.GoType("extPackage"), "example.EnumName"; got != want {
-		t.Errorf("enum.GoType() = %q; want %q", got, want)
-	}
-	enum.ForcePrefixedName = true
-	if got, want := enum.GoType("example"), "example.EnumName"; got != want {
-		t.Errorf("enum.GoType() = %q; want %q", got, want)
-	}
-
-}

+ 0 - 12
protoc-gen-openapiv2/internal/generator/generator.go

@@ -1,12 +0,0 @@
-// Package generator provides an abstract interface to code generators.
-package generator
-
-import (
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor"
-)
-
-// Generator is an abstraction of code generators.
-type Generator interface {
-	// Generate generates output files from input .proto files.
-	Generate(targets []*descriptor.File) ([]*descriptor.ResponseFile, error)
-}

+ 0 - 41
protoc-gen-openapiv2/internal/genopenapi/cycle_test.go

@@ -1,41 +0,0 @@
-package genopenapi
-
-import (
-	"testing"
-)
-
-func TestCycle(t *testing.T) {
-	for _, tt := range []struct {
-		max     int
-		attempt int
-		e       bool
-	}{
-		{
-			max:     3,
-			attempt: 3,
-			e:       true,
-		},
-		{
-			max:     5,
-			attempt: 6,
-		},
-		{
-			max:     1000,
-			attempt: 1001,
-		},
-	} {
-
-		c := newCycleChecker(tt.max)
-		var final bool
-		for i := 0; i < tt.attempt; i++ {
-			final = c.Check("a")
-			if !final {
-				break
-			}
-		}
-
-		if final != tt.e {
-			t.Errorf("got: %t wanted: %t", final, tt.e)
-		}
-	}
-}

+ 0 - 2
protoc-gen-openapiv2/internal/genopenapi/doc.go

@@ -1,2 +0,0 @@
-// Package genopenapi provides a code generator for OpenAPI v2.
-package genopenapi

+ 0 - 247
protoc-gen-openapiv2/internal/genopenapi/generator.go

@@ -1,247 +0,0 @@
-package genopenapi
-
-import (
-	"bytes"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"path/filepath"
-	"reflect"
-	"strings"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor"
-	gen "git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/generator"
-	"github.com/golang/glog"
-	anypb "github.com/golang/protobuf/ptypes/any"
-	openapi_options "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
-	statuspb "google.golang.org/genproto/googleapis/rpc/status"
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/types/descriptorpb"
-	"google.golang.org/protobuf/types/pluginpb"
-
-	//nolint:staticcheck // Known issue, will be replaced when possible
-	legacydescriptor "github.com/golang/protobuf/descriptor"
-)
-
-var (
-	errNoTargetService = errors.New("no target service defined in the file")
-)
-
-type generator struct {
-	reg *descriptor.Registry
-}
-
-type wrapper struct {
-	fileName string
-	swagger  *openapiSwaggerObject
-}
-
-type GeneratorOptions struct {
-	Registry       *descriptor.Registry
-	RecursiveDepth int
-}
-
-// 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 OpenAPI file (wrapper) to single one OpenAPI 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.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
-}
-
-// 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 openapiSwaggerObject) MarshalJSON() ([]byte, error) {
-	type alias openapiSwaggerObject
-	return extensionMarshalJSON(alias(so), so.extensions)
-}
-
-func (so openapiInfoObject) MarshalJSON() ([]byte, error) {
-	type alias openapiInfoObject
-	return extensionMarshalJSON(alias(so), so.extensions)
-}
-
-func (so openapiSecuritySchemeObject) MarshalJSON() ([]byte, error) {
-	type alias openapiSecuritySchemeObject
-	return extensionMarshalJSON(alias(so), so.extensions)
-}
-
-func (so openapiOperationObject) MarshalJSON() ([]byte, error) {
-	type alias openapiOperationObject
-	return extensionMarshalJSON(alias(so), so.extensions)
-}
-
-func (so openapiResponseObject) MarshalJSON() ([]byte, error) {
-	type alias openapiResponseObject
-	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 {
-	//   *openapiCore
-	//   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 openapiCore with the
-	// extensions appended.
-	fields := []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())
-}
-
-// encodeOpenAPI converts OpenAPI file obj to pluginpb.CodeGeneratorResponse_File
-func encodeOpenAPI(file *wrapper) (*descriptor.ResponseFile, 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 &descriptor.ResponseFile{
-		CodeGeneratorResponse_File: &pluginpb.CodeGeneratorResponse_File{
-			Name:    proto.String(output),
-			Content: proto.String(formatted.String()),
-		},
-	}, nil
-}
-
-func (g *generator) Generate(targets []*descriptor.File) ([]*descriptor.ResponseFile, error) {
-	var files []*descriptor.ResponseFile
-	if g.reg.IsAllowMerge() {
-		var mergedTarget *descriptor.File
-		// try to find proto leader
-		for _, f := range targets {
-			if proto.HasExtension(f.Options, openapi_options.E_Openapiv2Swagger) {
-				mergedTarget = f
-				break
-			}
-		}
-		// merge protos to leader
-		for _, f := range targets {
-			if mergedTarget == nil {
-				mergedTarget = f
-			} else if mergedTarget != f {
-				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 openapis []*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
-		}
-		openapis = append(openapis, &wrapper{
-			fileName: file.GetName(),
-			swagger:  swagger,
-		})
-	}
-
-	if g.reg.IsAllowMerge() {
-		targetOpenAPI := mergeTargetFile(openapis, g.reg.GetMergeFileName())
-		f, err := encodeOpenAPI(targetOpenAPI)
-		if err != nil {
-			return nil, fmt.Errorf("failed to encode OpenAPI for %s: %s", g.reg.GetMergeFileName(), err)
-		}
-		files = append(files, f)
-		glog.V(1).Infof("New OpenAPI file will emit")
-	} else {
-		for _, file := range openapis {
-			f, err := encodeOpenAPI(file)
-			if err != nil {
-				return nil, fmt.Errorf("failed to encode OpenAPI for %s: %s", file.fileName, err)
-			}
-			files = append(files, f)
-			glog.V(1).Infof("New OpenAPI file will emit")
-		}
-	}
-	return files, nil
-}
-
-// AddErrorDefs Adds google.rpc.Status and google.protobuf.Any
-// to registry (used for error-related API responses)
-func AddErrorDefs(reg *descriptor.Registry) error {
-	// load internal protos
-	any, _ := legacydescriptor.MessageDescriptorProto(&anypb.Any{})
-	any.SourceCodeInfo = new(descriptorpb.SourceCodeInfo)
-	status, _ := legacydescriptor.MessageDescriptorProto(&statuspb.Status{})
-	status.SourceCodeInfo = new(descriptorpb.SourceCodeInfo)
-	// TODO(johanbrandhorst): Use new conversion later when possible
-	// any := protodesc.ToFileDescriptorProto((&anypb.Any{}).ProtoReflect().Descriptor().ParentFile())
-	// status := protodesc.ToFileDescriptorProto((&statuspb.Status{}).ProtoReflect().Descriptor().ParentFile())
-	return reg.Load(&pluginpb.CodeGeneratorRequest{
-		ProtoFile: []*descriptorpb.FileDescriptorProto{
-			any,
-			status,
-		},
-	})
-}

+ 0 - 10
protoc-gen-openapiv2/internal/genopenapi/helpers.go

@@ -1,10 +0,0 @@
-//go:build go1.12
-// +build go1.12
-
-package genopenapi
-
-import "strings"
-
-func fieldName(k string) string {
-	return strings.ReplaceAll(strings.Title(k), "-", "_")
-}

+ 0 - 10
protoc-gen-openapiv2/internal/genopenapi/helpers_go111_old.go

@@ -1,10 +0,0 @@
-//go:build !go1.12
-// +build !go1.12
-
-package genopenapi
-
-import "strings"
-
-func fieldName(k string) string {
-	return strings.Replace(strings.Title(k), "-", "_", -1)
-}

+ 0 - 2454
protoc-gen-openapiv2/internal/genopenapi/template.go

@@ -1,2454 +0,0 @@
-package genopenapi
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"math"
-	"net/textproto"
-	"reflect"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"text/template"
-	"time"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/casing"
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor"
-	"github.com/golang/glog"
-	openapi_options "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
-	"google.golang.org/genproto/googleapis/api/annotations"
-	"google.golang.org/protobuf/encoding/protojson"
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/types/descriptorpb"
-	"google.golang.org/protobuf/types/known/structpb"
-)
-
-// wktSchemas are the schemas of well-known-types.
-// The schemas must match with the behavior of the JSON unmarshaler in
-// https://github.com/protocolbuffers/protobuf-go/blob/v1.25.0/encoding/protojson/well_known_types.go
-var wktSchemas = map[string]schemaCore{
-	".google.protobuf.FieldMask": {
-		Type: "string",
-	},
-	".google.protobuf.Timestamp": {
-		Type:   "string",
-		Format: "date-time",
-	},
-	".google.protobuf.Duration": {
-		Type: "integer",
-	},
-	".google.protobuf.StringValue": {
-		Type: "string",
-	},
-	".google.protobuf.BytesValue": {
-		Type:   "string",
-		Format: "byte",
-	},
-	".google.protobuf.Int32Value": {
-		Type:   "integer",
-		Format: "int32",
-	},
-	".google.protobuf.UInt32Value": {
-		Type:   "integer",
-		Format: "int64",
-	},
-	".google.protobuf.Int64Value": {
-		Type:   "integer",
-		Format: "int64",
-	},
-	".google.protobuf.UInt64Value": {
-		Type:   "integer",
-		Format: "uint64",
-	},
-	".google.protobuf.FloatValue": {
-		Type:   "number",
-		Format: "float",
-	},
-	".google.protobuf.DoubleValue": {
-		Type:   "number",
-		Format: "double",
-	},
-	".google.protobuf.BoolValue": {
-		Type: "boolean",
-	},
-	".google.protobuf.Empty": {},
-	".google.protobuf.Struct": {
-		Type: "object",
-	},
-	".google.protobuf.Value": {
-		Type: "object",
-	},
-	".google.protobuf.ListValue": {
-		Type: "array",
-		Items: (*openapiItemsObject)(&schemaCore{
-			Type: "object",
-		}),
-	},
-	".google.protobuf.NullValue": {
-		Type: "string",
-	},
-}
-
-func listEnumNames(enum *descriptor.Enum) (names []string) {
-	for _, value := range enum.GetValue() {
-		names = append(names, value.GetName())
-	}
-	return names
-}
-
-func listEnumNumbers(enum *descriptor.Enum) (numbers []string) {
-	for _, value := range enum.GetValue() {
-		numbers = append(numbers, strconv.Itoa(int(value.GetNumber())))
-	}
-	return
-}
-
-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 OpenAPI query parameters.
-func messageToQueryParameters(message *descriptor.Message, reg *descriptor.Registry, pathParams []descriptor.Parameter, body *descriptor.Body) (params []openapiParameterObject, err error) {
-	for _, field := range message.Fields {
-		p, err := queryParams(message, field, "", reg, pathParams, body, reg.GetRecursiveDepth())
-		if err != nil {
-			return nil, err
-		}
-		params = append(params, p...)
-	}
-	return params, nil
-}
-
-// queryParams converts a field to a list of OpenAPI query parameters recursively through the use of nestedQueryParams.
-func queryParams(message *descriptor.Message, field *descriptor.Field, prefix string, reg *descriptor.Registry, pathParams []descriptor.Parameter, body *descriptor.Body, recursiveCount int) (params []openapiParameterObject, err error) {
-	return nestedQueryParams(message, field, prefix, reg, pathParams, body, newCycleChecker(recursiveCount))
-}
-
-type cycleChecker struct {
-	m     map[string]int
-	count int
-}
-
-func newCycleChecker(recursive int) *cycleChecker {
-	return &cycleChecker{
-		m:     make(map[string]int),
-		count: recursive,
-	}
-}
-
-// Check returns whether name is still within recursion
-// toleration
-func (c *cycleChecker) Check(name string) bool {
-	count, ok := c.m[name]
-	count = count + 1
-	isCycle := count > c.count
-
-	if isCycle {
-		return false
-	}
-
-	// provision map entry if not available
-	if !ok {
-		c.m[name] = 1
-		return true
-	}
-
-	c.m[name] = count
-
-	return true
-}
-
-func (c *cycleChecker) Branch() *cycleChecker {
-	copy := &cycleChecker{
-		count: c.count,
-		m:     map[string]int{},
-	}
-
-	for k, v := range c.m {
-		copy.m[k] = v
-	}
-
-	return copy
-}
-
-// nestedQueryParams converts a field to a list of OpenAPI query parameters recursively.
-// This function is a helper function for queryParams, that keeps track of cyclical message references
-//
-//	through the use of
-//	    touched map[string]int
-//
-// If a cycle is discovered, an error is returned, as cyclical data structures are dangerous
-//
-//	in query parameters.
-func nestedQueryParams(message *descriptor.Message, field *descriptor.Field, prefix string, reg *descriptor.Registry, pathParams []descriptor.Parameter, body *descriptor.Body, cycle *cycleChecker) (params []openapiParameterObject, 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
-		}
-	}
-	// make sure the parameter is not already listed as a body parameter
-	if body != nil {
-		if body.FieldPath == nil {
-			return nil, nil
-		}
-		for _, fieldPath := range body.FieldPath {
-			if fieldPath.Target == field {
-				return nil, nil
-			}
-		}
-	}
-	schema := schemaOfField(field, reg, nil)
-	fieldType := field.GetTypeName()
-	if message.File != nil {
-		comments := fieldProtoComments(reg, message, field)
-		if err := updateOpenAPIDataFromComments(reg, &schema, message, comments, false); err != nil {
-			return nil, err
-		}
-	}
-
-	isEnum := field.GetType() == descriptorpb.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 := openapiParameterObject{
-			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"
-		}
-
-		param.Name = prefix + reg.FieldName(field)
-
-		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 = &openapiItemsObject{
-					Type: "string",
-					Enum: listEnumNames(enum),
-				}
-				if reg.GetEnumsAsInts() {
-					param.Items.Type = "integer"
-					param.Items.Enum = listEnumNumbers(enum)
-				}
-			} else {
-				param.Type = "string"
-				param.Enum = listEnumNames(enum)
-				param.Default = getEnumDefault(enum)
-				if reg.GetEnumsAsInts() {
-					param.Type = "integer"
-					param.Enum = listEnumNumbers(enum)
-					param.Default = "0"
-				}
-			}
-			valueComments := enumValueProtoComments(reg, enum)
-			if valueComments != "" {
-				param.Description = strings.TrimLeft(param.Description+"\n\n "+valueComments, "\n")
-			}
-		}
-		return []openapiParameterObject{param}, nil
-	}
-
-	// nested type, recurse
-	msg, err := reg.LookupMsg("", fieldType)
-	if err != nil {
-		return nil, fmt.Errorf("unknown message type %s", fieldType)
-	}
-
-	// Check for cyclical message reference:
-	isOK := cycle.Check(*msg.Name)
-	if !isOK {
-		return nil, fmt.Errorf("exceeded recursive count (%d) for query parameter %q", cycle.count, fieldType)
-	}
-
-	// Construct a new map with the message name so a cycle further down the recursive path can be detected.
-	// Do not keep anything in the original touched reference and do not pass that reference along.  This will
-	// prevent clobbering adjacent records while recursing.
-	touchedOut := cycle.Branch()
-
-	for _, nestedField := range msg.Fields {
-		fieldName := reg.FieldName(field)
-		p, err := nestedQueryParams(msg, nestedField, prefix+fieldName+".", reg, pathParams, body, touchedOut)
-		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
-			{
-				swgReqName, ok := fullyQualifiedNameToOpenAPIName(meth.RequestType.FQMN(), reg)
-				if !ok {
-					glog.Errorf("couldn't resolve OpenAPI name for FQMN '%v'", meth.RequestType.FQMN())
-					continue
-				}
-				if _, ok := refs[fmt.Sprintf("#/definitions/%s", swgReqName)]; ok {
-					if !skipRenderingRef(meth.RequestType.FQMN()) {
-						m[swgReqName] = meth.RequestType
-					}
-				}
-			}
-
-			swgRspName, ok := fullyQualifiedNameToOpenAPIName(meth.ResponseType.FQMN(), reg)
-			if !ok && !skipRenderingRef(meth.ResponseType.FQMN()) {
-				glog.Errorf("couldn't resolve OpenAPI name for FQMN '%v'", meth.ResponseType.FQMN())
-				continue
-			}
-
-			findNestedMessagesAndEnumerations(meth.RequestType, reg, m, e)
-
-			if !skipRenderingRef(meth.ResponseType.FQMN()) {
-				m[swgRspName] = 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 renderMessageAsDefinition(msg *descriptor.Message, reg *descriptor.Registry, customRefs refMap, excludeFields []*descriptor.Field) openapiSchemaObject {
-	schema := openapiSchemaObject{
-		schemaCore: schemaCore{
-			Type: "object",
-		},
-	}
-	msgComments := protoComments(reg, msg.File, msg.Outers, "MessageType", int32(msg.Index))
-	if err := updateOpenAPIDataFromComments(reg, &schema, msg, msgComments, false); err != nil {
-		panic(err)
-	}
-	opts, err := getMessageOpenAPIOption(reg, msg)
-	if err != nil {
-		panic(err)
-	}
-	if opts != nil {
-		protoSchema := openapiSchemaFromProtoSchema(opts, reg, customRefs, msg)
-
-		// 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
-		schema.XNullable = protoSchema.XNullable
-		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
-		}
-	}
-
-	schema.Required = filterOutExcludedFields(schema.Required, excludeFields, reg)
-
-	for _, f := range msg.Fields {
-		if shouldExcludeField(reg.FieldName(f), excludeFields, reg) {
-			continue
-		}
-		fieldValue := schemaOfField(f, reg, customRefs)
-		comments := fieldProtoComments(reg, msg, f)
-		if err := updateOpenAPIDataFromComments(reg, &fieldValue, f, comments, false); err != nil {
-			panic(err)
-		}
-
-		if requiredIdx := find(schema.Required, *f.Name); requiredIdx != -1 && reg.GetUseJSONNamesForFields() {
-			schema.Required[requiredIdx] = f.GetJsonName()
-		}
-
-		if fieldValue.Required != nil {
-			for _, req := range fieldValue.Required {
-				if reg.GetUseJSONNamesForFields() {
-					schema.Required = append(schema.Required, f.GetJsonName())
-				} else {
-					schema.Required = append(schema.Required, req)
-				}
-			}
-		}
-
-		kv := keyVal{Value: fieldValue}
-		kv.Key = reg.FieldName(f)
-		if schema.Properties == nil {
-			schema.Properties = &openapiSchemaObjectProperties{}
-		}
-		*schema.Properties = append(*schema.Properties, kv)
-	}
-	return schema
-}
-
-func renderMessagesAsDefinition(messages messageMap, d openapiDefinitionsObject, reg *descriptor.Registry, customRefs refMap, excludeFields []*descriptor.Field) {
-	for name, msg := range messages {
-		swgName, ok := fullyQualifiedNameToOpenAPIName(msg.FQMN(), reg)
-		if !ok {
-			panic(fmt.Sprintf("can't resolve OpenAPI name from '%v'", msg.FQMN()))
-		}
-		if skipRenderingRef(name) {
-			continue
-		}
-
-		if opt := msg.GetOptions(); opt != nil && opt.MapEntry != nil && *opt.MapEntry {
-			continue
-		}
-		d[swgName] = renderMessageAsDefinition(msg, reg, customRefs, excludeFields)
-	}
-}
-
-func shouldExcludeField(name string, excluded []*descriptor.Field, reg *descriptor.Registry) bool {
-	for _, f := range excluded {
-		if name == reg.FieldName(f) {
-			return true
-		}
-	}
-	return false
-}
-func filterOutExcludedFields(fields []string, excluded []*descriptor.Field, reg *descriptor.Registry) []string {
-	var filtered []string
-	for _, f := range fields {
-		if !shouldExcludeField(f, excluded, reg) {
-			filtered = append(filtered, f)
-		}
-	}
-	return filtered
-}
-
-// schemaOfField returns a OpenAPI Schema Object for a protobuf field.
-func schemaOfField(f *descriptor.Field, reg *descriptor.Registry, refs refMap) openapiSchemaObject {
-	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() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED {
-		aggregate = array
-	}
-
-	var props *openapiSchemaObjectProperties
-
-	switch ft := fd.GetType(); ft {
-	case descriptorpb.FieldDescriptorProto_TYPE_ENUM, descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, descriptorpb.FieldDescriptorProto_TYPE_GROUP:
-		if wktSchema, ok := wktSchemas[fd.GetTypeName()]; ok {
-			core = wktSchema
-
-			if fd.GetTypeName() == ".google.protobuf.Empty" {
-				props = &openapiSchemaObjectProperties{}
-			}
-		} else {
-			swgRef, ok := fullyQualifiedNameToOpenAPIName(fd.GetTypeName(), reg)
-			if !ok {
-				panic(fmt.Sprintf("can't resolve OpenAPI ref from typename '%v'", fd.GetTypeName()))
-			}
-			core = schemaCore{
-				Ref: "#/definitions/" + swgRef,
-			}
-			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 := openapiSchemaObject{}
-
-	switch aggregate {
-	case array:
-		ret = openapiSchemaObject{
-			schemaCore: schemaCore{
-				Type:  "array",
-				Items: (*openapiItemsObject)(&core),
-			},
-		}
-	case object:
-		ret = openapiSchemaObject{
-			schemaCore: schemaCore{
-				Type: "object",
-			},
-			AdditionalProperties: &openapiSchemaObject{Properties: props, schemaCore: core},
-		}
-	default:
-		ret = openapiSchemaObject{
-			schemaCore: core,
-			Properties: props,
-		}
-	}
-
-	if j, err := getFieldOpenAPIOption(reg, f); err == nil {
-		updateswaggerObjectFromJSONSchema(&ret, j, reg, f)
-	}
-
-	if j, err := getFieldBehaviorOption(reg, f); err == nil {
-		updateSwaggerObjectFromFieldBehavior(&ret, j, f)
-	}
-
-	if reg.GetProto3OptionalNullable() && f.GetProto3Optional() {
-		ret.XNullable = true
-	}
-
-	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 descriptorpb.FieldDescriptorProto_Type) (ftype, format string, ok bool) {
-	switch t {
-	case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE:
-		return "number", "double", true
-	case descriptorpb.FieldDescriptorProto_TYPE_FLOAT:
-		return "number", "float", true
-	case descriptorpb.FieldDescriptorProto_TYPE_INT64:
-		return "integer", "int64", true
-	case descriptorpb.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 OpenAPI spec.
-		// So we cannot expect that uint64 is commonly supported by OpenAPI processor.
-		return "integer", "uint64", true
-	case descriptorpb.FieldDescriptorProto_TYPE_INT32:
-		return "integer", "int32", true
-	case descriptorpb.FieldDescriptorProto_TYPE_FIXED64:
-		// Ditto.
-		return "integer", "uint64", true
-	case descriptorpb.FieldDescriptorProto_TYPE_FIXED32:
-		// Ditto.
-		return "integer", "int64", true
-	case descriptorpb.FieldDescriptorProto_TYPE_BOOL:
-		// NOTE: in OpenAPI specification, format should be empty on boolean type
-		return "boolean", "", true
-	case descriptorpb.FieldDescriptorProto_TYPE_STRING:
-		// NOTE: in OpenAPI specification, format should be empty on string type
-		return "string", "", true
-	case descriptorpb.FieldDescriptorProto_TYPE_BYTES:
-		return "string", "byte", true
-	case descriptorpb.FieldDescriptorProto_TYPE_UINT32:
-		// Ditto.
-		return "integer", "int64", true
-	case descriptorpb.FieldDescriptorProto_TYPE_SFIXED32:
-		return "integer", "int32", true
-	case descriptorpb.FieldDescriptorProto_TYPE_SFIXED64:
-		return "integer", "int64", true
-	case descriptorpb.FieldDescriptorProto_TYPE_SINT32:
-		return "integer", "int32", true
-	case descriptorpb.FieldDescriptorProto_TYPE_SINT64:
-		return "integer", "int64", true
-	default:
-		return "", "", false
-	}
-}
-
-// renderEnumerationsAsDefinition inserts enums into the definitions object.
-func renderEnumerationsAsDefinition(enums enumMap, d openapiDefinitionsObject, reg *descriptor.Registry) {
-	for _, enum := range enums {
-		swgName, ok := fullyQualifiedNameToOpenAPIName(enum.FQEN(), reg)
-		if !ok {
-			panic(fmt.Sprintf("can't resolve OpenAPI name from FQEN '%v'", enum.FQEN()))
-		}
-		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 := openapiSchemaObject{
-			schemaCore: schemaCore{
-				Type:    "string",
-				Enum:    enumNames,
-				Default: defaultValue,
-			},
-		}
-		if reg.GetEnumsAsInts() {
-			enumSchemaObject.Type = "integer"
-			enumSchemaObject.Format = "int32"
-			enumSchemaObject.Default = "0"
-			enumSchemaObject.Enum = listEnumNumbers(enum)
-		}
-		if err := updateOpenAPIDataFromComments(reg, &enumSchemaObject, enum, enumComments, false); err != nil {
-			panic(err)
-		}
-
-		d[swgName] = enumSchemaObject
-	}
-}
-
-// Take in a FQMN or FQEN and return a OpenAPI safe version of the FQMN and
-// a boolean indicating if FQMN was properly resolved.
-func fullyQualifiedNameToOpenAPIName(fqn string, reg *descriptor.Registry) (string, bool) {
-	registriesSeenMutex.Lock()
-	defer registriesSeenMutex.Unlock()
-	if mapping, present := registriesSeen[reg]; present {
-		ret, ok := mapping[fqn]
-		return ret, ok
-	}
-	mapping := resolveFullyQualifiedNameToOpenAPINames(append(reg.GetAllFQMNs(), reg.GetAllFQENs()...), reg.GetUseFQNForOpenAPIName())
-	registriesSeen[reg] = mapping
-	ret, ok := mapping[fqn]
-	return ret, ok
-}
-
-// Lookup message type by location.name and return a openapiv2-safe version
-// of its FQMN.
-func lookupMsgAndOpenAPIName(location, name string, reg *descriptor.Registry) (*descriptor.Message, string, error) {
-	msg, err := reg.LookupMsg(location, name)
-	if err != nil {
-		return nil, "", err
-	}
-	swgName, ok := fullyQualifiedNameToOpenAPIName(msg.FQMN(), reg)
-	if !ok {
-		return nil, "", fmt.Errorf("can't map OpenAPI name from FQMN '%v'", msg.FQMN())
-	}
-	return msg, swgName, nil
-}
-
-// registriesSeen is used to memoise calls to resolveFullyQualifiedNameToOpenAPINames 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 resolveFullyQualifiedNameToOpenAPINames(messages []string, useFQNForOpenAPIName 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 useFQNForOpenAPIName {
-			// 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_.]*).*}")
-
-// OpenAPI 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 templateToOpenAPIPath(path string, reg *descriptor.Registry, fields []*descriptor.Field, msgs []*descriptor.Message) 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)
-		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, fields, msgs))
-				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)
-		}
-	}
-
-	// 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 renderServiceTags(services []*descriptor.Service) []openapiTagObject {
-	var tags []openapiTagObject
-	for _, svc := range services {
-		tag := openapiTagObject{
-			Name: *svc.Name,
-		}
-		if proto.HasExtension(svc.Options, openapi_options.E_Openapiv2Tag) {
-			ext := proto.GetExtension(svc.Options, openapi_options.E_Openapiv2Tag)
-			opts, ok := ext.(*openapi_options.Tag)
-			if !ok {
-				glog.Errorf("extension is %T; want an OpenAPI Tag object", ext)
-				return nil
-			}
-
-			tag.Description = opts.Description
-			if opts.ExternalDocs != nil {
-				tag.ExternalDocs = &openapiExternalDocumentationObject{
-					Description: opts.ExternalDocs.Description,
-					URL:         opts.ExternalDocs.Url,
-				}
-			}
-		}
-		tags = append(tags, tag)
-	}
-	return tags
-}
-
-func renderServices(services []*descriptor.Service, paths openapiPathsObject, reg *descriptor.Registry, requestResponseRefs, customRefs refMap, msgs []*descriptor.Message) error {
-	// Correctness of svcIdx and methIdx depends on 'services' containing the services in the same order as the 'file.Service' array.
-	svcBaseIdx := 0
-	var lastFile *descriptor.File = nil
-	for svcIdx, svc := range services {
-		if svc.File != lastFile {
-			lastFile = svc.File
-			svcBaseIdx = svcIdx
-		}
-		for methIdx, meth := range svc.Methods {
-			for bIdx, b := range meth.Bindings {
-				// Iterate over all the OpenAPI parameters
-				parameters := openapiParametersObject{}
-				for _, parameter := range b.PathParams {
-
-					var paramType, paramFormat, desc, collectionFormat, defaultValue string
-					var enumNames []string
-					var items *openapiItemsObject
-					var minItems *int
-					switch pt := parameter.Target.GetType(); pt {
-					case descriptorpb.FieldDescriptorProto_TYPE_GROUP, descriptorpb.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 descriptorpb.FieldDescriptorProto_TYPE_ENUM:
-						enum, err := reg.LookupEnum("", parameter.Target.GetTypeName())
-						if err != nil {
-							return err
-						}
-						paramType = "string"
-						paramFormat = ""
-						enumNames = listEnumNames(enum)
-						if reg.GetEnumsAsInts() {
-							paramType = "integer"
-							paramFormat = ""
-							enumNames = listEnumNumbers(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 = (*openapiItemsObject)(&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, meth.RequestType.Fields, msgs)
-					}
-					parameters = append(parameters, openapiParameterObject{
-						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 openapiSchemaObject
-					desc := ""
-
-					if len(b.Body.FieldPath) == 0 {
-						schema = openapiSchemaObject{
-							schemaCore: schemaCore{},
-						}
-
-						wknSchemaCore, isWkn := wktSchemas[meth.RequestType.FQMN()]
-						if !isWkn {
-							var bodyExcludedFields []*descriptor.Field
-							if len(b.PathParams) != 0 {
-								for _, p := range b.PathParams {
-									// We only support excluding top-level fields captured by path parameters.
-									if len(p.FieldPath) == 1 {
-										bodyExcludedFields = append(bodyExcludedFields, p.FieldPath[0].Target)
-									}
-								}
-							}
-							if len(bodyExcludedFields) != 0 {
-								schema = renderMessageAsDefinition(meth.RequestType, reg, customRefs, bodyExcludedFields)
-								if schema.Properties == nil || len(*schema.Properties) == 0 {
-									glog.Errorf("created a body with 0 properties in the message, this might be unintended: %s", *meth.RequestType)
-								}
-							} else {
-								err := schema.setRefFromFQN(meth.RequestType.FQMN(), reg)
-								if err != nil {
-									return err
-								}
-							}
-						} 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 = &openapiSchemaObjectProperties{}
-							}
-						}
-					} 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, openapiParameterObject{
-						Name:        "body",
-						Description: desc,
-						In:          "body",
-						Required:    true,
-						Schema:      &schema,
-					})
-					// add the parameters to the query string
-					queryParams, err := messageToQueryParameters(meth.RequestType, reg, b.PathParams, b.Body)
-					if err != nil {
-						return err
-					}
-					parameters = append(parameters, queryParams...)
-				} else if b.HTTPMethod == "GET" || b.HTTPMethod == "DELETE" {
-					// add the parameters to the query string
-					queryParams, err := messageToQueryParameters(meth.RequestType, reg, b.PathParams, b.Body)
-					if err != nil {
-						return err
-					}
-					parameters = append(parameters, queryParams...)
-				}
-
-				pathItemObject, ok := paths[templateToOpenAPIPath(b.PathTmpl.Template, reg, meth.RequestType.Fields, msgs)]
-				if !ok {
-					pathItemObject = openapiPathItemObject{}
-				}
-
-				methProtoPath := protoPathIndex(reflect.TypeOf((*descriptorpb.ServiceDescriptorProto)(nil)), "Method")
-				desc := "A successful response."
-				var responseSchema openapiSchemaObject
-
-				if b.ResponseBody == nil || len(b.ResponseBody.FieldPath) == 0 {
-					responseSchema = openapiSchemaObject{
-						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 {
-						err := responseSchema.setRefFromFQN(meth.ResponseType.FQMN(), reg)
-						if err != nil {
-							return err
-						}
-					} 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 = &openapiSchemaObjectProperties{}
-						}
-					}
-				} 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)"
-					responseSchema.Type = "object"
-					swgRef, _ := fullyQualifiedNameToOpenAPIName(meth.ResponseType.FQMN(), reg)
-					responseSchema.Title = "Stream result of " + swgRef
-
-					props := openapiSchemaObjectProperties{
-						keyVal{
-							Key: "result",
-							Value: openapiSchemaObject{
-								schemaCore: schemaCore{
-									Ref: responseSchema.Ref,
-								},
-							},
-						},
-					}
-					statusDef, hasStatus := fullyQualifiedNameToOpenAPIName(".google.rpc.Status", reg)
-					if hasStatus {
-						props = append(props, keyVal{
-							Key: "error",
-							Value: openapiSchemaObject{
-								schemaCore: schemaCore{
-									Ref: fmt.Sprintf("#/definitions/%s", statusDef)},
-							},
-						})
-					}
-					responseSchema.Properties = &props
-					responseSchema.Ref = ""
-				}
-
-				tag := svc.GetName()
-				if pkg := svc.File.GetPackage(); pkg != "" && reg.IsIncludePackageInTags() {
-					tag = pkg + "." + tag
-				}
-
-				operationObject := &openapiOperationObject{
-					Tags:       []string{tag},
-					Parameters: parameters,
-					Responses: openapiResponsesObject{
-						"200": openapiResponseObject{
-							Description: desc,
-							Schema:      responseSchema,
-							Headers:     openapiHeadersObject{},
-						},
-					},
-				}
-				if !reg.GetDisableDefaultErrors() {
-					errDef, hasErrDef := fullyQualifiedNameToOpenAPIName(".google.rpc.Status", reg)
-					if hasErrDef {
-						// https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responses-object
-						operationObject.Responses["default"] = openapiResponseObject{
-							Description: "An unexpected error response.",
-							Schema: openapiSchemaObject{
-								schemaCore: schemaCore{
-									Ref: fmt.Sprintf("#/definitions/%s", errDef),
-								},
-							},
-						}
-					}
-				}
-				operationObject.OperationID = fmt.Sprintf("%s_%s", svc.GetName(), meth.GetName())
-				if reg.GetSimpleOperationIDs() {
-					operationObject.OperationID = meth.GetName()
-				}
-				if bIdx != 0 {
-					// OperationID must be unique in an OpenAPI v2 definition.
-					operationObject.OperationID += strconv.Itoa(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, "Service", int32(svcIdx-svcBaseIdx), methProtoPath, int32(methIdx))
-				if err := updateOpenAPIDataFromComments(reg, operationObject, meth, methComments, false); err != nil {
-					panic(err)
-				}
-
-				opts, err := getMethodOpenAPIOption(reg, meth)
-				if opts != nil {
-					if err != nil {
-						panic(err)
-					}
-					operationObject.ExternalDocs = protoExternalDocumentationToOpenAPIExternalDocumentation(opts.ExternalDocs, reg, meth)
-					// 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.OperationId != "" {
-						operationObject.OperationID = opts.OperationId
-					}
-					if opts.Security != nil {
-						newSecurity := []openapiSecurityRequirementObject{}
-						if operationObject.Security != nil {
-							newSecurity = *operationObject.Security
-						}
-						for _, secReq := range opts.Security {
-							newSecReq := openapiSecurityRequirementObject{}
-							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 {
-							// Merge response data into default response if available.
-							respObj := operationObject.Responses[name]
-							if resp.Description != "" {
-								respObj.Description = resp.Description
-							}
-							if resp.Schema != nil {
-								respObj.Schema = openapiSchemaFromProtoSchema(resp.Schema, reg, customRefs, meth)
-							}
-							if resp.Examples != nil {
-								respObj.Examples = openapiExamplesFromProtoExamples(resp.Examples)
-							}
-							if resp.Headers != nil {
-								hdrs, err := processHeaders(resp.Headers)
-								if err != nil {
-									return err
-								}
-								respObj.Headers = hdrs
-							}
-							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
-					}
-
-					if len(opts.Produces) > 0 {
-						operationObject.Produces = make([]string, len(opts.Produces))
-						copy(operationObject.Produces, opts.Produces)
-					}
-
-					// TODO(ivucica): add remaining fields of operation object
-				}
-
-				switch b.HTTPMethod {
-				case "DELETE":
-					pathItemObject.Delete = operationObject
-				case "GET":
-					pathItemObject.Get = operationObject
-				case "POST":
-					pathItemObject.Post = operationObject
-				case "PUT":
-					pathItemObject.Put = operationObject
-				case "PATCH":
-					pathItemObject.Patch = operationObject
-				}
-				paths[templateToOpenAPIPath(b.PathTmpl.Template, reg, meth.RequestType.Fields, msgs)] = 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) (*openapiSwaggerObject, error) {
-	// Create the basic template object. This is the object that everything is
-	// defined off of.
-	s := openapiSwaggerObject{
-		// OpenAPI 2.0 is the version of this document
-		Swagger:     "2.0",
-		Consumes:    []string{"application/json"},
-		Produces:    []string{"application/json"},
-		Paths:       make(openapiPathsObject),
-		Definitions: make(openapiDefinitionsObject),
-		Info: openapiInfoObject{
-			Title:   *p.File.Name,
-			Version: "version not set",
-		},
-		Schemes: []string{"HTTP", "HTTPS", "WS", "WSS"},
-	}
-
-	// 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, p.Messages); err != nil {
-		panic(err)
-	}
-	s.Tags = append(s.Tags, renderServiceTags(p.Services)...)
-
-	messages := messageMap{}
-	streamingMessages := messageMap{}
-	enums := enumMap{}
-
-	if !p.reg.GetDisableDefaultErrors() {
-		// Add the error type to the message map
-		runtimeError, swgRef, err := lookupMsgAndOpenAPIName("google.rpc", "Status", p.reg)
-		if err == nil {
-			messages[swgRef] = runtimeError
-		} else {
-			// just in case there is an error looking up runtimeError
-			glog.Error(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.
-	findServicesMessagesAndEnumerations(p.Services, p.reg, messages, streamingMessages, enums, requestResponseRefs)
-	renderMessagesAsDefinition(messages, s.Definitions, p.reg, customRefs, nil)
-	renderEnumerationsAsDefinition(enums, s.Definitions, p.reg)
-
-	// File itself might have some comments and metadata.
-	packageProtoPath := protoPathIndex(reflect.TypeOf((*descriptorpb.FileDescriptorProto)(nil)), "Package")
-	packageComments := protoComments(p.reg, p.File, nil, "Package", packageProtoPath)
-	if err := updateOpenAPIDataFromComments(p.reg, &s, p, packageComments, true); err != nil {
-		panic(err)
-	}
-
-	// There may be additional options in the OpenAPI option in the proto.
-	spb, err := getFileOpenAPIOption(p.reg, p.File)
-	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 = &openapiContactObject{}
-				}
-				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 = &openapiLicenseObject{}
-				}
-				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 = openapiSecurityDefinitionsObject{}
-			}
-			for secDefKey, secDefValue := range spb.SecurityDefinitions.Security {
-				var newSecDefValue openapiSecuritySchemeObject
-				if oldSecDefValue, ok := s.SecurityDefinitions[secDefKey]; !ok {
-					newSecDefValue = openapiSecuritySchemeObject{}
-				} else {
-					newSecDefValue = oldSecDefValue
-				}
-				if secDefValue.Type != openapi_options.SecurityScheme_TYPE_INVALID {
-					switch secDefValue.Type {
-					case openapi_options.SecurityScheme_TYPE_BASIC:
-						newSecDefValue.Type = "basic"
-					case openapi_options.SecurityScheme_TYPE_API_KEY:
-						newSecDefValue.Type = "apiKey"
-					case openapi_options.SecurityScheme_TYPE_OAUTH2:
-						newSecDefValue.Type = "oauth2"
-					}
-				}
-				if secDefValue.Description != "" {
-					newSecDefValue.Description = secDefValue.Description
-				}
-				if secDefValue.Name != "" {
-					newSecDefValue.Name = secDefValue.Name
-				}
-				if secDefValue.In != openapi_options.SecurityScheme_IN_INVALID {
-					switch secDefValue.In {
-					case openapi_options.SecurityScheme_IN_QUERY:
-						newSecDefValue.In = "query"
-					case openapi_options.SecurityScheme_IN_HEADER:
-						newSecDefValue.In = "header"
-					}
-				}
-				if secDefValue.Flow != openapi_options.SecurityScheme_FLOW_INVALID {
-					switch secDefValue.Flow {
-					case openapi_options.SecurityScheme_FLOW_IMPLICIT:
-						newSecDefValue.Flow = "implicit"
-					case openapi_options.SecurityScheme_FLOW_PASSWORD:
-						newSecDefValue.Flow = "password"
-					case openapi_options.SecurityScheme_FLOW_APPLICATION:
-						newSecDefValue.Flow = "application"
-					case openapi_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 = openapiScopesObject{}
-					}
-					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 {
-			var newSecurity []openapiSecurityRequirementObject
-			if s.Security != nil {
-				newSecurity = s.Security
-			}
-			for _, secReq := range spb.Security {
-				newSecReq := openapiSecurityRequirementObject{}
-				for secReqKey, secReqValue := range secReq.SecurityRequirement {
-					if secReqValue == nil {
-						return nil, fmt.Errorf("malformed security requirement spec for key %q; value is required", secReqKey)
-					}
-					newSecReqValue := make([]string, len(secReqValue.Scope))
-					copy(newSecReqValue, secReqValue.Scope)
-					newSecReq[secReqKey] = newSecReqValue
-				}
-				newSecurity = append(newSecurity, newSecReq)
-			}
-			s.Security = newSecurity
-		}
-		s.ExternalDocs = protoExternalDocumentationToOpenAPIExternalDocumentation(spb.ExternalDocs, p.reg, spb)
-		// 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 []openapiResponsesObject
-				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] = openapiResponseObject{
-							Description: v.Description,
-							Schema:      openapiSchemaFromProtoSchema(v.Schema, p.reg, customRefs, nil),
-							Examples:    openapiExamplesFromProtoExamples(v.Examples),
-						}
-					}
-				}
-			}
-		}
-
-		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 "OpenAPI" 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 := (&protojson.MarshalOptions{Indent: "  "}).Marshal(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
-}
-
-func validateHeaderTypeAndFormat(headerType string, format string) error {
-	// The type of the object. The value MUST be one of "string", "number", "integer", "boolean", or "array"
-	// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#headerObject
-	// Note: currently not implementing array as we are only implementing this in the operation response context
-	switch headerType {
-	// the format property is an open string-valued property, and can have any value to support documentation needs
-	// primary check for format is to ensure that the number/integer formats are extensions of the specified type
-	// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#dataTypeFormat
-	case "string":
-		return nil
-	case "number":
-		switch format {
-		case "uint",
-			"uint8",
-			"uint16",
-			"uint32",
-			"uint64",
-			"int",
-			"int8",
-			"int16",
-			"int32",
-			"int64",
-			"float",
-			"float32",
-			"float64",
-			"complex64",
-			"complex128",
-			"double",
-			"byte",
-			"rune",
-			"uintptr",
-			"":
-			return nil
-		default:
-			return fmt.Errorf("the provided format %q is not a valid extension of the type %q", format, headerType)
-		}
-	case "integer":
-		switch format {
-		case "uint",
-			"uint8",
-			"uint16",
-			"uint32",
-			"uint64",
-			"int",
-			"int8",
-			"int16",
-			"int32",
-			"int64",
-			"":
-			return nil
-		default:
-			return fmt.Errorf("the provided format %q is not a valid extension of the type %q", format, headerType)
-		}
-	case "boolean":
-		return nil
-	}
-	return fmt.Errorf("the provided header type %q is not supported", headerType)
-}
-
-func validateDefaultValueTypeAndFormat(headerType string, defaultValue string, format string) error {
-	switch headerType {
-	case "string":
-		if !isQuotedString(defaultValue) {
-			return fmt.Errorf("the provided default value %q does not match provider type %q, or is not properly quoted with escaped quotations", defaultValue, headerType)
-		}
-		switch format {
-		case "date-time":
-			unquoteTime := strings.Trim(defaultValue, `"`)
-			_, err := time.Parse(time.RFC3339, unquoteTime)
-			if err != nil {
-				return fmt.Errorf("the provided default value %q is not a valid RFC3339 date-time string", defaultValue)
-			}
-		case "date":
-			const (
-				layoutRFC3339Date = "2006-01-02"
-			)
-			unquoteDate := strings.Trim(defaultValue, `"`)
-			_, err := time.Parse(layoutRFC3339Date, unquoteDate)
-			if err != nil {
-				return fmt.Errorf("the provided default value %q is not a valid RFC3339 date-time string", defaultValue)
-			}
-		}
-	case "number":
-		err := isJSONNumber(defaultValue, headerType)
-		if err != nil {
-			return err
-		}
-	case "integer":
-		switch format {
-		case "int32":
-			_, err := strconv.ParseInt(defaultValue, 0, 32)
-			if err != nil {
-				return fmt.Errorf("the provided default value %q does not match provided format %q", defaultValue, format)
-			}
-		case "uint32":
-			_, err := strconv.ParseUint(defaultValue, 0, 32)
-			if err != nil {
-				return fmt.Errorf("the provided default value %q does not match provided format %q", defaultValue, format)
-			}
-		case "int64":
-			_, err := strconv.ParseInt(defaultValue, 0, 64)
-			if err != nil {
-				return fmt.Errorf("the provided default value %q does not match provided format %q", defaultValue, format)
-			}
-		case "uint64":
-			_, err := strconv.ParseUint(defaultValue, 0, 64)
-			if err != nil {
-				return fmt.Errorf("the provided default value %q does not match provided format %q", defaultValue, format)
-			}
-		default:
-			_, err := strconv.ParseInt(defaultValue, 0, 64)
-			if err != nil {
-				return fmt.Errorf("the provided default value %q does not match provided type %q", defaultValue, headerType)
-			}
-		}
-	case "boolean":
-		if !isBool(defaultValue) {
-			return fmt.Errorf("the provided default value %q does not match provider type %q", defaultValue, headerType)
-		}
-	}
-	return nil
-}
-
-func isQuotedString(s string) bool {
-	return len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"'
-}
-
-func isJSONNumber(s string, t string) error {
-	val, err := strconv.ParseFloat(s, 64)
-	if err != nil {
-		return fmt.Errorf("the provided default value %q does not match provider type %q", s, t)
-	}
-	// Floating point values that cannot be represented as sequences of digits (such as Infinity and NaN) are not permitted.
-	// See: https://tools.ietf.org/html/rfc4627#section-2.4
-	if math.IsInf(val, 0) || math.IsNaN(val) {
-		return fmt.Errorf("the provided number %q is not a valid JSON number", s)
-	}
-
-	return nil
-}
-
-func isBool(s string) bool {
-	// Unable to use strconv.ParseBool because it returns truthy values https://golang.org/pkg/strconv/#example_ParseBool
-	// per https://swagger.io/specification/v2/#data-types
-	// type: boolean represents two values: true and false. Note that truthy and falsy values such as "true", "", 0 or null are not considered boolean values.
-	return s == "true" || s == "false"
-}
-
-func processHeaders(inputHdrs map[string]*openapi_options.Header) (openapiHeadersObject, error) {
-	hdrs := map[string]openapiHeaderObject{}
-	for k, v := range inputHdrs {
-		header := textproto.CanonicalMIMEHeaderKey(k)
-		ret := openapiHeaderObject{
-			Description: v.Description,
-			Format:      v.Format,
-			Pattern:     v.Pattern,
-		}
-		err := validateHeaderTypeAndFormat(v.Type, v.Format)
-		if err != nil {
-			return nil, err
-		}
-		ret.Type = v.Type
-		if v.Default != "" {
-			err := validateDefaultValueTypeAndFormat(v.Type, v.Default, v.Format)
-			if err != nil {
-				return nil, err
-			}
-			ret.Default = json.RawMessage(v.Default)
-		}
-		hdrs[header] = ret
-	}
-	return hdrs, nil
-}
-
-// updateOpenAPIDataFromComments updates a OpenAPI 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 updateOpenAPIDataFromComments(reg *descriptor.Registry, swaggerObject interface{}, data interface{}, comment string, isPackageObject bool) error {
-	if len(comment) == 0 {
-		return nil
-	}
-
-	// Checks whether the "use_go_templates" flag is set to true
-	if reg.GetUseGoTemplate() {
-		comment = goTemplateComments(comment, data, reg)
-	}
-
-	// 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 OpenAPI 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((*descriptorpb.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((*descriptorpb.EnumDescriptorProto)(nil)), "Value")
-	var comments []string
-	for idx, value := range enum.GetValue() {
-		name := value.GetName()
-		if reg.GetEnumsAsInts() {
-			name = strconv.Itoa(int(value.GetNumber()))
-		}
-		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 ""
-}
-
-func goTemplateComments(comment string, data interface{}, reg *descriptor.Registry) string {
-	var temp bytes.Buffer
-	tpl, err := template.New("").Funcs(template.FuncMap{
-		// Allows importing documentation from a file
-		"import": func(name string) string {
-			file, err := ioutil.ReadFile(name)
-			if err != nil {
-				return err.Error()
-			}
-			// Runs template over imported file
-			return goTemplateComments(string(file), data, reg)
-		},
-		// Grabs title and description from a field
-		"fieldcomments": func(msg *descriptor.Message, field *descriptor.Field) string {
-			return strings.Replace(fieldProtoComments(reg, msg, field), "\n", "<br>", -1)
-		},
-	}).Parse(comment)
-	if err != nil {
-		// If there is an error parsing the templating insert the error as string in the comment
-		// to make it easier to debug the template error
-		return err.Error()
-	}
-	err = tpl.Execute(&temp, data)
-	if err != nil {
-		// If there is an error executing the templating insert the error as string in the comment
-		// to make it easier to debug the error
-		return err.Error()
-	}
-	return temp.String()
-}
-
-var messageProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.FileDescriptorProto)(nil)), "MessageType")
-var nestedProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.DescriptorProto)(nil)), "NestedType")
-var packageProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.FileDescriptorProto)(nil)), "Package")
-var serviceProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.FileDescriptorProto)(nil)), "Service")
-var methodProtoPath = protoPathIndex(reflect.TypeOf((*descriptorpb.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((*descriptorpb.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((*descriptorpb.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
-// openapi_options.Operation from a given proto method's descriptor.
-func extractOperationOptionFromMethodDescriptor(meth *descriptorpb.MethodDescriptorProto) (*openapi_options.Operation, error) {
-	if meth.Options == nil {
-		return nil, nil
-	}
-	if !proto.HasExtension(meth.Options, openapi_options.E_Openapiv2Operation) {
-		return nil, nil
-	}
-	ext := proto.GetExtension(meth.Options, openapi_options.E_Openapiv2Operation)
-	opts, ok := ext.(*openapi_options.Operation)
-	if !ok {
-		return nil, fmt.Errorf("extension is %T; want an Operation", ext)
-	}
-	return opts, nil
-}
-
-// extractSchemaOptionFromMessageDescriptor extracts the message of type
-// openapi_options.Schema from a given proto message's descriptor.
-func extractSchemaOptionFromMessageDescriptor(msg *descriptorpb.DescriptorProto) (*openapi_options.Schema, error) {
-	if msg.Options == nil {
-		return nil, nil
-	}
-	if !proto.HasExtension(msg.Options, openapi_options.E_Openapiv2Schema) {
-		return nil, nil
-	}
-	ext := proto.GetExtension(msg.Options, openapi_options.E_Openapiv2Schema)
-	opts, ok := ext.(*openapi_options.Schema)
-	if !ok {
-		return nil, fmt.Errorf("extension is %T; want a Schema", ext)
-	}
-	return opts, nil
-}
-
-// extractOpenAPIOptionFromFileDescriptor extracts the message of type
-// openapi_options.OpenAPI from a given proto method's descriptor.
-func extractOpenAPIOptionFromFileDescriptor(file *descriptorpb.FileDescriptorProto) (*openapi_options.Swagger, error) {
-	if file.Options == nil {
-		return nil, nil
-	}
-	if !proto.HasExtension(file.Options, openapi_options.E_Openapiv2Swagger) {
-		return nil, nil
-	}
-	ext := proto.GetExtension(file.Options, openapi_options.E_Openapiv2Swagger)
-	opts, ok := ext.(*openapi_options.Swagger)
-	if !ok {
-		return nil, fmt.Errorf("extension is %T; want a OpenAPI object", ext)
-	}
-	return opts, nil
-}
-
-func extractJSONSchemaFromFieldDescriptor(fd *descriptorpb.FieldDescriptorProto) (*openapi_options.JSONSchema, error) {
-	if fd.Options == nil {
-		return nil, nil
-	}
-	if !proto.HasExtension(fd.Options, openapi_options.E_Openapiv2Field) {
-		return nil, nil
-	}
-	ext := proto.GetExtension(fd.Options, openapi_options.E_Openapiv2Field)
-	opts, ok := ext.(*openapi_options.JSONSchema)
-	if !ok {
-		return nil, fmt.Errorf("extension is %T; want a JSONSchema object", ext)
-	}
-	return opts, nil
-}
-
-func extractFieldBehaviorFromFieldDescriptor(fd *descriptorpb.FieldDescriptorProto) ([]annotations.FieldBehavior, error) {
-	if fd.Options == nil {
-		return nil, nil
-	}
-	if !proto.HasExtension(fd.Options, annotations.E_FieldBehavior) {
-		return nil, nil
-	}
-	ext := proto.GetExtension(fd.Options, annotations.E_FieldBehavior)
-	opts, ok := ext.([]annotations.FieldBehavior)
-	if !ok {
-		return nil, fmt.Errorf("extension is %T; want a []FieldBehavior object", ext)
-	}
-	return opts, nil
-}
-
-func getMethodOpenAPIOption(reg *descriptor.Registry, meth *descriptor.Method) (*openapi_options.Operation, error) {
-	opts, err := extractOperationOptionFromMethodDescriptor(meth.MethodDescriptorProto)
-	if err != nil {
-		return nil, err
-	}
-	if opts != nil {
-		return opts, nil
-	}
-	opts, ok := reg.GetOpenAPIMethodOption(meth.FQMN())
-	if !ok {
-		return nil, nil
-	}
-	return opts, nil
-}
-
-func getMessageOpenAPIOption(reg *descriptor.Registry, msg *descriptor.Message) (*openapi_options.Schema, error) {
-	opts, err := extractSchemaOptionFromMessageDescriptor(msg.DescriptorProto)
-	if err != nil {
-		return nil, err
-	}
-	if opts != nil {
-		return opts, nil
-	}
-	opts, ok := reg.GetOpenAPIMessageOption(msg.FQMN())
-	if !ok {
-		return nil, nil
-	}
-	return opts, nil
-}
-
-func getFileOpenAPIOption(reg *descriptor.Registry, file *descriptor.File) (*openapi_options.Swagger, error) {
-	opts, err := extractOpenAPIOptionFromFileDescriptor(file.FileDescriptorProto)
-	if err != nil {
-		return nil, err
-	}
-	if opts != nil {
-		return opts, nil
-	}
-	opts, ok := reg.GetOpenAPIFileOption(*file.Name)
-	if !ok {
-		return nil, nil
-	}
-	return opts, nil
-}
-
-func getFieldOpenAPIOption(reg *descriptor.Registry, fd *descriptor.Field) (*openapi_options.JSONSchema, error) {
-	opts, err := extractJSONSchemaFromFieldDescriptor(fd.FieldDescriptorProto)
-	if err != nil {
-		return nil, err
-	}
-	if opts != nil {
-		return opts, nil
-	}
-	opts, ok := reg.GetOpenAPIFieldOption(fd.FQFN())
-	if !ok {
-		return nil, nil
-	}
-	return opts, nil
-}
-
-func getFieldBehaviorOption(reg *descriptor.Registry, fd *descriptor.Field) ([]annotations.FieldBehavior, error) {
-	opts, err := extractFieldBehaviorFromFieldDescriptor(fd.FieldDescriptorProto)
-	if err != nil {
-		return nil, err
-	}
-	if opts != nil {
-		return opts, nil
-	}
-	return opts, nil
-}
-
-func protoJSONSchemaToOpenAPISchemaCore(j *openapi_options.JSONSchema, reg *descriptor.Registry, refs refMap) schemaCore {
-	ret := schemaCore{}
-
-	if j.GetRef() != "" {
-		openapiName, ok := fullyQualifiedNameToOpenAPIName(j.GetRef(), reg)
-		if ok {
-			ret.Ref = "#/definitions/" + openapiName
-			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 *openapiSchemaObject, j *openapi_options.JSONSchema, reg *descriptor.Registry, data interface{}) {
-	s.Title = j.GetTitle()
-	s.Description = j.GetDescription()
-	if reg.GetUseGoTemplate() {
-		s.Title = goTemplateComments(s.Title, data, reg)
-		s.Description = goTemplateComments(s.Description, data, reg)
-	}
-
-	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()
-	s.Enum = j.GetEnum()
-	if overrideType := j.GetType(); len(overrideType) > 0 {
-		s.Type = strings.ToLower(overrideType[0].String())
-	}
-	if j != nil && j.GetExample() != "" {
-		s.Example = json.RawMessage(j.GetExample())
-	}
-	if j != nil && j.GetFormat() != "" {
-		s.Format = j.GetFormat()
-	}
-}
-
-func updateSwaggerObjectFromFieldBehavior(s *openapiSchemaObject, j []annotations.FieldBehavior, field *descriptor.Field) {
-	// Per the JSON Reference syntax: Any members other than "$ref" in a JSON Reference object SHALL be ignored.
-	// https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03#section-3
-	if s.Ref != "" {
-		return
-	}
-
-	for _, fb := range j {
-		switch fb {
-		case annotations.FieldBehavior_REQUIRED:
-			s.Required = append(s.Required, *field.Name)
-		case annotations.FieldBehavior_OUTPUT_ONLY:
-			s.ReadOnly = true
-		case annotations.FieldBehavior_FIELD_BEHAVIOR_UNSPECIFIED:
-		case annotations.FieldBehavior_OPTIONAL:
-		case annotations.FieldBehavior_INPUT_ONLY:
-			// OpenAPI v3 supports a writeOnly property, but this is not supported in Open API v2
-		case annotations.FieldBehavior_IMMUTABLE:
-		}
-	}
-}
-
-func openapiSchemaFromProtoSchema(s *openapi_options.Schema, reg *descriptor.Registry, refs refMap, data interface{}) openapiSchemaObject {
-	ret := openapiSchemaObject{
-		ExternalDocs: protoExternalDocumentationToOpenAPIExternalDocumentation(s.GetExternalDocs(), reg, data),
-	}
-
-	ret.schemaCore = protoJSONSchemaToOpenAPISchemaCore(s.GetJsonSchema(), reg, refs)
-	updateswaggerObjectFromJSONSchema(&ret, s.GetJsonSchema(), reg, data)
-
-	if s != nil && s.Example != "" {
-		ret.Example = json.RawMessage(s.Example)
-	}
-
-	return ret
-}
-
-func openapiExamplesFromProtoExamples(in map[string]string) map[string]interface{} {
-	if len(in) == 0 {
-		return nil
-	}
-	out := make(map[string]interface{})
-	for mimeType, exampleStr := range in {
-		switch mimeType {
-		case "application/json":
-			// JSON example objects are rendered raw.
-			out[mimeType] = json.RawMessage(exampleStr)
-		default:
-			// All other mimetype examples are rendered as strings.
-			out[mimeType] = exampleStr
-		}
-	}
-	return out
-}
-
-func protoJSONSchemaTypeToFormat(in []openapi_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 openapi_options.JSONSchema_UNKNOWN, openapi_options.JSONSchema_NULL:
-		return "", ""
-	case openapi_options.JSONSchema_OBJECT:
-		return "object", ""
-	case openapi_options.JSONSchema_ARRAY:
-		return "array", ""
-	case openapi_options.JSONSchema_BOOLEAN:
-		// NOTE: in OpenAPI specification, format should be empty on boolean type
-		return "boolean", ""
-	case openapi_options.JSONSchema_INTEGER:
-		return "integer", "int32"
-	case openapi_options.JSONSchema_NUMBER:
-		return "number", "double"
-	case openapi_options.JSONSchema_STRING:
-		// NOTE: in OpenAPI specification, format should be empty on string type
-		return "string", ""
-	default:
-		// Maybe panic?
-		return "", ""
-	}
-}
-
-func protoExternalDocumentationToOpenAPIExternalDocumentation(in *openapi_options.ExternalDocumentation, reg *descriptor.Registry, data interface{}) *openapiExternalDocumentationObject {
-	if in == nil {
-		return nil
-	}
-
-	if reg.GetUseGoTemplate() {
-		in.Description = goTemplateComments(in.Description, data, reg)
-	}
-
-	return &openapiExternalDocumentationObject{
-		Description: in.Description,
-		URL:         in.Url,
-	}
-}
-
-func addCustomRefs(d openapiDefinitionsObject, reg *descriptor.Registry, refs refMap) {
-	if len(refs) == 0 {
-		return
-	}
-	msgMap := make(messageMap)
-	enumMap := make(enumMap)
-	for ref := range refs {
-		swgName, swgOk := fullyQualifiedNameToOpenAPIName(ref, reg)
-		if !swgOk {
-			glog.Errorf("can't resolve OpenAPI name from CustomRef '%v'", ref)
-			continue
-		}
-		if _, ok := d[swgName]; ok {
-			// Skip already existing definitions
-			delete(refs, ref)
-			continue
-		}
-		msg, err := reg.LookupMsg("", ref)
-		if err == nil {
-			msgMap[swgName] = msg
-			continue
-		}
-		enum, err := reg.LookupEnum("", ref)
-		if err == nil {
-			enumMap[swgName] = enum
-			continue
-		}
-
-		// ?? Should be either enum or msg
-	}
-	renderMessagesAsDefinition(msgMap, d, reg, refs, nil)
-	renderEnumerationsAsDefinition(enumMap, d, reg)
-
-	// Run again in case any new refs were added
-	addCustomRefs(d, reg, refs)
-}
-
-func lowerCamelCase(fieldName string, fields []*descriptor.Field, msgs []*descriptor.Message) string {
-	for _, oneField := range fields {
-		if oneField.GetName() == fieldName {
-			return oneField.GetJsonName()
-		}
-	}
-	messageNameToFieldsToJSONName := make(map[string]map[string]string)
-	fieldNameToType := make(map[string]string)
-	for _, msg := range msgs {
-		fieldNameToJSONName := make(map[string]string)
-		for _, oneField := range msg.GetField() {
-			fieldNameToJSONName[oneField.GetName()] = oneField.GetJsonName()
-			fieldNameToType[oneField.GetName()] = oneField.GetTypeName()
-		}
-		messageNameToFieldsToJSONName[msg.GetName()] = fieldNameToJSONName
-	}
-	if strings.Contains(fieldName, ".") {
-		fieldNames := strings.Split(fieldName, ".")
-		fieldNamesWithCamelCase := make([]string, 0)
-		for i := 0; i < len(fieldNames)-1; i++ {
-			fieldNamesWithCamelCase = append(fieldNamesWithCamelCase, doCamelCase(string(fieldNames[i])))
-		}
-		prefix := strings.Join(fieldNamesWithCamelCase, ".")
-		reservedJSONName := getReservedJSONName(fieldName, messageNameToFieldsToJSONName, fieldNameToType)
-		if reservedJSONName != "" {
-			return prefix + "." + reservedJSONName
-		}
-	}
-	return doCamelCase(fieldName)
-}
-
-func doCamelCase(input string) string {
-	parameterString := casing.Camel(input)
-	builder := &strings.Builder{}
-	builder.WriteString(strings.ToLower(string(parameterString[0])))
-	builder.WriteString(parameterString[1:])
-	return builder.String()
-}
-
-func getReservedJSONName(fieldName string, messageNameToFieldsToJSONName map[string]map[string]string, fieldNameToType map[string]string) string {
-	if len(strings.Split(fieldName, ".")) == 2 {
-		fieldNames := strings.Split(fieldName, ".")
-		firstVariable := fieldNames[0]
-		firstType := fieldNameToType[firstVariable]
-		firstTypeShortNames := strings.Split(firstType, ".")
-		firstTypeShortName := firstTypeShortNames[len(firstTypeShortNames)-1]
-		return messageNameToFieldsToJSONName[firstTypeShortName][fieldNames[1]]
-	}
-	fieldNames := strings.Split(fieldName, ".")
-	return getReservedJSONName(strings.Join(fieldNames[1:], "."), messageNameToFieldsToJSONName, fieldNameToType)
-}
-
-func find(a []string, x string) int {
-	// This is a linear search but we are dealing with a small number of fields
-	for i, n := range a {
-		if x == n {
-			return i
-		}
-	}
-	return -1
-}

+ 0 - 4635
protoc-gen-openapiv2/internal/genopenapi/template_test.go

@@ -1,4635 +0,0 @@
-package genopenapi
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"math"
-	"reflect"
-	"strings"
-	"testing"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor"
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor/openapiconfig"
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/httprule"
-	"github.com/google/go-cmp/cmp"
-	openapi_options "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
-	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
-	"google.golang.org/genproto/googleapis/api/annotations"
-	"google.golang.org/genproto/protobuf/field_mask"
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/reflect/protodesc"
-	"google.golang.org/protobuf/types/descriptorpb"
-	"google.golang.org/protobuf/types/known/durationpb"
-	"google.golang.org/protobuf/types/known/structpb"
-	"google.golang.org/protobuf/types/known/timestamppb"
-	"google.golang.org/protobuf/types/known/wrapperspb"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-var marshaler = &runtime.JSONPb{}
-
-func crossLinkFixture(f *descriptor.File) *descriptor.File {
-	for _, m := range f.Messages {
-		m.File = f
-	}
-	for _, svc := range f.Services {
-		svc.File = f
-		for _, m := range svc.Methods {
-			m.Service = svc
-			for _, b := range m.Bindings {
-				b.Method = m
-				for _, param := range b.PathParams {
-					param.Method = m
-				}
-			}
-		}
-	}
-	return f
-}
-
-func reqFromFile(f *descriptor.File) *pluginpb.CodeGeneratorRequest {
-	return &pluginpb.CodeGeneratorRequest{
-		ProtoFile: []*descriptorpb.FileDescriptorProto{
-			f.FileDescriptorProto,
-		},
-		FileToGenerate: []string{f.GetName()},
-	}
-}
-
-func TestMessageToQueryParametersWithEnumAsInt(t *testing.T) {
-	type test struct {
-		MsgDescs []*descriptorpb.DescriptorProto
-		Message  string
-		Params   []openapiParameterObject
-	}
-
-	tests := []test{
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("ExampleMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:   proto.String("a"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number: proto.Int32(1),
-						},
-						{
-							Name:   proto.String("b"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_DOUBLE.Enum(),
-							Number: proto.Int32(2),
-						},
-						{
-							Name:   proto.String("c"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Label:  descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
-							Number: proto.Int32(3),
-						},
-					},
-				},
-			},
-			Message: "ExampleMessage",
-			Params: []openapiParameterObject{
-				{
-					Name:     "a",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-				},
-				{
-					Name:     "b",
-					In:       "query",
-					Required: false,
-					Type:     "number",
-					Format:   "double",
-				},
-				{
-					Name:             "c",
-					In:               "query",
-					Required:         false,
-					Type:             "array",
-					CollectionFormat: "multi",
-				},
-			},
-		},
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("ExampleMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("nested"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.Nested"),
-							Number:   proto.Int32(1),
-						},
-					},
-				},
-				{
-					Name: proto.String("Nested"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:   proto.String("a"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number: proto.Int32(1),
-						},
-						{
-							Name:     proto.String("deep"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.Nested.DeepNested"),
-							Number:   proto.Int32(2),
-						},
-					},
-					NestedType: []*descriptorpb.DescriptorProto{{
-						Name: proto.String("DeepNested"),
-						Field: []*descriptorpb.FieldDescriptorProto{
-							{
-								Name:   proto.String("b"),
-								Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-								Number: proto.Int32(1),
-							},
-							{
-								Name:     proto.String("c"),
-								Type:     descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
-								TypeName: proto.String(".example.Nested.DeepNested.DeepEnum"),
-								Number:   proto.Int32(2),
-							},
-						},
-						EnumType: []*descriptorpb.EnumDescriptorProto{
-							{
-								Name: proto.String("DeepEnum"),
-								Value: []*descriptorpb.EnumValueDescriptorProto{
-									{Name: proto.String("FALSE"), Number: proto.Int32(0)},
-									{Name: proto.String("TRUE"), Number: proto.Int32(1)},
-								},
-							},
-						},
-					}},
-				},
-			},
-			Message: "ExampleMessage",
-			Params: []openapiParameterObject{
-				{
-					Name:     "nested.a",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-				},
-				{
-					Name:     "nested.deep.b",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-				},
-				{
-					Name:     "nested.deep.c",
-					In:       "query",
-					Required: false,
-					Type:     "integer",
-					Enum:     []string{"0", "1"},
-					Default:  "0",
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		reg := descriptor.NewRegistry()
-		reg.SetEnumsAsInts(true)
-		msgs := []*descriptor.Message{}
-		for _, msgdesc := range test.MsgDescs {
-			msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
-		}
-		file := descriptor.File{
-			FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-				SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-				Name:           proto.String("example.proto"),
-				Package:        proto.String("example"),
-				Dependency:     []string{},
-				MessageType:    test.MsgDescs,
-				Service:        []*descriptorpb.ServiceDescriptorProto{},
-				Options: &descriptorpb.FileOptions{
-					GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-				},
-			},
-			GoPkg: descriptor.GoPackage{
-				Path: "example.com/path/to/example/example.pb",
-				Name: "example_pb",
-			},
-			Messages: msgs,
-		}
-		err := reg.Load(&pluginpb.CodeGeneratorRequest{
-			ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-		})
-		if err != nil {
-			t.Fatalf("failed to load code generator request: %v", err)
-		}
-
-		message, err := reg.LookupMsg("", ".example."+test.Message)
-		if err != nil {
-			t.Fatalf("failed to lookup message: %s", err)
-		}
-		params, err := messageToQueryParameters(message, reg, []descriptor.Parameter{}, nil)
-		if err != nil {
-			t.Fatalf("failed to convert message to query parameters: %s", err)
-		}
-		// avoid checking Items for array types
-		for i := range params {
-			params[i].Items = nil
-		}
-		if !reflect.DeepEqual(params, test.Params) {
-			t.Errorf("expected %v, got %v", test.Params, params)
-		}
-	}
-}
-
-func TestMessageToQueryParameters(t *testing.T) {
-	type test struct {
-		MsgDescs []*descriptorpb.DescriptorProto
-		Message  string
-		Params   []openapiParameterObject
-	}
-
-	tests := []test{
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("ExampleMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:   proto.String("a"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number: proto.Int32(1),
-						},
-						{
-							Name:   proto.String("b"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_DOUBLE.Enum(),
-							Number: proto.Int32(2),
-						},
-						{
-							Name:   proto.String("c"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Label:  descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
-							Number: proto.Int32(3),
-						},
-					},
-				},
-			},
-			Message: "ExampleMessage",
-			Params: []openapiParameterObject{
-				{
-					Name:     "a",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-				},
-				{
-					Name:     "b",
-					In:       "query",
-					Required: false,
-					Type:     "number",
-					Format:   "double",
-				},
-				{
-					Name:             "c",
-					In:               "query",
-					Required:         false,
-					Type:             "array",
-					CollectionFormat: "multi",
-				},
-			},
-		},
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("ExampleMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("nested"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.Nested"),
-							Number:   proto.Int32(1),
-						},
-					},
-				},
-				{
-					Name: proto.String("Nested"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:   proto.String("a"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number: proto.Int32(1),
-						},
-						{
-							Name:     proto.String("deep"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.Nested.DeepNested"),
-							Number:   proto.Int32(2),
-						},
-					},
-					NestedType: []*descriptorpb.DescriptorProto{{
-						Name: proto.String("DeepNested"),
-						Field: []*descriptorpb.FieldDescriptorProto{
-							{
-								Name:   proto.String("b"),
-								Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-								Number: proto.Int32(1),
-							},
-							{
-								Name:     proto.String("c"),
-								Type:     descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
-								TypeName: proto.String(".example.Nested.DeepNested.DeepEnum"),
-								Number:   proto.Int32(2),
-							},
-						},
-						EnumType: []*descriptorpb.EnumDescriptorProto{
-							{
-								Name: proto.String("DeepEnum"),
-								Value: []*descriptorpb.EnumValueDescriptorProto{
-									{Name: proto.String("FALSE"), Number: proto.Int32(0)},
-									{Name: proto.String("TRUE"), Number: proto.Int32(1)},
-								},
-							},
-						},
-					}},
-				},
-			},
-			Message: "ExampleMessage",
-			Params: []openapiParameterObject{
-				{
-					Name:     "nested.a",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-				},
-				{
-					Name:     "nested.deep.b",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-				},
-				{
-					Name:     "nested.deep.c",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-					Enum:     []string{"FALSE", "TRUE"},
-					Default:  "FALSE",
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		reg := descriptor.NewRegistry()
-		msgs := []*descriptor.Message{}
-		for _, msgdesc := range test.MsgDescs {
-			msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
-		}
-		file := descriptor.File{
-			FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-				SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-				Name:           proto.String("example.proto"),
-				Package:        proto.String("example"),
-				Dependency:     []string{},
-				MessageType:    test.MsgDescs,
-				Service:        []*descriptorpb.ServiceDescriptorProto{},
-				Options: &descriptorpb.FileOptions{
-					GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-				},
-			},
-			GoPkg: descriptor.GoPackage{
-				Path: "example.com/path/to/example/example.pb",
-				Name: "example_pb",
-			},
-			Messages: msgs,
-		}
-		err := reg.Load(&pluginpb.CodeGeneratorRequest{
-			ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-		})
-		if err != nil {
-			t.Fatalf("failed to load code generator request: %v", err)
-		}
-
-		message, err := reg.LookupMsg("", ".example."+test.Message)
-		if err != nil {
-			t.Fatalf("failed to lookup message: %s", err)
-		}
-		params, err := messageToQueryParameters(message, reg, []descriptor.Parameter{}, nil)
-		if err != nil {
-			t.Fatalf("failed to convert message to query parameters: %s", err)
-		}
-		// avoid checking Items for array types
-		for i := range params {
-			params[i].Items = nil
-		}
-		if !reflect.DeepEqual(params, test.Params) {
-			t.Errorf("expected %v, got %v", test.Params, params)
-		}
-	}
-}
-
-// TestMessagetoQueryParametersNoRecursive, is a check that cyclical references between messages
-//
-//	are not falsely detected given previous known edge-cases.
-func TestMessageToQueryParametersNoRecursive(t *testing.T) {
-	type test struct {
-		MsgDescs []*descriptorpb.DescriptorProto
-		Message  string
-	}
-
-	tests := []test{
-		// First test:
-		// Here is a message that has two of another message adjacent to one another in a nested message.
-		// There is no loop but this was previouly falsely flagged as a cycle.
-		// Example proto:
-		// message NonRecursiveMessage {
-		//      string field = 1;
-		// }
-		// message BaseMessage {
-		//      NonRecursiveMessage first = 1;
-		//      NonRecursiveMessage second = 2;
-		// }
-		// message QueryMessage {
-		//      BaseMessage first = 1;
-		//      string second = 2;
-		// }
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("QueryMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("first"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.BaseMessage"),
-							Number:   proto.Int32(1),
-						},
-						{
-							Name:   proto.String("second"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number: proto.Int32(2),
-						},
-					},
-				},
-				{
-					Name: proto.String("BaseMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("first"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.NonRecursiveMessage"),
-							Number:   proto.Int32(1),
-						},
-						{
-							Name:     proto.String("second"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.NonRecursiveMessage"),
-							Number:   proto.Int32(2),
-						},
-					},
-				},
-				// Note there is no recursive nature to this message
-				{
-					Name: proto.String("NonRecursiveMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name: proto.String("field"),
-							//Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number: proto.Int32(1),
-						},
-					},
-				},
-			},
-			Message: "QueryMessage",
-		},
-	}
-
-	for _, test := range tests {
-		reg := descriptor.NewRegistry()
-		msgs := []*descriptor.Message{}
-		for _, msgdesc := range test.MsgDescs {
-			msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
-		}
-		file := descriptor.File{
-			FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-				SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-				Name:           proto.String("example.proto"),
-				Package:        proto.String("example"),
-				Dependency:     []string{},
-				MessageType:    test.MsgDescs,
-				Service:        []*descriptorpb.ServiceDescriptorProto{},
-				Options: &descriptorpb.FileOptions{
-					GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-				},
-			},
-			GoPkg: descriptor.GoPackage{
-				Path: "example.com/path/to/example/example.pb",
-				Name: "example_pb",
-			},
-			Messages: msgs,
-		}
-		err := reg.Load(&pluginpb.CodeGeneratorRequest{
-			ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-		})
-		if err != nil {
-			t.Fatalf("failed to load code generator request: %v", err)
-		}
-
-		message, err := reg.LookupMsg("", ".example."+test.Message)
-		if err != nil {
-			t.Fatalf("failed to lookup message: %s", err)
-		}
-
-		_, err = messageToQueryParameters(message, reg, []descriptor.Parameter{}, nil)
-		if err != nil {
-			t.Fatalf("No recursion error should be thrown: %s", err)
-		}
-	}
-}
-
-// TestMessagetoQueryParametersRecursive, is a check that cyclical references between messages
-//
-//	are handled gracefully. The goal is to insure that attempts to add messages with cyclical
-//	references to query-parameters returns an error message.
-func TestMessageToQueryParametersRecursive(t *testing.T) {
-	type test struct {
-		MsgDescs []*descriptorpb.DescriptorProto
-		Message  string
-	}
-
-	tests := []test{
-		// First test:
-		// Here we test that a message that references it self through a field will return an error.
-		// Example proto:
-		// message DirectRecursiveMessage {
-		//      DirectRecursiveMessage nested = 1;
-		// }
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("DirectRecursiveMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("nested"),
-							Label:    descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.DirectRecursiveMessage"),
-							Number:   proto.Int32(1),
-						},
-					},
-				},
-			},
-			Message: "DirectRecursiveMessage",
-		},
-		// Second test:
-		// Here we test that a cycle through multiple messages is detected and that an error is returned.
-		// Sample:
-		// message Root { NodeMessage nested = 1; }
-		// message NodeMessage { CycleMessage nested = 1; }
-		// message CycleMessage { Root nested = 1; }
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("RootMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("nested"),
-							Label:    descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.NodeMessage"),
-							Number:   proto.Int32(1),
-						},
-					},
-				},
-				{
-					Name: proto.String("NodeMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("nested"),
-							Label:    descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.CycleMessage"),
-							Number:   proto.Int32(1),
-						},
-					},
-				},
-				{
-					Name: proto.String("CycleMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("nested"),
-							Label:    descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.RootMessage"),
-							Number:   proto.Int32(1),
-						},
-					},
-				},
-			},
-			Message: "RootMessage",
-		},
-	}
-
-	for _, test := range tests {
-		reg := descriptor.NewRegistry()
-		msgs := []*descriptor.Message{}
-		for _, msgdesc := range test.MsgDescs {
-			msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
-		}
-		file := descriptor.File{
-			FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-				SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-				Name:           proto.String("example.proto"),
-				Package:        proto.String("example"),
-				Dependency:     []string{},
-				MessageType:    test.MsgDescs,
-				Service:        []*descriptorpb.ServiceDescriptorProto{},
-				Options: &descriptorpb.FileOptions{
-					GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-				},
-			},
-			GoPkg: descriptor.GoPackage{
-				Path: "example.com/path/to/example/example.pb",
-				Name: "example_pb",
-			},
-			Messages: msgs,
-		}
-		err := reg.Load(&pluginpb.CodeGeneratorRequest{
-			ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-		})
-		if err != nil {
-			t.Fatalf("failed to load code generator request: %v", err)
-		}
-
-		message, err := reg.LookupMsg("", ".example."+test.Message)
-		if err != nil {
-			t.Fatalf("failed to lookup message: %s", err)
-		}
-		_, err = messageToQueryParameters(message, reg, []descriptor.Parameter{}, nil)
-		if err == nil {
-			t.Fatalf("It should not be allowed to have recursive query parameters")
-		}
-	}
-}
-
-func TestMessageToQueryParametersWithJsonName(t *testing.T) {
-	type test struct {
-		MsgDescs []*descriptorpb.DescriptorProto
-		Message  string
-		Params   []openapiParameterObject
-	}
-
-	tests := []test{
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("ExampleMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("test_field_a"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number:   proto.Int32(1),
-							JsonName: proto.String("testFieldA"),
-						},
-					},
-				},
-			},
-			Message: "ExampleMessage",
-			Params: []openapiParameterObject{
-				{
-					Name:     "testFieldA",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-				},
-			},
-		},
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("SubMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("test_field_a"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number:   proto.Int32(1),
-							JsonName: proto.String("testFieldA"),
-						},
-					},
-				},
-				{
-					Name: proto.String("ExampleMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("sub_message"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".example.SubMessage"),
-							Number:   proto.Int32(1),
-							JsonName: proto.String("subMessage"),
-						},
-					},
-				},
-			},
-			Message: "ExampleMessage",
-			Params: []openapiParameterObject{
-				{
-					Name:     "subMessage.testFieldA",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		reg := descriptor.NewRegistry()
-		reg.SetUseJSONNamesForFields(true)
-		msgs := []*descriptor.Message{}
-		for _, msgdesc := range test.MsgDescs {
-			msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
-		}
-		file := descriptor.File{
-			FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-				SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-				Name:           proto.String("example.proto"),
-				Package:        proto.String("example"),
-				Dependency:     []string{},
-				MessageType:    test.MsgDescs,
-				Service:        []*descriptorpb.ServiceDescriptorProto{},
-				Options: &descriptorpb.FileOptions{
-					GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-				},
-			},
-			GoPkg: descriptor.GoPackage{
-				Path: "example.com/path/to/example/example.pb",
-				Name: "example_pb",
-			},
-			Messages: msgs,
-		}
-		err := reg.Load(&pluginpb.CodeGeneratorRequest{
-			ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-		})
-		if err != nil {
-			t.Fatalf("failed to load code generator request: %v", err)
-		}
-
-		message, err := reg.LookupMsg("", ".example."+test.Message)
-		if err != nil {
-			t.Fatalf("failed to lookup message: %s", err)
-		}
-		params, err := messageToQueryParameters(message, reg, []descriptor.Parameter{}, nil)
-		if err != nil {
-			t.Fatalf("failed to convert message to query parameters: %s", err)
-		}
-		if !reflect.DeepEqual(params, test.Params) {
-			t.Errorf("expected %v, got %v", test.Params, params)
-		}
-	}
-}
-
-func TestMessageToQueryParametersWellKnownTypes(t *testing.T) {
-	type test struct {
-		MsgDescs          []*descriptorpb.DescriptorProto
-		WellKnownMsgDescs []*descriptorpb.DescriptorProto
-		Message           string
-		Params            []openapiParameterObject
-	}
-
-	tests := []test{
-		{
-			MsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("ExampleMessage"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:     proto.String("a_field_mask"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".google.protobuf.FieldMask"),
-							Number:   proto.Int32(1),
-						},
-						{
-							Name:     proto.String("a_timestamp"),
-							Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-							TypeName: proto.String(".google.protobuf.Timestamp"),
-							Number:   proto.Int32(2),
-						},
-					},
-				},
-			},
-			WellKnownMsgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("FieldMask"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:   proto.String("paths"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Label:  descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
-							Number: proto.Int32(1),
-						},
-					},
-				},
-				{
-					Name: proto.String("Timestamp"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:   proto.String("seconds"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_INT64.Enum(),
-							Number: proto.Int32(1),
-						},
-						{
-							Name:   proto.String("nanos"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
-							Number: proto.Int32(2),
-						},
-					},
-				},
-			},
-			Message: "ExampleMessage",
-			Params: []openapiParameterObject{
-				{
-					Name:     "a_field_mask",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-				},
-				{
-					Name:     "a_timestamp",
-					In:       "query",
-					Required: false,
-					Type:     "string",
-					Format:   "date-time",
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		reg := descriptor.NewRegistry()
-		reg.SetEnumsAsInts(true)
-		err := reg.Load(&pluginpb.CodeGeneratorRequest{
-			ProtoFile: []*descriptorpb.FileDescriptorProto{
-				{
-					SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-					Name:           proto.String("google/well_known.proto"),
-					Package:        proto.String("google.protobuf"),
-					Dependency:     []string{},
-					MessageType:    test.WellKnownMsgDescs,
-					Service:        []*descriptorpb.ServiceDescriptorProto{},
-					Options: &descriptorpb.FileOptions{
-						GoPackage: proto.String("google/well_known"),
-					},
-				},
-				{
-					SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-					Name:           proto.String("acme/example.proto"),
-					Package:        proto.String("example"),
-					Dependency:     []string{"google/well_known.proto"},
-					MessageType:    test.MsgDescs,
-					Service:        []*descriptorpb.ServiceDescriptorProto{},
-					Options: &descriptorpb.FileOptions{
-						GoPackage: proto.String("acme/example"),
-					},
-				},
-			},
-		})
-		if err != nil {
-			t.Fatalf("failed to load CodeGeneratorRequest: %v", err)
-		}
-
-		message, err := reg.LookupMsg("", ".example."+test.Message)
-		if err != nil {
-			t.Fatalf("failed to lookup message: %s", err)
-		}
-		params, err := messageToQueryParameters(message, reg, []descriptor.Parameter{}, nil)
-		if err != nil {
-			t.Fatalf("failed to convert message to query parameters: %s", err)
-		}
-		if !reflect.DeepEqual(params, test.Params) {
-			t.Errorf("expected %v, got %v", test.Params, params)
-		}
-	}
-}
-
-func TestApplyTemplateSimple(t *testing.T) {
-	msgdesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("ExampleMessage"),
-	}
-	meth := &descriptorpb.MethodDescriptorProto{
-		Name:       proto.String("Example"),
-		InputType:  proto.String("ExampleMessage"),
-		OutputType: proto.String("ExampleMessage"),
-	}
-	svc := &descriptorpb.ServiceDescriptorProto{
-		Name:   proto.String("ExampleService"),
-		Method: []*descriptorpb.MethodDescriptorProto{meth},
-	}
-	msg := &descriptor.Message{
-		DescriptorProto: msgdesc,
-	}
-	file := descriptor.File{
-		FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-			SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-			Name:           proto.String("example.proto"),
-			Package:        proto.String("example"),
-			MessageType:    []*descriptorpb.DescriptorProto{msgdesc},
-			Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-			Options: &descriptorpb.FileOptions{
-				GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-			},
-		},
-		GoPkg: descriptor.GoPackage{
-			Path: "example.com/path/to/example/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*descriptor.Message{msg},
-		Services: []*descriptor.Service{
-			{
-				ServiceDescriptorProto: svc,
-				Methods: []*descriptor.Method{
-					{
-						MethodDescriptorProto: meth,
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*descriptor.Binding{
-							{
-								HTTPMethod: "GET",
-								Body:       &descriptor.Body{FieldPath: nil},
-								PathTmpl: httprule.Template{
-									Version:  1,
-									OpCodes:  []int{0, 0},
-									Template: "/v1/echo", // TODO(achew22): Figure out what this should really be
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-	reg := descriptor.NewRegistry()
-	if err := AddErrorDefs(reg); err != nil {
-		t.Errorf("AddErrorDefs(%#v) failed with %v; want success", reg, err)
-		return
-	}
-	fileCL := crossLinkFixture(&file)
-	err := reg.Load(reqFromFile(fileCL))
-	if err != nil {
-		t.Errorf("reg.Load(%#v) failed with %v; want success", file, err)
-		return
-	}
-	result, err := applyTemplate(param{File: fileCL, reg: reg})
-	if err != nil {
-		t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
-		return
-	}
-	if want, is, name := "2.0", result.Swagger, "Swagger"; !reflect.DeepEqual(is, want) {
-		t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-	}
-	if want, is, name := "", result.BasePath, "BasePath"; !reflect.DeepEqual(is, want) {
-		t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-	}
-	if want, is, name := ([]string)(nil), result.Schemes, "Schemes"; !reflect.DeepEqual(is, want) {
-		t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-	}
-	if want, is, name := []string{"application/json"}, result.Consumes, "Consumes"; !reflect.DeepEqual(is, want) {
-		t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-	}
-	if want, is, name := []string{"application/json"}, result.Produces, "Produces"; !reflect.DeepEqual(is, want) {
-		t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-	}
-
-	// If there was a failure, print out the input and the json result for debugging.
-	if t.Failed() {
-		t.Errorf("had: %s", file)
-		t.Errorf("got: %s", fmt.Sprint(result))
-	}
-}
-
-func TestApplyTemplateMultiService(t *testing.T) {
-	msgdesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("ExampleMessage"),
-	}
-	meth := &descriptorpb.MethodDescriptorProto{
-		Name:       proto.String("Example"),
-		InputType:  proto.String("ExampleMessage"),
-		OutputType: proto.String("ExampleMessage"),
-	}
-
-	// Create two services that have the same method name. We will test that the
-	// operation IDs are different
-	svc := &descriptorpb.ServiceDescriptorProto{
-		Name:   proto.String("ExampleService"),
-		Method: []*descriptorpb.MethodDescriptorProto{meth},
-	}
-	svc2 := &descriptorpb.ServiceDescriptorProto{
-		Name:   proto.String("OtherService"),
-		Method: []*descriptorpb.MethodDescriptorProto{meth},
-	}
-
-	msg := &descriptor.Message{
-		DescriptorProto: msgdesc,
-	}
-	file := descriptor.File{
-		FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-			SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-			Name:           proto.String("example.proto"),
-			Package:        proto.String("example"),
-			MessageType:    []*descriptorpb.DescriptorProto{msgdesc},
-			Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-			Options: &descriptorpb.FileOptions{
-				GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-			},
-		},
-		GoPkg: descriptor.GoPackage{
-			Path: "example.com/path/to/example/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*descriptor.Message{msg},
-		Services: []*descriptor.Service{
-			{
-				ServiceDescriptorProto: svc,
-				Methods: []*descriptor.Method{
-					{
-						MethodDescriptorProto: meth,
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*descriptor.Binding{
-							{
-								HTTPMethod: "GET",
-								Body:       &descriptor.Body{FieldPath: nil},
-								PathTmpl: httprule.Template{
-									Version:  1,
-									OpCodes:  []int{0, 0},
-									Template: "/v1/echo",
-								},
-							},
-						},
-					},
-				},
-			},
-			{
-				ServiceDescriptorProto: svc2,
-				Methods: []*descriptor.Method{
-					{
-						MethodDescriptorProto: meth,
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*descriptor.Binding{
-							{
-								HTTPMethod: "GET",
-								Body:       &descriptor.Body{FieldPath: nil},
-								PathTmpl: httprule.Template{
-									Version:  1,
-									OpCodes:  []int{0, 0},
-									Template: "/v1/ping",
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-	reg := descriptor.NewRegistry()
-	if err := AddErrorDefs(reg); err != nil {
-		t.Errorf("AddErrorDefs(%#v) failed with %v; want success", reg, err)
-		return
-	}
-	fileCL := crossLinkFixture(&file)
-	err := reg.Load(reqFromFile(fileCL))
-	if err != nil {
-		t.Errorf("reg.Load(%#v) failed with %v; want success", file, err)
-		return
-	}
-	result, err := applyTemplate(param{File: fileCL, reg: reg})
-	if err != nil {
-		t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
-		return
-	}
-
-	// Check that the two services have unique operation IDs even though they
-	// have the same method name.
-	if want, is := "ExampleService_Example", result.Paths["/v1/echo"].Get.OperationID; !reflect.DeepEqual(is, want) {
-		t.Errorf("applyTemplate(%#v).Paths[0].Get.OperationID = %s want to be %s", file, is, want)
-	}
-	if want, is := "OtherService_Example", result.Paths["/v1/ping"].Get.OperationID; !reflect.DeepEqual(is, want) {
-		t.Errorf("applyTemplate(%#v).Paths[0].Get.OperationID = %s want to be %s", file, is, want)
-	}
-
-	// If there was a failure, print out the input and the json result for debugging.
-	if t.Failed() {
-		t.Errorf("had: %s", file)
-		t.Errorf("got: %s", fmt.Sprint(result))
-	}
-}
-
-func TestApplyTemplateOverrideOperationID(t *testing.T) {
-	newFile := func() *descriptor.File {
-		msgdesc := &descriptorpb.DescriptorProto{
-			Name: proto.String("ExampleMessage"),
-		}
-		meth := &descriptorpb.MethodDescriptorProto{
-			Name:       proto.String("Example"),
-			InputType:  proto.String("ExampleMessage"),
-			OutputType: proto.String("ExampleMessage"),
-			Options:    &descriptorpb.MethodOptions{},
-		}
-		svc := &descriptorpb.ServiceDescriptorProto{
-			Name:   proto.String("ExampleService"),
-			Method: []*descriptorpb.MethodDescriptorProto{meth},
-		}
-		msg := &descriptor.Message{
-			DescriptorProto: msgdesc,
-		}
-		return &descriptor.File{
-			FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-				SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-				Name:           proto.String("example.proto"),
-				Package:        proto.String("example"),
-				MessageType:    []*descriptorpb.DescriptorProto{msgdesc},
-				Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-				Options: &descriptorpb.FileOptions{
-					GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-				},
-			},
-			GoPkg: descriptor.GoPackage{
-				Path: "example.com/path/to/example/example.pb",
-				Name: "example_pb",
-			},
-			Messages: []*descriptor.Message{msg},
-			Services: []*descriptor.Service{
-				{
-					ServiceDescriptorProto: svc,
-					Methods: []*descriptor.Method{
-						{
-							MethodDescriptorProto: meth,
-							RequestType:           msg,
-							ResponseType:          msg,
-							Bindings: []*descriptor.Binding{
-								{
-									HTTPMethod: "GET",
-									Body:       &descriptor.Body{FieldPath: nil},
-									PathTmpl: httprule.Template{
-										Version:  1,
-										OpCodes:  []int{0, 0},
-										Template: "/v1/echo", // TODO(achew22): Figure out what this should really be
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		}
-	}
-
-	verifyTemplateFromReq := func(t *testing.T, reg *descriptor.Registry, file *descriptor.File, opts *openapiconfig.OpenAPIOptions) {
-		if err := AddErrorDefs(reg); err != nil {
-			t.Errorf("AddErrorDefs(%#v) failed with %v; want success", reg, err)
-			return
-		}
-		fileCL := crossLinkFixture(file)
-		err := reg.Load(reqFromFile(fileCL))
-		if err != nil {
-			t.Errorf("reg.Load(%#v) failed with %v; want success", *file, err)
-			return
-		}
-		if opts != nil {
-			if err := reg.RegisterOpenAPIOptions(opts); err != nil {
-				t.Fatalf("failed to register OpenAPI options: %s", err)
-			}
-		}
-		result, err := applyTemplate(param{File: fileCL, reg: reg})
-		if err != nil {
-			t.Errorf("applyTemplate(%#v) failed with %v; want success", *file, err)
-			return
-		}
-		if want, is := "MyExample", result.Paths["/v1/echo"].Get.OperationID; !reflect.DeepEqual(is, want) {
-			t.Errorf("applyTemplate(%#v).Paths[0].Get.OperationID = %s want to be %s", *file, is, want)
-		}
-
-		// If there was a failure, print out the input and the json result for debugging.
-		if t.Failed() {
-			t.Errorf("had: %s", *file)
-			t.Errorf("got: %s", fmt.Sprint(result))
-		}
-	}
-
-	openapiOperation := openapi_options.Operation{
-		OperationId: "MyExample",
-	}
-
-	t.Run("verify override via method option", func(t *testing.T) {
-		file := newFile()
-		proto.SetExtension(proto.Message(file.Services[0].Methods[0].MethodDescriptorProto.Options),
-			openapi_options.E_Openapiv2Operation, &openapiOperation)
-
-		reg := descriptor.NewRegistry()
-		verifyTemplateFromReq(t, reg, file, nil)
-	})
-
-	t.Run("verify override options annotations", func(t *testing.T) {
-		file := newFile()
-		reg := descriptor.NewRegistry()
-		opts := &openapiconfig.OpenAPIOptions{
-			Method: []*openapiconfig.OpenAPIMethodOption{
-				{
-					Method: "example.ExampleService.Example",
-					Option: &openapiOperation,
-				},
-			},
-		}
-		verifyTemplateFromReq(t, reg, file, opts)
-	})
-}
-
-func TestApplyTemplateExtensions(t *testing.T) {
-	newFile := func() *descriptor.File {
-		msgdesc := &descriptorpb.DescriptorProto{
-			Name: proto.String("ExampleMessage"),
-		}
-		meth := &descriptorpb.MethodDescriptorProto{
-			Name:       proto.String("Example"),
-			InputType:  proto.String("ExampleMessage"),
-			OutputType: proto.String("ExampleMessage"),
-			Options:    &descriptorpb.MethodOptions{},
-		}
-		svc := &descriptorpb.ServiceDescriptorProto{
-			Name:   proto.String("ExampleService"),
-			Method: []*descriptorpb.MethodDescriptorProto{meth},
-		}
-		msg := &descriptor.Message{
-			DescriptorProto: msgdesc,
-		}
-		return &descriptor.File{
-			FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-				SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-				Name:           proto.String("example.proto"),
-				Package:        proto.String("example"),
-				MessageType:    []*descriptorpb.DescriptorProto{msgdesc},
-				Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-				Options: &descriptorpb.FileOptions{
-					GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-				},
-			},
-			GoPkg: descriptor.GoPackage{
-				Path: "example.com/path/to/example/example.pb",
-				Name: "example_pb",
-			},
-			Messages: []*descriptor.Message{msg},
-			Services: []*descriptor.Service{
-				{
-					ServiceDescriptorProto: svc,
-					Methods: []*descriptor.Method{
-						{
-							MethodDescriptorProto: meth,
-							RequestType:           msg,
-							ResponseType:          msg,
-							Bindings: []*descriptor.Binding{
-								{
-									HTTPMethod: "GET",
-									Body:       &descriptor.Body{FieldPath: nil},
-									PathTmpl: httprule.Template{
-										Version:  1,
-										OpCodes:  []int{0, 0},
-										Template: "/v1/echo", // TODO(achew22): Figure out what this should really be
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		}
-	}
-	swagger := openapi_options.Swagger{
-		Info: &openapi_options.Info{
-			Title: "test",
-			Extensions: map[string]*structpb.Value{
-				"x-info-extension": {Kind: &structpb.Value_StringValue{StringValue: "bar"}},
-			},
-		},
-		Extensions: map[string]*structpb.Value{
-			"x-foo": {Kind: &structpb.Value_StringValue{StringValue: "bar"}},
-			"x-bar": {Kind: &structpb.Value_ListValue{ListValue: &structpb.ListValue{
-				Values: []*structpb.Value{{Kind: &structpb.Value_StringValue{StringValue: "baz"}}},
-			}}},
-		},
-		SecurityDefinitions: &openapi_options.SecurityDefinitions{
-			Security: map[string]*openapi_options.SecurityScheme{
-				"somescheme": {
-					Extensions: map[string]*structpb.Value{
-						"x-security-baz": {Kind: &structpb.Value_BoolValue{BoolValue: true}},
-					},
-				},
-			},
-		},
-	}
-	openapiOperation := openapi_options.Operation{
-		Responses: map[string]*openapi_options.Response{
-			"200": {
-				Extensions: map[string]*structpb.Value{
-					"x-resp-id": {Kind: &structpb.Value_StringValue{StringValue: "resp1000"}},
-				},
-			},
-		},
-		Extensions: map[string]*structpb.Value{
-			"x-op-foo": {Kind: &structpb.Value_StringValue{StringValue: "baz"}},
-		},
-	}
-	verifyTemplateExtensions := func(t *testing.T, reg *descriptor.Registry, file *descriptor.File,
-		opts *openapiconfig.OpenAPIOptions) {
-		if err := AddErrorDefs(reg); err != nil {
-			t.Errorf("AddErrorDefs(%#v) failed with %v; want success", reg, err)
-			return
-		}
-		fileCL := crossLinkFixture(file)
-		err := reg.Load(reqFromFile(fileCL))
-		if err != nil {
-			t.Errorf("reg.Load(%#v) failed with %v; want success", file, err)
-			return
-		}
-		if opts != nil {
-			if err := reg.RegisterOpenAPIOptions(opts); err != nil {
-				t.Fatalf("failed to register OpenAPI annotations: %s", err)
-			}
-		}
-		result, err := applyTemplate(param{File: fileCL, reg: reg})
-		if err != nil {
-			t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
-			return
-		}
-		if want, is, name := "2.0", result.Swagger, "Swagger"; !reflect.DeepEqual(is, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-		}
-		if got, want := len(result.extensions), 2; got != want {
-			t.Fatalf("len(applyTemplate(%#v).Extensions) = %d want to be %d", file, got, want)
-		}
-		if got, want := result.extensions[0].key, "x-bar"; got != want {
-			t.Errorf("applyTemplate(%#v).Extensions[0].key = %s want to be %s", file, got, want)
-		}
-		if got, want := result.extensions[1].key, "x-foo"; got != want {
-			t.Errorf("applyTemplate(%#v).Extensions[1].key = %s want to be %s", file, got, want)
-		}
-		{
-			var got []string
-			err = marshaler.Unmarshal(result.extensions[0].value, &got)
-			if err != nil {
-				t.Fatalf("marshaler.Unmarshal failed: %v", err)
-			}
-			want := []string{"baz"}
-			if diff := cmp.Diff(got, want); diff != "" {
-				t.Errorf(diff)
-			}
-		}
-		{
-			var got string
-			err = marshaler.Unmarshal(result.extensions[1].value, &got)
-			if err != nil {
-				t.Fatalf("marshaler.Unmarshal failed: %v", err)
-			}
-			want := "bar"
-			if diff := cmp.Diff(got, want); diff != "" {
-				t.Errorf(diff)
-			}
-		}
-
-		var scheme openapiSecuritySchemeObject
-		for _, v := range result.SecurityDefinitions {
-			scheme = v
-		}
-		if want, is, name := []extension{
-			{key: "x-security-baz", value: json.RawMessage("true")},
-		}, scheme.extensions, "SecurityScheme.Extensions"; !reflect.DeepEqual(is, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-		}
-
-		if want, is, name := []extension{
-			{key: "x-info-extension", value: json.RawMessage("\"bar\"")},
-		}, result.Info.extensions, "Info.Extensions"; !reflect.DeepEqual(is, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-		}
-
-		var operation *openapiOperationObject
-		var response openapiResponseObject
-		for _, v := range result.Paths {
-			operation = v.Get
-			response = v.Get.Responses["200"]
-		}
-		if want, is, name := []extension{
-			{key: "x-op-foo", value: json.RawMessage("\"baz\"")},
-		}, operation.extensions, "operation.Extensions"; !reflect.DeepEqual(is, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-		}
-		if want, is, name := []extension{
-			{key: "x-resp-id", value: json.RawMessage("\"resp1000\"")},
-		}, response.extensions, "response.Extensions"; !reflect.DeepEqual(is, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-		}
-	}
-	t.Run("verify template options set via proto options", func(t *testing.T) {
-		file := newFile()
-		proto.SetExtension(proto.Message(file.FileDescriptorProto.Options), openapi_options.E_Openapiv2Swagger, &swagger)
-		proto.SetExtension(proto.Message(file.Services[0].Methods[0].Options), openapi_options.E_Openapiv2Operation, &openapiOperation)
-		reg := descriptor.NewRegistry()
-		verifyTemplateExtensions(t, reg, file, nil)
-	})
-	t.Run("verify template options set via annotations", func(t *testing.T) {
-		file := newFile()
-		opts := &openapiconfig.OpenAPIOptions{
-			File: []*openapiconfig.OpenAPIFileOption{
-				{
-					File:   "example.proto",
-					Option: &swagger,
-				},
-			},
-			Method: []*openapiconfig.OpenAPIMethodOption{
-				{
-					Method: "example.ExampleService.Example",
-					Option: &openapiOperation,
-				},
-			},
-		}
-		reg := descriptor.NewRegistry()
-		verifyTemplateExtensions(t, reg, file, opts)
-	})
-}
-
-func TestApplyTemplateHeaders(t *testing.T) {
-	newFile := func() *descriptor.File {
-		msgdesc := &descriptorpb.DescriptorProto{
-			Name: proto.String("ExampleMessage"),
-		}
-		meth := &descriptorpb.MethodDescriptorProto{
-			Name:       proto.String("Example"),
-			InputType:  proto.String("ExampleMessage"),
-			OutputType: proto.String("ExampleMessage"),
-			Options:    &descriptorpb.MethodOptions{},
-		}
-		svc := &descriptorpb.ServiceDescriptorProto{
-			Name:   proto.String("ExampleService"),
-			Method: []*descriptorpb.MethodDescriptorProto{meth},
-		}
-		msg := &descriptor.Message{
-			DescriptorProto: msgdesc,
-		}
-		return &descriptor.File{
-			FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-				SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-				Name:           proto.String("example.proto"),
-				Package:        proto.String("example"),
-				MessageType:    []*descriptorpb.DescriptorProto{msgdesc},
-				Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-				Options: &descriptorpb.FileOptions{
-					GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-				},
-			},
-			GoPkg: descriptor.GoPackage{
-				Path: "example.com/path/to/example/example.pb",
-				Name: "example_pb",
-			},
-			Messages: []*descriptor.Message{msg},
-			Services: []*descriptor.Service{
-				{
-					ServiceDescriptorProto: svc,
-					Methods: []*descriptor.Method{
-						{
-							MethodDescriptorProto: meth,
-							RequestType:           msg,
-							ResponseType:          msg,
-							Bindings: []*descriptor.Binding{
-								{
-									HTTPMethod: "GET",
-									Body:       &descriptor.Body{FieldPath: nil},
-									PathTmpl: httprule.Template{
-										Version:  1,
-										OpCodes:  []int{0, 0},
-										Template: "/v1/echo", // TODO(achew22): Figure out what this should really be
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		}
-	}
-	openapiOperation := openapi_options.Operation{
-		Responses: map[string]*openapi_options.Response{
-			"200": &openapi_options.Response{
-				Description: "Testing Headers",
-				Headers: map[string]*openapi_options.Header{
-					"string": {
-						Description: "string header description",
-						Type:        "string",
-						Format:      "uuid",
-						Pattern:     "",
-					},
-					"boolean": {
-						Description: "boolean header description",
-						Type:        "boolean",
-						Default:     "true",
-						Pattern:     "^true|false$",
-					},
-					"integer": {
-						Description: "integer header description",
-						Type:        "integer",
-						Default:     "0",
-						Pattern:     "^[0-9]$",
-					},
-					"number": {
-						Description: "number header description",
-						Type:        "number",
-						Default:     "1.2",
-						Pattern:     "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$",
-					},
-				},
-			},
-		},
-	}
-	verifyTemplateHeaders := func(t *testing.T, reg *descriptor.Registry, file *descriptor.File,
-		opts *openapiconfig.OpenAPIOptions) {
-		if err := AddErrorDefs(reg); err != nil {
-			t.Errorf("AddErrorDefs(%#v) failed with %v; want success", reg, err)
-			return
-		}
-		fileCL := crossLinkFixture(file)
-		err := reg.Load(reqFromFile(fileCL))
-		if err != nil {
-			t.Errorf("reg.Load(%#v) failed with %v; want success", file, err)
-			return
-		}
-		if opts != nil {
-			if err := reg.RegisterOpenAPIOptions(opts); err != nil {
-				t.Fatalf("failed to register OpenAPI annotations: %s", err)
-			}
-		}
-		result, err := applyTemplate(param{File: fileCL, reg: reg})
-		if err != nil {
-			t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
-			return
-		}
-		if want, is, name := "2.0", result.Swagger, "Swagger"; !reflect.DeepEqual(is, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-		}
-
-		var response openapiResponseObject
-		for _, v := range result.Paths {
-			response = v.Get.Responses["200"]
-		}
-		if want, is, name := []openapiHeadersObject{
-			{
-				"String": openapiHeaderObject{
-					Description: "string header description",
-					Type:        "string",
-					Format:      "uuid",
-					Pattern:     "",
-				},
-				"Boolean": openapiHeaderObject{
-					Description: "boolean header description",
-					Type:        "boolean",
-					Default:     json.RawMessage("true"),
-					Pattern:     "^true|false$",
-				},
-				"Integer": openapiHeaderObject{
-					Description: "integer header description",
-					Type:        "integer",
-					Default:     json.RawMessage("0"),
-					Pattern:     "^[0-9]$",
-				},
-				"Number": openapiHeaderObject{
-					Description: "number header description",
-					Type:        "number",
-					Default:     json.RawMessage("1.2"),
-					Pattern:     "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$",
-				},
-			},
-		}[0], response.Headers, "response.Headers"; !reflect.DeepEqual(is, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
-		}
-
-	}
-	t.Run("verify template options set via proto options", func(t *testing.T) {
-		file := newFile()
-		proto.SetExtension(proto.Message(file.Services[0].Methods[0].Options), openapi_options.E_Openapiv2Operation, &openapiOperation)
-		reg := descriptor.NewRegistry()
-		verifyTemplateHeaders(t, reg, file, nil)
-	})
-}
-
-func TestValidateHeaderType(t *testing.T) {
-	type test struct {
-		Type          string
-		Format        string
-		expectedError error
-	}
-	tests := []test{
-		{
-			"string",
-			"date-time",
-			nil,
-		},
-		{
-			"boolean",
-			"",
-			nil,
-		},
-		{
-			"integer",
-			"uint",
-			nil,
-		},
-		{
-			"integer",
-			"uint8",
-			nil,
-		},
-		{
-			"integer",
-			"uint16",
-			nil,
-		},
-		{
-			"integer",
-			"uint32",
-			nil,
-		},
-		{
-			"integer",
-			"uint64",
-			nil,
-		},
-		{
-			"integer",
-			"int",
-			nil,
-		},
-		{
-			"integer",
-			"int8",
-			nil,
-		},
-		{
-			"integer",
-			"int16",
-			nil,
-		},
-		{
-			"integer",
-			"int32",
-			nil,
-		},
-		{
-			"integer",
-			"int64",
-			nil,
-		},
-		{
-			"integer",
-			"float64",
-			errors.New("the provided format \"float64\" is not a valid extension of the type \"integer\""),
-		},
-		{
-			"integer",
-			"uuid",
-			errors.New("the provided format \"uuid\" is not a valid extension of the type \"integer\""),
-		},
-		{
-			"number",
-			"uint",
-			nil,
-		},
-		{
-			"number",
-			"uint8",
-			nil,
-		},
-		{
-			"number",
-			"uint16",
-			nil,
-		},
-		{
-			"number",
-			"uint32",
-			nil,
-		},
-		{
-			"number",
-			"uint64",
-			nil,
-		},
-		{
-			"number",
-			"int",
-			nil,
-		},
-		{
-			"number",
-			"int8",
-			nil,
-		},
-		{
-			"number",
-			"int16",
-			nil,
-		},
-		{
-			"number",
-			"int32",
-			nil,
-		},
-		{
-			"number",
-			"int64",
-			nil,
-		},
-		{
-			"number",
-			"float",
-			nil,
-		},
-		{
-			"number",
-			"float32",
-			nil,
-		},
-		{
-			"number",
-			"float64",
-			nil,
-		},
-		{
-			"number",
-			"complex64",
-			nil,
-		},
-		{
-			"number",
-			"complex128",
-			nil,
-		},
-		{
-			"number",
-			"double",
-			nil,
-		},
-		{
-			"number",
-			"byte",
-			nil,
-		},
-		{
-			"number",
-			"rune",
-			nil,
-		},
-		{
-			"number",
-			"uintptr",
-			nil,
-		},
-		{
-			"number",
-			"date",
-			errors.New("the provided format \"date\" is not a valid extension of the type \"number\""),
-		},
-		{
-			"array",
-			"",
-			errors.New("the provided header type \"array\" is not supported"),
-		},
-		{
-			"foo",
-			"",
-			errors.New("the provided header type \"foo\" is not supported"),
-		},
-	}
-	for _, v := range tests {
-		err := validateHeaderTypeAndFormat(v.Type, v.Format)
-
-		if v.expectedError == nil {
-			if err != nil {
-				t.Errorf("unexpected error %v", err)
-			}
-		} else {
-			if err == nil {
-				t.Fatal("expected header error not returned")
-			}
-			if err.Error() != v.expectedError.Error() {
-				t.Errorf("expected error malformed, expected %q, got %q", v.expectedError.Error(), err.Error())
-			}
-		}
-	}
-
-}
-
-func TestValidateDefaultValueType(t *testing.T) {
-	type test struct {
-		Type          string
-		Value         string
-		Format        string
-		expectedError error
-	}
-	tests := []test{
-		{
-			"string",
-			`"string"`,
-			"",
-			nil,
-		},
-		{
-			"string",
-			"\"2012-11-01T22:08:41+00:00\"",
-			"date-time",
-			nil,
-		},
-		{
-			"string",
-			"\"2012-11-01\"",
-			"date",
-			nil,
-		},
-		{
-			"string",
-			"0",
-			"",
-			errors.New("the provided default value \"0\" does not match provider type \"string\", or is not properly quoted with escaped quotations"),
-		},
-		{
-			"string",
-			"false",
-			"",
-			errors.New("the provided default value \"false\" does not match provider type \"string\", or is not properly quoted with escaped quotations"),
-		},
-		{
-			"boolean",
-			"true",
-			"",
-			nil,
-		},
-		{
-			"boolean",
-			"0",
-			"",
-			errors.New("the provided default value \"0\" does not match provider type \"boolean\""),
-		},
-		{
-			"boolean",
-			`"string"`,
-			"",
-			errors.New("the provided default value \"\\\"string\\\"\" does not match provider type \"boolean\""),
-		},
-		{
-			"number",
-			"1.2",
-			"",
-			nil,
-		},
-		{
-			"number",
-			"123",
-			"",
-			nil,
-		},
-		{
-			"number",
-			"nan",
-			"",
-			errors.New("the provided number \"nan\" is not a valid JSON number"),
-		},
-		{
-			"number",
-			"NaN",
-			"",
-			errors.New("the provided number \"NaN\" is not a valid JSON number"),
-		},
-		{
-			"number",
-			"-459.67",
-			"",
-			nil,
-		},
-		{
-			"number",
-			"inf",
-			"",
-			errors.New("the provided number \"inf\" is not a valid JSON number"),
-		},
-		{
-			"number",
-			"infinity",
-			"",
-			errors.New("the provided number \"infinity\" is not a valid JSON number"),
-		},
-		{
-			"number",
-			"Inf",
-			"",
-			errors.New("the provided number \"Inf\" is not a valid JSON number"),
-		},
-		{
-			"number",
-			"Infinity",
-			"",
-			errors.New("the provided number \"Infinity\" is not a valid JSON number"),
-		},
-		{
-			"number",
-			"false",
-			"",
-			errors.New("the provided default value \"false\" does not match provider type \"number\""),
-		},
-		{
-			"number",
-			`"string"`,
-			"",
-			errors.New("the provided default value \"\\\"string\\\"\" does not match provider type \"number\""),
-		},
-		{
-			"integer",
-			"2",
-			"",
-			nil,
-		},
-		{
-			"integer",
-			fmt.Sprint(math.MaxInt32),
-			"int32",
-			nil,
-		},
-		{
-			"integer",
-			fmt.Sprint(math.MaxInt32 + 1),
-			"int32",
-			errors.New("the provided default value \"2147483648\" does not match provided format \"int32\""),
-		},
-		{
-			"integer",
-			fmt.Sprint(math.MaxInt64),
-			"int64",
-			nil,
-		},
-		{
-			"integer",
-			"9223372036854775808",
-			"int64",
-			errors.New("the provided default value \"9223372036854775808\" does not match provided format \"int64\""),
-		},
-		{
-			"integer",
-			"18446744073709551615",
-			"uint64",
-			nil,
-		},
-		{
-			"integer",
-			"false",
-			"",
-			errors.New("the provided default value \"false\" does not match provided type \"integer\""),
-		},
-		{
-			"integer",
-			"1.2",
-			"",
-			errors.New("the provided default value \"1.2\" does not match provided type \"integer\""),
-		},
-		{
-			"integer",
-			`"string"`,
-			"",
-			errors.New("the provided default value \"\\\"string\\\"\" does not match provided type \"integer\""),
-		},
-	}
-	for _, v := range tests {
-		err := validateDefaultValueTypeAndFormat(v.Type, v.Value, v.Format)
-
-		if v.expectedError == nil {
-			if err != nil {
-				t.Errorf("unexpected error '%v'", err)
-			}
-		} else {
-			if err == nil {
-				t.Error("expected update error not returned")
-			}
-			if err.Error() != v.expectedError.Error() {
-				t.Errorf("expected error malformed, expected %q, got %q", v.expectedError.Error(), err.Error())
-			}
-		}
-	}
-
-}
-
-func TestApplyTemplateRequestWithoutClientStreaming(t *testing.T) {
-	msgdesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("ExampleMessage"),
-		Field: []*descriptorpb.FieldDescriptorProto{
-			{
-				Name:     proto.String("nested"),
-				Label:    descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-				Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				TypeName: proto.String("NestedMessage"),
-				Number:   proto.Int32(1),
-			},
-		},
-	}
-	nesteddesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("NestedMessage"),
-		Field: []*descriptorpb.FieldDescriptorProto{
-			{
-				Name:   proto.String("int32"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
-				Number: proto.Int32(1),
-			},
-			{
-				Name:   proto.String("bool"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),
-				Number: proto.Int32(2),
-			},
-		},
-	}
-	meth := &descriptorpb.MethodDescriptorProto{
-		Name:            proto.String("Echo"),
-		InputType:       proto.String("ExampleMessage"),
-		OutputType:      proto.String("ExampleMessage"),
-		ClientStreaming: proto.Bool(false),
-	}
-	svc := &descriptorpb.ServiceDescriptorProto{
-		Name:   proto.String("ExampleService"),
-		Method: []*descriptorpb.MethodDescriptorProto{meth},
-	}
-
-	meth.ServerStreaming = proto.Bool(false)
-
-	msg := &descriptor.Message{
-		DescriptorProto: msgdesc,
-	}
-	nested := &descriptor.Message{
-		DescriptorProto: nesteddesc,
-	}
-
-	nestedField := &descriptor.Field{
-		Message:              msg,
-		FieldDescriptorProto: msg.GetField()[0],
-	}
-	intField := &descriptor.Field{
-		Message:              nested,
-		FieldDescriptorProto: nested.GetField()[0],
-	}
-	boolField := &descriptor.Field{
-		Message:              nested,
-		FieldDescriptorProto: nested.GetField()[1],
-	}
-	file := descriptor.File{
-		FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-			SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-			Name:           proto.String("example.proto"),
-			Package:        proto.String("example"),
-			MessageType:    []*descriptorpb.DescriptorProto{msgdesc, nesteddesc},
-			Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-			Options: &descriptorpb.FileOptions{
-				GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-			},
-		},
-		GoPkg: descriptor.GoPackage{
-			Path: "example.com/path/to/example/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*descriptor.Message{msg, nested},
-		Services: []*descriptor.Service{
-			{
-				ServiceDescriptorProto: svc,
-				Methods: []*descriptor.Method{
-					{
-						MethodDescriptorProto: meth,
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*descriptor.Binding{
-							{
-								HTTPMethod: "POST",
-								PathTmpl: httprule.Template{
-									Version:  1,
-									OpCodes:  []int{0, 0},
-									Template: "/v1/echo", // TODO(achew): Figure out what this hsould really be
-								},
-								PathParams: []descriptor.Parameter{
-									{
-										FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
-											{
-												Name:   "nested",
-												Target: nestedField,
-											},
-											{
-												Name:   "int32",
-												Target: intField,
-											},
-										}),
-										Target: intField,
-									},
-								},
-								Body: &descriptor.Body{
-									FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
-										{
-											Name:   "nested",
-											Target: nestedField,
-										},
-										{
-											Name:   "bool",
-											Target: boolField,
-										},
-									}),
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-	reg := descriptor.NewRegistry()
-	if err := AddErrorDefs(reg); err != nil {
-		t.Errorf("AddErrorDefs(%#v) failed with %v; want success", reg, err)
-		return
-	}
-	err := reg.Load(&pluginpb.CodeGeneratorRequest{
-		ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-	})
-	if err != nil {
-		t.Fatalf("failed to load code generator request: %v", err)
-	}
-	result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
-	if err != nil {
-		t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
-		return
-	}
-	if want, got := "2.0", result.Swagger; !reflect.DeepEqual(got, want) {
-		t.Errorf("applyTemplate(%#v).Swagger = %s want to be %s", file, got, want)
-	}
-	if want, got := "", result.BasePath; !reflect.DeepEqual(got, want) {
-		t.Errorf("applyTemplate(%#v).BasePath = %s want to be %s", file, got, want)
-	}
-	if want, got := ([]string)(nil), result.Schemes; !reflect.DeepEqual(got, want) {
-		t.Errorf("applyTemplate(%#v).Schemes = %s want to be %s", file, got, want)
-	}
-	if want, got := []string{"application/json"}, result.Consumes; !reflect.DeepEqual(got, want) {
-		t.Errorf("applyTemplate(%#v).Consumes = %s want to be %s", file, got, want)
-	}
-	if want, got := []string{"application/json"}, result.Produces; !reflect.DeepEqual(got, want) {
-		t.Errorf("applyTemplate(%#v).Produces = %s want to be %s", file, got, want)
-	}
-
-	// If there was a failure, print out the input and the json result for debugging.
-	if t.Failed() {
-		t.Errorf("had: %s", file)
-		t.Errorf("got: %s", fmt.Sprint(result))
-	}
-}
-
-func TestApplyTemplateRequestWithClientStreaming(t *testing.T) {
-	msgdesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("ExampleMessage"),
-		Field: []*descriptorpb.FieldDescriptorProto{
-			{
-				Name:     proto.String("nested"),
-				Label:    descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-				Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				TypeName: proto.String("NestedMessage"),
-				Number:   proto.Int32(1),
-			},
-		},
-	}
-	nesteddesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("NestedMessage"),
-		Field: []*descriptorpb.FieldDescriptorProto{
-			{
-				Name:   proto.String("int32"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
-				Number: proto.Int32(1),
-			},
-			{
-				Name:   proto.String("bool"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_BOOL.Enum(),
-				Number: proto.Int32(2),
-			},
-		},
-	}
-	meth := &descriptorpb.MethodDescriptorProto{
-		Name:            proto.String("Echo"),
-		InputType:       proto.String("ExampleMessage"),
-		OutputType:      proto.String("ExampleMessage"),
-		ClientStreaming: proto.Bool(true),
-		ServerStreaming: proto.Bool(true),
-	}
-	svc := &descriptorpb.ServiceDescriptorProto{
-		Name:   proto.String("ExampleService"),
-		Method: []*descriptorpb.MethodDescriptorProto{meth},
-	}
-
-	msg := &descriptor.Message{
-		DescriptorProto: msgdesc,
-	}
-	nested := &descriptor.Message{
-		DescriptorProto: nesteddesc,
-	}
-
-	nestedField := &descriptor.Field{
-		Message:              msg,
-		FieldDescriptorProto: msg.GetField()[0],
-	}
-	intField := &descriptor.Field{
-		Message:              nested,
-		FieldDescriptorProto: nested.GetField()[0],
-	}
-	boolField := &descriptor.Field{
-		Message:              nested,
-		FieldDescriptorProto: nested.GetField()[1],
-	}
-	file := descriptor.File{
-		FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-			SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-			Name:           proto.String("example.proto"),
-			Package:        proto.String("example"),
-			MessageType:    []*descriptorpb.DescriptorProto{msgdesc, nesteddesc},
-			Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-			Options: &descriptorpb.FileOptions{
-				GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-			},
-		},
-		GoPkg: descriptor.GoPackage{
-			Path: "example.com/path/to/example/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*descriptor.Message{msg, nested},
-		Services: []*descriptor.Service{
-			{
-				ServiceDescriptorProto: svc,
-				Methods: []*descriptor.Method{
-					{
-						MethodDescriptorProto: meth,
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*descriptor.Binding{
-							{
-								HTTPMethod: "POST",
-								PathTmpl: httprule.Template{
-									Version:  1,
-									OpCodes:  []int{0, 0},
-									Template: "/v1/echo", // TODO(achew): Figure out what this hsould really be
-								},
-								PathParams: []descriptor.Parameter{
-									{
-										FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
-											{
-												Name:   "nested",
-												Target: nestedField,
-											},
-											{
-												Name:   "int32",
-												Target: intField,
-											},
-										}),
-										Target: intField,
-									},
-								},
-								Body: &descriptor.Body{
-									FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
-										{
-											Name:   "nested",
-											Target: nestedField,
-										},
-										{
-											Name:   "bool",
-											Target: boolField,
-										},
-									}),
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-	reg := descriptor.NewRegistry()
-	if err := AddErrorDefs(reg); err != nil {
-		t.Errorf("AddErrorDefs(%#v) failed with %v; want success", reg, err)
-		return
-	}
-	err := reg.Load(&pluginpb.CodeGeneratorRequest{
-		ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-	})
-	if err != nil {
-		t.Fatalf("failed to load code generator request: %v", err)
-	}
-	result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
-	if err != nil {
-		t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
-		return
-	}
-
-	// Only ExampleMessage must be present, not NestedMessage
-	if want, got, name := 3, len(result.Definitions), "len(Definitions)"; !reflect.DeepEqual(got, want) {
-		t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
-	}
-	if _, ok := result.Paths["/v1/echo"].Post.Responses["200"]; !ok {
-		t.Errorf("applyTemplate(%#v).%s = expected 200 response to be defined", file, `result.Paths["/v1/echo"].Post.Responses["200"]`)
-	} else {
-		if want, got, name := "A successful response.(streaming responses)", result.Paths["/v1/echo"].Post.Responses["200"].Description, `result.Paths["/v1/echo"].Post.Responses["200"].Description`; !reflect.DeepEqual(got, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
-		}
-		streamExampleExampleMessage := result.Paths["/v1/echo"].Post.Responses["200"].Schema
-		if want, got, name := "object", streamExampleExampleMessage.Type, `result.Paths["/v1/echo"].Post.Responses["200"].Schema.Type`; !reflect.DeepEqual(got, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
-		}
-		if want, got, name := "Stream result of exampleExampleMessage", streamExampleExampleMessage.Title, `result.Paths["/v1/echo"].Post.Responses["200"].Schema.Title`; !reflect.DeepEqual(got, want) {
-			t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
-		}
-		streamExampleExampleMessageProperties := *(streamExampleExampleMessage.Properties)
-		if want, got, name := 2, len(streamExampleExampleMessageProperties), `len(StreamDefinitions["exampleExampleMessage"].Properties)`; !reflect.DeepEqual(got, want) {
-			t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
-		} else {
-			resultProperty := streamExampleExampleMessageProperties[0]
-			if want, got, name := "result", resultProperty.Key, `(*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Key`; !reflect.DeepEqual(got, want) {
-				t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
-			}
-			result := resultProperty.Value.(openapiSchemaObject)
-			if want, got, name := "#/definitions/exampleExampleMessage", result.Ref, `((*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Value.(openapiSchemaObject)).Ref`; !reflect.DeepEqual(got, want) {
-				t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
-			}
-			errorProperty := streamExampleExampleMessageProperties[1]
-			if want, got, name := "error", errorProperty.Key, `(*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Key`; !reflect.DeepEqual(got, want) {
-				t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
-			}
-			err := errorProperty.Value.(openapiSchemaObject)
-			if want, got, name := "#/definitions/rpcStatus", err.Ref, `((*(StreamDefinitions["exampleExampleMessage"].Properties))[0].Value.(openapiSchemaObject)).Ref`; !reflect.DeepEqual(got, want) {
-				t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
-			}
-		}
-	}
-
-	// If there was a failure, print out the input and the json result for debugging.
-	if t.Failed() {
-		t.Errorf("had: %s", file)
-		t.Errorf("got: %s", fmt.Sprint(result))
-	}
-}
-
-func TestApplyTemplateRequestWithUnusedReferences(t *testing.T) {
-	reqdesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("ExampleMessage"),
-		Field: []*descriptorpb.FieldDescriptorProto{
-			{
-				Name:   proto.String("string"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-				Number: proto.Int32(1),
-			},
-		},
-	}
-	respdesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("EmptyMessage"),
-	}
-	meth := &descriptorpb.MethodDescriptorProto{
-		Name:            proto.String("Example"),
-		InputType:       proto.String("ExampleMessage"),
-		OutputType:      proto.String("EmptyMessage"),
-		ClientStreaming: proto.Bool(false),
-		ServerStreaming: proto.Bool(false),
-	}
-	svc := &descriptorpb.ServiceDescriptorProto{
-		Name:   proto.String("ExampleService"),
-		Method: []*descriptorpb.MethodDescriptorProto{meth},
-	}
-
-	req := &descriptor.Message{
-		DescriptorProto: reqdesc,
-	}
-	resp := &descriptor.Message{
-		DescriptorProto: respdesc,
-	}
-	stringField := &descriptor.Field{
-		Message:              req,
-		FieldDescriptorProto: req.GetField()[0],
-	}
-	file := descriptor.File{
-		FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-			SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-			Name:           proto.String("example.proto"),
-			Package:        proto.String("example"),
-			MessageType:    []*descriptorpb.DescriptorProto{reqdesc, respdesc},
-			Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-			Options: &descriptorpb.FileOptions{
-				GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-			},
-		},
-		GoPkg: descriptor.GoPackage{
-			Path: "example.com/path/to/example/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*descriptor.Message{req, resp},
-		Services: []*descriptor.Service{
-			{
-				ServiceDescriptorProto: svc,
-				Methods: []*descriptor.Method{
-					{
-						MethodDescriptorProto: meth,
-						RequestType:           req,
-						ResponseType:          resp,
-						Bindings: []*descriptor.Binding{
-							{
-								HTTPMethod: "GET",
-								PathTmpl: httprule.Template{
-									Version:  1,
-									OpCodes:  []int{0, 0},
-									Template: "/v1/example",
-								},
-							},
-							{
-								HTTPMethod: "POST",
-								PathTmpl: httprule.Template{
-									Version:  1,
-									OpCodes:  []int{0, 0},
-									Template: "/v1/example/{string}",
-								},
-								PathParams: []descriptor.Parameter{
-									{
-										FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
-											{
-												Name:   "string",
-												Target: stringField,
-											},
-										}),
-										Target: stringField,
-									},
-								},
-								Body: &descriptor.Body{
-									FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
-										{
-											Name:   "string",
-											Target: stringField,
-										},
-									}),
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-
-	reg := descriptor.NewRegistry()
-	if err := AddErrorDefs(reg); err != nil {
-		t.Errorf("AddErrorDefs(%#v) failed with %v; want success", reg, err)
-		return
-	}
-	err := reg.Load(&pluginpb.CodeGeneratorRequest{
-		ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-	})
-	if err != nil {
-		t.Fatalf("failed to load code generator request: %v", err)
-	}
-	result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
-	if err != nil {
-		t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
-		return
-	}
-
-	// Only EmptyMessage must be present, not ExampleMessage (plus error status)
-	if want, got, name := 3, len(result.Definitions), "len(Definitions)"; !reflect.DeepEqual(got, want) {
-		t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
-	}
-
-	// If there was a failure, print out the input and the json result for debugging.
-	if t.Failed() {
-		t.Errorf("had: %s", file)
-		t.Errorf("got: %s", fmt.Sprint(result))
-	}
-}
-
-func TestApplyTemplateRequestWithBodyQueryParameters(t *testing.T) {
-	bookDesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("Book"),
-		Field: []*descriptorpb.FieldDescriptorProto{
-			{
-				Name:   proto.String("name"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-				Number: proto.Int32(1),
-			},
-			{
-				Name:   proto.String("id"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-				Number: proto.Int32(2),
-			},
-		},
-	}
-	createDesc := &descriptorpb.DescriptorProto{
-		Name: proto.String("CreateBookRequest"),
-		Field: []*descriptorpb.FieldDescriptorProto{
-			{
-				Name:   proto.String("parent"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-				Number: proto.Int32(1),
-			},
-			{
-				Name:   proto.String("book"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-				Number: proto.Int32(2),
-			},
-			{
-				Name:   proto.String("book_id"),
-				Label:  descriptorpb.FieldDescriptorProto_LABEL_REQUIRED.Enum(),
-				Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-				Number: proto.Int32(3),
-			},
-		},
-	}
-	meth := &descriptorpb.MethodDescriptorProto{
-		Name:       proto.String("CreateBook"),
-		InputType:  proto.String("CreateBookRequest"),
-		OutputType: proto.String("Book"),
-	}
-	svc := &descriptorpb.ServiceDescriptorProto{
-		Name:   proto.String("BookService"),
-		Method: []*descriptorpb.MethodDescriptorProto{meth},
-	}
-
-	bookMsg := &descriptor.Message{
-		DescriptorProto: bookDesc,
-	}
-	createMsg := &descriptor.Message{
-		DescriptorProto: createDesc,
-	}
-
-	parentField := &descriptor.Field{
-		Message:              createMsg,
-		FieldDescriptorProto: createMsg.GetField()[0],
-	}
-	bookField := &descriptor.Field{
-		Message:              createMsg,
-		FieldMessage:         bookMsg,
-		FieldDescriptorProto: createMsg.GetField()[1],
-	}
-	bookIDField := &descriptor.Field{
-		Message:              createMsg,
-		FieldDescriptorProto: createMsg.GetField()[2],
-	}
-
-	createMsg.Fields = []*descriptor.Field{parentField, bookField, bookIDField}
-
-	file := descriptor.File{
-		FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-			SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-			Name:           proto.String("book.proto"),
-			MessageType:    []*descriptorpb.DescriptorProto{bookDesc, createDesc},
-			Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-			Options: &descriptorpb.FileOptions{
-				GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-			},
-		},
-		GoPkg: descriptor.GoPackage{
-			Path: "example.com/path/to/book.pb",
-			Name: "book_pb",
-		},
-		Messages: []*descriptor.Message{bookMsg, createMsg},
-		Services: []*descriptor.Service{
-			{
-				ServiceDescriptorProto: svc,
-				Methods: []*descriptor.Method{
-					{
-						MethodDescriptorProto: meth,
-						RequestType:           createMsg,
-						ResponseType:          bookMsg,
-						Bindings: []*descriptor.Binding{
-							{
-								HTTPMethod: "POST",
-								PathTmpl: httprule.Template{
-									Version:  1,
-									OpCodes:  []int{0, 0},
-									Template: "/v1/{parent=publishers/*}/books",
-								},
-								PathParams: []descriptor.Parameter{
-									{
-										FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
-											{
-												Name:   "parent",
-												Target: parentField,
-											},
-										}),
-										Target: parentField,
-									},
-								},
-								Body: &descriptor.Body{
-									FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
-										{
-											Name:   "book",
-											Target: bookField,
-										},
-									}),
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-	reg := descriptor.NewRegistry()
-	if err := AddErrorDefs(reg); err != nil {
-		t.Errorf("AddErrorDefs(%#v) failed with %v; want success", reg, err)
-		return
-	}
-	err := reg.Load(&pluginpb.CodeGeneratorRequest{ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto}})
-	if err != nil {
-		t.Errorf("Registry.Load() failed with %v; want success", err)
-		return
-	}
-	result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
-	if err != nil {
-		t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
-		return
-	}
-
-	if _, ok := result.Paths["/v1/{parent=publishers/*}/books"].Post.Responses["200"]; !ok {
-		t.Errorf("applyTemplate(%#v).%s = expected 200 response to be defined", file, `result.Paths["/v1/{parent=publishers/*}/books"].Post.Responses["200"]`)
-	} else {
-		if want, got, name := 3, len(result.Paths["/v1/{parent=publishers/*}/books"].Post.Parameters), `len(result.Paths["/v1/{parent=publishers/*}/books"].Post.Parameters)`; !reflect.DeepEqual(got, want) {
-			t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
-		}
-
-		type param struct {
-			Name     string
-			In       string
-			Required bool
-		}
-
-		p0 := result.Paths["/v1/{parent=publishers/*}/books"].Post.Parameters[0]
-		if want, got, name := (param{"parent", "path", true}), (param{p0.Name, p0.In, p0.Required}), `result.Paths["/v1/{parent=publishers/*}/books"].Post.Parameters[0]`; !reflect.DeepEqual(got, want) {
-			t.Errorf("applyTemplate(%#v).%s = %v want to be %v", file, name, got, want)
-		}
-		p1 := result.Paths["/v1/{parent=publishers/*}/books"].Post.Parameters[1]
-		if want, got, name := (param{"body", "body", true}), (param{p1.Name, p1.In, p1.Required}), `result.Paths["/v1/{parent=publishers/*}/books"].Post.Parameters[1]`; !reflect.DeepEqual(got, want) {
-			t.Errorf("applyTemplate(%#v).%s = %v want to be %v", file, name, got, want)
-		}
-		p2 := result.Paths["/v1/{parent=publishers/*}/books"].Post.Parameters[2]
-		if want, got, name := (param{"book_id", "query", false}), (param{p2.Name, p2.In, p2.Required}), `result.Paths["/v1/{parent=publishers/*}/books"].Post.Parameters[1]`; !reflect.DeepEqual(got, want) {
-			t.Errorf("applyTemplate(%#v).%s = %v want to be %v", file, name, got, want)
-		}
-	}
-
-	// If there was a failure, print out the input and the json result for debugging.
-	if t.Failed() {
-		t.Errorf("had: %s", file)
-		t.Errorf("got: %s", fmt.Sprint(result))
-	}
-}
-
-func generateFieldsForJSONReservedName() []*descriptor.Field {
-	fields := make([]*descriptor.Field, 0)
-	fieldName := string("json_name")
-	fieldJSONName := string("jsonNAME")
-	fieldDescriptor := descriptorpb.FieldDescriptorProto{Name: &fieldName, JsonName: &fieldJSONName}
-	field := &descriptor.Field{FieldDescriptorProto: &fieldDescriptor}
-	return append(fields, field)
-}
-
-func generateMsgsForJSONReservedName() []*descriptor.Message {
-	result := make([]*descriptor.Message, 0)
-	// The first message, its field is field_abc and its type is NewType
-	// NewType field_abc
-	fieldName := "field_abc"
-	fieldJSONName := "fieldAbc"
-	messageName1 := "message1"
-	messageType := "pkg.a.NewType"
-	pfd := descriptorpb.FieldDescriptorProto{Name: &fieldName, JsonName: &fieldJSONName, TypeName: &messageType}
-	result = append(result,
-		&descriptor.Message{
-			DescriptorProto: &descriptorpb.DescriptorProto{
-				Name: &messageName1, Field: []*descriptorpb.FieldDescriptorProto{&pfd},
-			},
-		})
-	// The second message, its name is NewName, its type is string
-	// message NewType {
-	//    string field_newName [json_name = RESERVEDJSONNAME]
-	// }
-	messageName := "NewType"
-	field := "field_newName"
-	fieldJSONName2 := "RESERVEDJSONNAME"
-	pfd2 := descriptorpb.FieldDescriptorProto{Name: &field, JsonName: &fieldJSONName2}
-	result = append(result, &descriptor.Message{
-		DescriptorProto: &descriptorpb.DescriptorProto{
-			Name: &messageName, Field: []*descriptorpb.FieldDescriptorProto{&pfd2},
-		},
-	})
-	return result
-}
-
-func TestTemplateWithJsonCamelCase(t *testing.T) {
-	var tests = []struct {
-		input    string
-		expected string
-	}{
-		{"/test/{test_id}", "/test/{testId}"},
-		{"/test1/{test1_id}/test2/{test2_id}", "/test1/{test1Id}/test2/{test2Id}"},
-		{"/test1/{test1_id}/{test2_id}", "/test1/{test1Id}/{test2Id}"},
-		{"/test1/test2/{test1_id}/{test2_id}", "/test1/test2/{test1Id}/{test2Id}"},
-		{"/test1/{test1_id1_id2}", "/test1/{test1Id1Id2}"},
-		{"/test1/{test1_id1_id2}/test2/{test2_id3_id4}", "/test1/{test1Id1Id2}/test2/{test2Id3Id4}"},
-		{"/test1/test2/{test1_id1_id2}/{test2_id3_id4}", "/test1/test2/{test1Id1Id2}/{test2Id3Id4}"},
-		{"test/{a}", "test/{a}"},
-		{"test/{ab}", "test/{ab}"},
-		{"test/{a_a}", "test/{aA}"},
-		{"test/{ab_c}", "test/{abC}"},
-		{"test/{json_name}", "test/{jsonNAME}"},
-		{"test/{field_abc.field_newName}", "test/{fieldAbc.RESERVEDJSONNAME}"},
-	}
-	reg := descriptor.NewRegistry()
-	reg.SetUseJSONNamesForFields(true)
-	for _, data := range tests {
-		actual := templateToOpenAPIPath(data.input, reg, generateFieldsForJSONReservedName(), generateMsgsForJSONReservedName())
-		if data.expected != actual {
-			t.Errorf("Expected templateToOpenAPIPath(%v) = %v, actual: %v", data.input, data.expected, actual)
-		}
-	}
-}
-
-func TestTemplateWithoutJsonCamelCase(t *testing.T) {
-	var tests = []struct {
-		input    string
-		expected string
-	}{
-		{"/test/{test_id}", "/test/{test_id}"},
-		{"/test1/{test1_id}/test2/{test2_id}", "/test1/{test1_id}/test2/{test2_id}"},
-		{"/test1/{test1_id}/{test2_id}", "/test1/{test1_id}/{test2_id}"},
-		{"/test1/test2/{test1_id}/{test2_id}", "/test1/test2/{test1_id}/{test2_id}"},
-		{"/test1/{test1_id1_id2}", "/test1/{test1_id1_id2}"},
-		{"/test1/{test1_id1_id2}/test2/{test2_id3_id4}", "/test1/{test1_id1_id2}/test2/{test2_id3_id4}"},
-		{"/test1/test2/{test1_id1_id2}/{test2_id3_id4}", "/test1/test2/{test1_id1_id2}/{test2_id3_id4}"},
-		{"test/{a}", "test/{a}"},
-		{"test/{ab}", "test/{ab}"},
-		{"test/{a_a}", "test/{a_a}"},
-		{"test/{json_name}", "test/{json_name}"},
-		{"test/{field_abc.field_newName}", "test/{field_abc.field_newName}"},
-	}
-	reg := descriptor.NewRegistry()
-	reg.SetUseJSONNamesForFields(false)
-	for _, data := range tests {
-		actual := templateToOpenAPIPath(data.input, reg, generateFieldsForJSONReservedName(), generateMsgsForJSONReservedName())
-		if data.expected != actual {
-			t.Errorf("Expected templateToOpenAPIPath(%v) = %v, actual: %v", data.input, data.expected, actual)
-		}
-	}
-}
-
-func TestTemplateToOpenAPIPath(t *testing.T) {
-	var tests = []struct {
-		input    string
-		expected string
-	}{
-		{"/test", "/test"},
-		{"/{test}", "/{test}"},
-		{"/{test=prefix/*}", "/{test}"},
-		{"/{test=prefix/that/has/multiple/parts/to/it/*}", "/{test}"},
-		{"/{test1}/{test2}", "/{test1}/{test2}"},
-		{"/{test1}/{test2}/", "/{test1}/{test2}/"},
-		{"/{name=prefix/*}", "/{name=prefix/*}"},
-		{"/{name=prefix1/*/prefix2/*}", "/{name=prefix1/*/prefix2/*}"},
-		{"/{user.name=prefix/*}", "/{user.name=prefix/*}"},
-		{"/{user.name=prefix1/*/prefix2/*}", "/{user.name=prefix1/*/prefix2/*}"},
-		{"/{parent=prefix/*}/children", "/{parent=prefix/*}/children"},
-		{"/{name=prefix/*}:customMethod", "/{name=prefix/*}:customMethod"},
-		{"/{name=prefix1/*/prefix2/*}:customMethod", "/{name=prefix1/*/prefix2/*}:customMethod"},
-		{"/{user.name=prefix/*}:customMethod", "/{user.name=prefix/*}:customMethod"},
-		{"/{user.name=prefix1/*/prefix2/*}:customMethod", "/{user.name=prefix1/*/prefix2/*}:customMethod"},
-		{"/{parent=prefix/*}/children:customMethod", "/{parent=prefix/*}/children:customMethod"},
-	}
-	reg := descriptor.NewRegistry()
-	reg.SetUseJSONNamesForFields(false)
-	for _, data := range tests {
-		actual := templateToOpenAPIPath(data.input, reg, generateFieldsForJSONReservedName(), generateMsgsForJSONReservedName())
-		if data.expected != actual {
-			t.Errorf("Expected templateToOpenAPIPath(%v) = %v, actual: %v", data.input, data.expected, actual)
-		}
-	}
-	reg.SetUseJSONNamesForFields(true)
-	for _, data := range tests {
-		actual := templateToOpenAPIPath(data.input, reg, generateFieldsForJSONReservedName(), generateMsgsForJSONReservedName())
-		if data.expected != actual {
-			t.Errorf("Expected templateToOpenAPIPath(%v) = %v, actual: %v", data.input, data.expected, actual)
-		}
-	}
-}
-
-func BenchmarkTemplateToOpenAPIPath(b *testing.B) {
-	const input = "/{user.name=prefix1/*/prefix2/*}:customMethod"
-
-	b.Run("with JSON names", func(b *testing.B) {
-		reg := descriptor.NewRegistry()
-		reg.SetUseJSONNamesForFields(false)
-
-		for i := 0; i < b.N; i++ {
-			_ = templateToOpenAPIPath(input, reg, generateFieldsForJSONReservedName(), generateMsgsForJSONReservedName())
-		}
-	})
-
-	b.Run("without JSON names", func(b *testing.B) {
-		reg := descriptor.NewRegistry()
-		reg.SetUseJSONNamesForFields(true)
-
-		for i := 0; i < b.N; i++ {
-			_ = templateToOpenAPIPath(input, reg, generateFieldsForJSONReservedName(), generateMsgsForJSONReservedName())
-		}
-	})
-}
-
-func TestResolveFullyQualifiedNameToOpenAPIName(t *testing.T) {
-	var tests = []struct {
-		input                string
-		output               string
-		listOfFQMNs          []string
-		useFQNForOpenAPIName bool
-	}{
-		{
-			".a.b.C",
-			"C",
-			[]string{
-				".a.b.C",
-			},
-			false,
-		},
-		{
-			".a.b.C",
-			"abC",
-			[]string{
-				".a.C",
-				".a.b.C",
-			},
-			false,
-		},
-		{
-			".a.b.C",
-			"abC",
-			[]string{
-				".C",
-				".a.C",
-				".a.b.C",
-			},
-			false,
-		},
-		{
-			".a.b.C",
-			"a.b.C",
-			[]string{
-				".C",
-				".a.C",
-				".a.b.C",
-			},
-			true,
-		},
-	}
-
-	for _, data := range tests {
-		names := resolveFullyQualifiedNameToOpenAPINames(data.listOfFQMNs, data.useFQNForOpenAPIName)
-		output := names[data.input]
-		if output != data.output {
-			t.Errorf("Expected fullyQualifiedNameToOpenAPIName(%v) to be %s but got %s",
-				data.input, data.output, output)
-		}
-	}
-}
-
-func TestFQMNtoOpenAPIName(t *testing.T) {
-	var tests = []struct {
-		input    string
-		expected string
-	}{
-		{"/test", "/test"},
-		{"/{test}", "/{test}"},
-		{"/{test=prefix/*}", "/{test}"},
-		{"/{test=prefix/that/has/multiple/parts/to/it/*}", "/{test}"},
-		{"/{test1}/{test2}", "/{test1}/{test2}"},
-		{"/{test1}/{test2}/", "/{test1}/{test2}/"},
-	}
-	reg := descriptor.NewRegistry()
-	reg.SetUseJSONNamesForFields(false)
-	for _, data := range tests {
-		actual := templateToOpenAPIPath(data.input, reg, generateFieldsForJSONReservedName(), generateMsgsForJSONReservedName())
-		if data.expected != actual {
-			t.Errorf("Expected templateToOpenAPIPath(%v) = %v, actual: %v", data.input, data.expected, actual)
-		}
-	}
-	reg.SetUseJSONNamesForFields(true)
-	for _, data := range tests {
-		actual := templateToOpenAPIPath(data.input, reg, generateFieldsForJSONReservedName(), generateMsgsForJSONReservedName())
-		if data.expected != actual {
-			t.Errorf("Expected templateToOpenAPIPath(%v) = %v, actual: %v", data.input, data.expected, actual)
-		}
-	}
-}
-
-func TestSchemaOfField(t *testing.T) {
-	type test struct {
-		field          *descriptor.Field
-		refs           refMap
-		expected       openapiSchemaObject
-		openAPIOptions *openapiconfig.OpenAPIOptions
-	}
-
-	jsonSchema := &openapi_options.JSONSchema{
-		Title:       "field title",
-		Description: "field description",
-	}
-
-	var fieldOptions = new(descriptorpb.FieldOptions)
-	proto.SetExtension(fieldOptions, openapi_options.E_Openapiv2Field, jsonSchema)
-
-	var requiredField = []annotations.FieldBehavior{annotations.FieldBehavior_REQUIRED}
-	var requiredFieldOptions = new(descriptorpb.FieldOptions)
-	proto.SetExtension(requiredFieldOptions, annotations.E_FieldBehavior, requiredField)
-
-	var outputOnlyField = []annotations.FieldBehavior{annotations.FieldBehavior_OUTPUT_ONLY}
-	var outputOnlyOptions = new(descriptorpb.FieldOptions)
-	proto.SetExtension(outputOnlyOptions, annotations.E_FieldBehavior, outputOnlyField)
-
-	tests := []test{
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name: proto.String("primitive_field"),
-					Type: descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "string",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:  proto.String("repeated_primitive_field"),
-					Type:  descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-					Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "array",
-					Items: &openapiItemsObject{
-						Type: "string",
-					},
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.FieldMask"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "string",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.Timestamp"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "string",
-					Format: "date-time",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.Duration"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "string",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.StringValue"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "string",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("repeated_wrapped_field"),
-					TypeName: proto.String(".google.protobuf.StringValue"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-					Label:    descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "array",
-					Items: &openapiItemsObject{
-						Type: "string",
-					},
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.BytesValue"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "string",
-					Format: "byte",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.Int32Value"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "integer",
-					Format: "int32",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.UInt32Value"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "integer",
-					Format: "int64",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.Int64Value"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "string",
-					Format: "int64",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.UInt64Value"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "string",
-					Format: "uint64",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.FloatValue"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "number",
-					Format: "float",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.DoubleValue"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "number",
-					Format: "double",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.BoolValue"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "boolean",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.Struct"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "object",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.Value"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "object",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.ListValue"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "array",
-					Items: (*openapiItemsObject)(&schemaCore{
-						Type: "object",
-					}),
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("wrapped_field"),
-					TypeName: proto.String(".google.protobuf.NullValue"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_ENUM.Enum(),
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "string",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("message_field"),
-					TypeName: proto.String(".example.Message"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-				},
-			},
-			refs: refMap{".example.Message": struct{}{}},
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Ref: "#/definitions/exampleMessage",
-				},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("map_field"),
-					Label:    descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-					TypeName: proto.String(".example.Message.MapFieldEntry"),
-					Options:  fieldOptions,
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "object",
-				},
-				AdditionalProperties: &openapiSchemaObject{
-					schemaCore: schemaCore{Type: "string"},
-				},
-				Title:       "field title",
-				Description: "field description",
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:    proto.String("array_field"),
-					Label:   descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
-					Type:    descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-					Options: fieldOptions,
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:  "array",
-					Items: (*openapiItemsObject)(&schemaCore{Type: "string"}),
-				},
-				Title:       "field title",
-				Description: "field description",
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:    proto.String("primitive_field"),
-					Label:   descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-					Type:    descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
-					Options: fieldOptions,
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "integer",
-					Format: "int32",
-				},
-				Title:       "field title",
-				Description: "field description",
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("message_field"),
-					Label:    descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-					TypeName: proto.String(".example.Empty"),
-					Options:  fieldOptions,
-				},
-			},
-			refs: refMap{".example.Empty": struct{}{}},
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Ref: "#/definitions/exampleEmpty",
-				},
-				Title:       "field title",
-				Description: "field description",
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("map_field"), // should be called map_field_option but it's not valid map field name
-					Label:    descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-					TypeName: proto.String(".example.Message.MapFieldEntry"),
-				},
-			},
-			openAPIOptions: &openapiconfig.OpenAPIOptions{
-				Field: []*openapiconfig.OpenAPIFieldOption{
-					{
-						Field:  "example.Message.map_field",
-						Option: jsonSchema,
-					},
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "object",
-				},
-				AdditionalProperties: &openapiSchemaObject{
-					schemaCore: schemaCore{Type: "string"},
-				},
-				Title:       "field title",
-				Description: "field description",
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:  proto.String("array_field_option"),
-					Label: descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
-					Type:  descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-				},
-			},
-			openAPIOptions: &openapiconfig.OpenAPIOptions{
-				Field: []*openapiconfig.OpenAPIFieldOption{
-					{
-						Field:  "example.Message.array_field_option",
-						Option: jsonSchema,
-					},
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:  "array",
-					Items: (*openapiItemsObject)(&schemaCore{Type: "string"}),
-				},
-				Title:       "field title",
-				Description: "field description",
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:  proto.String("primitive_field_option"),
-					Label: descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-					Type:  descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
-				},
-			},
-			openAPIOptions: &openapiconfig.OpenAPIOptions{
-				Field: []*openapiconfig.OpenAPIFieldOption{
-					{
-						Field:  "example.Message.primitive_field_option",
-						Option: jsonSchema,
-					},
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type:   "integer",
-					Format: "int32",
-				},
-				Title:       "field title",
-				Description: "field description",
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("message_field_option"),
-					Label:    descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-					TypeName: proto.String(".example.Empty"),
-				},
-			},
-			openAPIOptions: &openapiconfig.OpenAPIOptions{
-				Field: []*openapiconfig.OpenAPIFieldOption{
-					{
-						Field:  "example.Message.message_field_option",
-						Option: jsonSchema,
-					},
-				},
-			},
-			refs: refMap{".example.Empty": struct{}{}},
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Ref: "#/definitions/exampleEmpty",
-				},
-				Title:       "field title",
-				Description: "field description",
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:    proto.String("required_via_field_behavior_field"),
-					Type:    descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-					Options: requiredFieldOptions,
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "string",
-				},
-				Required: []string{"required_via_field_behavior_field"},
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:    proto.String("readonly_via_field_behavior_field"),
-					Type:    descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-					Options: outputOnlyOptions,
-				},
-			},
-			refs: make(refMap),
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Type: "string",
-				},
-				ReadOnly: true,
-			},
-		},
-		{
-			field: &descriptor.Field{
-				FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-					Name:     proto.String("message_field"),
-					TypeName: proto.String(".example.Message"),
-					Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
-					Options:  requiredFieldOptions,
-				},
-			},
-			refs: refMap{".example.Message": struct{}{}},
-			expected: openapiSchemaObject{
-				schemaCore: schemaCore{
-					Ref: "#/definitions/exampleMessage",
-				},
-			},
-		},
-	}
-	for _, test := range tests {
-		reg := descriptor.NewRegistry()
-		req := &pluginpb.CodeGeneratorRequest{
-			ProtoFile: []*descriptorpb.FileDescriptorProto{
-				{
-					Name:    proto.String("third_party/google.proto"),
-					Package: proto.String("google.protobuf"),
-					Options: &descriptorpb.FileOptions{
-						GoPackage: proto.String("third_party/google"),
-					},
-					MessageType: []*descriptorpb.DescriptorProto{
-						protodesc.ToDescriptorProto((&structpb.Struct{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&structpb.Value{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&structpb.ListValue{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&field_mask.FieldMask{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&timestamppb.Timestamp{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&durationpb.Duration{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&wrapperspb.StringValue{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&wrapperspb.BytesValue{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&wrapperspb.Int32Value{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&wrapperspb.UInt32Value{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&wrapperspb.Int64Value{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&wrapperspb.UInt64Value{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&wrapperspb.FloatValue{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&wrapperspb.DoubleValue{}).ProtoReflect().Descriptor()),
-						protodesc.ToDescriptorProto((&wrapperspb.BoolValue{}).ProtoReflect().Descriptor()),
-					},
-					EnumType: []*descriptorpb.EnumDescriptorProto{
-						protodesc.ToEnumDescriptorProto(structpb.NullValue(0).Descriptor()),
-					},
-				},
-				{
-					SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-					Name:           proto.String("example.proto"),
-					Package:        proto.String("example"),
-					Dependency:     []string{"third_party/google.proto"},
-					Options: &descriptorpb.FileOptions{
-						GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-					},
-					MessageType: []*descriptorpb.DescriptorProto{
-						{
-							Name: proto.String("Message"),
-							Field: []*descriptorpb.FieldDescriptorProto{
-								{
-									Name:   proto.String("value"),
-									Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-									Number: proto.Int32(1),
-								},
-								func() *descriptorpb.FieldDescriptorProto {
-									fd := test.field.FieldDescriptorProto
-									fd.Number = proto.Int32(2)
-									return fd
-								}(),
-							},
-							NestedType: []*descriptorpb.DescriptorProto{
-								{
-									Name:    proto.String("MapFieldEntry"),
-									Options: &descriptorpb.MessageOptions{MapEntry: proto.Bool(true)},
-									Field: []*descriptorpb.FieldDescriptorProto{
-										{
-											Name:   proto.String("key"),
-											Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-											Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-											Number: proto.Int32(1),
-										},
-										{
-											Name:   proto.String("value"),
-											Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
-											Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-											Number: proto.Int32(2),
-										},
-									},
-								},
-							},
-						},
-						{
-							Name: proto.String("Empty"),
-						},
-					},
-					EnumType: []*descriptorpb.EnumDescriptorProto{
-						{
-							Name: proto.String("MessageType"),
-							Value: []*descriptorpb.EnumValueDescriptorProto{
-								{
-									Name:   proto.String("MESSAGE_TYPE_1"),
-									Number: proto.Int32(0),
-								},
-							},
-						},
-					},
-					Service: []*descriptorpb.ServiceDescriptorProto{},
-				},
-			},
-		}
-		err := reg.Load(req)
-		if err != nil {
-			t.Errorf("failed to reg.Load(req): %v", err)
-		}
-
-		// set field's parent message pointer to message so field can resolve its FQFN
-		test.field.Message = &descriptor.Message{
-			DescriptorProto: req.ProtoFile[1].MessageType[0],
-			File: &descriptor.File{
-				FileDescriptorProto: req.ProtoFile[1],
-			},
-		}
-
-		if test.openAPIOptions != nil {
-			if err := reg.RegisterOpenAPIOptions(test.openAPIOptions); err != nil {
-				t.Fatalf("failed to register OpenAPI options: %s", err)
-			}
-		}
-
-		refs := make(refMap)
-		actual := schemaOfField(test.field, reg, refs)
-		expectedSchemaObject := test.expected
-		if e, a := expectedSchemaObject, actual; !reflect.DeepEqual(a, e) {
-			t.Errorf("Expected schemaOfField(%v) = \n%#+v, actual: \n%#+v", test.field, e, a)
-		}
-		if !reflect.DeepEqual(refs, test.refs) {
-			t.Errorf("Expected schemaOfField(%v) to add refs %v, not %v", test.field, test.refs, refs)
-		}
-	}
-}
-
-func TestRenderMessagesAsDefinition(t *testing.T) {
-	jsonSchema := &openapi_options.JSONSchema{
-		Title:       "field title",
-		Description: "field description",
-		Required:    []string{"aRequiredField"},
-	}
-
-	var requiredField = new(descriptorpb.FieldOptions)
-	proto.SetExtension(requiredField, openapi_options.E_Openapiv2Field, jsonSchema)
-
-	var fieldBehaviorRequired = []annotations.FieldBehavior{annotations.FieldBehavior_REQUIRED}
-	var requiredFieldOptions = new(descriptorpb.FieldOptions)
-	proto.SetExtension(requiredFieldOptions, annotations.E_FieldBehavior, fieldBehaviorRequired)
-
-	var fieldBehaviorOutputOnlyField = []annotations.FieldBehavior{annotations.FieldBehavior_OUTPUT_ONLY}
-	var fieldBehaviorOutputOnlyOptions = new(descriptorpb.FieldOptions)
-	proto.SetExtension(fieldBehaviorOutputOnlyOptions, annotations.E_FieldBehavior, fieldBehaviorOutputOnlyField)
-
-	tests := []struct {
-		descr          string
-		msgDescs       []*descriptorpb.DescriptorProto
-		schema         map[string]openapi_options.Schema // per-message schema to add
-		defs           openapiDefinitionsObject
-		openAPIOptions *openapiconfig.OpenAPIOptions
-		excludedFields []*descriptor.Field
-	}{
-		{
-			descr: "no OpenAPI options",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{Name: proto.String("Message")},
-			},
-			schema: map[string]openapi_options.Schema{},
-			defs: map[string]openapiSchemaObject{
-				"Message": {schemaCore: schemaCore{Type: "object"}},
-			},
-		},
-		{
-			descr: "example option",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{Name: proto.String("Message")},
-			},
-			schema: map[string]openapi_options.Schema{
-				"Message": {
-					Example: `{"foo":"bar"}`,
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {schemaCore: schemaCore{
-					Type:    "object",
-					Example: json.RawMessage(`{"foo":"bar"}`),
-				}},
-			},
-		},
-		{
-			descr: "example option with something non-json",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{Name: proto.String("Message")},
-			},
-			schema: map[string]openapi_options.Schema{
-				"Message": {
-					Example: `XXXX anything goes XXXX`,
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {schemaCore: schemaCore{
-					Type:    "object",
-					Example: json.RawMessage(`XXXX anything goes XXXX`),
-				}},
-			},
-		},
-		{
-			descr: "external docs option",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{Name: proto.String("Message")},
-			},
-			schema: map[string]openapi_options.Schema{
-				"Message": {
-					ExternalDocs: &openapi_options.ExternalDocumentation{
-						Description: "glorious docs",
-						Url:         "https://nada",
-					},
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {
-					schemaCore: schemaCore{
-						Type: "object",
-					},
-					ExternalDocs: &openapiExternalDocumentationObject{
-						Description: "glorious docs",
-						URL:         "https://nada",
-					},
-				},
-			},
-		},
-		{
-			descr: "JSONSchema options",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{Name: proto.String("Message")},
-			},
-			schema: map[string]openapi_options.Schema{
-				"Message": {
-					JsonSchema: &openapi_options.JSONSchema{
-						Title:            "title",
-						Description:      "desc",
-						MultipleOf:       100,
-						Maximum:          101,
-						ExclusiveMaximum: true,
-						Minimum:          1,
-						ExclusiveMinimum: true,
-						MaxLength:        10,
-						MinLength:        3,
-						Pattern:          "[a-z]+",
-						MaxItems:         20,
-						MinItems:         2,
-						UniqueItems:      true,
-						MaxProperties:    33,
-						MinProperties:    22,
-						Required:         []string{"req"},
-						ReadOnly:         true,
-					},
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {
-					schemaCore: schemaCore{
-						Type: "object",
-					},
-					Title:            "title",
-					Description:      "desc",
-					MultipleOf:       100,
-					Maximum:          101,
-					ExclusiveMaximum: true,
-					Minimum:          1,
-					ExclusiveMinimum: true,
-					MaxLength:        10,
-					MinLength:        3,
-					Pattern:          "[a-z]+",
-					MaxItems:         20,
-					MinItems:         2,
-					UniqueItems:      true,
-					MaxProperties:    33,
-					MinProperties:    22,
-					Required:         []string{"req"},
-					ReadOnly:         true,
-				},
-			},
-		},
-		{
-			descr: "JSONSchema options from registry",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{Name: proto.String("Message")},
-			},
-			openAPIOptions: &openapiconfig.OpenAPIOptions{
-				Message: []*openapiconfig.OpenAPIMessageOption{
-					{
-						Message: "example.Message",
-						Option: &openapi_options.Schema{
-							JsonSchema: &openapi_options.JSONSchema{
-								Title:            "title",
-								Description:      "desc",
-								MultipleOf:       100,
-								Maximum:          101,
-								ExclusiveMaximum: true,
-								Minimum:          1,
-								ExclusiveMinimum: true,
-								MaxLength:        10,
-								MinLength:        3,
-								Pattern:          "[a-z]+",
-								MaxItems:         20,
-								MinItems:         2,
-								UniqueItems:      true,
-								MaxProperties:    33,
-								MinProperties:    22,
-								Required:         []string{"req"},
-								ReadOnly:         true,
-							},
-						},
-					},
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {
-					schemaCore: schemaCore{
-						Type: "object",
-					},
-					Title:            "title",
-					Description:      "desc",
-					MultipleOf:       100,
-					Maximum:          101,
-					ExclusiveMaximum: true,
-					Minimum:          1,
-					ExclusiveMinimum: true,
-					MaxLength:        10,
-					MinLength:        3,
-					Pattern:          "[a-z]+",
-					MaxItems:         20,
-					MinItems:         2,
-					UniqueItems:      true,
-					MaxProperties:    33,
-					MinProperties:    22,
-					Required:         []string{"req"},
-					ReadOnly:         true,
-				},
-			},
-		},
-		{
-			descr: "JSONSchema with required properties",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("Message"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:    proto.String("aRequiredField"),
-							Type:    descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number:  proto.Int32(1),
-							Options: requiredField,
-						},
-					},
-				},
-			},
-			schema: map[string]openapi_options.Schema{
-				"Message": {
-					JsonSchema: &openapi_options.JSONSchema{
-						Title:       "title",
-						Description: "desc",
-						Required:    []string{"req"},
-					},
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {
-					schemaCore: schemaCore{
-						Type: "object",
-					},
-					Title:       "title",
-					Description: "desc",
-					Required:    []string{"req", "aRequiredField"},
-					Properties: &openapiSchemaObjectProperties{
-						{
-							Key: "aRequiredField",
-							Value: openapiSchemaObject{
-								schemaCore: schemaCore{
-									Type: "string",
-								},
-								Description: "field description",
-								Title:       "field title",
-								Required:    []string{"aRequiredField"},
-							},
-						},
-					},
-				},
-			},
-		},
-		{
-			descr: "JSONSchema with excluded fields",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("Message"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:    proto.String("aRequiredField"),
-							Type:    descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number:  proto.Int32(1),
-							Options: requiredField,
-						},
-						{
-							Name:   proto.String("anExcludedField"),
-							Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number: proto.Int32(2),
-						},
-					},
-				},
-			},
-			schema: map[string]openapi_options.Schema{
-				"Message": {
-					JsonSchema: &openapi_options.JSONSchema{
-						Title:       "title",
-						Description: "desc",
-						Required:    []string{"req"},
-					},
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {
-					schemaCore: schemaCore{
-						Type: "object",
-					},
-					Title:       "title",
-					Description: "desc",
-					Required:    []string{"req", "aRequiredField"},
-					Properties: &openapiSchemaObjectProperties{
-						{
-							Key: "aRequiredField",
-							Value: openapiSchemaObject{
-								schemaCore: schemaCore{
-									Type: "string",
-								},
-								Description: "field description",
-								Title:       "field title",
-								Required:    []string{"aRequiredField"},
-							},
-						},
-					},
-				},
-			},
-			excludedFields: []*descriptor.Field{
-				{
-					FieldDescriptorProto: &descriptorpb.FieldDescriptorProto{
-						Name: strPtr("anExcludedField"),
-					},
-				},
-			},
-		},
-		{
-			descr: "JSONSchema with required properties via field_behavior",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{
-					Name: proto.String("Message"),
-					Field: []*descriptorpb.FieldDescriptorProto{
-						{
-							Name:    proto.String("aRequiredField"),
-							Type:    descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number:  proto.Int32(1),
-							Options: requiredFieldOptions,
-						},
-						{
-							Name:    proto.String("aOutputOnlyField"),
-							Type:    descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
-							Number:  proto.Int32(2),
-							Options: fieldBehaviorOutputOnlyOptions,
-						},
-					},
-				},
-			},
-			schema: map[string]openapi_options.Schema{
-				"Message": {
-					JsonSchema: &openapi_options.JSONSchema{
-						Title:       "title",
-						Description: "desc",
-						Required:    []string{"req"},
-					},
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {
-					schemaCore: schemaCore{
-						Type: "object",
-					},
-					Title:       "title",
-					Description: "desc",
-					Required:    []string{"req", "aRequiredField"},
-					Properties: &openapiSchemaObjectProperties{
-						{
-							Key: "aRequiredField",
-							Value: openapiSchemaObject{
-								schemaCore: schemaCore{
-									Type: "string",
-								},
-								Required: []string{"aRequiredField"},
-							},
-						},
-						{
-							Key: "aOutputOnlyField",
-							Value: openapiSchemaObject{
-								schemaCore: schemaCore{
-									Type: "string",
-								},
-								ReadOnly: true,
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.descr, func(t *testing.T) {
-
-			msgs := []*descriptor.Message{}
-			for _, msgdesc := range test.msgDescs {
-				msgdesc.Options = &descriptorpb.MessageOptions{}
-				msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
-			}
-
-			reg := descriptor.NewRegistry()
-			file := descriptor.File{
-				FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-					SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-					Name:           proto.String("example.proto"),
-					Package:        proto.String("example"),
-					Dependency:     []string{},
-					MessageType:    test.msgDescs,
-					EnumType:       []*descriptorpb.EnumDescriptorProto{},
-					Service:        []*descriptorpb.ServiceDescriptorProto{},
-					Options: &descriptorpb.FileOptions{
-						GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-					},
-				},
-				Messages: msgs,
-			}
-			err := reg.Load(&pluginpb.CodeGeneratorRequest{
-				ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-			})
-			if err != nil {
-				t.Fatalf("failed to load code generator request: %v", err)
-			}
-
-			msgMap := map[string]*descriptor.Message{}
-			for _, d := range test.msgDescs {
-				name := d.GetName()
-				msg, err := reg.LookupMsg("example", name)
-				if err != nil {
-					t.Fatalf("lookup message %v: %v", name, err)
-				}
-				msgMap[msg.FQMN()] = msg
-
-				if schema, ok := test.schema[name]; ok {
-					proto.SetExtension(d.Options, openapi_options.E_Openapiv2Schema, &schema)
-				}
-			}
-
-			if test.openAPIOptions != nil {
-				if err := reg.RegisterOpenAPIOptions(test.openAPIOptions); err != nil {
-					t.Fatalf("failed to register OpenAPI options: %s", err)
-				}
-			}
-
-			refs := make(refMap)
-			actual := make(openapiDefinitionsObject)
-			renderMessagesAsDefinition(msgMap, actual, reg, refs, test.excludedFields)
-
-			if !reflect.DeepEqual(actual, test.defs) {
-				t.Errorf("Expected renderMessagesAsDefinition() to add defs %+v, not %+v", test.defs, actual)
-			}
-		})
-	}
-}
-
-func strPtr(s string) *string {
-	return &s
-}
-
-func TestUpdateOpenAPIDataFromComments(t *testing.T) {
-
-	tests := []struct {
-		descr                 string
-		openapiSwaggerObject  interface{}
-		comments              string
-		expectedError         error
-		expectedOpenAPIObject interface{}
-		useGoTemplate         bool
-	}{
-		{
-			descr:                 "empty comments",
-			openapiSwaggerObject:  nil,
-			expectedOpenAPIObject: nil,
-			comments:              "",
-			expectedError:         nil,
-		},
-		{
-			descr:                "set field to read only",
-			openapiSwaggerObject: &openapiSchemaObject{},
-			expectedOpenAPIObject: &openapiSchemaObject{
-				ReadOnly:    true,
-				Description: "... Output only. ...",
-			},
-			comments:      "... Output only. ...",
-			expectedError: nil,
-		},
-		{
-			descr:                "set title",
-			openapiSwaggerObject: &openapiSchemaObject{},
-			expectedOpenAPIObject: &openapiSchemaObject{
-				Title: "Comment with no trailing dot",
-			},
-			comments:      "Comment with no trailing dot",
-			expectedError: nil,
-		},
-		{
-			descr:                "set description",
-			openapiSwaggerObject: &openapiSchemaObject{},
-			expectedOpenAPIObject: &openapiSchemaObject{
-				Description: "Comment with trailing dot.",
-			},
-			comments:      "Comment with trailing dot.",
-			expectedError: nil,
-		},
-		{
-			descr: "use info object",
-			openapiSwaggerObject: &openapiSwaggerObject{
-				Info: openapiInfoObject{},
-			},
-			expectedOpenAPIObject: &openapiSwaggerObject{
-				Info: openapiInfoObject{
-					Description: "Comment with trailing dot.",
-				},
-			},
-			comments:      "Comment with trailing dot.",
-			expectedError: nil,
-		},
-		{
-			descr:                "multi line comment with title",
-			openapiSwaggerObject: &openapiSchemaObject{},
-			expectedOpenAPIObject: &openapiSchemaObject{
-				Title:       "First line",
-				Description: "Second line",
-			},
-			comments:      "First line\n\nSecond line",
-			expectedError: nil,
-		},
-		{
-			descr:                "multi line comment no title",
-			openapiSwaggerObject: &openapiSchemaObject{},
-			expectedOpenAPIObject: &openapiSchemaObject{
-				Description: "First line.\n\nSecond line",
-			},
-			comments:      "First line.\n\nSecond line",
-			expectedError: nil,
-		},
-		{
-			descr:                "multi line comment with summary with dot",
-			openapiSwaggerObject: &openapiOperationObject{},
-			expectedOpenAPIObject: &openapiOperationObject{
-				Summary:     "First line.",
-				Description: "Second line",
-			},
-			comments:      "First line.\n\nSecond line",
-			expectedError: nil,
-		},
-		{
-			descr:                "multi line comment with summary no dot",
-			openapiSwaggerObject: &openapiOperationObject{},
-			expectedOpenAPIObject: &openapiOperationObject{
-				Summary:     "First line",
-				Description: "Second line",
-			},
-			comments:      "First line\n\nSecond line",
-			expectedError: nil,
-		},
-		{
-			descr:                 "multi line comment with summary no dot",
-			openapiSwaggerObject:  &schemaCore{},
-			expectedOpenAPIObject: &schemaCore{},
-			comments:              "Any comment",
-			expectedError:         errors.New("no description nor summary property"),
-		},
-		{
-			descr:                "without use_go_template",
-			openapiSwaggerObject: &openapiSchemaObject{},
-			expectedOpenAPIObject: &openapiSchemaObject{
-				Title:       "First line",
-				Description: "{{import \"documentation.md\"}}",
-			},
-			comments:      "First line\n\n{{import \"documentation.md\"}}",
-			expectedError: nil,
-		},
-		{
-			descr:                "error with use_go_template",
-			openapiSwaggerObject: &openapiSchemaObject{},
-			expectedOpenAPIObject: &openapiSchemaObject{
-				Title:       "First line",
-				Description: "open noneexistingfile.txt: no such file or directory",
-			},
-			comments:      "First line\n\n{{import \"noneexistingfile.txt\"}}",
-			expectedError: nil,
-			useGoTemplate: true,
-		},
-		{
-			descr:                "template with use_go_template",
-			openapiSwaggerObject: &openapiSchemaObject{},
-			expectedOpenAPIObject: &openapiSchemaObject{
-				Title:       "Template",
-				Description: `Description "which means nothing"`,
-			},
-			comments:      "Template\n\nDescription {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
-			expectedError: nil,
-			useGoTemplate: true,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.descr, func(t *testing.T) {
-			reg := descriptor.NewRegistry()
-			if test.useGoTemplate {
-				reg.SetUseGoTemplate(true)
-			}
-			err := updateOpenAPIDataFromComments(reg, test.openapiSwaggerObject, nil, test.comments, false)
-			if test.expectedError == nil {
-				if err != nil {
-					t.Errorf("unexpected error '%v'", err)
-				}
-				if !reflect.DeepEqual(test.openapiSwaggerObject, test.expectedOpenAPIObject) {
-					t.Errorf("openapiSwaggerObject was not updated correctly, expected '%+v', got '%+v'", test.expectedOpenAPIObject, test.openapiSwaggerObject)
-				}
-			} else {
-				if err == nil {
-					t.Error("expected update error not returned")
-				}
-				if !reflect.DeepEqual(test.openapiSwaggerObject, test.expectedOpenAPIObject) {
-					t.Errorf("openapiSwaggerObject was not updated correctly, expected '%+v', got '%+v'", test.expectedOpenAPIObject, test.openapiSwaggerObject)
-				}
-				if err.Error() != test.expectedError.Error() {
-					t.Errorf("expected error malformed, expected %q, got %q", test.expectedError.Error(), err.Error())
-				}
-			}
-		})
-	}
-}
-
-func TestMessageOptionsWithGoTemplate(t *testing.T) {
-	tests := []struct {
-		descr          string
-		msgDescs       []*descriptorpb.DescriptorProto
-		schema         map[string]openapi_options.Schema // per-message schema to add
-		defs           openapiDefinitionsObject
-		openAPIOptions *openapiconfig.OpenAPIOptions
-		useGoTemplate  bool
-	}{
-		{
-			descr: "external docs option",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{Name: proto.String("Message")},
-			},
-			schema: map[string]openapi_options.Schema{
-				"Message": {
-					JsonSchema: &openapi_options.JSONSchema{
-						Title:       "{{.Name}}",
-						Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
-					},
-					ExternalDocs: &openapi_options.ExternalDocumentation{
-						Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
-					},
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {
-					schemaCore: schemaCore{
-						Type: "object",
-					},
-					Title:       "Message",
-					Description: `Description "which means nothing"`,
-					ExternalDocs: &openapiExternalDocumentationObject{
-						Description: `Description "which means nothing"`,
-					},
-				},
-			},
-			useGoTemplate: true,
-		},
-		{
-			descr: "external docs option",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{Name: proto.String("Message")},
-			},
-			schema: map[string]openapi_options.Schema{
-				"Message": {
-					JsonSchema: &openapi_options.JSONSchema{
-						Title:       "{{.Name}}",
-						Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
-					},
-					ExternalDocs: &openapi_options.ExternalDocumentation{
-						Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
-					},
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {
-					schemaCore: schemaCore{
-						Type: "object",
-					},
-					Title:       "{{.Name}}",
-					Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
-					ExternalDocs: &openapiExternalDocumentationObject{
-						Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
-					},
-				},
-			},
-			useGoTemplate: false,
-		},
-		{
-			descr: "registered OpenAPIOption",
-			msgDescs: []*descriptorpb.DescriptorProto{
-				{Name: proto.String("Message")},
-			},
-			openAPIOptions: &openapiconfig.OpenAPIOptions{
-				Message: []*openapiconfig.OpenAPIMessageOption{
-					{
-						Message: "example.Message",
-						Option: &openapi_options.Schema{
-							JsonSchema: &openapi_options.JSONSchema{
-								Title:       "{{.Name}}",
-								Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
-							},
-							ExternalDocs: &openapi_options.ExternalDocumentation{
-								Description: "Description {{with \"which means nothing\"}}{{printf \"%q\" .}}{{end}}",
-							},
-						},
-					},
-				},
-			},
-			defs: map[string]openapiSchemaObject{
-				"Message": {
-					schemaCore: schemaCore{
-						Type: "object",
-					},
-					Title:       "Message",
-					Description: `Description "which means nothing"`,
-					ExternalDocs: &openapiExternalDocumentationObject{
-						Description: `Description "which means nothing"`,
-					},
-				},
-			},
-			useGoTemplate: true,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.descr, func(t *testing.T) {
-
-			msgs := []*descriptor.Message{}
-			for _, msgdesc := range test.msgDescs {
-				msgdesc.Options = &descriptorpb.MessageOptions{}
-				msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
-			}
-
-			reg := descriptor.NewRegistry()
-			reg.SetUseGoTemplate(test.useGoTemplate)
-			file := descriptor.File{
-				FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-					SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-					Name:           proto.String("example.proto"),
-					Package:        proto.String("example"),
-					Dependency:     []string{},
-					MessageType:    test.msgDescs,
-					EnumType:       []*descriptorpb.EnumDescriptorProto{},
-					Service:        []*descriptorpb.ServiceDescriptorProto{},
-					Options: &descriptorpb.FileOptions{
-						GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-					},
-				},
-				Messages: msgs,
-			}
-			err := reg.Load(&pluginpb.CodeGeneratorRequest{
-				ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto},
-			})
-			if err != nil {
-				t.Fatalf("failed to load code generator request: %v", err)
-			}
-
-			msgMap := map[string]*descriptor.Message{}
-			for _, d := range test.msgDescs {
-				name := d.GetName()
-				msg, err := reg.LookupMsg("example", name)
-				if err != nil {
-					t.Fatalf("lookup message %v: %v", name, err)
-				}
-				msgMap[msg.FQMN()] = msg
-
-				if schema, ok := test.schema[name]; ok {
-					proto.SetExtension(d.Options, openapi_options.E_Openapiv2Schema, &schema)
-				}
-			}
-
-			if test.openAPIOptions != nil {
-				if err := reg.RegisterOpenAPIOptions(test.openAPIOptions); err != nil {
-					t.Fatalf("failed to register OpenAPI options: %s", err)
-				}
-			}
-
-			refs := make(refMap)
-			actual := make(openapiDefinitionsObject)
-			renderMessagesAsDefinition(msgMap, actual, reg, refs, nil)
-
-			if !reflect.DeepEqual(actual, test.defs) {
-				t.Errorf("Expected renderMessagesAsDefinition() to add defs %+v, not %+v", test.defs, actual)
-			}
-		})
-	}
-}
-
-func TestTemplateWithoutErrorDefinition(t *testing.T) {
-	msgdesc := &descriptorpb.DescriptorProto{
-		Name:  proto.String("ExampleMessage"),
-		Field: []*descriptorpb.FieldDescriptorProto{},
-	}
-	meth := &descriptorpb.MethodDescriptorProto{
-		Name:       proto.String("Echo"),
-		InputType:  proto.String("ExampleMessage"),
-		OutputType: proto.String("ExampleMessage"),
-	}
-	svc := &descriptorpb.ServiceDescriptorProto{
-		Name:   proto.String("ExampleService"),
-		Method: []*descriptorpb.MethodDescriptorProto{meth},
-	}
-
-	msg := &descriptor.Message{
-		DescriptorProto: msgdesc,
-	}
-
-	file := descriptor.File{
-		FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-			SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-			Name:           proto.String("example.proto"),
-			Package:        proto.String("example"),
-			MessageType:    []*descriptorpb.DescriptorProto{msgdesc},
-			Service:        []*descriptorpb.ServiceDescriptorProto{svc},
-			Options: &descriptorpb.FileOptions{
-				GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-			},
-		},
-		GoPkg: descriptor.GoPackage{
-			Path: "example.com/path/to/example/example.pb",
-			Name: "example_pb",
-		},
-		Messages: []*descriptor.Message{msg},
-		Services: []*descriptor.Service{
-			{
-				ServiceDescriptorProto: svc,
-				Methods: []*descriptor.Method{
-					{
-						MethodDescriptorProto: meth,
-						RequestType:           msg,
-						ResponseType:          msg,
-						Bindings: []*descriptor.Binding{
-							{
-								HTTPMethod: "POST",
-								PathTmpl: httprule.Template{
-									Version:  1,
-									OpCodes:  []int{0, 0},
-									Template: "/v1/echo",
-								},
-								Body: &descriptor.Body{
-									FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{}),
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-	reg := descriptor.NewRegistry()
-	err := reg.Load(&pluginpb.CodeGeneratorRequest{ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto}})
-	if err != nil {
-		t.Errorf("failed to reg.Load(): %v", err)
-		return
-	}
-	result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
-	if err != nil {
-		t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
-		return
-	}
-
-	defRsp, ok := result.Paths["/v1/echo"].Post.Responses["default"]
-	if !ok {
-		return
-	}
-
-	ref := defRsp.Schema.schemaCore.Ref
-	refName := strings.TrimPrefix(ref, "#/definitions/")
-	if refName == "" {
-		t.Fatal("created default Error response with empty reflink")
-	}
-
-	if _, ok := result.Definitions[refName]; !ok {
-		t.Errorf("default Error response with reflink '%v', but its definition was not found", refName)
-	}
-}
-
-func Test_getReservedJsonName(t *testing.T) {
-	type args struct {
-		fieldName                     string
-		messageNameToFieldsToJSONName map[string]map[string]string
-		fieldNameToType               map[string]string
-	}
-	tests := []struct {
-		name string
-		args args
-		want string
-	}{
-		{
-			"test case 1: single dot use case",
-			args{
-				fieldName: "abc.a_1",
-				messageNameToFieldsToJSONName: map[string]map[string]string{
-					"Msg": {
-						"a_1": "a1JSONNAME",
-						"b_1": "b1JSONNAME",
-					},
-				},
-				fieldNameToType: map[string]string{
-					"abc": "pkg1.test.Msg",
-					"bcd": "pkg1.test.Msg",
-				},
-			},
-			"a1JSONNAME",
-		},
-		{
-			"test case 2: single dot use case with no existing field",
-			args{
-				fieldName: "abc.d_1",
-				messageNameToFieldsToJSONName: map[string]map[string]string{
-					"Msg": {
-						"a_1": "a1JSONNAME",
-						"b_1": "b1JSONNAME",
-					},
-				},
-				fieldNameToType: map[string]string{
-					"abc": "pkg1.test.Msg",
-					"bcd": "pkg1.test.Msg",
-				},
-			},
-			"",
-		},
-		{
-			"test case 3: double dot use case",
-			args{
-				fieldName: "pkg.abc.a_1",
-				messageNameToFieldsToJSONName: map[string]map[string]string{
-					"Msg": {
-						"a_1": "a1JSONNAME",
-						"b_1": "b1JSONNAME",
-					},
-				},
-				fieldNameToType: map[string]string{
-					"abc": "pkg1.test.Msg",
-					"bcd": "pkg1.test.Msg",
-				},
-			},
-			"a1JSONNAME",
-		},
-		{
-			"test case 4: double dot use case with a not existed field",
-			args{
-				fieldName: "pkg.abc.c_1",
-				messageNameToFieldsToJSONName: map[string]map[string]string{
-					"Msg": {
-						"a_1": "a1JSONNAME",
-						"b_1": "b1JSONNAME",
-					},
-				},
-				fieldNameToType: map[string]string{
-					"abc": "pkg1.test.Msg",
-					"bcd": "pkg1.test.Msg",
-				},
-			},
-			"",
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := getReservedJSONName(tt.args.fieldName, tt.args.messageNameToFieldsToJSONName, tt.args.fieldNameToType); got != tt.want {
-				t.Errorf("getReservedJSONName() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestParseIncompleteSecurityRequirement(t *testing.T) {
-	swagger := openapi_options.Swagger{
-		Security: []*openapi_options.SecurityRequirement{
-			{
-				SecurityRequirement: map[string]*openapi_options.SecurityRequirement_SecurityRequirementValue{
-					"key": nil,
-				},
-			},
-		},
-	}
-	file := descriptor.File{
-		FileDescriptorProto: &descriptorpb.FileDescriptorProto{
-			SourceCodeInfo: &descriptorpb.SourceCodeInfo{},
-			Name:           proto.String("example.proto"),
-			Package:        proto.String("example"),
-			Options: &descriptorpb.FileOptions{
-				GoPackage: proto.String("github.com/grpc-ecosystem/grpc-gateway/runtime/internal/examplepb;example"),
-			},
-		},
-	}
-	proto.SetExtension(proto.Message(file.FileDescriptorProto.Options), openapi_options.E_Openapiv2Swagger, &swagger)
-	reg := descriptor.NewRegistry()
-	err := reg.Load(&pluginpb.CodeGeneratorRequest{ProtoFile: []*descriptorpb.FileDescriptorProto{file.FileDescriptorProto}})
-	if err != nil {
-		t.Errorf("failed to reg.Load(): %v", err)
-		return
-	}
-	_, err = applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
-	if err == nil {
-		t.Errorf("applyTemplate(%#v) did not error as expected", file)
-		return
-	}
-}

+ 0 - 282
protoc-gen-openapiv2/internal/genopenapi/types.go

@@ -1,282 +0,0 @@
-package genopenapi
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor"
-)
-
-type param struct {
-	*descriptor.File
-	reg *descriptor.Registry
-}
-
-// http://swagger.io/specification/#infoObject
-type openapiInfoObject struct {
-	Title          string `json:"title"`
-	Description    string `json:"description,omitempty"`
-	TermsOfService string `json:"termsOfService,omitempty"`
-	Version        string `json:"version"`
-
-	Contact *openapiContactObject `json:"contact,omitempty"`
-	License *openapiLicenseObject `json:"license,omitempty"`
-
-	extensions []extension
-}
-
-// https://swagger.io/specification/#tagObject
-type openapiTagObject struct {
-	Name         string                              `json:"name"`
-	Description  string                              `json:"description,omitempty"`
-	ExternalDocs *openapiExternalDocumentationObject `json:"externalDocs,omitempty"`
-}
-
-// http://swagger.io/specification/#contactObject
-type openapiContactObject struct {
-	Name  string `json:"name,omitempty"`
-	URL   string `json:"url,omitempty"`
-	Email string `json:"email,omitempty"`
-}
-
-// http://swagger.io/specification/#licenseObject
-type openapiLicenseObject struct {
-	Name string `json:"name,omitempty"`
-	URL  string `json:"url,omitempty"`
-}
-
-// http://swagger.io/specification/#externalDocumentationObject
-type openapiExternalDocumentationObject 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 openapiSwaggerObject struct {
-	Swagger             string                              `json:"swagger"`
-	Info                openapiInfoObject                   `json:"info"`
-	Tags                []openapiTagObject                  `json:"tags,omitempty"`
-	Host                string                              `json:"host,omitempty"`
-	BasePath            string                              `json:"basePath,omitempty"`
-	Schemes             []string                            `json:"schemes,omitempty"`
-	Consumes            []string                            `json:"consumes"`
-	Produces            []string                            `json:"produces"`
-	Paths               openapiPathsObject                  `json:"paths"`
-	Definitions         openapiDefinitionsObject            `json:"definitions"`
-	SecurityDefinitions openapiSecurityDefinitionsObject    `json:"securityDefinitions,omitempty"`
-	Security            []openapiSecurityRequirementObject  `json:"security,omitempty"`
-	ExternalDocs        *openapiExternalDocumentationObject `json:"externalDocs,omitempty"`
-
-	extensions []extension
-}
-
-// http://swagger.io/specification/#securityDefinitionsObject
-type openapiSecurityDefinitionsObject map[string]openapiSecuritySchemeObject
-
-// http://swagger.io/specification/#securitySchemeObject
-type openapiSecuritySchemeObject 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           openapiScopesObject `json:"scopes,omitempty"`
-
-	extensions []extension
-}
-
-// http://swagger.io/specification/#scopesObject
-type openapiScopesObject map[string]string
-
-// http://swagger.io/specification/#securityRequirementObject
-type openapiSecurityRequirementObject map[string][]string
-
-// http://swagger.io/specification/#pathsObject
-type openapiPathsObject map[string]openapiPathItemObject
-
-// http://swagger.io/specification/#pathItemObject
-type openapiPathItemObject struct {
-	Get    *openapiOperationObject `json:"get,omitempty"`
-	Delete *openapiOperationObject `json:"delete,omitempty"`
-	Post   *openapiOperationObject `json:"post,omitempty"`
-	Put    *openapiOperationObject `json:"put,omitempty"`
-	Patch  *openapiOperationObject `json:"patch,omitempty"`
-}
-
-// http://swagger.io/specification/#operationObject
-type openapiOperationObject struct {
-	Summary     string                  `json:"summary,omitempty"`
-	Description string                  `json:"description,omitempty"`
-	OperationID string                  `json:"operationId"`
-	Responses   openapiResponsesObject  `json:"responses"`
-	Parameters  openapiParametersObject `json:"parameters,omitempty"`
-	Tags        []string                `json:"tags,omitempty"`
-	Deprecated  bool                    `json:"deprecated,omitempty"`
-	Produces    []string                `json:"produces,omitempty"`
-
-	Security     *[]openapiSecurityRequirementObject `json:"security,omitempty"`
-	ExternalDocs *openapiExternalDocumentationObject `json:"externalDocs,omitempty"`
-
-	extensions []extension
-}
-
-type openapiParametersObject []openapiParameterObject
-
-// http://swagger.io/specification/#parameterObject
-type openapiParameterObject 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            *openapiItemsObject `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 *openapiSchemaObject `json:"schema,omitempty"`
-}
-
-// core part of schema, which is common to itemsObject and schemaObject.
-// http://swagger.io/specification/v2/#itemsObject
-// The OAS3 spec (https://swagger.io/specification/#schemaObject) defines the
-// `nullable` field as part of a Schema Object. This behavior has been
-// "back-ported" to OAS2 as the Specification Extension `x-nullable`, and is
-// supported by generation tools such as swagger-codegen and go-swagger.
-// For protoc-gen-openapiv3, we'd want to add `nullable` instead.
-type schemaCore struct {
-	Type      string          `json:"type,omitempty"`
-	Format    string          `json:"format,omitempty"`
-	Ref       string          `json:"$ref,omitempty"`
-	XNullable bool            `json:"x-nullable,omitempty"`
-	Example   json.RawMessage `json:"example,omitempty"`
-
-	Items *openapiItemsObject `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"`
-}
-
-func (s *schemaCore) setRefFromFQN(ref string, reg *descriptor.Registry) error {
-	name, ok := fullyQualifiedNameToOpenAPIName(ref, reg)
-	if !ok {
-		return fmt.Errorf("setRefFromFQN: can't resolve OpenAPI name from '%v'", ref)
-	}
-	s.Ref = fmt.Sprintf("#/definitions/%s", name)
-	return nil
-}
-
-type openapiItemsObject schemaCore
-
-// http://swagger.io/specification/#responsesObject
-type openapiResponsesObject map[string]openapiResponseObject
-
-// http://swagger.io/specification/#responseObject
-type openapiResponseObject struct {
-	Description string                 `json:"description"`
-	Schema      openapiSchemaObject    `json:"schema"`
-	Examples    map[string]interface{} `json:"examples,omitempty"`
-	Headers     openapiHeadersObject   `json:"headers,omitempty"`
-
-	extensions []extension
-}
-
-type openapiHeadersObject map[string]openapiHeaderObject
-
-// http://swagger.io/specification/#headerObject
-type openapiHeaderObject struct {
-	Description string          `json:"description,omitempty"`
-	Type        string          `json:"type,omitempty"`
-	Format      string          `json:"format,omitempty"`
-	Default     json.RawMessage `json:"default,omitempty"`
-	Pattern     string          `json:"pattern,omitempty"`
-}
-
-type keyVal struct {
-	Key   string
-	Value interface{}
-}
-
-type openapiSchemaObjectProperties []keyVal
-
-func (op openapiSchemaObjectProperties) 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 openapiSchemaObject struct {
-	schemaCore
-	// Properties can be recursively defined
-	Properties           *openapiSchemaObjectProperties `json:"properties,omitempty"`
-	AdditionalProperties *openapiSchemaObject           `json:"additionalProperties,omitempty"`
-
-	Description string `json:"description,omitempty"`
-	Title       string `json:"title,omitempty"`
-
-	ExternalDocs *openapiExternalDocumentationObject `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/#definitionsObject
-type openapiDefinitionsObject map[string]openapiSchemaObject
-
-// 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{}

+ 0 - 121
protoc-gen-openapiv2/internal/httprule/compile.go

@@ -1,121 +0,0 @@
-package httprule
-
-import (
-	"github.com/grpc-ecosystem/grpc-gateway/v2/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 {
-			// eof segment literal represents the "/" path pattern
-			if op.str == eof {
-				op.str = ""
-			}
-			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,
-	}
-}

+ 0 - 129
protoc-gen-openapiv2/internal/httprule/compile_test.go

@@ -1,129 +0,0 @@
-package httprule
-
-import (
-	"reflect"
-	"testing"
-
-	"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
-)
-
-const (
-	operandFiller = 0
-)
-
-func TestCompile(t *testing.T) {
-	for _, spec := range []struct {
-		segs []segment
-		verb string
-
-		ops    []int
-		pool   []string
-		fields []string
-	}{
-		{},
-		{
-			segs: []segment{
-				literal(eof),
-			},
-			ops:  []int{int(utilities.OpLitPush), 0},
-			pool: []string{""},
-		},
-		{
-			segs: []segment{
-				wildcard{},
-			},
-			ops: []int{int(utilities.OpPush), operandFiller},
-		},
-		{
-			segs: []segment{
-				deepWildcard{},
-			},
-			ops: []int{int(utilities.OpPushM), operandFiller},
-		},
-		{
-			segs: []segment{
-				literal("v1"),
-			},
-			ops:  []int{int(utilities.OpLitPush), 0},
-			pool: []string{"v1"},
-		},
-		{
-			segs: []segment{
-				literal("v1"),
-			},
-			verb: "LOCK",
-			ops:  []int{int(utilities.OpLitPush), 0},
-			pool: []string{"v1"},
-		},
-		{
-			segs: []segment{
-				variable{
-					path: "name.nested",
-					segments: []segment{
-						wildcard{},
-					},
-				},
-			},
-			ops: []int{
-				int(utilities.OpPush), operandFiller,
-				int(utilities.OpConcatN), 1,
-				int(utilities.OpCapture), 0,
-			},
-			pool:   []string{"name.nested"},
-			fields: []string{"name.nested"},
-		},
-		{
-			segs: []segment{
-				literal("obj"),
-				variable{
-					path: "name.nested",
-					segments: []segment{
-						literal("a"),
-						wildcard{},
-						literal("b"),
-					},
-				},
-				variable{
-					path: "obj",
-					segments: []segment{
-						deepWildcard{},
-					},
-				},
-			},
-			ops: []int{
-				int(utilities.OpLitPush), 0,
-				int(utilities.OpLitPush), 1,
-				int(utilities.OpPush), operandFiller,
-				int(utilities.OpLitPush), 2,
-				int(utilities.OpConcatN), 3,
-				int(utilities.OpCapture), 3,
-				int(utilities.OpPushM), operandFiller,
-				int(utilities.OpConcatN), 1,
-				int(utilities.OpCapture), 0,
-			},
-			pool:   []string{"obj", "a", "b", "name.nested"},
-			fields: []string{"name.nested", "obj"},
-		},
-	} {
-		tmpl := template{
-			segments: spec.segs,
-			verb:     spec.verb,
-		}
-		compiled := tmpl.Compile()
-		if got, want := compiled.Version, opcodeVersion; got != want {
-			t.Errorf("tmpl.Compile().Version = %d; want %d; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
-		}
-		if got, want := compiled.OpCodes, spec.ops; !reflect.DeepEqual(got, want) {
-			t.Errorf("tmpl.Compile().OpCodes = %v; want %v; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
-		}
-		if got, want := compiled.Pool, spec.pool; !reflect.DeepEqual(got, want) {
-			t.Errorf("tmpl.Compile().Pool = %q; want %q; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
-		}
-		if got, want := compiled.Verb, spec.verb; got != want {
-			t.Errorf("tmpl.Compile().Verb = %q; want %q; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
-		}
-		if got, want := compiled.Fields, spec.fields; !reflect.DeepEqual(got, want) {
-			t.Errorf("tmpl.Compile().Fields = %q; want %q; segs=%#v, verb=%q", got, want, spec.segs, spec.verb)
-		}
-	}
-}

+ 0 - 12
protoc-gen-openapiv2/internal/httprule/fuzz.go

@@ -1,12 +0,0 @@
-//go:build gofuzz
-// +build gofuzz
-
-package httprule
-
-func Fuzz(data []byte) int {
-	_, err := Parse(string(data))
-	if err != nil {
-		return 0
-	}
-	return 0
-}

+ 0 - 369
protoc-gen-openapiv2/internal/httprule/parse.go

@@ -1,369 +0,0 @@
-package httprule
-
-import (
-	"fmt"
-	"strings"
-)
-
-// 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
-	)
-	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)
-	// See
-	// https://github.com/grpc-ecosystem/grpc-gateway/pull/1947#issuecomment-774523693 ;
-	// although normal and backwards-compat logic here is to use the last index
-	// of a colon, if the final segment is a variable followed by a colon, the
-	// part following the colon must be a verb. Hence if the previous token is
-	// an end var marker, we switch the index we're looking for to Index instead
-	// of LastIndex, so that we correctly grab the remaining part of the path as
-	// the verb.
-	var penultimateTokenIsEndVar bool
-	switch l {
-	case 0, 1:
-		// Not enough to be variable so skip this logic and don't result in an
-		// invalid index
-	default:
-		penultimateTokenIsEndVar = tokens[l-2] == "}"
-	}
-	t := tokens[l-1]
-	var idx int
-	if penultimateTokenIsEndVar {
-		idx = strings.Index(t, ":")
-	} else {
-		idx = strings.LastIndex(t, ":")
-	}
-	if 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) {
-	if _, err := p.accept(typeEOF); err == nil {
-		p.tokens = p.tokens[:0]
-		return []segment{literal(eof)}, nil
-	}
-	segs, err := p.segments()
-	if err != nil {
-		return nil, err
-	}
-	if _, err := p.accept(typeEOF); err != nil {
-		return nil, fmt.Errorf("unexpected token %q after segments %q", p.tokens[0], strings.Join(p.accepted, ""))
-	}
-	return segs, nil
-}
-
-func (p *parser) segments() ([]segment, error) {
-	s, err := p.segment()
-	if err != nil {
-		return nil, err
-	}
-
-	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)
-	}
-}
-
-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
-}

+ 0 - 366
protoc-gen-openapiv2/internal/httprule/parse_test.go

@@ -1,366 +0,0 @@
-package httprule
-
-import (
-	"flag"
-	"fmt"
-	"reflect"
-	"testing"
-
-	"github.com/golang/glog"
-)
-
-func TestTokenize(t *testing.T) {
-	for _, spec := range []struct {
-		src    string
-		tokens []string
-		verb   string
-	}{
-		{
-			src:    "",
-			tokens: []string{eof},
-		},
-		{
-			src:    "v1",
-			tokens: []string{"v1", eof},
-		},
-		{
-			src:    "v1/b",
-			tokens: []string{"v1", "/", "b", eof},
-		},
-		{
-			src:    "v1/endpoint/*",
-			tokens: []string{"v1", "/", "endpoint", "/", "*", eof},
-		},
-		{
-			src:    "v1/endpoint/**",
-			tokens: []string{"v1", "/", "endpoint", "/", "**", eof},
-		},
-		{
-			src: "v1/b/{bucket_name=*}",
-			tokens: []string{
-				"v1", "/",
-				"b", "/",
-				"{", "bucket_name", "=", "*", "}",
-				eof,
-			},
-		},
-		{
-			src: "v1/b/{bucket_name=buckets/*}",
-			tokens: []string{
-				"v1", "/",
-				"b", "/",
-				"{", "bucket_name", "=", "buckets", "/", "*", "}",
-				eof,
-			},
-		},
-		{
-			src: "v1/b/{bucket_name=buckets/*}/o",
-			tokens: []string{
-				"v1", "/",
-				"b", "/",
-				"{", "bucket_name", "=", "buckets", "/", "*", "}", "/",
-				"o",
-				eof,
-			},
-		},
-		{
-			src: "v1/b/{bucket_name=buckets/*}/o/{name}",
-			tokens: []string{
-				"v1", "/",
-				"b", "/",
-				"{", "bucket_name", "=", "buckets", "/", "*", "}", "/",
-				"o", "/", "{", "name", "}",
-				eof,
-			},
-		},
-		{
-			src: "v1/a=b&c=d;e=f:g/endpoint.rdf",
-			tokens: []string{
-				"v1", "/",
-				"a=b&c=d;e=f:g", "/",
-				"endpoint.rdf",
-				eof,
-			},
-		},
-		{
-			src: "v1/a/{endpoint}:a",
-			tokens: []string{
-				"v1", "/",
-				"a", "/",
-				"{", "endpoint", "}",
-				eof,
-			},
-			verb: "a",
-		},
-		{
-			src: "v1/a/{endpoint}:b:c",
-			tokens: []string{
-				"v1", "/",
-				"a", "/",
-				"{", "endpoint", "}",
-				eof,
-			},
-			verb: "b:c",
-		},
-	} {
-		tokens, verb := tokenize(spec.src)
-		if got, want := tokens, spec.tokens; !reflect.DeepEqual(got, want) {
-			t.Errorf("tokenize(%q) = %q, _; want %q, _", spec.src, got, want)
-		}
-
-		switch {
-		case spec.verb != "":
-			if got, want := verb, spec.verb; !reflect.DeepEqual(got, want) {
-				t.Errorf("tokenize(%q) = %q, _; want %q, _", spec.src, got, want)
-			}
-
-		default:
-			if got, want := verb, ""; got != want {
-				t.Errorf("tokenize(%q) = _, %q; want _, %q", spec.src, got, want)
-			}
-
-			src := fmt.Sprintf("%s:%s", spec.src, "LOCK")
-			tokens, verb = tokenize(src)
-			if got, want := tokens, spec.tokens; !reflect.DeepEqual(got, want) {
-				t.Errorf("tokenize(%q) = %q, _; want %q, _", src, got, want)
-			}
-			if got, want := verb, "LOCK"; got != want {
-				t.Errorf("tokenize(%q) = _, %q; want _, %q", src, got, want)
-			}
-		}
-	}
-}
-
-func TestParseSegments(t *testing.T) {
-	err := flag.Set("v", "3")
-	if err != nil {
-		t.Fatalf("failed to set flag: %v", err)
-	}
-	for _, spec := range []struct {
-		tokens []string
-		want   []segment
-	}{
-		{
-			tokens: []string{eof},
-			want: []segment{
-				literal(eof),
-			},
-		},
-		{
-			// Note: this case will never arise as tokenize() will never return such a sequence of tokens
-			// and even if it does it will be treated as [eof]
-			tokens: []string{eof, "v1", eof},
-			want: []segment{
-				literal(eof),
-			},
-		},
-		{
-			tokens: []string{"v1", eof},
-			want: []segment{
-				literal("v1"),
-			},
-		},
-		{
-			tokens: []string{"/", eof},
-			want: []segment{
-				wildcard{},
-			},
-		},
-		{
-			tokens: []string{"-._~!$&'()*+,;=:@", eof},
-			want: []segment{
-				literal("-._~!$&'()*+,;=:@"),
-			},
-		},
-		{
-			tokens: []string{"%e7%ac%ac%e4%b8%80%e7%89%88", eof},
-			want: []segment{
-				literal("%e7%ac%ac%e4%b8%80%e7%89%88"),
-			},
-		},
-		{
-			tokens: []string{"v1", "/", "*", eof},
-			want: []segment{
-				literal("v1"),
-				wildcard{},
-			},
-		},
-		{
-			tokens: []string{"v1", "/", "**", eof},
-			want: []segment{
-				literal("v1"),
-				deepWildcard{},
-			},
-		},
-		{
-			tokens: []string{"{", "name", "}", eof},
-			want: []segment{
-				variable{
-					path: "name",
-					segments: []segment{
-						wildcard{},
-					},
-				},
-			},
-		},
-		{
-			tokens: []string{"{", "name", "=", "*", "}", eof},
-			want: []segment{
-				variable{
-					path: "name",
-					segments: []segment{
-						wildcard{},
-					},
-				},
-			},
-		},
-		{
-			tokens: []string{"{", "field", ".", "nested", ".", "nested2", "=", "*", "}", eof},
-			want: []segment{
-				variable{
-					path: "field.nested.nested2",
-					segments: []segment{
-						wildcard{},
-					},
-				},
-			},
-		},
-		{
-			tokens: []string{"{", "name", "=", "a", "/", "b", "/", "*", "}", eof},
-			want: []segment{
-				variable{
-					path: "name",
-					segments: []segment{
-						literal("a"),
-						literal("b"),
-						wildcard{},
-					},
-				},
-			},
-		},
-		{
-			tokens: []string{
-				"v1", "/",
-				"{",
-				"name", ".", "nested", ".", "nested2",
-				"=",
-				"a", "/", "b", "/", "*",
-				"}", "/",
-				"o", "/",
-				"{",
-				"another_name",
-				"=",
-				"a", "/", "b", "/", "*", "/", "c",
-				"}", "/",
-				"**",
-				eof,
-			},
-			want: []segment{
-				literal("v1"),
-				variable{
-					path: "name.nested.nested2",
-					segments: []segment{
-						literal("a"),
-						literal("b"),
-						wildcard{},
-					},
-				},
-				literal("o"),
-				variable{
-					path: "another_name",
-					segments: []segment{
-						literal("a"),
-						literal("b"),
-						wildcard{},
-						literal("c"),
-					},
-				},
-				deepWildcard{},
-			},
-		},
-	} {
-		p := parser{tokens: spec.tokens}
-		segs, err := p.topLevelSegments()
-		if err != nil {
-			t.Errorf("parser{%q}.segments() failed with %v; want success", spec.tokens, err)
-			continue
-		}
-		if got, want := segs, spec.want; !reflect.DeepEqual(got, want) {
-			t.Errorf("parser{%q}.segments() = %#v; want %#v", spec.tokens, got, want)
-		}
-		if got := p.tokens; len(got) > 0 {
-			t.Errorf("p.tokens = %q; want []; spec.tokens=%q", got, spec.tokens)
-		}
-	}
-}
-
-func TestParseSegmentsWithErrors(t *testing.T) {
-	err := flag.Set("v", "3")
-	if err != nil {
-		t.Fatalf("failed to set flag: %v", err)
-	}
-	for _, spec := range []struct {
-		tokens []string
-	}{
-		{
-			// double slash
-			tokens: []string{"//", eof},
-		},
-		{
-			// invalid literal
-			tokens: []string{"a?b", eof},
-		},
-		{
-			// invalid percent-encoding
-			tokens: []string{"%", eof},
-		},
-		{
-			// invalid percent-encoding
-			tokens: []string{"%2", eof},
-		},
-		{
-			// invalid percent-encoding
-			tokens: []string{"a%2z", eof},
-		},
-		{
-			// unterminated variable
-			tokens: []string{"{", "name", eof},
-		},
-		{
-			// unterminated variable
-			tokens: []string{"{", "name", "=", eof},
-		},
-		{
-			// unterminated variable
-			tokens: []string{"{", "name", "=", "*", eof},
-		},
-		{
-			// empty component in field path
-			tokens: []string{"{", "name", ".", "}", eof},
-		},
-		{
-			// empty component in field path
-			tokens: []string{"{", "name", ".", ".", "nested", "}", eof},
-		},
-		{
-			// invalid character in identifier
-			tokens: []string{"{", "field-name", "}", eof},
-		},
-		{
-			// no slash between segments
-			tokens: []string{"v1", "endpoint", eof},
-		},
-		{
-			// no slash between segments
-			tokens: []string{"v1", "{", "name", "}", eof},
-		},
-	} {
-		p := parser{tokens: spec.tokens}
-		segs, err := p.topLevelSegments()
-		if err == nil {
-			t.Errorf("parser{%q}.segments() succeeded; want InvalidTemplateError; accepted %#v", spec.tokens, segs)
-			continue
-		}
-		glog.V(1).Info(err)
-	}
-}

+ 0 - 60
protoc-gen-openapiv2/internal/httprule/types.go

@@ -1,60 +0,0 @@
-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
-}

+ 0 - 91
protoc-gen-openapiv2/internal/httprule/types_test.go

@@ -1,91 +0,0 @@
-package httprule
-
-import (
-	"fmt"
-	"testing"
-)
-
-func TestTemplateStringer(t *testing.T) {
-	for _, spec := range []struct {
-		segs []segment
-		want string
-	}{
-		{
-			segs: []segment{
-				literal("v1"),
-			},
-			want: "/v1",
-		},
-		{
-			segs: []segment{
-				wildcard{},
-			},
-			want: "/*",
-		},
-		{
-			segs: []segment{
-				deepWildcard{},
-			},
-			want: "/**",
-		},
-		{
-			segs: []segment{
-				variable{
-					path: "name",
-					segments: []segment{
-						literal("a"),
-					},
-				},
-			},
-			want: "/{name=a}",
-		},
-		{
-			segs: []segment{
-				variable{
-					path: "name",
-					segments: []segment{
-						literal("a"),
-						wildcard{},
-						literal("b"),
-					},
-				},
-			},
-			want: "/{name=a/*/b}",
-		},
-		{
-			segs: []segment{
-				literal("v1"),
-				variable{
-					path: "name",
-					segments: []segment{
-						literal("a"),
-						wildcard{},
-						literal("b"),
-					},
-				},
-				literal("c"),
-				variable{
-					path: "field.nested",
-					segments: []segment{
-						wildcard{},
-						literal("d"),
-					},
-				},
-				wildcard{},
-				literal("e"),
-				deepWildcard{},
-			},
-			want: "/v1/{name=a/*/b}/c/{field.nested=*/d}/*/e/**",
-		},
-	} {
-		tmpl := template{segments: spec.segs}
-		if got, want := tmpl.String(), spec.want; got != want {
-			t.Errorf("%#v.String() = %q; want %q", tmpl, got, want)
-		}
-
-		tmpl.verb = "LOCK"
-		if got, want := tmpl.String(), fmt.Sprintf("%s:LOCK", spec.want); got != want {
-			t.Errorf("%#v.String() = %q; want %q", tmpl, got, want)
-		}
-	}
-}

+ 0 - 228
protoc-gen-openapiv2/main.go

@@ -1,228 +0,0 @@
-package main
-
-import (
-	"flag"
-	"fmt"
-	"os"
-	"strings"
-
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/codegenerator"
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/descriptor"
-	"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/internal/genopenapi"
-	"github.com/golang/glog"
-	"google.golang.org/protobuf/proto"
-	"google.golang.org/protobuf/types/pluginpb"
-)
-
-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 file which describes the gRPC API Configuration in YAML format")
-	allowMerge                 = flag.Bool("allow_merge", false, "if set, generation one OpenAPI file out of multiple protos")
-	mergeFileName              = flag.String("merge_file_name", "apidocs", "target OpenAPI file name prefix after merge")
-	useJSONNamesForFields      = flag.Bool("json_names_for_fields", true, "if disabled, the original proto name will be used for generating OpenAPI definitions")
-	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 version")
-	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")
-	useFQNForOpenAPIName       = flag.Bool("fqn_for_openapi_name", false, "if set, the object's OpenAPI names will use the fully qualified names from the proto definition (ie my.package.MyMessage.MyInnerMessage")
-	useGoTemplate              = flag.Bool("use_go_templates", false, "if set, you can use Go templates in protofile comments")
-	disableDefaultErrors       = flag.Bool("disable_default_errors", false, "if set, disables generation of default errors. This is useful if you have defined custom error handling")
-	enumsAsInts                = flag.Bool("enums_as_ints", false, "whether to render enum values as integers, as opposed to string values")
-	simpleOperationIDs         = flag.Bool("simple_operation_ids", false, "whether to remove the service prefix in the operationID generation. Can introduce duplicate operationIDs, use with caution.")
-	proto3OptionalNullable     = flag.Bool("proto3_optional_nullable", false, "whether Proto3 Optional fields should be marked as x-nullable")
-	openAPIConfiguration       = flag.String("openapi_configuration", "", "path to file which describes the OpenAPI Configuration in YAML format")
-	generateUnboundMethods     = flag.Bool("generate_unbound_methods", false, "generate swagger metadata even for RPC methods that have no HttpRule annotation")
-	generateRPCMethods         = flag.Bool("generate_rpc_methods", false, "generate swagger metadata even for RPC methods without HttpRule annotation")
-	recursiveDepth             = flag.Int("recursive-depth", 1000, "maximum recursion count allowed for a field type")
-)
-
-// Variables set by goreleaser at build time
-var (
-	version = "dev123"
-	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.SetUseFQNForOpenAPIName(*useFQNForOpenAPIName)
-	reg.SetUseGoTemplate(*useGoTemplate)
-	reg.SetEnumsAsInts(*enumsAsInts)
-	reg.SetDisableDefaultErrors(*disableDefaultErrors)
-	reg.SetSimpleOperationIDs(*simpleOperationIDs)
-	reg.SetProto3OptionalNullable(*proto3OptionalNullable)
-	reg.SetGenerateUnboundMethods(*generateUnboundMethods)
-	reg.SetGenerateRPCMethods(*generateRPCMethods)
-	reg.SetRecursiveDepth(*recursiveDepth)
-	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 := genopenapi.New(reg)
-
-	if err := genopenapi.AddErrorDefs(reg); err != nil {
-		emitError(err)
-		return
-	}
-
-	if err := reg.Load(req); err != nil {
-		emitError(err)
-		return
-	}
-
-	if *openAPIConfiguration != "" {
-		if err := reg.LoadOpenAPIConfigFromYAML(*openAPIConfiguration); 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 []*descriptor.ResponseFile) {
-	files := make([]*pluginpb.CodeGeneratorResponse_File, len(out))
-	for idx, item := range out {
-		files[idx] = item.CodeGeneratorResponse_File
-	}
-	resp := &pluginpb.CodeGeneratorResponse{File: files}
-	codegenerator.SetSupportedFeaturesOnCodeGeneratorResponse(resp)
-	emitResp(resp)
-}
-
-func emitError(err error) {
-	emitResp(&pluginpb.CodeGeneratorResponse{Error: proto.String(err.Error())})
-}
-
-func emitResp(resp *pluginpb.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
-}

+ 0 - 186
protoc-gen-openapiv2/main_test.go

@@ -1,186 +0,0 @@
-package main
-
-import (
-	"errors"
-	"flag"
-	"reflect"
-	"testing"
-)
-
-func TestParseReqParam(t *testing.T) {
-
-	testcases := []struct {
-		name                       string
-		expected                   map[string]string
-		request                    string
-		expectedError              error
-		allowDeleteBodyV           bool
-		allowMergeV                bool
-		allowRepeatedFieldsInBodyV bool
-		includePackageInTagsV      bool
-		fileV                      string
-		importPathV                string
-		mergeFileNameV             string
-		useFQNForOpenAPINameV      bool
-	}{
-		{
-			// this one must be first - with no leading clearFlags call it
-			// verifies our expectation of default values as we reset by
-			// clearFlags
-			name:             "Test 0",
-			expected:         map[string]string{},
-			request:          "",
-			allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
-			fileV: "-", importPathV: "", mergeFileNameV: "apidocs",
-		},
-		{
-			name:             "Test 1",
-			expected:         map[string]string{"google/api/annotations.proto": "github.com/googleapis/googleapis/google/api"},
-			request:          "allow_delete_body,allow_merge,allow_repeated_fields_in_body,include_package_in_tags,file=./foo.pb,import_prefix=/bar/baz,Mgoogle/api/annotations.proto=github.com/googleapis/googleapis/google/api",
-			allowDeleteBodyV: true, allowMergeV: true, allowRepeatedFieldsInBodyV: true, includePackageInTagsV: true,
-			fileV: "./foo.pb", importPathV: "/bar/baz", mergeFileNameV: "apidocs",
-		},
-		{
-			name:             "Test 2",
-			expected:         map[string]string{"google/api/annotations.proto": "github.com/googleapis/googleapis/google/api"},
-			request:          "allow_delete_body=true,allow_merge=true,allow_repeated_fields_in_body=true,include_package_in_tags=true,merge_file_name=test_name,file=./foo.pb,import_prefix=/bar/baz,Mgoogle/api/annotations.proto=github.com/googleapis/googleapis/google/api",
-			allowDeleteBodyV: true, allowMergeV: true, allowRepeatedFieldsInBodyV: true, includePackageInTagsV: true,
-			fileV: "./foo.pb", importPathV: "/bar/baz", mergeFileNameV: "test_name",
-		},
-		{
-			name:             "Test 3",
-			expected:         map[string]string{"a/b/c.proto": "github.com/x/y/z", "f/g/h.proto": "github.com/1/2/3/"},
-			request:          "allow_delete_body=false,allow_merge=false,Ma/b/c.proto=github.com/x/y/z,Mf/g/h.proto=github.com/1/2/3/",
-			allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
-			fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
-		},
-		{
-			name:             "Test 4",
-			expected:         map[string]string{},
-			request:          "",
-			allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
-			fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
-		},
-		{
-			name:             "Test 5",
-			expected:         map[string]string{},
-			request:          "unknown_param=17",
-			expectedError:    errors.New("cannot set flag unknown_param=17: no such flag -unknown_param"),
-			allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
-			fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
-		},
-		{
-			name:             "Test 6",
-			expected:         map[string]string{},
-			request:          "Mfoo",
-			expectedError:    errors.New("cannot set flag Mfoo: no such flag -Mfoo"),
-			allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
-			fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
-		},
-		{
-			name:             "Test 7",
-			expected:         map[string]string{},
-			request:          "allow_delete_body,file,import_prefix,allow_merge,allow_repeated_fields_in_body,include_package_in_tags,merge_file_name",
-			allowDeleteBodyV: true, allowMergeV: true, allowRepeatedFieldsInBodyV: true, includePackageInTagsV: true,
-			fileV: "", importPathV: "", mergeFileNameV: "",
-		},
-		{
-			name:             "Test 8",
-			expected:         map[string]string{},
-			request:          "allow_delete_body,file,import_prefix,allow_merge,allow_repeated_fields_in_body=3,merge_file_name",
-			expectedError:    errors.New(`cannot set flag allow_repeated_fields_in_body=3: parse error`),
-			allowDeleteBodyV: true, allowMergeV: true, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
-			fileV: "", importPathV: "", mergeFileNameV: "apidocs",
-		},
-		{
-			name:             "Test 9",
-			expected:         map[string]string{},
-			request:          "include_package_in_tags=3",
-			expectedError:    errors.New(`cannot set flag include_package_in_tags=3: parse error`),
-			allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false,
-			fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
-		},
-		{
-			name:             "Test 10",
-			expected:         map[string]string{},
-			request:          "fqn_for_openapi_name=3",
-			expectedError:    errors.New(`cannot set flag fqn_for_openapi_name=3: parse error`),
-			allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false, useFQNForOpenAPINameV: false,
-			fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
-		},
-		{
-			name:             "Test 11",
-			expected:         map[string]string{},
-			request:          "fqn_for_openapi_name=true",
-			allowDeleteBodyV: false, allowMergeV: false, allowRepeatedFieldsInBodyV: false, includePackageInTagsV: false, useFQNForOpenAPINameV: true,
-			fileV: "stdin", importPathV: "", mergeFileNameV: "apidocs",
-		},
-	}
-
-	for i, tc := range testcases {
-		t.Run(tc.name, func(tt *testing.T) {
-			f := flag.CommandLine
-			pkgMap := make(map[string]string)
-			err := parseReqParam(tc.request, f, pkgMap)
-			if tc.expectedError == nil {
-				if err != nil {
-					tt.Errorf("unexpected parse error '%v'", err)
-				}
-				if !reflect.DeepEqual(pkgMap, tc.expected) {
-					tt.Errorf("pkgMap parse error, expected '%v', got '%v'", tc.expected, pkgMap)
-				}
-			} else {
-				if err == nil {
-					tt.Error("expected parse error not returned")
-				}
-				if !reflect.DeepEqual(pkgMap, tc.expected) {
-					tt.Errorf("pkgMap parse error, expected '%v', got '%v'", tc.expected, pkgMap)
-				}
-				if err.Error() != tc.expectedError.Error() {
-					tt.Errorf("expected error malformed, expected %q, got %q", tc.expectedError.Error(), err.Error())
-				}
-			}
-			checkFlags(tc.allowDeleteBodyV, tc.allowMergeV, tc.allowRepeatedFieldsInBodyV, tc.includePackageInTagsV, tc.useFQNForOpenAPINameV, tc.fileV, tc.importPathV, tc.mergeFileNameV, tt, i)
-
-			clearFlags()
-		})
-	}
-
-}
-
-func checkFlags(allowDeleteV, allowMergeV, allowRepeatedFieldsInBodyV, includePackageInTagsV bool, useFQNForOpenAPINameV bool, fileV, importPathV, mergeFileNameV string, t *testing.T, tid int) {
-	if *importPrefix != importPathV {
-		t.Errorf("Test %v: import_prefix misparsed, expected '%v', got '%v'", tid, importPathV, *importPrefix)
-	}
-	if *file != fileV {
-		t.Errorf("Test %v: file misparsed, expected '%v', got '%v'", tid, fileV, *file)
-	}
-	if *allowDeleteBody != allowDeleteV {
-		t.Errorf("Test %v: allow_delete_body misparsed, expected '%v', got '%v'", tid, allowDeleteV, *allowDeleteBody)
-	}
-	if *allowMerge != allowMergeV {
-		t.Errorf("Test %v: allow_merge misparsed, expected '%v', got '%v'", tid, allowMergeV, *allowMerge)
-	}
-	if *mergeFileName != mergeFileNameV {
-		t.Errorf("Test %v: merge_file_name misparsed, expected '%v', got '%v'", tid, mergeFileNameV, *mergeFileName)
-	}
-	if *allowRepeatedFieldsInBody != allowRepeatedFieldsInBodyV {
-		t.Errorf("Test %v: allow_repeated_fields_in_body misparsed, expected '%v', got '%v'", tid, allowRepeatedFieldsInBodyV, *allowRepeatedFieldsInBody)
-	}
-	if *includePackageInTags != includePackageInTagsV {
-		t.Errorf("Test %v: include_package_in_tags misparsed, expected '%v', got '%v'", tid, includePackageInTagsV, *includePackageInTags)
-	}
-	if *useFQNForOpenAPIName != useFQNForOpenAPINameV {
-		t.Errorf("Test %v: fqn_for_openapi_name misparsed, expected '%v', got '%v'", tid, useFQNForOpenAPINameV, *useFQNForOpenAPIName)
-	}
-}
-
-func clearFlags() {
-	*importPrefix = ""
-	*file = "stdin"
-	*allowDeleteBody = false
-	*allowMerge = false
-	*allowRepeatedFieldsInBody = false
-	*includePackageInTags = false
-	*mergeFileName = "apidocs"
-}

+ 0 - 0
openapiv2/swagger_ui/dist/favicon-16x16.png → q/swagger-ui/favicon-16x16.png


+ 0 - 0
openapiv2/swagger_ui/dist/favicon-32x32.png → q/swagger-ui/favicon-32x32.png


+ 16 - 0
q/swagger-ui/index.css

@@ -0,0 +1,16 @@
+html {
+    box-sizing: border-box;
+    overflow: -moz-scrollbars-vertical;
+    overflow-y: scroll;
+}
+
+*,
+*:before,
+*:after {
+    box-sizing: inherit;
+}
+
+body {
+    margin: 0;
+    background: #fafafa;
+}

+ 9 - 26
openapiv2/swagger_ui/dist/index.html → q/swagger-ui/index.html

@@ -2,36 +2,19 @@
 <!DOCTYPE html>
 <html lang="en">
 <head>
-	<meta charset="UTF-8">
-	<title>Swagger UI</title>
-	<link rel="stylesheet" type="text/css" href="/q/swagger-ui/swagger-ui.css"/>
-	<link rel="icon" type="image/png" href="/q/swagger-ui/favicon-32x32.png" sizes="32x32"/>
-	<link rel="icon" type="image/png" href="/q/swagger-ui/favicon-16x16.png" sizes="16x16"/>
-	<style>
-		html {
-			box-sizing: border-box;
-			overflow: -moz-scrollbars-vertical;
-			overflow-y: scroll;
-		}
-
-		*,
-		*:before,
-		*:after {
-			box-sizing: inherit;
-		}
-
-		body {
-			margin: 0;
-			background: #fafafa;
-		}
-	</style>
+    <meta charset="UTF-8">
+    <title>Swagger UI</title>
+    <link rel="stylesheet" type="text/css" href="./swagger-ui.css"/>
+    <link rel="stylesheet" type="text/css" href="index.css"/>
+    <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32"/>
+    <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16"/>
 </head>
 
 <body>
 <div id="swagger-ui"></div>
-
-<script src="/q/swagger-ui/swagger-ui-bundle.js" charset="UTF-8"></script>
-<script src="/q/swagger-ui/swagger-ui-standalone-preset.js" charset="UTF-8"></script>
+<script src="./swagger-ui-bundle.js" charset="UTF-8"></script>
+<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"></script>
+<script src="./swagger-initializer.js" charset="UTF-8"></script>
 <script>
     window.onload = function () {
         const servicesUrl = new URL("/q/services", window.location.href);

+ 10 - 6
openapiv2/swagger_ui/dist/oauth2-redirect.html → q/swagger-ui/oauth2-redirect.html

@@ -13,7 +13,7 @@
         var isValid, qp, arr;
 
         if (/code|token|error/.test(window.location.hash)) {
-            qp = window.location.hash.substring(1);
+            qp = window.location.hash.substring(1).replace('?', '&');
         } else {
             qp = location.search.substring(1);
         }
@@ -38,7 +38,7 @@
                     authId: oauth2.auth.name,
                     source: "auth",
                     level: "warning",
-                    message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
+                    message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
                 });
             }
 
@@ -58,7 +58,7 @@
                     authId: oauth2.auth.name,
                     source: "auth",
                     level: "error",
-                    message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
+                    message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
                 });
             }
         } else {
@@ -67,9 +67,13 @@
         window.close();
     }
 
-    window.addEventListener('DOMContentLoaded', function () {
-      run();
-    });
+    if (document.readyState !== 'loading') {
+        run();
+    } else {
+        document.addEventListener('DOMContentLoaded', function () {
+            run();
+        });
+    }
 </script>
 </body>
 </html>

+ 20 - 0
q/swagger-ui/swagger-initializer.js

@@ -0,0 +1,20 @@
+window.onload = function() {
+  //<editor-fold desc="Changeable Configuration Block">
+
+  // the following lines will be replaced by docker/configurator, when it runs in a docker-container
+  window.ui = SwaggerUIBundle({
+    url: "https://petstore.swagger.io/v2/swagger.json",
+    dom_id: '#swagger-ui',
+    deepLinking: true,
+    presets: [
+      SwaggerUIBundle.presets.apis,
+      SwaggerUIStandalonePreset
+    ],
+    plugins: [
+      SwaggerUIBundle.plugins.DownloadUrl
+    ],
+    layout: "StandaloneLayout"
+  });
+
+  //</editor-fold>
+};

Fișier diff suprimat deoarece este prea mare
+ 1 - 0
q/swagger-ui/swagger-ui-bundle.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
q/swagger-ui/swagger-ui-bundle.js.map


Fișier diff suprimat deoarece este prea mare
+ 1 - 0
q/swagger-ui/swagger-ui-es-bundle-core.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
q/swagger-ui/swagger-ui-es-bundle-core.js.map


Fișier diff suprimat deoarece este prea mare
+ 1 - 0
q/swagger-ui/swagger-ui-es-bundle.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
q/swagger-ui/swagger-ui-es-bundle.js.map


Fișier diff suprimat deoarece este prea mare
+ 1 - 0
q/swagger-ui/swagger-ui-standalone-preset.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
q/swagger-ui/swagger-ui-standalone-preset.js.map


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
q/swagger-ui/swagger-ui.css


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
q/swagger-ui/swagger-ui.css.map


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
q/swagger-ui/swagger-ui.js


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
q/swagger-ui/swagger-ui.js.map


+ 87 - 0
service.go

@@ -0,0 +1,87 @@
+package swagger_api
+
+import (
+	"context"
+	"fmt"
+	//"git.ikuban.com/server/swagger-api/protoc-gen-openapiv2/generator"
+	"git.ikuban.com/server/gnostic/protoc-gen-openapi/generator"
+	"github.com/go-kratos/kratos/v2/api/metadata"
+	"github.com/xmkuban/utils/utils"
+	"google.golang.org/grpc"
+	"google.golang.org/protobuf/compiler/protogen"
+	"google.golang.org/protobuf/types/descriptorpb"
+	"google.golang.org/protobuf/types/pluginpb"
+)
+
+// Service is service
+type Service struct {
+	ser            *metadata.Server
+	serviceInfoMap map[string]grpc.ServiceInfo
+}
+
+// New service
+func New(srv *grpc.Server) *Service {
+	return &Service{
+		ser: metadata.NewServer(srv),
+	}
+}
+
+// ListServices list services
+func (s *Service) ListServices(ctx context.Context, in *metadata.ListServicesRequest) (*metadata.ListServicesReply, error) {
+	return s.ser.ListServices(ctx, &metadata.ListServicesRequest{})
+}
+
+// GetServiceOpenAPI get service open api
+func (s *Service) GetServiceOpenAPI(ctx context.Context, in *metadata.GetServiceDescRequest, onlyRPC bool) (string, error) {
+	protoSet, err := s.ser.GetServiceDesc(ctx, in)
+	if err != nil {
+		return "", err
+	}
+	files := protoSet.FileDescSet.File
+	newFiles := make([]*descriptorpb.FileDescriptorProto, 0)
+	newFileMap := make(map[string]byte)
+	for _, v := range files {
+		if _, ok := newFileMap[v.GetName()]; !ok {
+			newFiles = append(newFiles, v)
+			newFileMap[v.GetName()] = 1
+		}
+	}
+	files = newFiles
+	var target string
+	if len(files) == 0 {
+		return "", fmt.Errorf("proto file is empty")
+	}
+	if files[len(files)-1].Name == nil {
+		return "", fmt.Errorf("proto file's name is null")
+	}
+	target = *files[len(files)-1].Name
+
+	req := new(pluginpb.CodeGeneratorRequest)
+	req.FileToGenerate = []string{target}
+	var para = ""
+	req.Parameter = &para
+	req.ProtoFile = files
+
+	opts := protogen.Options{}
+	plugin, err := opts.New(req)
+	if err != nil {
+		return "", err
+	}
+	plugin.SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)
+	gen := generator.NewOpenAPIv3Generator(plugin, generator.Configuration{
+		Version:         utils.ToPointString("1.0"),
+		Title:           utils.ToPointString(""),
+		Description:     utils.ToPointString(""),
+		Naming:          utils.ToPointString("json"),
+		FQSchemaNaming:  utils.ToPointBool(true),
+		EnumType:        utils.ToPointString("integer"),
+		CircularDepth:   utils.ToPointInt(2),
+		DefaultResponse: utils.ToPointBool(false),
+		OutputMode:      utils.ToPointString("merged"),
+	}, plugin.Files)
+	content, err := gen.RunV2()
+	if err != nil {
+		return "", err
+	}
+	return string(content), nil
+}

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff