@@ -30,11 +30,7 @@ type Schema struct {
30
30
once sync.Once
31
31
m map [string ]TypeDef
32
32
33
- // Once used to protect the initialization of `lock` field.
34
- lockOnce sync.Once
35
- // Lock which protects writes to resolvedTypes. Used as pointer so that
36
- // schema may be used as a value type
37
- lock * sync.Mutex
33
+ lock sync.Mutex
38
34
// Cached results of resolving type references to atoms. Only stores
39
35
// type references which require fields of Atom to be overriden.
40
36
resolvedTypes map [TypeRef ]Atom
@@ -163,6 +159,31 @@ func (m *Map) FindField(name string) (StructField, bool) {
163
159
return sf , ok
164
160
}
165
161
162
+ // CopyInto this instance of Map into the other
163
+ // If other is nil this method does nothing.
164
+ // If other is already initialized, overwrites it with this instance
165
+ // Warning: Not thread safe
166
+ func (m * Map ) CopyInto (dst * Map ) {
167
+ if dst == nil {
168
+ return
169
+ }
170
+
171
+ // Map type is considered immutable so sharing references
172
+ dst .Fields = m .Fields
173
+ dst .ElementType = m .ElementType
174
+ dst .Unions = m .Unions
175
+ dst .ElementRelationship = m .ElementRelationship
176
+
177
+ if m .m != nil {
178
+ // If cache is non-nil then the once token had been consumed.
179
+ // Must reset token and use it again to ensure same semantics.
180
+ dst .once = sync.Once {}
181
+ dst .once .Do (func () {
182
+ dst .m = m .m
183
+ })
184
+ }
185
+ }
186
+
166
187
// UnionFields are mapping between the fields that are part of the union and
167
188
// their discriminated value. The discriminated value has to be set, and
168
189
// should not conflict with other discriminated value in the list.
@@ -289,15 +310,13 @@ func (s *Schema) Resolve(tr TypeRef) (Atom, bool) {
289
310
return s .resolveNoOverrides (tr )
290
311
}
291
312
292
- // Check to see if we have a cached version of this type
293
- s .lockOnce .Do (func () {
294
- s .lock = & sync.Mutex {}
295
- s .resolvedTypes = make (map [TypeRef ]Atom )
296
- })
297
-
298
313
s .lock .Lock ()
299
314
defer s .lock .Unlock ()
300
315
316
+ if s .resolvedTypes == nil {
317
+ s .resolvedTypes = make (map [TypeRef ]Atom )
318
+ }
319
+
301
320
var result Atom
302
321
var exists bool
303
322
@@ -308,7 +327,8 @@ func (s *Schema) Resolve(tr TypeRef) (Atom, bool) {
308
327
// Allow field-level electives to override the referred type's modifiers
309
328
switch {
310
329
case result .Map != nil :
311
- mapCopy := * result .Map
330
+ mapCopy := Map {}
331
+ result .Map .CopyInto (& mapCopy )
312
332
mapCopy .ElementRelationship = * tr .ElementRelationship
313
333
result .Map = & mapCopy
314
334
case result .List != nil :
@@ -335,7 +355,7 @@ func (s *Schema) Resolve(tr TypeRef) (Atom, bool) {
335
355
// If other is nil this method does nothing.
336
356
// If other is already initialized, overwrites it with this instance
337
357
// Warning: Not thread safe
338
- func (s Schema ) CopyInto (dst * Schema ) {
358
+ func (s * Schema ) CopyInto (dst * Schema ) {
339
359
if dst == nil {
340
360
return
341
361
}
0 commit comments