public static EntityTemplate Parse(string templateJson, IAntlrErrorStrategy errorStrategy = null)
        {
            var lexer  = new EntityTemplateLexer(new AntlrInputStream(templateJson));
            var parser = new EntityTemplateParser(new CommonTokenStream(lexer))
            {
                ErrorHandler = errorStrategy ?? new BailErrorStrategy()
            };

            var ast = parser.template();

            ValidatorVisitor.Reset();
            ValidatorVisitor.Visit(ast);

            try
            {
                ValidatorVisitor.ThrowExceptionIfErrors();
            }
            catch (Exception e)
            {
                throw new InvalidDataException($"Tried to parse template from json: '{templateJson}' but failed. See inner exception for details", e);
            }
            var parserVisitor = new EntityTemplateParserVisitor();

            return(parserVisitor.Visit(ast));
        }
        public override EntityTemplate VisitRegularField(EntityTemplateParser.RegularFieldContext context)
        {
            //we only care about entity template child objects, since they define entity hierarchy.
            if (context.value().@object() == null)
            {
                throw new InvalidDataException(
                          $"Expected from the field '{context.key.Text.Trim(1,1)}' to be an object but it wasn't");
            }

            var childParserVisitor  = new EntityTemplateParserVisitor();
            var childEntityTemplate = childParserVisitor.Visit(context.value().@object());

            var childParserValidator = new EntityTemplateValidatorVisitor();

            childParserValidator.Visit(context.value().@object());
            if (!childParserValidator.HasIdentifierField)
            {
                childEntityTemplate.Id = context.key.Text.Trim(1, 1);
            }

            try
            {
                DefaultResult.Children.Add(context.key.Text.Trim(1, 1), childEntityTemplate);
            }
            catch (ArgumentException e)
            {
                throw new InvalidDataException(
                          $"Found duplicate child entity template field. ('{context.key.Text.Trim(1, 1)}'). Did you execute template validation visitor?", e);
            }

            return(DefaultResult);
        }