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;
}