Matteo Scandolo | a6a3aee | 2019-11-26 13:30:14 -0700 | [diff] [blame] | 1 | package genswagger |
| 2 | |
| 3 | import ( |
| 4 | "bytes" |
| 5 | "encoding/json" |
| 6 | |
| 7 | "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor" |
| 8 | ) |
| 9 | |
| 10 | type param struct { |
| 11 | *descriptor.File |
| 12 | reg *descriptor.Registry |
| 13 | } |
| 14 | |
| 15 | type binding struct { |
| 16 | *descriptor.Binding |
| 17 | } |
| 18 | |
| 19 | // http://swagger.io/specification/#infoObject |
| 20 | type swaggerInfoObject struct { |
| 21 | Title string `json:"title"` |
| 22 | Description string `json:"description,omitempty"` |
| 23 | TermsOfService string `json:"termsOfService,omitempty"` |
| 24 | Version string `json:"version"` |
| 25 | |
| 26 | Contact *swaggerContactObject `json:"contact,omitempty"` |
| 27 | License *swaggerLicenseObject `json:"license,omitempty"` |
| 28 | |
| 29 | extensions []extension |
| 30 | } |
| 31 | |
| 32 | // http://swagger.io/specification/#contactObject |
| 33 | type swaggerContactObject struct { |
| 34 | Name string `json:"name,omitempty"` |
| 35 | URL string `json:"url,omitempty"` |
| 36 | Email string `json:"email,omitempty"` |
| 37 | } |
| 38 | |
| 39 | // http://swagger.io/specification/#licenseObject |
| 40 | type swaggerLicenseObject struct { |
| 41 | Name string `json:"name,omitempty"` |
| 42 | URL string `json:"url,omitempty"` |
| 43 | } |
| 44 | |
| 45 | // http://swagger.io/specification/#externalDocumentationObject |
| 46 | type swaggerExternalDocumentationObject struct { |
| 47 | Description string `json:"description,omitempty"` |
| 48 | URL string `json:"url,omitempty"` |
| 49 | } |
| 50 | |
| 51 | type extension struct { |
| 52 | key string |
| 53 | value json.RawMessage |
| 54 | } |
| 55 | |
| 56 | // http://swagger.io/specification/#swaggerObject |
| 57 | type swaggerObject struct { |
| 58 | Swagger string `json:"swagger"` |
| 59 | Info swaggerInfoObject `json:"info"` |
| 60 | Host string `json:"host,omitempty"` |
| 61 | BasePath string `json:"basePath,omitempty"` |
Arjun E K | 57a7fcb | 2020-01-30 06:44:45 +0000 | [diff] [blame] | 62 | Schemes []string `json:"schemes,omitempty"` |
Matteo Scandolo | a6a3aee | 2019-11-26 13:30:14 -0700 | [diff] [blame] | 63 | Consumes []string `json:"consumes"` |
| 64 | Produces []string `json:"produces"` |
| 65 | Paths swaggerPathsObject `json:"paths"` |
| 66 | Definitions swaggerDefinitionsObject `json:"definitions"` |
Matteo Scandolo | a6a3aee | 2019-11-26 13:30:14 -0700 | [diff] [blame] | 67 | SecurityDefinitions swaggerSecurityDefinitionsObject `json:"securityDefinitions,omitempty"` |
| 68 | Security []swaggerSecurityRequirementObject `json:"security,omitempty"` |
| 69 | ExternalDocs *swaggerExternalDocumentationObject `json:"externalDocs,omitempty"` |
| 70 | |
| 71 | extensions []extension |
| 72 | } |
| 73 | |
| 74 | // http://swagger.io/specification/#securityDefinitionsObject |
| 75 | type swaggerSecurityDefinitionsObject map[string]swaggerSecuritySchemeObject |
| 76 | |
| 77 | // http://swagger.io/specification/#securitySchemeObject |
| 78 | type swaggerSecuritySchemeObject struct { |
| 79 | Type string `json:"type"` |
| 80 | Description string `json:"description,omitempty"` |
| 81 | Name string `json:"name,omitempty"` |
| 82 | In string `json:"in,omitempty"` |
| 83 | Flow string `json:"flow,omitempty"` |
| 84 | AuthorizationURL string `json:"authorizationUrl,omitempty"` |
| 85 | TokenURL string `json:"tokenUrl,omitempty"` |
| 86 | Scopes swaggerScopesObject `json:"scopes,omitempty"` |
| 87 | |
| 88 | extensions []extension |
| 89 | } |
| 90 | |
| 91 | // http://swagger.io/specification/#scopesObject |
| 92 | type swaggerScopesObject map[string]string |
| 93 | |
| 94 | // http://swagger.io/specification/#securityRequirementObject |
| 95 | type swaggerSecurityRequirementObject map[string][]string |
| 96 | |
| 97 | // http://swagger.io/specification/#pathsObject |
| 98 | type swaggerPathsObject map[string]swaggerPathItemObject |
| 99 | |
| 100 | // http://swagger.io/specification/#pathItemObject |
| 101 | type swaggerPathItemObject struct { |
| 102 | Get *swaggerOperationObject `json:"get,omitempty"` |
| 103 | Delete *swaggerOperationObject `json:"delete,omitempty"` |
| 104 | Post *swaggerOperationObject `json:"post,omitempty"` |
| 105 | Put *swaggerOperationObject `json:"put,omitempty"` |
| 106 | Patch *swaggerOperationObject `json:"patch,omitempty"` |
| 107 | } |
| 108 | |
| 109 | // http://swagger.io/specification/#operationObject |
| 110 | type swaggerOperationObject struct { |
| 111 | Summary string `json:"summary,omitempty"` |
| 112 | Description string `json:"description,omitempty"` |
| 113 | OperationID string `json:"operationId"` |
| 114 | Responses swaggerResponsesObject `json:"responses"` |
| 115 | Parameters swaggerParametersObject `json:"parameters,omitempty"` |
| 116 | Tags []string `json:"tags,omitempty"` |
| 117 | Deprecated bool `json:"deprecated,omitempty"` |
| 118 | |
| 119 | Security *[]swaggerSecurityRequirementObject `json:"security,omitempty"` |
| 120 | ExternalDocs *swaggerExternalDocumentationObject `json:"externalDocs,omitempty"` |
| 121 | |
| 122 | extensions []extension |
| 123 | } |
| 124 | |
| 125 | type swaggerParametersObject []swaggerParameterObject |
| 126 | |
| 127 | // http://swagger.io/specification/#parameterObject |
| 128 | type swaggerParameterObject struct { |
| 129 | Name string `json:"name"` |
| 130 | Description string `json:"description,omitempty"` |
| 131 | In string `json:"in,omitempty"` |
| 132 | Required bool `json:"required"` |
| 133 | Type string `json:"type,omitempty"` |
| 134 | Format string `json:"format,omitempty"` |
| 135 | Items *swaggerItemsObject `json:"items,omitempty"` |
| 136 | Enum []string `json:"enum,omitempty"` |
| 137 | CollectionFormat string `json:"collectionFormat,omitempty"` |
| 138 | Default string `json:"default,omitempty"` |
| 139 | MinItems *int `json:"minItems,omitempty"` |
| 140 | |
| 141 | // Or you can explicitly refer to another type. If this is defined all |
| 142 | // other fields should be empty |
| 143 | Schema *swaggerSchemaObject `json:"schema,omitempty"` |
| 144 | } |
| 145 | |
| 146 | // core part of schema, which is common to itemsObject and schemaObject. |
| 147 | // http://swagger.io/specification/#itemsObject |
| 148 | type schemaCore struct { |
| 149 | Type string `json:"type,omitempty"` |
| 150 | Format string `json:"format,omitempty"` |
| 151 | Ref string `json:"$ref,omitempty"` |
| 152 | Example json.RawMessage `json:"example,omitempty"` |
| 153 | |
| 154 | Items *swaggerItemsObject `json:"items,omitempty"` |
| 155 | |
| 156 | // If the item is an enumeration include a list of all the *NAMES* of the |
| 157 | // enum values. I'm not sure how well this will work but assuming all enums |
| 158 | // start from 0 index it will be great. I don't think that is a good assumption. |
| 159 | Enum []string `json:"enum,omitempty"` |
| 160 | Default string `json:"default,omitempty"` |
| 161 | } |
| 162 | |
| 163 | type swaggerItemsObject schemaCore |
| 164 | |
| 165 | // http://swagger.io/specification/#responsesObject |
| 166 | type swaggerResponsesObject map[string]swaggerResponseObject |
| 167 | |
| 168 | // http://swagger.io/specification/#responseObject |
| 169 | type swaggerResponseObject struct { |
| 170 | Description string `json:"description"` |
| 171 | Schema swaggerSchemaObject `json:"schema"` |
| 172 | |
| 173 | extensions []extension |
| 174 | } |
| 175 | |
| 176 | type keyVal struct { |
| 177 | Key string |
| 178 | Value interface{} |
| 179 | } |
| 180 | |
| 181 | type swaggerSchemaObjectProperties []keyVal |
| 182 | |
| 183 | func (op swaggerSchemaObjectProperties) MarshalJSON() ([]byte, error) { |
| 184 | var buf bytes.Buffer |
| 185 | buf.WriteString("{") |
| 186 | for i, kv := range op { |
| 187 | if i != 0 { |
| 188 | buf.WriteString(",") |
| 189 | } |
| 190 | key, err := json.Marshal(kv.Key) |
| 191 | if err != nil { |
| 192 | return nil, err |
| 193 | } |
| 194 | buf.Write(key) |
| 195 | buf.WriteString(":") |
| 196 | val, err := json.Marshal(kv.Value) |
| 197 | if err != nil { |
| 198 | return nil, err |
| 199 | } |
| 200 | buf.Write(val) |
| 201 | } |
| 202 | |
| 203 | buf.WriteString("}") |
| 204 | return buf.Bytes(), nil |
| 205 | } |
| 206 | |
| 207 | // http://swagger.io/specification/#schemaObject |
| 208 | type swaggerSchemaObject struct { |
| 209 | schemaCore |
| 210 | // Properties can be recursively defined |
| 211 | Properties *swaggerSchemaObjectProperties `json:"properties,omitempty"` |
| 212 | AdditionalProperties *swaggerSchemaObject `json:"additionalProperties,omitempty"` |
| 213 | |
| 214 | Description string `json:"description,omitempty"` |
| 215 | Title string `json:"title,omitempty"` |
| 216 | |
| 217 | ExternalDocs *swaggerExternalDocumentationObject `json:"externalDocs,omitempty"` |
| 218 | |
| 219 | ReadOnly bool `json:"readOnly,omitempty"` |
| 220 | MultipleOf float64 `json:"multipleOf,omitempty"` |
| 221 | Maximum float64 `json:"maximum,omitempty"` |
| 222 | ExclusiveMaximum bool `json:"exclusiveMaximum,omitempty"` |
| 223 | Minimum float64 `json:"minimum,omitempty"` |
| 224 | ExclusiveMinimum bool `json:"exclusiveMinimum,omitempty"` |
| 225 | MaxLength uint64 `json:"maxLength,omitempty"` |
| 226 | MinLength uint64 `json:"minLength,omitempty"` |
| 227 | Pattern string `json:"pattern,omitempty"` |
| 228 | MaxItems uint64 `json:"maxItems,omitempty"` |
| 229 | MinItems uint64 `json:"minItems,omitempty"` |
| 230 | UniqueItems bool `json:"uniqueItems,omitempty"` |
| 231 | MaxProperties uint64 `json:"maxProperties,omitempty"` |
| 232 | MinProperties uint64 `json:"minProperties,omitempty"` |
| 233 | Required []string `json:"required,omitempty"` |
| 234 | } |
| 235 | |
| 236 | // http://swagger.io/specification/#referenceObject |
| 237 | type swaggerReferenceObject struct { |
| 238 | Ref string `json:"$ref"` |
| 239 | } |
| 240 | |
| 241 | // http://swagger.io/specification/#definitionsObject |
| 242 | type swaggerDefinitionsObject map[string]swaggerSchemaObject |
| 243 | |
| 244 | // Internal type mapping from FQMN to descriptor.Message. Used as a set by the |
| 245 | // findServiceMessages function. |
| 246 | type messageMap map[string]*descriptor.Message |
| 247 | |
| 248 | // Internal type mapping from FQEN to descriptor.Enum. Used as a set by the |
| 249 | // findServiceMessages function. |
| 250 | type enumMap map[string]*descriptor.Enum |
| 251 | |
| 252 | // Internal type to store used references. |
| 253 | type refMap map[string]struct{} |