// Code generated by go generate using refs.tmpl; DO NOT EDIT refs.go. package {{ .Package }} import ( "context" "encoding/json" "net/url" "strings" "github.com/go-openapi/jsonpointer" ) {{ range $type := .Types }} // {{ $type.Name }}Ref represents either a {{ $type.Name }} or a $ref to a {{ $type.Name }}. // When serializing and both fields are set, Ref is preferred over Value. type {{ $type.Name }}Ref struct { // Extensions only captures fields starting with 'x-' as no other fields // are allowed by the openapi spec. Extensions map[string]any Origin *Origin `json:"-" yaml:"-"` Ref string Value *{{ $type.Name }} extra []string {{- if eq $type.Name "Schema" }} // sibling holds keyword siblings of a $ref (OAS 3.1 / JSON Schema 2020-12). // It is populated during unmarshal and applied to Value after $ref resolution. sibling *Schema {{- end }} refPath *url.URL } var _ jsonpointer.JSONPointable = (*{{ $type.Name }}Ref)(nil) func (x *{{ $type.Name }}Ref) isEmpty() bool { return x == nil || x.Ref == "" && x.Value == nil } // RefString returns the $ref value. func (x *{{ $type.Name }}Ref) RefString() string { return x.Ref } // CollectionName returns the JSON string used for a collection of these components. func (x *{{ $type.Name }}Ref) CollectionName() string { return "{{ $type.CollectionName }}" } // RefPath returns the path of the $ref relative to the root document. func (x *{{ $type.Name }}Ref) RefPath() *url.URL { return copyURI(x.refPath) } func (x *{{ $type.Name }}Ref) setRefPath(u *url.URL) { // Once the refPath is set don't override. References can be loaded // multiple times not all with access to the correct path info. if x.refPath != nil { return } x.refPath = copyURI(u) } // MarshalYAML returns the YAML encoding of {{ $type.Name }}Ref. func (x {{ $type.Name }}Ref) MarshalYAML() (any, error) { if ref := x.Ref; ref != "" { return &Ref{Ref: ref, Extensions: x.Extensions}, nil } return x.Value.MarshalYAML() } // MarshalJSON returns the JSON encoding of {{ $type.Name }}Ref. func (x {{ $type.Name }}Ref) MarshalJSON() ([]byte, error) { y, err := x.MarshalYAML() if err != nil { return nil, err } return json.Marshal(y) } // UnmarshalJSON sets {{ $type.Name }}Ref to a copy of data. func (x *{{ $type.Name }}Ref) UnmarshalJSON(data []byte) error { var refOnly Ref if err := json.Unmarshal(data, &refOnly); err == nil && refOnly.Ref != "" { extra := map[string]any{} _ = json.Unmarshal(data, &extra) delete(extra, "$ref") x.Ref = refOnly.Ref x.Origin = refOnly.Origin if len(extra) != 0 { x.extra = componentNames(extra) {{- if eq $type.Name "Schema" }} // OAS 3.1 / JSON Schema 2020-12: sibling keywords alongside $ref are valid // and must be merged with the resolved reference. Parse the full object so // the sibling fields are available after $ref resolution in resolveSchemaRef. hasSiblings := false for k := range extra { if !strings.HasPrefix(k, "x-") { hasSiblings = true break } } if hasSiblings { var sibling Schema if err := json.Unmarshal(data, &sibling); err == nil { x.sibling = &sibling } } {{- end }} for k := range extra { if !strings.HasPrefix(k, "x-") { delete(extra, k) } } if len(extra) != 0 { x.Extensions = extra } } return nil } return json.Unmarshal(data, &x.Value) } // validateExtras returns an error if {{ $type.Name }}Ref has sibling fields // alongside $ref that are not allowed by the validation options. func (x *{{ $type.Name }}Ref) validateExtras(ctx context.Context) error { validationOpts := getValidationOptions(ctx) var extras []string allowed := validationOpts.extraSiblingFieldsAllowed if allowed == nil { allowed = make(map[string]struct{}) } for _, ex := range x.extra { if _, ok := allowed[ex]; !ok { if _, ok := x.Extensions[ex]; !ok { extras = append(extras, ex) } // extras in the Extensions checked below } } if validationOpts.schemaExtensionsInRefProhibited { for _, ex := range componentNames(x.Extensions) { if _, ok := allowed[ex]; !ok { extras = append(extras, ex) } // extras in the Extensions checked below } } if len(extras) != 0 { {{- if eq $type.Name "Schema" }} if !validationOpts.isOpenAPI31OrLater { return newExtraSiblingFields(extras, x.Origin) } {{- else }} return newExtraSiblingFields(extras, x.Origin) {{- end }} } return nil } // Validate returns an error if {{ $type.Name }}Ref does not comply with the OpenAPI spec. func (x *{{ $type.Name }}Ref) Validate(ctx context.Context, opts ...ValidationOption) error { ctx = WithValidationOptions(ctx, opts...) if err := x.validateExtras(ctx); err != nil { return err } if v := x.Value; v != nil { return v.Validate(ctx) } return newUnresolvedRef(x.Ref, x.Origin) } // JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable func (x *{{ $type.Name }}Ref) JSONLookup(token string) (any, error) { if token == "$ref" { return x.Ref, nil } if v, ok := x.Extensions[token]; ok { return v, nil } ptr, _, err := jsonpointer.GetForToken(x.Value, token) return ptr, err } {{ end -}}