in source/dotnet/Library/AdaptiveCards.Templating/AdaptiveCardsTemplateVisitor.cs [411:540]
public override AdaptiveCardsTemplateResult VisitObj([NotNull] AdaptiveCardsTemplateParser.ObjContext context)
{
// checks if parsing failed, if failed, return failed segment as string unchanged
if (!ValidateParserRuleContext(context))
{
return new AdaptiveCardsTemplateResult(context.GetText());
}
var hasDataContext = false;
var isArrayType = false;
var pairs = context.pair();
// pair that was used for data context
AdaptiveCardsTemplateParser.PairContext dataPair = null;
// find and set data context
// visit the first data context available, the rest is ignored
foreach (var pair in pairs)
{
if (pair is AdaptiveCardsTemplateParser.TemplateDataContext || pair is AdaptiveCardsTemplateParser.TemplateRootDataContext)
{
if (pair.exception == null)
{
Visit(pair);
hasDataContext = true;
isArrayType = GetCurrentDataContext().IsArrayType;
dataPair = pair;
break;
}
}
}
int repeatsCounts = 1;
var dataContext = GetCurrentDataContext();
if (isArrayType && hasDataContext)
{
var jarray = dataContext.token as JArray;
repeatsCounts = jarray.Count;
}
AdaptiveCardsTemplateResult combinedResult = new AdaptiveCardsTemplateResult();
// indicates the number of removed json object(s)
int removedCounts = 0;
var comma = context.COMMA();
string jsonPairDelimieter = (comma != null && comma.Length > 0) ? comma[0].GetText() : "";
// loop for repeating obj parsed in the inner loop
for (int iObj = 0; iObj < repeatsCounts; iObj++)
{
if (isArrayType)
{
// set new data context
try
{
PushDataContext(dataContext.GetDataContextAtIndex(iObj));
}
catch (Exception e)
{
throw new Exception($"setting data context failed with '{context.GetText()}' at line, '{context.Start.Line}'", e);
}
}
// parse obj
AdaptiveCardsTemplateResult result = new AdaptiveCardsTemplateResult(context.LCB().GetText());
var whenEvaluationResult = AdaptiveCardsTemplateResult.EvaluationResult.NotEvaluated;
bool isPairAdded = false;
for (int iPair = 0; iPair < pairs.Length; iPair++)
{
var pair = pairs[iPair];
// if the pair refers to same pair that was used for data context, do not add its entry
if (pair != dataPair)
{
var returnedResult = Visit(pair);
// add a delimiter, e.g ',' before appending
// a pair after first pair is added
if (isPairAdded && !returnedResult.IsWhen)
{
result.Append(jsonPairDelimieter);
}
result.Append(returnedResult);
if (returnedResult.IsWhen)
{
whenEvaluationResult = returnedResult.WhenEvaluationResult;
}
else
{
isPairAdded = true;
}
}
}
result.Append(context.RCB().GetText());
if (whenEvaluationResult != AdaptiveCardsTemplateResult.EvaluationResult.EvaluatedToFalse)
{
if (iObj != repeatsCounts - 1)
{
result.Append(jsonPairDelimieter);
}
combinedResult.Append(result);
}
else
{
removedCounts++;
}
if (isArrayType)
{
PopDataContext();
}
}
if (hasDataContext)
{
PopDataContext();
}
// all existing json obj in input and repeated json obj if any have been removed
if (removedCounts == repeatsCounts)
{
combinedResult.HasItBeenDropped = true;
}
return combinedResult;
}