@@ -174,59 +174,25 @@ func (w *mergingWalker) visitListItems(t *schema.List, lhs, rhs value.List) (err
174
174
}
175
175
out := make ([]interface {}, 0 , outLen )
176
176
177
- createPathElementsValues := func (name string , list value.List ) ([]fieldpath.PathElement , fieldpath.PathElementValueMap , ValidationErrors ) {
178
- var errs ValidationErrors
179
- length := 0
180
- if list != nil {
181
- length = list .Length ()
182
- }
183
- observed := fieldpath .MakePathElementValueMap (length )
184
- pes := make ([]fieldpath.PathElement , 0 , length )
185
- for i := 0 ; i < length ; i ++ {
186
- child := list .At (i )
187
- pe , err := listItemToPathElement (w .allocator , w .schema , t , i , child )
188
- if err != nil {
189
- errs = append (errs , errorf ("%s: element %v: %v" , name , i , err .Error ())... )
190
- // If we can't construct the path element, we can't
191
- // even report errors deeper in the schema, so bail on
192
- // this element.
193
- continue
194
- }
195
- if _ , found := observed .Get (pe ); found {
196
- errs = append (errs , errorf ("%s: duplicate entries for key %v" , name , pe .String ())... )
197
- continue
198
- }
199
- observed .Insert (pe , child )
200
- pes = append (pes , pe )
201
- }
202
- return pes , observed , errs
203
- }
204
-
205
- lhsOrder , observedLHS , lhsErrs := createPathElementsValues ("lhs" , lhs )
177
+ lhsOrder , observedLHS , lhsErrs := w .visitListOperand (t , lhs )
206
178
errs = append (errs , lhsErrs ... )
207
- rhsOrder , observedRHS , rhsErrs := createPathElementsValues ( "rhs" , rhs )
179
+ rhsOrder , observedRHS , rhsErrs := w . visitListOperand ( t , rhs )
208
180
errs = append (errs , rhsErrs ... )
209
181
seen := fieldpath .MakePathElementSet (outLen )
210
182
211
183
lLen , rLen = len (lhsOrder ), len (rhsOrder )
212
184
for lI , rI := 0 , 0 ; lI < lLen || rI < rLen ; {
213
- merge := func (pe fieldpath.PathElement , lChild , rChild value.Value ) {
214
- w2 := w .prepareDescent (pe , t .ElementType )
215
- w2 .lhs = lChild
216
- w2 .rhs = rChild
217
- errs = append (errs , w2 .merge (pe .String )... )
218
- if w2 .out != nil {
219
- out = append (out , * w2 .out )
220
- }
221
- w .finishDescent (w2 )
222
- seen .Insert (pe )
223
- }
224
185
if lI < lLen && rI < rLen && lhsOrder [lI ].Equals (rhsOrder [rI ]) {
225
186
// merge LHS & RHS items
226
187
pe := lhsOrder [lI ]
227
188
lChild , _ := observedLHS .Get (pe )
228
189
rChild , _ := observedRHS .Get (pe )
229
- merge (pe , lChild , rChild )
190
+ mergeOut , errs := w .mergeListItem (t , pe , lChild , rChild )
191
+ errs = append (errs , errs ... )
192
+ if mergeOut != nil {
193
+ out = append (out , * mergeOut )
194
+ }
195
+ seen .Insert (pe )
230
196
lI ++
231
197
rI ++
232
198
continue
@@ -240,7 +206,12 @@ func (w *mergingWalker) visitListItems(t *schema.List, lhs, rhs value.List) (err
240
206
} else if _ , ok := observedRHS .Get (pe ); ! ok {
241
207
// Take the LHS item, without a matching RHS item to merge with
242
208
lChild , _ := observedLHS .Get (pe )
243
- merge (pe , lChild , nil )
209
+ mergeOut , errs := w .mergeListItem (t , pe , lChild , nil )
210
+ errs = append (errs , errs ... )
211
+ if mergeOut != nil {
212
+ out = append (out , * mergeOut )
213
+ }
214
+ seen .Insert (pe )
244
215
lI ++
245
216
continue
246
217
}
@@ -250,7 +221,12 @@ func (w *mergingWalker) visitListItems(t *schema.List, lhs, rhs value.List) (err
250
221
pe := rhsOrder [rI ]
251
222
rChild , _ := observedRHS .Get (pe )
252
223
lChild , _ := observedLHS .Get (pe ) // may be nil
253
- merge (pe , lChild , rChild )
224
+ mergeOut , errs := w .mergeListItem (t , pe , lChild , rChild )
225
+ errs = append (errs , errs ... )
226
+ if mergeOut != nil {
227
+ out = append (out , * mergeOut )
228
+ }
229
+ seen .Insert (pe )
254
230
rI ++
255
231
}
256
232
}
@@ -263,6 +239,46 @@ func (w *mergingWalker) visitListItems(t *schema.List, lhs, rhs value.List) (err
263
239
return errs
264
240
}
265
241
242
+ func (w * mergingWalker ) visitListOperand (t * schema.List , list value.List ) ([]fieldpath.PathElement , fieldpath.PathElementValueMap , ValidationErrors ) {
243
+ var errs ValidationErrors
244
+ length := 0
245
+ if list != nil {
246
+ length = list .Length ()
247
+ }
248
+ observed := fieldpath .MakePathElementValueMap (length )
249
+ pes := make ([]fieldpath.PathElement , 0 , length )
250
+ for i := 0 ; i < length ; i ++ {
251
+ child := list .At (i )
252
+ pe , err := listItemToPathElement (w .allocator , w .schema , t , i , child )
253
+ if err != nil {
254
+ errs = append (errs , errorf ("element %v: %v" , i , err .Error ())... )
255
+ // If we can't construct the path element, we can't
256
+ // even report errors deeper in the schema, so bail on
257
+ // this element.
258
+ continue
259
+ }
260
+ if _ , found := observed .Get (pe ); found {
261
+ errs = append (errs , errorf ("duplicate entries for key %v" , pe .String ())... )
262
+ continue
263
+ }
264
+ observed .Insert (pe , child )
265
+ pes = append (pes , pe )
266
+ }
267
+ return pes , observed , errs
268
+ }
269
+
270
+ func (w * mergingWalker ) mergeListItem (t * schema.List , pe fieldpath.PathElement , lChild , rChild value.Value ) (out * interface {}, errs ValidationErrors ) {
271
+ w2 := w .prepareDescent (pe , t .ElementType )
272
+ w2 .lhs = lChild
273
+ w2 .rhs = rChild
274
+ errs = append (errs , w2 .merge (pe .String )... )
275
+ if w2 .out != nil {
276
+ out = w2 .out
277
+ }
278
+ w .finishDescent (w2 )
279
+ return
280
+ }
281
+
266
282
func (w * mergingWalker ) derefList (prefix string , v value.Value ) (value.List , ValidationErrors ) {
267
283
if v == nil {
268
284
return nil , nil
0 commit comments