public static QueryListBlock CreateBlock(string id, string op, IQuerySource source, string value)
        {
            var attr = FindBlock(id);

            QueryMarker.TryParse(value, out var marker);
            var isValidMarker = marker.valid && marker.type == "list";

            if (attr != null)
            {
                if (isValidMarker)
                {
                    return(new QueryListMarkerBlock(source, id, marker, attr));
                }

                return((QueryListBlock)Activator.CreateInstance(attr.type, new object[] { source, id, value, attr }));
            }
            else if (isValidMarker)
            {
                return(new QueryListMarkerBlock(source, id, id, op, marker));
            }
            return(null);
        }
        public static bool TryParse(StringView text, out QueryMarker marker)
        {
            marker = none;
            if (!IsQueryMarker(text))
            {
                return(false);
            }

            var innerText = text.Substring(k_StartToken.Length, text.Length - k_StartToken.Length - k_EndToken.Length);

            var indexOfColon = innerText.IndexOf(':');

            if (indexOfColon < 0)
            {
                return(false);
            }

            var controlType     = innerText.Substring(0, indexOfColon).Trim().ToString();
            var args            = new List <StringView>();
            var level           = 0;
            var currentArgStart = indexOfColon + 1;

            for (var i = currentArgStart; i < innerText.Length; ++i)
            {
                if (ParserUtils.IsOpener(innerText[i]))
                {
                    ++level;
                }
                if (ParserUtils.IsCloser(innerText[i]))
                {
                    --level;
                }
                if (innerText[i] != ',' || level != 0)
                {
                    continue;
                }
                if (i + 1 == innerText.Length)
                {
                    return(false);
                }

                args.Add(innerText.Substring(currentArgStart, i - currentArgStart).Trim());
                currentArgStart = i + 1;
            }

            if (currentArgStart == innerText.Length)
            {
                return(false); // No arguments
            }
            // Extract the final argument, since there is no comma after the last argument
            args.Add(innerText.Substring(currentArgStart, innerText.Length - currentArgStart).Trim());

            var queryMarkerArguments = new List <QueryMarkerArgument>();

            using (var context = SearchService.CreateContext(""))
            {
                foreach (var arg in args)
                {
                    var parserArgs = new SearchExpressionParserArgs(arg, context, SearchExpressionParserFlags.ImplicitLiterals);
                    SearchExpression expression = null;
                    try
                    {
                        expression = SearchExpression.Parse(parserArgs);
                    }
                    catch (SearchExpressionParseException)
                    { }

                    if (expression == null || !expression.types.HasAny(SearchExpressionType.Literal))
                    {
                        queryMarkerArguments.Add(new QueryMarkerArgument {
                            rawText = arg, expression = expression, value = expression == null ? arg.ToString() : null
                        });
                        continue;
                    }
                    var results             = expression.Execute(context);
                    var resolvedValue       = results.FirstOrDefault(item => item != null);
                    var resolvedValueObject = resolvedValue?.value;
                    queryMarkerArguments.Add(new QueryMarkerArgument {
                        rawText = arg, expression = expression, value = resolvedValueObject
                    });
                }
            }

            marker = new QueryMarker {
                type = controlType, text = text, args = queryMarkerArguments.ToArray()
            };
            return(true);
        }
 public static bool TryParse(string text, out QueryMarker marker)
 {
     return(TryParse(text.GetStringView(), out marker));
 }