in wstl1/mapping_engine/util/jsonutil/jsonutil.go [207:279]
func (w DefaultAccessor) getFieldSegmented(src JSONToken, segments []string) (JSONToken, error) {
if len(segments) == 0 {
return src, nil
}
if src == nil {
return nil, nil
}
seg := segments[0]
switch o := src.(type) {
case JSONArr:
if seg == "[]" {
return nil, fmt.Errorf("expected an array index with brackets like [123] but got []")
}
if !IsIndex(seg) {
return nil, fmt.Errorf("expected an array index with brackets like [123] but got %s", seg)
}
idxSubstr := seg[1 : len(seg)-1]
if idxSubstr == "*" {
flatten := JSONArr{}
for i := range o {
f, err := w.getFieldSegmented(o[i], segments[1:])
if err != nil {
return nil, fmt.Errorf("error expanding [*] on item index %d: %v", i, err)
}
// If an array expansion occurs down the line, we need to unnest the resulting array here.
if f != nil && hasArrayStar(segments[1:]) {
fArr, ok := f.(JSONArr)
if !ok {
return nil, fmt.Errorf("this is an internal bug: found nested [*] but value was not an array (was %T)", f)
}
flatten = append(flatten, fArr...)
} else {
flatten = append(flatten, f)
}
}
return flatten, nil
}
idx, err := strconv.Atoi(idxSubstr)
if err != nil {
return nil, fmt.Errorf("could not parse array index %s: %v", seg, err)
}
if idx < 0 {
return nil, fmt.Errorf("negative array indices are not supported but got %d", idx)
}
if idx >= len(o) {
// TODO(): Consider returning a different value for fields that don't exist vs
// fields that are actually set to null.
return nil, nil
}
return w.getFieldSegmented(o[idx], segments[1:])
case JSONContainer:
if seg == "" || seg == "." {
return w.getFieldSegmented(o, segments[1:])
}
if item, ok := o[seg]; ok {
return w.getFieldSegmented(*item, segments[1:])
}
// TODO(): Consider returning a different value for fields that don't exist vs
// fields that are actually set to null.
return nil, nil
case JSONNum, JSONStr, JSONBool:
return nil, fmt.Errorf("attempt to key into primitive with key %s", seg)
}
return nil, fmt.Errorf("this is an internal bug: JSON contained unknown data type %T at %s", src, seg)
}