func evaluateValueSourceSource()

in wstl1/mapping_engine/mapping/engine.go [315:391]


func evaluateValueSourceSource(vs *mappb.ValueSource, args []jsonutil.JSONMetaNode, output jsonutil.JSONToken, pctx *types.Context, a jsonutil.JSONTokenAccessor) (jsonutil.JSONMetaNode, error) {
	var metaNode jsonutil.JSONMetaNode
	var err error
	var location string
	switch s := vs.Source.(type) {

	// Constants:
	case *mappb.ValueSource_ConstString:
		location = "const string"
		metaNode, err = jsonutil.TokenToNodeWithProvenance(jsonutil.JSONStr(s.ConstString), fmt.Sprintf("%q", s.ConstString), jsonutil.Provenance{})
	case *mappb.ValueSource_ConstInt:
		location = "const int"
		metaNode, err = jsonutil.TokenToNodeWithProvenance(jsonutil.JSONNum(s.ConstInt), fmt.Sprintf("%d", s.ConstInt), jsonutil.Provenance{})
	case *mappb.ValueSource_ConstFloat:
		location = "const float"
		metaNode, err = jsonutil.TokenToNodeWithProvenance(jsonutil.JSONNum(s.ConstFloat), fmt.Sprintf("%f", s.ConstFloat), jsonutil.Provenance{})
	case *mappb.ValueSource_ConstBool:
		location = "const bool"
		metaNode, err = jsonutil.TokenToNodeWithProvenance(jsonutil.JSONBool(s.ConstBool), fmt.Sprintf("%v", s.ConstBool), jsonutil.Provenance{})

	// More complicated things:
	case *mappb.ValueSource_FromSource:
		location = fmt.Sprintf("From Source %q", s.FromSource)
		as, asErr := fromSourceToArgSource(s, args)
		if asErr != nil {
			return nil, asErr
		}
		metaNode, err = EvaluateArgSource(as, args, pctx)
	case *mappb.ValueSource_FromDestination:
		location = fmt.Sprintf("From Destination %q", s.FromDestination)
		token, lerr := EvaluateFromDestination(s, output, a)
		if lerr != nil {
			return nil, lerr
		}
		metaNode, err = jsonutil.TokenToNodeWithProvenance(token, fmt.Sprintf("%s's output field %s", pctx.Projector(), s.FromDestination), jsonutil.Provenance{})
	case *mappb.ValueSource_FromLocalVar:
		location = fmt.Sprintf("From Var %q", s.FromLocalVar)
		// TODO(): Provenance support for vars.
		token, lerr := EvaluateFromVar(s, pctx, a)
		if lerr != nil {
			return nil, lerr
		}
		metaNode, err = jsonutil.TokenToNodeWithProvenance(token, fmt.Sprintf("%s's var %s", pctx.Projector(), s.FromLocalVar), jsonutil.Provenance{})
	case *mappb.ValueSource_ProjectedValue:
		if s.ProjectedValue.Projector != "" {
			location = "Argument for " + s.ProjectedValue.Projector
		} else {
			location = "Nested expression"
		}
		metaNode, err = EvaluateValueSource(s.ProjectedValue, args, output, pctx, a)
	// TODO(): token Key = Gvid(); Parent = common ancestor of all args
	// No need to mutate parent though.
	case *mappb.ValueSource_FromArg:
		if s.FromArg < 0 || int(s.FromArg) > len(args) {
			return nil, fmt.Errorf("from_arg is out of range. Requested arg %d but projector only got %d", s.FromArg, len(args))
		}

		location = fmt.Sprintf("from arg %d", s.FromArg)
		if s.FromArg == 0 {
			location += " (all args)"
			metaNode = jsonutil.JSONMetaArrayNode{Items: args}
		} else {
			metaNode = args[s.FromArg-1]
		}
	case *mappb.ValueSource_FromInput:
		metaNode, err = EvaluateArgSource(s.FromInput, args, pctx)
		location = fmt.Sprintf("input arg %d field %q", s.FromInput.Arg, s.FromInput.Field)
	default:
		return nil, fmt.Errorf("unknown value source %T", vs.Source)
	}

	if err != nil {
		return nil, errs.Wrap(errs.Locationf(location), err)
	}

	return metaNode, nil
}