11package openapi3
22
33import (
4+ "context"
45 "errors"
56 "fmt"
67 "mime/multipart"
@@ -80,17 +81,20 @@ type OperationContext struct {
8081 HTTPStatus int
8182 RespContentType string
8283 RespHeaderMapping map [string ]string
84+
85+ ProcessingResponse bool
86+ ProcessingIn string
8387}
8488
8589// SetupRequest sets up operation parameters.
8690func (r * Reflector ) SetupRequest (oc OperationContext ) error {
8791 return joinErrors (
88- r .parseParametersIn (oc . Operation , oc . Input , ParameterInQuery , oc .ReqQueryMapping ),
89- r .parseParametersIn (oc . Operation , oc . Input , ParameterInPath , oc .ReqPathMapping ),
90- r .parseParametersIn (oc . Operation , oc . Input , ParameterInCookie , oc .ReqCookieMapping ),
91- r .parseParametersIn (oc . Operation , oc . Input , ParameterInHeader , oc .ReqHeaderMapping ),
92- r .parseRequestBody (oc . Operation , oc . Input , tagJSON , mimeJSON , oc .HTTPMethod , nil ),
93- r .parseRequestBody (oc . Operation , oc . Input , tagFormData , mimeFormUrlencoded , oc .HTTPMethod , oc .ReqFormDataMapping ),
92+ r .parseParametersIn (oc , ParameterInQuery , oc .ReqQueryMapping ),
93+ r .parseParametersIn (oc , ParameterInPath , oc .ReqPathMapping ),
94+ r .parseParametersIn (oc , ParameterInCookie , oc .ReqCookieMapping ),
95+ r .parseParametersIn (oc , ParameterInHeader , oc .ReqHeaderMapping ),
96+ r .parseRequestBody (oc , tagJSON , mimeJSON , oc .HTTPMethod , nil ),
97+ r .parseRequestBody (oc , tagFormData , mimeFormUrlencoded , oc .HTTPMethod , oc .ReqFormDataMapping ),
9498 )
9599}
96100
@@ -120,8 +124,11 @@ type RequestBodyEnforcer interface {
120124}
121125
122126func (r * Reflector ) parseRequestBody (
123- o * Operation , input interface {} , tag , mime string , httpMethod string , mapping map [string ]string ,
127+ oc OperationContext , tag , mime string , httpMethod string , mapping map [string ]string ,
124128) error {
129+ o := oc .Operation
130+ input := oc .Input
131+
125132 httpMethod = strings .ToUpper (httpMethod )
126133 _ , forceRequestBody := input .(RequestBodyEnforcer )
127134
@@ -153,6 +160,7 @@ func (r *Reflector) parseRequestBody(
153160 }
154161
155162 schema , err := r .Reflect (input ,
163+ r .withOperation (oc , false , "body" ),
156164 jsonschema .DefinitionsPrefix ("#/components/schemas/" + definitionPrefix ),
157165 jsonschema .RootRef ,
158166 jsonschema .PropertyNameMapping (mapping ),
@@ -217,13 +225,17 @@ const (
217225)
218226
219227func (r * Reflector ) parseParametersIn (
220- o * Operation , input interface {} , in ParameterIn , propertyMapping map [string ]string ,
228+ oc OperationContext , in ParameterIn , propertyMapping map [string ]string ,
221229) error {
230+ o := oc .Operation
231+ input := oc .Input
232+
222233 if refl .IsSliceOrMap (input ) {
223234 return nil
224235 }
225236
226237 s , err := r .Reflect (input ,
238+ r .withOperation (oc , false , string (in )),
227239 jsonschema .DefinitionsPrefix ("#/components/schemas/" ),
228240 jsonschema .CollectDefinitions (r .collectDefinition ),
229241 jsonschema .PropertyNameMapping (propertyMapping ),
@@ -265,6 +277,7 @@ func (r *Reflector) parseParametersIn(
265277 property := reflect .New (field .Type ).Interface ()
266278 if refl .HasTaggedFields (property , tagJSON ) {
267279 propertySchema , err := r .Reflect (property ,
280+ r .withOperation (oc , false , string (in )),
268281 jsonschema .DefinitionsPrefix ("#/components/schemas/" ),
269282 jsonschema .CollectDefinitions (r .collectDefinition ),
270283 jsonschema .RootRef ,
@@ -278,7 +291,9 @@ func (r *Reflector) parseParametersIn(
278291 p .Schema = nil
279292 p .WithContentItem ("application/json" , MediaType {Schema : & openapiSchema })
280293 } else {
281- ps , err := r .Reflect (reflect .New (field .Type ).Interface (), jsonschema .InlineRefs )
294+ ps , err := r .Reflect (reflect .New (field .Type ).Interface (),
295+ r .withOperation (oc , false , string (in )),
296+ jsonschema .InlineRefs )
282297 if err != nil {
283298 return err
284299 }
@@ -339,10 +354,14 @@ func (r *Reflector) collectDefinition(name string, schema jsonschema.Schema) {
339354 r .SpecEns ().ComponentsEns ().SchemasEns ().WithMapOfSchemaOrRefValuesItem (name , s )
340355}
341356
342- func (r * Reflector ) parseResponseHeader (resp * Response , output interface {}, mapping map [string ]string ) error {
357+ func (r * Reflector ) parseResponseHeader (resp * Response , oc OperationContext ) error {
358+ output := oc .Output
359+ mapping := oc .RespHeaderMapping
360+
343361 res := make (map [string ]HeaderOrRef )
344362
345363 schema , err := r .Reflect (output ,
364+ r .withOperation (oc , true , "header" ),
346365 jsonschema .InlineRefs ,
347366 jsonschema .PropertyNameMapping (mapping ),
348367 jsonschema .PropertyNameTag ("header" ),
@@ -418,12 +437,12 @@ func (r *Reflector) SetupResponse(oc OperationContext) error {
418437 if oc .Output != nil {
419438 oc .RespContentType = strings .Split (oc .RespContentType , ";" )[0 ]
420439
421- err := r .parseJSONResponse (& resp , oc . Output , oc . RespContentType )
440+ err := r .parseJSONResponse (& resp , oc )
422441 if err != nil {
423442 return err
424443 }
425444
426- err = r .parseResponseHeader (& resp , oc . Output , oc . RespHeaderMapping )
445+ err = r .parseResponseHeader (& resp , oc )
427446 if err != nil {
428447 return err
429448 }
@@ -456,13 +475,17 @@ func (r *Reflector) ensureResponseContentType(resp *Response, contentType string
456475 }
457476}
458477
459- func (r * Reflector ) parseJSONResponse (resp * Response , output interface {}, contentType string ) error {
478+ func (r * Reflector ) parseJSONResponse (resp * Response , oc OperationContext ) error {
479+ output := oc .Output
480+ contentType := oc .RespContentType
481+
460482 // Check if output structure exposes meaningful schema.
461483 if hasJSONBody , err := r .hasJSONBody (output ); err == nil && ! hasJSONBody {
462484 return nil
463485 }
464486
465487 schema , err := r .Reflect (output ,
488+ r .withOperation (oc , true , "body" ),
466489 jsonschema .RootRef ,
467490 jsonschema .DefinitionsPrefix ("#/components/schemas/" ),
468491 jsonschema .CollectDefinitions (r .collectDefinition ),
@@ -500,3 +523,23 @@ func (r *Reflector) parseJSONResponse(resp *Response, output interface{}, conten
500523
501524 return nil
502525}
526+
527+ type ocCtxKey struct {}
528+
529+ func (r * Reflector ) withOperation (oc OperationContext , processingResponse bool , in string ) func (rc * jsonschema.ReflectContext ) {
530+ return func (rc * jsonschema.ReflectContext ) {
531+ oc .ProcessingResponse = processingResponse
532+ oc .ProcessingIn = in
533+
534+ rc .Context = context .WithValue (rc .Context , ocCtxKey {}, oc )
535+ }
536+ }
537+
538+ // OperationCtx retrieves operation context from reflect context.
539+ func OperationCtx (rc * jsonschema.ReflectContext ) (OperationContext , bool ) {
540+ if oc , ok := rc .Value (ocCtxKey {}).(OperationContext ); ok {
541+ return oc , true
542+ }
543+
544+ return OperationContext {}, false
545+ }
0 commit comments