go: vendor the oapi-codegen cmd
See the comment in tools.go, I cannot fully explain what's happening here. Somehow, Go 1.14 wants to use the vendored version of oapi-codegen but without this file, oapi-codegen isn't vendored so the generation fails. Signed-off-by: Ondřej Budai <ondrej@budai.cz>
This commit is contained in:
parent
1a3cbb282a
commit
2241a8d9ed
75 changed files with 11211 additions and 0 deletions
534
vendor/github.com/deepmap/oapi-codegen/pkg/codegen/utils.go
generated
vendored
Normal file
534
vendor/github.com/deepmap/oapi-codegen/pkg/codegen/utils.go
generated
vendored
Normal file
|
|
@ -0,0 +1,534 @@
|
|||
// Copyright 2019 DeepMap, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
)
|
||||
|
||||
var pathParamRE *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
pathParamRE = regexp.MustCompile("{[.;?]?([^{}*]+)\\*?}")
|
||||
}
|
||||
|
||||
// Uppercase the first character in a string. This assumes UTF-8, so we have
|
||||
// to be careful with unicode, don't treat it as a byte array.
|
||||
func UppercaseFirstCharacter(str string) string {
|
||||
if str == "" {
|
||||
return ""
|
||||
}
|
||||
runes := []rune(str)
|
||||
runes[0] = unicode.ToUpper(runes[0])
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
// Same as above, except lower case
|
||||
func LowercaseFirstCharacter(str string) string {
|
||||
if str == "" {
|
||||
return ""
|
||||
}
|
||||
runes := []rune(str)
|
||||
runes[0] = unicode.ToLower(runes[0])
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
// This function will convert query-arg style strings to CamelCase. We will
|
||||
// use `., -, +, :, ;, _, ~, ' ', (, ), {, }, [, ]` as valid delimiters for words.
|
||||
// So, "word.word-word+word:word;word_word~word word(word)word{word}[word]"
|
||||
// would be converted to WordWordWordWordWordWordWordWordWordWordWordWordWord
|
||||
func ToCamelCase(str string) string {
|
||||
separators := "-#@!$&=.+:;_~ (){}[]"
|
||||
s := strings.Trim(str, " ")
|
||||
|
||||
n := ""
|
||||
capNext := true
|
||||
for _, v := range s {
|
||||
if unicode.IsUpper(v) {
|
||||
n += string(v)
|
||||
}
|
||||
if unicode.IsDigit(v) {
|
||||
n += string(v)
|
||||
}
|
||||
if unicode.IsLower(v) {
|
||||
if capNext {
|
||||
n += strings.ToUpper(string(v))
|
||||
} else {
|
||||
n += string(v)
|
||||
}
|
||||
}
|
||||
|
||||
if strings.ContainsRune(separators, v) {
|
||||
capNext = true
|
||||
} else {
|
||||
capNext = false
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// This function returns the keys of the given SchemaRef dictionary in sorted
|
||||
// order, since Golang scrambles dictionary keys
|
||||
func SortedSchemaKeys(dict map[string]*openapi3.SchemaRef) []string {
|
||||
keys := make([]string, len(dict))
|
||||
i := 0
|
||||
for key := range dict {
|
||||
keys[i] = key
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// This function is the same as above, except it sorts the keys for a Paths
|
||||
// dictionary.
|
||||
func SortedPathsKeys(dict openapi3.Paths) []string {
|
||||
keys := make([]string, len(dict))
|
||||
i := 0
|
||||
for key := range dict {
|
||||
keys[i] = key
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// This function returns Operation dictionary keys in sorted order
|
||||
func SortedOperationsKeys(dict map[string]*openapi3.Operation) []string {
|
||||
keys := make([]string, len(dict))
|
||||
i := 0
|
||||
for key := range dict {
|
||||
keys[i] = key
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// This function returns Responses dictionary keys in sorted order
|
||||
func SortedResponsesKeys(dict openapi3.Responses) []string {
|
||||
keys := make([]string, len(dict))
|
||||
i := 0
|
||||
for key := range dict {
|
||||
keys[i] = key
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// This returns Content dictionary keys in sorted order
|
||||
func SortedContentKeys(dict openapi3.Content) []string {
|
||||
keys := make([]string, len(dict))
|
||||
i := 0
|
||||
for key := range dict {
|
||||
keys[i] = key
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// This returns string map keys in sorted order
|
||||
func SortedStringKeys(dict map[string]string) []string {
|
||||
keys := make([]string, len(dict))
|
||||
i := 0
|
||||
for key := range dict {
|
||||
keys[i] = key
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// This returns sorted keys for a ParameterRef dict
|
||||
func SortedParameterKeys(dict map[string]*openapi3.ParameterRef) []string {
|
||||
keys := make([]string, len(dict))
|
||||
i := 0
|
||||
for key := range dict {
|
||||
keys[i] = key
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
func SortedRequestBodyKeys(dict map[string]*openapi3.RequestBodyRef) []string {
|
||||
keys := make([]string, len(dict))
|
||||
i := 0
|
||||
for key := range dict {
|
||||
keys[i] = key
|
||||
i++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// This function checks whether the specified string is present in an array
|
||||
// of strings
|
||||
func StringInArray(str string, array []string) bool {
|
||||
for _, elt := range array {
|
||||
if elt == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// This function takes a $ref value and converts it to a Go typename.
|
||||
// #/components/schemas/Foo -> Foo
|
||||
// #/components/parameters/Bar -> Bar
|
||||
// #/components/responses/Baz -> Baz
|
||||
// Remote components (document.json#/Foo) are supported if they present in --import-mapping
|
||||
// URL components (http://deepmap.com/schemas/document.json#Foo) are supported if they present in --import-mapping
|
||||
//
|
||||
func RefPathToGoType(refPath string) (string, error) {
|
||||
if refPath[0] == '#' {
|
||||
pathParts := strings.Split(refPath, "/")
|
||||
if depth := len(pathParts); depth != 4 {
|
||||
return "", fmt.Errorf("Parameter nesting is deeper than supported: %s has %d", refPath, depth)
|
||||
}
|
||||
return SchemaNameToTypeName(pathParts[3]), nil
|
||||
}
|
||||
pathParts := strings.Split(refPath, "#")
|
||||
if len(pathParts) != 2 {
|
||||
return "", fmt.Errorf("unsupported reference: %s", refPath)
|
||||
}
|
||||
remoteComponent, flatComponent := pathParts[0], pathParts[1]
|
||||
if goImport, ok := importMapping[remoteComponent]; !ok {
|
||||
return "", fmt.Errorf("unrecognized external reference '%s'; please provide the known import for this reference using option --import-mapping", remoteComponent)
|
||||
} else {
|
||||
goType, err := RefPathToGoType("#" + flatComponent)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%s.%s", goImport.alias, goType), nil
|
||||
}
|
||||
}
|
||||
|
||||
// This function converts a swagger style path URI with parameters to a
|
||||
// Echo compatible path URI. We need to replace all of Swagger parameters with
|
||||
// ":param". Valid input parameters are:
|
||||
// {param}
|
||||
// {param*}
|
||||
// {.param}
|
||||
// {.param*}
|
||||
// {;param}
|
||||
// {;param*}
|
||||
// {?param}
|
||||
// {?param*}
|
||||
func SwaggerUriToEchoUri(uri string) string {
|
||||
return pathParamRE.ReplaceAllString(uri, ":$1")
|
||||
}
|
||||
|
||||
// This function converts a swagger style path URI with parameters to a
|
||||
// Chi compatible path URI. We need to replace all of Swagger parameters with
|
||||
// "{param}". Valid input parameters are:
|
||||
// {param}
|
||||
// {param*}
|
||||
// {.param}
|
||||
// {.param*}
|
||||
// {;param}
|
||||
// {;param*}
|
||||
// {?param}
|
||||
// {?param*}
|
||||
func SwaggerUriToChiUri(uri string) string {
|
||||
return pathParamRE.ReplaceAllString(uri, "{$1}")
|
||||
}
|
||||
|
||||
// Returns the argument names, in order, in a given URI string, so for
|
||||
// /path/{param1}/{.param2*}/{?param3}, it would return param1, param2, param3
|
||||
func OrderedParamsFromUri(uri string) []string {
|
||||
matches := pathParamRE.FindAllStringSubmatch(uri, -1)
|
||||
result := make([]string, len(matches))
|
||||
for i, m := range matches {
|
||||
result[i] = m[1]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Replaces path parameters with %s
|
||||
func ReplacePathParamsWithStr(uri string) string {
|
||||
return pathParamRE.ReplaceAllString(uri, "%s")
|
||||
}
|
||||
|
||||
// Reorders the given parameter definitions to match those in the path URI.
|
||||
func SortParamsByPath(path string, in []ParameterDefinition) ([]ParameterDefinition, error) {
|
||||
pathParams := OrderedParamsFromUri(path)
|
||||
n := len(in)
|
||||
if len(pathParams) != n {
|
||||
return nil, fmt.Errorf("path '%s' has %d positional parameters, but spec has %d declared",
|
||||
path, len(pathParams), n)
|
||||
}
|
||||
out := make([]ParameterDefinition, len(in))
|
||||
for i, name := range pathParams {
|
||||
p := ParameterDefinitions(in).FindByName(name)
|
||||
if p == nil {
|
||||
return nil, fmt.Errorf("path '%s' refers to parameter '%s', which doesn't exist in specification",
|
||||
path, name)
|
||||
}
|
||||
out[i] = *p
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Returns whether the given string is a go keyword
|
||||
func IsGoKeyword(str string) bool {
|
||||
keywords := []string{
|
||||
"break",
|
||||
"case",
|
||||
"chan",
|
||||
"const",
|
||||
"continue",
|
||||
"default",
|
||||
"defer",
|
||||
"else",
|
||||
"fallthrough",
|
||||
"for",
|
||||
"func",
|
||||
"go",
|
||||
"goto",
|
||||
"if",
|
||||
"import",
|
||||
"interface",
|
||||
"map",
|
||||
"package",
|
||||
"range",
|
||||
"return",
|
||||
"select",
|
||||
"struct",
|
||||
"switch",
|
||||
"type",
|
||||
"var",
|
||||
}
|
||||
|
||||
for _, k := range keywords {
|
||||
if k == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsPredeclaredGoIdentifier returns whether the given string
|
||||
// is a predefined go indentifier.
|
||||
//
|
||||
// See https://golang.org/ref/spec#Predeclared_identifiers
|
||||
func IsPredeclaredGoIdentifier(str string) bool {
|
||||
predeclaredIdentifiers := []string{
|
||||
// Types
|
||||
"bool",
|
||||
"byte",
|
||||
"complex64",
|
||||
"complex128",
|
||||
"error",
|
||||
"float32",
|
||||
"float64",
|
||||
"int",
|
||||
"int8",
|
||||
"int16",
|
||||
"int32",
|
||||
"int64",
|
||||
"rune",
|
||||
"string",
|
||||
"uint",
|
||||
"uint8",
|
||||
"uint16",
|
||||
"uint32",
|
||||
"uint64",
|
||||
"uintptr",
|
||||
// Constants
|
||||
"true",
|
||||
"false",
|
||||
"iota",
|
||||
// Zero value
|
||||
"nil",
|
||||
// Functions
|
||||
"append",
|
||||
"cap",
|
||||
"close",
|
||||
"complex",
|
||||
"copy",
|
||||
"delete",
|
||||
"imag",
|
||||
"len",
|
||||
"make",
|
||||
"new",
|
||||
"panic",
|
||||
"print",
|
||||
"println",
|
||||
"real",
|
||||
"recover",
|
||||
}
|
||||
|
||||
for _, k := range predeclaredIdentifiers {
|
||||
if k == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsGoIdentity checks if the given string can be used as an identity
|
||||
// in the generated code like a type name or constant name.
|
||||
//
|
||||
// See https://golang.org/ref/spec#Identifiers
|
||||
func IsGoIdentity(str string) bool {
|
||||
for i, c := range str {
|
||||
if !isValidRuneForGoID(i, c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return IsGoKeyword(str)
|
||||
}
|
||||
|
||||
func isValidRuneForGoID(index int, char rune) bool {
|
||||
if index == 0 && unicode.IsNumber(char) {
|
||||
return false
|
||||
}
|
||||
|
||||
return unicode.IsLetter(char) || char == '_' || unicode.IsNumber(char)
|
||||
}
|
||||
|
||||
// IsValidGoIdentity checks if the given string can be used as a
|
||||
// name of variable, constant, or type.
|
||||
func IsValidGoIdentity(str string) bool {
|
||||
if IsGoIdentity(str) {
|
||||
return false
|
||||
}
|
||||
|
||||
return !IsPredeclaredGoIdentifier(str)
|
||||
}
|
||||
|
||||
// SanitizeGoIdentity deletes and replaces the illegal runes in the given
|
||||
// string to use the string as a valid identity.
|
||||
func SanitizeGoIdentity(str string) string {
|
||||
sanitized := []rune(str)
|
||||
|
||||
for i, c := range sanitized {
|
||||
if !isValidRuneForGoID(i, c) {
|
||||
sanitized[i] = '_'
|
||||
} else {
|
||||
sanitized[i] = c
|
||||
}
|
||||
}
|
||||
|
||||
str = string(sanitized)
|
||||
|
||||
if IsGoKeyword(str) || IsPredeclaredGoIdentifier(str) {
|
||||
str = "_" + str
|
||||
}
|
||||
|
||||
if !IsValidGoIdentity(str) {
|
||||
panic("here is a bug")
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// SanitizeEnumNames fixes illegal chars in the enum names
|
||||
// and removes duplicates
|
||||
func SanitizeEnumNames(enumNames []string) map[string]string {
|
||||
dupCheck := make(map[string]int, len(enumNames))
|
||||
deDup := make([]string, 0, len(enumNames))
|
||||
|
||||
for _, n := range enumNames {
|
||||
if _, dup := dupCheck[n]; !dup {
|
||||
deDup = append(deDup, n)
|
||||
}
|
||||
|
||||
dupCheck[n] = 0
|
||||
}
|
||||
|
||||
dupCheck = make(map[string]int, len(deDup))
|
||||
sanitizedDeDup := make(map[string]string, len(deDup))
|
||||
|
||||
for _, n := range deDup {
|
||||
sanitized := SanitizeGoIdentity(n)
|
||||
|
||||
if _, dup := dupCheck[sanitized]; !dup {
|
||||
sanitizedDeDup[sanitized] = n
|
||||
dupCheck[sanitized]++
|
||||
} else {
|
||||
sanitizedDeDup[sanitized+strconv.Itoa(dupCheck[sanitized])] = n
|
||||
}
|
||||
}
|
||||
|
||||
return sanitizedDeDup
|
||||
}
|
||||
|
||||
// Converts a Schema name to a valid Go type name. It converts to camel case, and makes sure the name is
|
||||
// valid in Go
|
||||
func SchemaNameToTypeName(name string) string {
|
||||
name = ToCamelCase(name)
|
||||
// Prepend "N" to schemas starting with a number
|
||||
if name != "" && unicode.IsDigit([]rune(name)[0]) {
|
||||
name = "N" + name
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// According to the spec, additionalProperties may be true, false, or a
|
||||
// schema. If not present, true is implied. If it's a schema, true is implied.
|
||||
// If it's false, no additional properties are allowed. We're going to act a little
|
||||
// differently, in that if you want additionalProperties code to be generated,
|
||||
// you must specify an additionalProperties type
|
||||
// If additionalProperties it true/false, this field will be non-nil.
|
||||
func SchemaHasAdditionalProperties(schema *openapi3.Schema) bool {
|
||||
if schema.AdditionalPropertiesAllowed != nil {
|
||||
return *schema.AdditionalPropertiesAllowed
|
||||
}
|
||||
if schema.AdditionalProperties != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// This converts a path, like Object/field1/nestedField into a go
|
||||
// type name.
|
||||
func PathToTypeName(path []string) string {
|
||||
for i, p := range path {
|
||||
path[i] = ToCamelCase(p)
|
||||
}
|
||||
return strings.Join(path, "_")
|
||||
}
|
||||
|
||||
// StringToGoComment renders a possible multi-line string as a valid Go-Comment.
|
||||
// Each line is prefixed as a comment.
|
||||
func StringToGoComment(in string) string {
|
||||
// Normalize newlines from Windows/Mac to Linux
|
||||
in = strings.Replace(in, "\r\n", "\n", -1)
|
||||
in = strings.Replace(in, "\r", "\n", -1)
|
||||
|
||||
// Add comment to each line
|
||||
var lines []string
|
||||
for _, line := range strings.Split(in, "\n") {
|
||||
lines = append(lines, fmt.Sprintf("// %s", line))
|
||||
}
|
||||
in = strings.Join(lines, "\n")
|
||||
|
||||
// in case we have a multiline string which ends with \n, we would generate
|
||||
// empty-line-comments, like `// `. Therefore remove this line comment.
|
||||
in = strings.TrimSuffix(in, "\n// ")
|
||||
return in
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue