@Override
  public Mapper parse(ParseContext context) throws IOException {
    QueryShardContext queryShardContext = new QueryShardContext(this.queryShardContext);
    if (context.doc().getField(queryBuilderField.name()) != null) {
      // If a percolator query has been defined in an array object then multiple percolator queries
      // could be provided. In order to prevent this we fail if we try to parse more than one query
      // for the current document.
      throw new IllegalArgumentException("a document can only contain one percolator query");
    }

    XContentParser parser = context.parser();
    QueryBuilder queryBuilder =
        parseQueryBuilder(queryShardContext.newParseContext(parser), parser.getTokenLocation());
    verifyQuery(queryBuilder);
    // Fetching of terms, shapes and indexed scripts happen during this rewrite:
    queryBuilder = queryBuilder.rewrite(queryShardContext);

    try (XContentBuilder builder = XContentFactory.contentBuilder(QUERY_BUILDER_CONTENT_TYPE)) {
      queryBuilder.toXContent(builder, new MapParams(Collections.emptyMap()));
      builder.flush();
      byte[] queryBuilderAsBytes = BytesReference.toBytes(builder.bytes());
      context
          .doc()
          .add(
              new Field(
                  queryBuilderField.name(), queryBuilderAsBytes, queryBuilderField.fieldType()));
    }

    Query query = toQuery(queryShardContext, mapUnmappedFieldAsString, queryBuilder);
    processQuery(query, context);
    return null;
  }
  public void testMustRewrite() throws Exception {
    String templateString = "{ \"file\": \"storedTemplate\" ,\"params\":{\"template\":\"all\" } } ";

    XContentParser templateSourceParser =
        XContentFactory.xContent(templateString).createParser(templateString);
    context.reset();
    templateSourceParser.nextToken();
    try {
      TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser))
          .toQuery(context);
      fail();
    } catch (UnsupportedOperationException ex) {
      assertEquals("this query must be rewritten first", ex.getMessage());
    }
  }
  public void testParserCanExtractTemplateNames() throws Exception {
    String templateString = "{ \"file\": \"storedTemplate\" ,\"params\":{\"template\":\"all\" } } ";

    XContentParser templateSourceParser =
        XContentFactory.xContent(templateString).createParser(templateString);
    context.reset();
    templateSourceParser.nextToken();

    Query query =
        QueryBuilder.rewriteQuery(
                TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)),
                context)
            .toQuery(context);
    assertTrue("Parsing template query failed.", query instanceof MatchAllDocsQuery);
  }
  public void testParser() throws IOException {
    String templateString =
        "{" + "\"query\":{\"match_{{template}}\": {}}," + "\"params\":{\"template\":\"all\"}" + "}";

    XContentParser templateSourceParser =
        XContentFactory.xContent(templateString).createParser(templateString);
    context.reset();
    templateSourceParser.nextToken();

    Query query =
        QueryBuilder.rewriteQuery(
                TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)),
                context)
            .toQuery(context);
    assertTrue("Parsing template query failed.", query instanceof MatchAllDocsQuery);
  }
 private Query parse(AliasMetaData alias, QueryShardContext shardContext) {
   if (alias.filter() == null) {
     return null;
   }
   try {
     byte[] filterSource = alias.filter().uncompressed();
     try (XContentParser parser =
         XContentFactory.xContent(filterSource).createParser(filterSource)) {
       Optional<QueryBuilder> innerQueryBuilder =
           shardContext.newParseContext(parser).parseInnerQueryBuilder();
       if (innerQueryBuilder.isPresent()) {
         return shardContext.toFilter(innerQueryBuilder.get()).query();
       }
       return null;
     }
   } catch (IOException ex) {
     throw new AliasFilterParsingException(
         shardContext.index(), alias.getAlias(), "Invalid alias filter", ex);
   }
 }
  public void testParseTemplateAsSingleStringWithConditionalClause() throws IOException {
    String templateString =
        "{"
            + "  \"inline\" : \"{ \\\"match_{{#use_it}}{{template}}{{/use_it}}\\\":{} }\","
            + "  \"params\":{"
            + "    \"template\":\"all\","
            + "    \"use_it\": true"
            + "  }"
            + "}";
    XContentParser templateSourceParser =
        XContentFactory.xContent(templateString).createParser(templateString);
    context.reset();

    Query query =
        QueryBuilder.rewriteQuery(
                TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser)),
                context)
            .toQuery(context);
    assertTrue("Parsing template query failed.", query instanceof MatchAllDocsQuery);
  }
  /**
   * Test that the template query parser can parse and evaluate template expressed as a single
   * string but still it expects only the query specification (thus this test should fail with
   * specific exception).
   */
  public void testParseTemplateFailsToParseCompleteQueryAsSingleString() throws IOException {
    String templateString =
        "{"
            + "  \"inline\" : \"{ \\\"size\\\": \\\"{{size}}\\\", \\\"query\\\":{\\\"match_all\\\":{}}}\","
            + "  \"params\":{"
            + "    \"size\":2"
            + "  }\n"
            + "}";

    XContentParser templateSourceParser =
        XContentFactory.xContent(templateString).createParser(templateString);
    context.reset();

    try {
      TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser))
          .rewrite(context);
      fail("Expected ParsingException");
    } catch (ParsingException e) {
      assertThat(e.getMessage(), containsString("query malformed, no field after start_object"));
    }
  }
 public static Query parseQuery(
     QueryShardContext context, boolean mapUnmappedFieldsAsString, XContentParser parser)
     throws IOException {
   return parseQuery(context, mapUnmappedFieldsAsString, context.newParseContext(parser), parser);
 }