public override List VisitStructuredBody()

in libraries/Microsoft.Bot.Builder.LanguageGeneration/Expander.cs [189:292]


        public override List<object> VisitStructuredBody([NotNull] LGTemplateParser.StructuredBodyContext context)
        {
            var templateRefValues = new Dictionary<string, List<object>>();
            var stb = context.structuredTemplateBody();
            var result = new JObject();
            var typeName = stb.structuredBodyNameLine().STRUCTURE_NAME().GetText();
            result[Evaluator.LGType] = typeName;
            var expandedResult = new List<JObject>
            {
                result
            };
            var bodys = stb.structuredBodyContentLine();
            foreach (var body in bodys)
            {
                var isKVPairBody = body.keyValueStructureLine() != null;
                if (isKVPairBody)
                {
                    var property = body.keyValueStructureLine().STRUCTURE_IDENTIFIER().GetText().ToLowerInvariant();
                    var value = VisitStructureValue(body.keyValueStructureLine());
                    if (value != null && value.Count > 0)
                    {
                        if (value.Count > 1)
                        {
                            var valueList = new JArray();
                            foreach (var item in value)
                            {
                                var id = Guid.NewGuid().ToString();
                                if (item.Count > 0)
                                {
                                    valueList.Add(id);
                                    templateRefValues.Add(id, item);
                                }
                                else
                                {
                                    valueList.Add(new JArray());
                                }
                            }

                            expandedResult.ForEach(x => x[property] = valueList);
                        }
                        else
                        {
                            var id = Guid.NewGuid().ToString();
                            if (value[0].Count > 0)
                            {
                                expandedResult.ForEach(x => x[property] = id);
                                templateRefValues.Add(id, value[0]);
                            }
                            else
                            {
                                expandedResult.ForEach(x => x[property] = new JArray());
                            }
                        }
                    }
                }
                else
                {
                    var propertyObjects = EvalExpression(body.expressionInStructure().GetText(), body.GetText()).Where(x => x != null).Select(x => JObject.Parse(x.ToString())).ToList();
                    var tempResult = new List<JObject>();
                    foreach (var res in expandedResult)
                    {
                        foreach (var propertyObject in propertyObjects)
                        {
                            var tempRes = JObject.FromObject(res);

                            // Full reference to another structured template is limited to the structured template with same type 
                            if (propertyObject[Evaluator.LGType] != null && propertyObject[Evaluator.LGType].ToString() == typeName)
                            {
                                foreach (var item in propertyObject)
                                {
                                    if (tempRes.Property(item.Key, StringComparison.Ordinal) == null)
                                    {
                                        tempRes[item.Key] = item.Value;
                                    }
                                }
                            }

                            tempResult.Add(tempRes);
                        }
                    }

                    expandedResult = tempResult;
                }
            }

            var exps = expandedResult;

            var finalResult = new List<object>(exps);
            foreach (var templateRefValue in templateRefValues)
            {
                var tempRes = new List<object>();
                foreach (var res in finalResult)
                {
                    foreach (var refValue in templateRefValue.Value)
                    {
                        tempRes.Add(res.ToString().Replace(templateRefValue.Key, refValue.ToString().Replace("\"", "\\\"")));
                    }
                }

                finalResult = tempRes;
            }

            return finalResult;
        }