private ExpressionFnOuter Element()

in src/PSRule.Rules.Azure/Data/Template/ExpressionBuilder.cs [70:116]


    private ExpressionFnOuter Element(TokenStream stream, ExpressionToken element)
    {
        ExpressionFnOuter result = null;

        // function
        if (stream.Skip(ExpressionTokenType.GroupStart))
        {
            // Try to find a known ARM function.
            if (!_Functions.TryDescriptor(element.Content, out var descriptor))
                throw new NotImplementedException(string.Format(Thread.CurrentThread.CurrentCulture, PSRuleResources.FunctionNotFound, element.Content));

            var fnParams = new List<ExpressionFnOuter>();
            while (!stream.Skip(ExpressionTokenType.GroupEnd))
            {
                fnParams.Add(Inner(stream));
            }
            var aParams = fnParams.ToArray();
            var symbolName = element.Content;
            var symbol = new DebugSymbol(descriptor.Name, symbolName);
            result = (context) => descriptor.Invoke(context, symbol, aParams);

            while (stream.TryTokenType(ExpressionTokenType.IndexStart, out var token) || stream.TryTokenType(ExpressionTokenType.Property, out token))
            {
                if (token.Type == ExpressionTokenType.IndexStart)
                {
                    // Invert: index(fn1(p1, p2), 0)
                    var inner = Inner(stream);
                    var outer = AddIndex(result, inner);
                    result = outer;

                    stream.Skip(ExpressionTokenType.IndexEnd);
                }
                else if (token.Type == ExpressionTokenType.Property)
                {
                    // Invert: property(fn1(p1, p2), "name")
                    var outer = AddProperty(result, token.Content);
                    result = outer;
                }
            }
        }
        // integer
        else
        {
            result = (context) => element.Content;
        }
        return result;
    }