forked from getkin/kin-openapi
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrefs.tmpl
More file actions
159 lines (137 loc) · 4.26 KB
/
refs.tmpl
File metadata and controls
159 lines (137 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Code generated by go generate using refs.tmpl; DO NOT EDIT refs.go.
package {{ .Package }}
import (
"context"
"encoding/json"
"fmt"
"net/url"
"sort"
"strings"
"github.com/go-openapi/jsonpointer"
"github.com/perimeterx/marshmallow"
)
{{ 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
Ref string
Value *{{ $type.Name }}
extra []string
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}, 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 extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != "" {
x.Ref = refOnly.Ref
x.Origin = refOnly.Origin
if len(extra) != 0 {
x.extra = make([]string, 0, len(extra))
for key := range extra {
x.extra = append(x.extra, key)
}
sort.Strings(x.extra)
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)
}
// 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...)
exProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited
var extras []string
if extra := x.extra; len(extra) != 0 {
allowed := getValidationOptions(ctx).extraSiblingFieldsAllowed
for _, ex := range extra {
if allowed != nil {
if _, ok := allowed[ex]; ok {
continue
}
}
// extras in the Extensions checked below
if _, ok := x.Extensions[ex]; !ok {
extras = append(extras, ex)
}
}
}
if extra := x.Extensions; exProhibited && len(extra) != 0 {
allowed := getValidationOptions(ctx).extraSiblingFieldsAllowed
for ex := range extra {
if allowed != nil {
if _, ok := allowed[ex]; ok {
continue
}
}
extras = append(extras, ex)
}
}
if len(extras) != 0 {
{{- if eq $type.Name "Schema" }}
if !getValidationOptions(ctx).jsonSchema2020ValidationEnabled {
return fmt.Errorf("extra sibling fields: %+v", extras)
}
{{- else }}
return fmt.Errorf("extra sibling fields: %+v", extras)
{{- end }}
}
if v := x.Value; v != nil {
return v.Validate(ctx)
}
return foundUnresolvedRef(x.Ref)
}
// 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 -}}