parser grammar EsParser;

options {
 tokenVocab  =  EsLexer;
 contextSuperClass = com.chenyang.druid.sql.dialect.es.ast.EsParserContextBase;
 superClass =  com.chenyang.druid.sql.dialect.es.ast.EsParserBase;
}

/**
    解析的DSL 头部组成为：
    METHOD  URI  JSON|NDJSON
    example:
    _SEARCH
    GET /_SEARCH  JSONBODY
    GET /<index>/_SEARCH  JSONBODY
    GET /<index>/<mapping>/_SEARCH  JSONBODY

    _MAPPING
    GET /_mapping   所有映射
    GET /<index>/_mapping  index的映射
    PUT /<index>/_mapping JSONBODY  新增映射
    POST /<index/_mapping JSONBODY  更新映射
    GET /
    PUT /index/
**/
// ENTRANCE
statement:
            //ddl statement
              createIndexStatement                  { apiType = 64;     type=100;}
            | updateIndexStatement                  { apiType = 64;     type=101;}
            | deleteIndexStatement                  { apiType = 64;     type=102;}
            | reindexStatement                      { apiType = 64;     type=103;}
            //dml statement
            | deleteDataStatement                   { apiType = 4;      type=201;}
            | bulkStatement                         { apiType = 16;     type=204;}
            | termvectorsStatement                  { apiType = 8;      type=3;  }
            | mtermvecotrsStatement                 { apiType = 8;      type=4;  }
            | createEnrichStatement                 { apiType = 1;      type=111;}
            | deleteEnrichStatement                 { apiType = 4;      type=110;}
            | getEnrichStatement                    { apiType = 8;      type=5;  }
            | executeEnrichStatement                { apiType = 8;      type=6;  }
            | statsEnrichStatement                  { apiType = 2048;   type=900;}
            | autoScalingCreateOrUpdateStatement    { apiType = 64;     type=150;}
            | autoScalingGetStatement               { apiType = 64;     type=151;}
            | autoScalingGetPolicyStatement         { apiType = 64;     type=152;}
            | autoScalingDeleteStatement            { apiType = 64;     type=153;}
            | catStatement                          { apiType = 2048;   type=900;}
            | clusterStatement                      { apiType = 2048;   type=900;}
            | clusterClusterReplicationStatement    { apiType = 2048;   type=900;}
            | dataStreamStatement                   { apiType = 2048;   type=900;}
            | featuresStatement                     { apiType = 2048;   type=900;}
            | fleetStatement                        { apiType = 2048;   type=900;}
            | graphStatement                        { apiType = 2048;   type=900;}
            | closeIndexStatement                   { apiType = 64;     type=104;}
            | openIndexStatement                    { apiType = 64;     type=105;}
            | shrinkIndexStatement                  { apiType = 64;     type=106;}
            | cloneIndexStatement                   { apiType = 64;     type=107;}
            | rolloverIndexStatement                { apiType = 64;     type=108;}
            | unfreezeIndexStatement                { apiType = 64;     type=110;}
            | freezeIndexStatement                  { apiType = 64;     type=109;}
            | resloveIndexStatement                 { apiType = 64;     type=111;}
            | queryDataRenderStatement              { apiType = 8;      type=7;  }
            | queryDataSearchShardsStatement        { apiType = 8;      type=8;  }
            | insertDataStatement                   { apiType = 1;      type=202;}
            | updateDataStatement                   { apiType = 2;      type=203;}
            | querySchemaStatement                  { apiType = 8;      type=9;  }
            | queryDataStatement                    { apiType = 8;      type=1;  }
            // other statement
            | otherStatement                        { apiType = 2048;   type=900;}
            ;


otherStatement : (httpMethod=(GET|POST|PUT|DELETE|HEAD|OPTIONS)  SLASH? (SLASH uriSeg)*  SLASH? uriFragments?  ) obj?  ;

//DDL PART BEGIN
//INSERT NEW MAPPING
createIndexStatement: httpMethod=PUT SLASH? indexName=uriSegIndex SLASH? uriFragments? createIndexStatementBody?;
createIndexStatementBody : LPAREN (createIndexStatementMappings|createIndexStatementAliases|createIndexStatementSettings)+ RPAREN;
createIndexStatementAliases : ALIASES COLON jvalue;
createIndexStatementSettings : SETTINGS COLON jvalue;
createIndexStatementMeta : META COLON jvalue;
createIndexStatementMappings : MAPPINGS2 COLON LPAREN  (createIndexStatementMappingsType|createIndexStatementMeta|ddlMappingPropertiesDynamic|ddlMappingPropertiesDynamicTemplates|pairs)*  RPAREN ;
createIndexStatementMappingsType : ddlMappingProperties | (mappingName=mappingString COLON LPAREN ddlMappingProperties RPAREN) ;

//UPDATE EXISTS MAPPING OF INDEX
updateIndexStatement : httpMethod=(PUT|POST) SLASH? indexName=uriSegIndex SLASH MAPPING1 SLASH? uriFragments? updateMappingStatementBody;
updateMappingStatementBody: LPAREN ddlMappingProperties RPAREN;

//DELETE EXISTS MAPPING OF INDEX
deleteIndexStatement: httpMethod=DELETE SLASH? indexName=uriSegIndex SLASH? uriFragments?;
closeIndexStatement : httpMethod=POST  SLASH? indexName=uriSegIndex SLASH CLOSE SLASH? uriFragments?;
openIndexStatement : httpMethod=POST  SLASH? indexName=uriSegIndex SLASH OPEN SLASH? uriFragments?;
shrinkIndexStatement : httpMethod=POST SLASH? indexName=uriSegIndex SLASH SHRINK SLASH shrinkIndexName=uriSeg SLASH? uriFragments? option=obj;
cloneIndexStatement : httpMethod=POST SLASH? indexName=uriSegIndex SLASH CLONE SLASH cloneIndexName=uriSeg SLASH? uriFragments? option=obj;
rolloverIndexStatement : httpMethod=POST SLASH? indexName=uriSegIndex SLASH ROLLOVER SLASH? uriFragments? option=obj;
unfreezeIndexStatement : httpMethod=POST SLASH? indexName=uriSegIndex SLASH UNFREEZE SLASH? uriFragments? option=obj;
freezeIndexStatement : httpMethod=POST SLASH? indexName=uriSegIndex SLASH FREEZE SLASH? uriFragments? option=obj;
resloveIndexStatement : httpMethod=GET SLASH? RESLOVE SLASH indexName=uriSegIndex SLASH? uriFragments? option=obj;
queryDataRenderStatement : httpMethod=GET SLASH? RENDER SLASH uriSegIndex (SLASH templateId=uriSeg)? SLASH? uriFragments? option=obj;
queryDataSearchShardsStatement : httpMethod=GET SLASH? indexName=uriSegIndex SLASH SEARCH_SHARDS SLASH? uriFragments? option=obj;

//DML COMMON PART
ddlMappingProperties : (ddlMappingPropertiesDefine | ddlMappingPropertiesDynamic | ddlMappingPropertiesDynamicTemplates | createIndexStatementMeta | ddlMappingPropertiesAll)+;
ddlMappingPropertiesDynamic : DYNAMIC COLON jvalue;
ddlMappingPropertiesDynamicTemplates : DYNAMIC_TEMPLATES COLON jvalue;
ddlMappingPropertiesAll : DEFINE_ALL COLON jvalue;

ddlMappingPropertiesDefine : (PROPERTIES COLON LPAREN fields+=ddlFieldDecl+ RPAREN) ;
ddlFieldDecl : fieldName=string COLON LPAREN decl=ddlField RPAREN { $ctx.addField($ctx.fieldName);  };
ddlField: (type=ddlFieldType| (children=ddlMappingPropertiesDefine)  | option=pairs)+;
ddlFieldType: TYPE2 COLON value=string;

// query mapping defination
querySchemaStatement:  querySchemaStatementIndex | querySchemaStatementALL;
querySchemaStatementALL: httpMethod=(HEAD | GET) SLASH? MAPPING1 SLASH? uriFragments?;
querySchemaStatementIndex: httpMethod=(HEAD | GET) SLASH? indexName=uriSegIndex (SLASH MAPPING1)? SLASH? uriFragments?;

//query data statement decl

// bulk statement
bulkStatement :  httpMethod=(PUT|POST) (SLASH? indexName=uriSegIndex)? SLASH? BULK SLASH? uriFragments? (bulkStatementBody)+;

bulkStatementBody :  bulkStatementCreate
                    | bulkStatementDelete
                    | bulkStatementIndex
                    | bulkStatementUpdate
                    | bulkStatementDoc
                    | bulkStatementScript
                    | bulkStatementFields
                    ;

//bulk create
bulkStatementCreate : LPAREN CREATE1 COLON LPAREN (bulkStatementIndexPart | bulkStatementIdPart | option=pairs)+ RPAREN RPAREN ;//(bulkStatementFields|bulkStatementScript) +;
//bulk delete
bulkStatementDelete :  LPAREN DELETE1 COLON LPAREN (bulkStatementIndexPart | bulkStatementIdPart | option=pairs)+ RPAREN RPAREN;
//bulk index
bulkStatementIndex :  LPAREN INDEX COLON LPAREN (bulkStatementIndexPart | bulkStatementIdPart | option=pairs)+ RPAREN RPAREN  ;//(bulkStatementScript |bulkStatementFields)  +;
//bulk update
bulkStatementUpdate :  LPAREN UPDATE1 COLON LPAREN (bulkStatementIndexPart | bulkStatementIdPart | option=pairs)+ RPAREN RPAREN ;// (bulkStatementDoc| bulkStatementFields|bulkStatementScript ) +;
bulkStatementDoc : LPAREN (bulkStatementDocItem  | bulkStatementDocItemSource)+ RPAREN;
bulkStatementDocItemSource : SOURCE1 COLON jvalue;
bulkStatementDocItem: DOC COLON LPAREN (bulkStatementDocItemField  | option=pairs) + RPAREN;
bulkStatementDocItemField : (fieldName=string COLON fieldValue=string) { $ctx.addFieldValue($ctx.fieldName,$ctx.fieldValue); };
bulkStatementFields : obj+ ;
bulkStatementScript : LPAREN ((SCRIPT COLON jvalue) | option=pairs )+ RPAREN ;
bulkStatementIndexPart : INDEX1 COLON indexName=string;
bulkStatementIdPart : ID1 COLON documentId=string;

//DDL PART END

// DML PART BEGIN

// <index>/_search
// <index>/<mapping>/_search
queryDataStatement:
//                    | queryDataStatementSearchAll             { type=1;   }
                    queryDataStatementMGET                  { type=10;  }
                    | queryDataStatementSearch              { type = 1;}
//                    | queryDataStatementSearchIndex         { type=11;  }
//                    | queryDataStatementSearchMapping       { type=12;  }
                    | queryDataStatementById                { type=2;   }
                    | queryDataStatementMSearch             { type=13;   }
                    | queryDataStatementCount               { type=14;   }
                    | queryDataStatementTermsEnum           { type=15;   }
                    | queryDataStatementExplain             { type=16;   }
                    | queryDataStatementFieldCaps           { type=17;   }
                    | queryDataStatementRankEval            { type=18;   }
                    ;

//query data by id
queryDataStatementById : httpMethod=(GET|HEAD) SLASH? indexName=uriSegIndex SLASH mappingName=uriSegIndex SLASH (id=uriSeg)? uriFragments? queryDataStatementSearchBody?;

// mget query
//queryDataStatementMGET : queryDataStatementMGETForm1 | queryDataStatementMGETForm2 | queryDataStatementMGETForm3;
//queryDataStatementMGETForm1 : httpMethod=GET SLASH? (indexName=uriSeg SLASH)? (mappingName=uriSeg SLASH)? MGET SLASH? uriFragments? queryDataStatementMGETBody;
//queryDataStatementMGETForm2 : httpMethod=GET SLASH? indexName=uriSeg SLASH MGET SLASH? uriFragments? queryDataStatementMGETBody;
//queryDataStatementMGETForm3 : httpMethod=GET SLASH? indexName=uriSeg SLASH mappingName=uriSeg SLASH MGET SLASH? uriFragments? queryDataStatementMGETBody;
queryDataStatementMGET : httpMethod=GET SLASH? (indexName=uriSegIndex SLASH)? (mappingName=uriSegIndex SLASH)? MGET SLASH? uriFragments? queryDataStatementMGETBody;
queryDataStatementMGETBody : LPAREN ((queryDataStatementMGETDocs) | (queryDataStatementMGETIds))+ RPAREN;
queryDataStatementMGETDocs : DOCS COLON LSQUARE (queryDataStatementMGETDoc)* RSQUARE;
queryDataStatementMGETDoc :  LPAREN (queryDataStatementMGETDocId |queryDataStatementMGETDocSource | queryDataStatementMGETStoredFields | queryDataStatementMGETDocIndex | queryDataStatementMGETDocType | option=pairs) + RPAREN ;
queryDataStatementMGETDocId : ID1 COLON documentId=string;
queryDataStatementMGETDocIndex : INDEX1 COLON indexName=string;
queryDataStatementMGETDocType : TYPE1 COLON mappingName=string|mappingNames=stringArr;
queryDataStatementMGETDocSource : SOURCE1 COLON (queryDataStatementMGETDocSourceBoolean | queryDataStatementMGETDocSourceObj | queryDataStatementMGETDocSourceArr)+;
queryDataStatementMGETDocSourceBoolean : (BOOLEAN_TRUE | BOOLEAN_FALSE);
queryDataStatementMGETDocSourceArr :  fieldNames=stringArr {  $ctx.addField($ctx.fieldNames); } ;
queryDataStatementMGETDocSourceObj : LPAREN (queryDataStatementMGETDocIncldue | queryDataStatementMGETDocExclude)+ RPAREN;
queryDataStatementMGETDocIncldue : (SOURCE_INCLUDE|INCLUDE) COLON fieldNames=stringArr  {  $ctx.addField($ctx.fieldNames); } ;
queryDataStatementMGETDocExclude : (SOURCE_EXCLUDE|EXCLUDE) COLON fieldNames=stringArr  {  $ctx.addField($ctx.fieldNames); } ;
queryDataStatementMGETStoredFields : (STORED_FIELDS1|STORED_FIELDS) COLON fieldNames=stringArr  {  $ctx.addField($ctx.fieldNames); } ;
queryDataStatementMGETIds : IDS COLON documentIds=stringArr;

//_msearch
queryDataStatementMSearch : httpMethod=GET SLASH?  (SLASH? indexName=uriSegIndex)? (SLASH? mappingName=uriSegIndex)? SLASH MSEARCH SLASH? uriFragments? queryDataStatementMSearchBody;
//queryDataStatementMSearchBody : (queryDataStatementMSearchEmpty|queryDataStatementSearchBody|queryDataStatementMSearchIndex)+;
queryDataStatementMSearchBody : (queryDataStatementMSearchEmpty|queryDataStatementSearchBody)+;
queryDataStatementMSearchEmpty : LPAREN RPAREN ;
// meged with queryDataStatementSearchBody
//queryDataStatementMSearchQuery : LPAREN queryBody RPAREN ;
// merged to search body
//queryDataStatementMSearchIndex : LPAREN ((INDEX COLON indexName=string)|(TYPE COLON mappingName=string)|(option=pairs))+ RPAREN;

//_count
queryDataStatementCount : httpMethod=GET SLASH? indexName=uriSegIndex SLASH COUNT SLASH? uriFragments? queryDataStatementCountBody?;
queryDataStatementCountBody:  LPAREN queryBody RPAREN ;

// _terms_enum
queryDataStatementTermsEnum : httpMethod=POST SLASH? indexName=uriSegIndex SLASH TERMS_ENUM SLASH? uriFragments? queryDataStatementTermsEnumBody?;
queryDataStatementTermsEnumBody:  LPAREN (queryDataStatementTermsEnumField|queryDataStatementTermsEnumValue|pairs)+  RPAREN ;
queryDataStatementTermsEnumField:  FIELD COLON fieldName=string {  $ctx.addField($ctx.fieldName); } ;
queryDataStatementTermsEnumValue:  STRING1 COLON fieldValue=string { $ctx.addValue($ctx.fieldValue);  };

// _explain
queryDataStatementExplain : httpMethod=GET SLASH? indexName=uriSegIndex SLASH EXPLAIN SLASH id=uriSeg SLASH? uriFragments? queryDataStatementExplainBody?;
queryDataStatementExplainBody : LPAREN queryBody RPAREN ;

// _field_caps
queryDataStatementFieldCaps: httpMethod=(GET|POST) indexName=uriSegIndex SLASH FIELD_CAPS SLASH? uriFragments? queryDataStatementFieldCapsBody?;
queryDataStatementFieldCapsBody : LPAREN (queryDataStatementSearchBodyRuntimeMappings | queryDataStatementFieldCapsBodyIndexFiter)+ RPAREN ;
queryDataStatementFieldCapsBodyIndexFiter : INDEX_FILTER COLON LPAREN queryFilter RPAREN;

//_rank_eval
queryDataStatementRankEval : httpMethod=(GET|POST) SLASH? indexName=uriSegIndex SLASH RANK_EVAL SLASH? uriFragments? queryDataStatementRankEvalBody?;
queryDataStatementRankEvalBody : LPAREN (queryDataStatementRankEvalRequests | pairs)+ RPAREN ;
queryDataStatementRankEvalRequests : REQUESTS COLON LSQUARE queryDataStatementRankEvalRequestBody+ RSQUARE;
queryDataStatementRankEvalRequestBody : LPAREN (queryDataStatementRankEvalRequest|queryDataStatementRankEvalRatings|pairs)+ RPAREN;
queryDataStatementRankEvalRequest : REQUEST COLON LPAREN queryBody RPAREN;
queryDataStatementRankEvalRatings : RATINGS COLON LSQUARE queryDataStatementRankEvalRating+ RSQUARE;
queryDataStatementRankEvalRating : LPAREN (queryDataStatementRankEvalRatingIndex|queryDataStatementRankEvalRatingId|pairs)+ RPAREN;
queryDataStatementRankEvalRatingIndex : INDEX1 COLON indexName=string;
queryDataStatementRankEvalRatingId : ID1 COLON id=string;

// _search
// 这三个可以合并为1个，先展开，后合并。
queryDataStatementSearch : httpMethod=(GET|POST) (SLASH? indexName=uriSegIndex)? (SLASH? mappingName=uriSegIndex)?  (SLASH? (SEARCH|ASYNC_SEARCH)) uriFragments? queryDataStatementSearchBody?;
//queryDataStatementSearchMapping: httpMethod=(GET|POST) SLASH? (indexName=uriSegIndex)? (SLASH? mappingName=uriSegIndex)? SLASH (SEARCH|ASYNC_SEARCH) uriFragments? queryDataStatementSearchBody?;
//queryDataStatementSearchIndex: httpMethod=(GET|POST) SLASH? indexName=uriSegIndex SLASH (SEARCH|ASYNC_SEARCH) uriFragments? queryDataStatementSearchBody;
//queryDataStatementSearchAll: httpMethod=(GET|POST) SLASH? (SEARCH|ASYNC_SEARCH)  SLASH? uriFragments? queryDataStatementSearchBody;
queryDataStatementSearchBody : (LPAREN
                                 (
                                     (queryDataStatementSearchBodyDocValueFields)
                                    | (queryDataStatementSearchBodyFields)
                                    | (queryDataStatementSearchBodyQuery)
                                    | (queryDataStatementSearchBodyRuntimeMappings)
                                    | (queryDataStatementSearchBodySource)
                                    | (queryDataStatementSearchBodyAgg)
                                    | (queryDataStatementSearchSort)
                                    | (queryDataStatementSearchBodyStoredFields)
                                    | (queryDataStatementSearchBodyIndicesBoost)
                                    | (queryDataStatementSearchBodyIndexTypes)
                                    | (option=pairs)
                                 )*
                            RPAREN)
                            ;


//docvalue_fields
queryDataStatementSearchBodyDocValueFields : DOCVALUE_FIELDS COLON LSQUARE fieldExpr RSQUARE;
// field part of fields
fieldExpr :(field)+;
field : fieldString | fieldObj;
fieldString : fieldName=string  {  $ctx.addField($ctx.fieldName); } ;
//fieldObj : LPAREN ((FIELD COLON fieldName+=string) | option=pairs)+ RPAREN;
fieldObj : LPAREN (fieldNameExpr | option=pairs)+ RPAREN;

//stored fields
queryDataStatementSearchBodyStoredFields: STORED_FIELDS COLON LSQUARE fieldExpr RSQUARE;
queryDataStatementSearchBodyIndicesBoost : INDICES_BOOST COLON LSQUARE (queryDataStatementSearchBodyIndicesBoostItem |(option=pairs))* RSQUARE;
queryDataStatementSearchBodyIndicesBoostItem : (indexName=string()) COLON jvalue;
//_msearch merged here to body
queryDataStatementSearchBodyIndexTypes : (queryDataStatementSearchBodyIndex |queryDataStatementSearchBodyType)+;
queryDataStatementSearchBodyIndex : INDEX COLON (indexName=string|indexNames=stringArr);
queryDataStatementSearchBodyType : TYPE2 COLON (mappingName=string|mappingNames=stringArr);
// runtime
queryDataStatementSearchBodyRuntimeMappings: (queryDataStatementSearchBodyRuntimeMappingObj | queryDataStatementSearchBodyRuntimeMappingsArr );
queryDataStatementSearchBodyRuntimeMappingObj: RUNTIME_MAPPINGS1 COLON LPAREN fields+=queryDataStatementSearchBodyRuntimeMappingObjFieldExpr+ RPAREN;
queryDataStatementSearchBodyRuntimeMappingObjFieldExpr :  (fieldName=string COLON LPAREN (fieldType=queryDataStatementSearchBodyRuntimeMappingObjFieldExprType|fieldScript=queryDataStatementSearchBodyRuntimeMappingObjFieldExprScript)+ RPAREN) {  $ctx.addField($ctx.fieldName); } ;
queryDataStatementSearchBodyRuntimeMappingObjFieldExprType : TYPE2 COLON value=string;
queryDataStatementSearchBodyRuntimeMappingObjFieldExprScript : SCRIPT COLON value=string;
//PERHAPS INCORRECT
queryDataStatementSearchBodyRuntimeMappingsArr : (RUNTIME_MAPPINGS COLON LSQUARE runTimeMappingFieldExprs RSQUARE );
runTimeMappingFieldExprs: (runtimeMappingField)+;
runtimeMappingField: (LPAREN ((fieldName=string) | option=pairs)+ RPAREN) {  $ctx.addField($ctx.fieldName); } ;
//query
queryDataStatementSearchBodyQuery: queryBody;
//fields
queryDataStatementSearchBodyFields: FIELDS COLON LSQUARE fieldExpr RSQUARE;
//stat
queryDataStatementSearchBodyAgg: (AGGS|AGGREGATIONS) COLON LPAREN (queryDataStatementSearchBodyAggBody)+ RPAREN;
queryDataStatementSearchBodyAggBody : aggName=string COLON LPAREN ((aggs) | (queryDataStatementSearchBodyAgg)  | option=pairs) + RPAREN;
//sort
queryDataStatementSearchSort: SORT COLON LPAREN sortField+ RPAREN;
sortField: fieldName=string COLON order=string  {  $ctx.addField($ctx.fieldName); } ;
//_source
queryDataStatementSearchBodySource : SOURCE1 COLON fields=sourceFieldExpr;
sourceFieldExpr : boolVal=sourceFieldBoolenExpr|wildcardVal=sourceFieldWildcardPatternExpr|objVal=sourceFieldObjectExpr;
sourceFieldBoolenExpr : value=(BOOLEAN_TRUE | BOOLEAN_FALSE);
sourceFieldWildcardPatternExpr : (fieldName=string | fieldNames=stringArr)  {  $ctx.addField($ctx.fieldName,$ctx.fieldNames); } ;
sourceFieldObjectExpr : LPAREN (include=sourceFieldIncludeExpr | exclude=sourceFieldExcludeExpr | option+=pairs)+ RPAREN;
sourceFieldIncludeExpr : INCLUDES COLON ( fieldNames=stringArr | fieldName=string ) {  $ctx.addField($ctx.fieldNames,$ctx.fieldName); } ;
sourceFieldExcludeExpr : EXCLUDES COLON  ( fieldNames=stringArr | fieldName=string )  {  $ctx.addField($ctx.fieldNames,$ctx.fieldName); };

// insert data statement
insertDataStatement : (insertDataStatementForm1 | insertDataStatementForm2) ;

//uri: PUT SLASH? indexName=uriSeg SLASH mappingName=uriSeg SLASH (id=uriSeg)? SLASH? uriFragments? ;

insertDataStatementForm1 : httpMethod=PUT SLASH? indexName=uriSegIndex SLASH opName=CREATE SLASH id=uriSeg SLASH? uriFragments? cuDataStatementBody;
insertDataStatementForm2 : httpMethod=PUT SLASH? indexName=uriSegIndex SLASH mappingName=uriSegIndex SLASH (id=uriSeg)? SLASH? uriFragments? cuDataStatementBody;
// update data statement
updateDataStatement : updateDataStatementByQuery | updateDataStatementById;
updateDataStatementById :  (updateDataStatementPart1|updateDataStatementPart2) ;
updateDataStatementPart1 : httpMethod=POST SLASH? indexName=uriSegIndex SLASH UPDATE SLASH id=uriSeg SLASH? uriFragments? cuDataStatementBody;
updateDataStatementPart2 : httpMethod=POST SLASH? indexName=uriSegIndex SLASH mappingName=uriSegIndex (SLASH id=uriSeg)? SLASH? uriFragments? cuDataStatementBody;
updateDataStatementByQuery : httpMethod=POST SLASH? indexName=uriSegIndex SLASH UPDATE_BY_QUERY SLASH? uriFragments?  updateDataStatementByQueryBody;
updateDataStatementByQueryBody : LPAREN (queryBody |option=pairs)* RPAREN;

// delete data statement
deleteDataStatement : deleteDataByIdStatement | deleteDataByQueryStatement;
deleteDataByIdStatement : httpMethod=DELETE SLASH? indexName=uriSegIndex SLASH mappingName=uriSegIndex SLASH id=uriSeg SLASH? uriFragments?;
deleteDataByQueryStatement : httpMethod=POST SLASH? indexName=uriSegIndex SLASH DELETE_BY_QUERY SLASH? uriFragments? LPAREN queryBody? RPAREN;

// data statement body
cuDataStatementBody : cuDataStatementValue;

cuDataStatementValue : arrayVal=cuDataStatementArrayValue | objVal=cuDataStatementObjValue | stringVal=string | boolVal=bool | numberVal=NUMBER | NULL;
cuDataStatementObjValue : LPAREN  objVals+=cuDataStatementObjValuePair* RPAREN;
cuDataStatementArrayValue : LSQUARE arrayVals+=cuDataStatementValue* RSQUARE;
cuDataStatementObjValuePair : script=cuDataStatementFieldScript | (fieldName=string COLON fieldValue=cuDataStatementValue { $ctx.addFieldValue($ctx.fieldName,$ctx.fieldValue); });
cuDataStatementFieldScript : SCRIPT COLON value=cuDataStatementValue;

/*
The default query for combining multiple leaf or compound query clauses, as must, should, must_not, or filter clauses.
 The must and should clauses have their scores combined — the more matching clauses, the better — while the must_not and filter clauses are executed in filter context.
*/

queryBody : QUERY COLON ((LPAREN queryFilter  RPAREN) | string );
queryFilter: comboundFilter;
// COMBOUND FILTER
comboundFilter: mustFilter
               | filterFilter
               | shouldFilter
               | boolFilter
               | spanFilter
               | boostingFilter
               | constantScoreFilter
               | dismaxFilter
               | functionScoreFilter
               | nsetedFilter
               | hasChildFilter
               | hasParentFilter
               | parentIdFilter
               | intervalFilter
               | leafFilter
               ;

nsetedFilter :  NESTED COLON LPAREN  nsetedFilterItem+ RPAREN;
nsetedFilterItem : path=nsetedFilterItemPath | queryBody | option=pairs;
nsetedFilterItemPath : PATH COLON field;
boostingFilter : BOOSTING COLON LPAREN (boostingFilterBody | option=pairs) + RPAREN;
boostingFilterBody : type=string COLON LPAREN ((comboundFilter) | option=pairs) +  RPAREN;

hasChildFilter : HAS_CHILD COLON LPAREN (queryBody | option=pairs)+ RPAREN;
hasParentFilter : HAS_PARENT COLON LPAREN (queryBody | option=pairs)+ RPAREN;
parentIdFilter : PARENT_ID COLON LPAREN (queryBody | option=pairs)+ RPAREN;

boolFilter : BOOL COLON LPAREN  ((comboundFilter) | option=pairs) + RPAREN;

mustFilter :  (MUST|MUST_NOT)  COLON  (mustFilterN | mustFilter1);
mustFilterN : LSQUARE mustFilter1+ RSQUARE;
mustFilter1 : LPAREN  ((comboundFilter) | option=pairs) + RPAREN;

filterFilter : FILTER COLON (filterFilterN | filterFilter1);
filterFilterN: LSQUARE filterFilter1+ RSQUARE;
filterFilter1:  LPAREN  ((comboundFilter) | option=pairs)+ RPAREN;

shouldFilter : SHOULD COLON (shouldFilterN | shouldFilter1);
shouldFilterN : LSQUARE shouldFilter1+  RSQUARE;
shouldFilter1 : LPAREN (comboundFilter|option=pairs)+ RPAREN;

constantScoreFilter :  CONSTANT_SCORE COLON LPAREN (comboundFilter | option=pairs) + RPAREN;

dismaxFilter :  DIS_MAX COLON LPAREN (dismaxFilterQueriesBody | option=pairs) + RPAREN;
dismaxFilterQueriesBody :QUERIES COLON LSQUARE dismaxFilterQueriesBodyItems +  RSQUARE;
dismaxFilterQueriesBodyItems : LPAREN (comboundFilter | option=pairs)+  RPAREN;
functionScoreFilter : FUNCTION_SCORE COLON LPAREN ((queryBody)|queryFilter|fieldFilter| option=pairs) +  RPAREN;

// LEAF FILTER
leafFilter : leafMatchFilter
           | leafTermFilter
           | leafMatchAllFilter
           | leafMatchNoneFilter
           | leafGeoFilter
           | leafShapeFilter
           | leafOtherFilter
           ;
// SIMPLES QUERY: match_all
leafMatchAllFilter : MATCH_ALL COLON LPAREN option=pairs* RPAREN;
// SIMPLES QUERY: match_none
leafMatchNoneFilter : MATCH_NONE COLON LPAREN option=pairs* RPAREN;

// LEAF MATCH
leafMatchFilter : filterMatch                       //PASS
                | filterMatchBoolPrefix
                | filterMatchPhrase
                | filterMatchPhrasePrefix
                | filterCombinedFields
                | filterMultiMatch
                | filterCommon
                | filterQueryString
                | filterSimpleQueryString
                | intervalFilter
                ;
intervalFilter :INTERVALS COLON LPAREN fieldName = string COLON LPAREN intervalFilterItem+ RPAREN RPAREN  { $ctx.addField($ctx.fieldName); }
                ;

intervalFilterRuleAnyOf : ANYOF COLON LPAREN (intervalFilterRuleInterval|intervalFilterRuleFilter)* RPAREN;
intervalFilterRuleAllOf : ALLOF COLON LPAREN (intervalFilterRuleInterval|intervalFilterRuleFilter|option=pairs)* RPAREN;
intervalFilterRuleMatch : MATCH COLON LPAREN (intervalFilterRuleMatchQuery|intervalFilterRuleMatchUseField|intervalFilterRuleFilter|option=pairs)*RPAREN;

intervalFilterRuleMatchQuery : QUERY COLON fieldValue = string  { $ctx.addValue($ctx.fieldValue); };
intervalFilterRuleMatchUseField : USE_FIELD COLON fieldName = string  { $ctx.addField($ctx.fieldName); };

intervalFilterRulePrefix : PREFIX COLON LPAREN (intervalFilterRuleMatchUseField|intervalFilterRulePrefixPrefix|option=pairs)* RPAREN;
intervalFilterRulePrefixPrefix : PREFIX COLON fieldName = string COLON fieldValue = string          { $ctx.addFieldValue($ctx.fieldName,$ctx.fieldValue); };

intervalFilterRuleWildcard : WILDCARD COLON LPAREN (intervalFilterRuleMatchUseField|intervalFilterRuleWildcardPattern| option=pairs)* RPAREN;
intervalFilterRuleWildcardPattern : PATTERN COLON fieldName = string COLON fieldValue = string      { $ctx.addFieldValue($ctx.fieldName,$ctx.fieldValue); };

intervalFilterRuleFuzzy : FUZZY COLON LPAREN (intervalFilterRuleMatchUseField| option=pairs)* RPAREN;
intervalFilterRuleFilter : FILTER COLON LPAREN option=pairs* RPAREN;
intervalFilterRuleInterval :INTERVALS COLON LSQUARE  intervalFilterIntervalItem+ RSQUARE ;
intervalFilterItem : intervalFilterRuleAnyOf|intervalFilterRuleAllOf|intervalFilterRuleMatch|intervalFilterRulePrefix|intervalFilterRuleWildcard|intervalFilterRuleFuzzy|option=pairs;

intervalFilterIntervalItem : intervalFilterIntervalRuleAnyOf|intervalFilterIntervalRuleAllOf|intervalFilterIntervalRuleMatch|intervalFilterIntervalRulePrefix|intervalFilterIntervalRuleWildcard|intervalFilterIntervalRuleFuzzy;
intervalFilterIntervalRuleAnyOf : LPAREN intervalFilterRuleAnyOf RPAREN;
intervalFilterIntervalRuleAllOf : LPAREN intervalFilterRuleAllOf RPAREN;
intervalFilterIntervalRuleMatch : LPAREN intervalFilterRuleMatch RPAREN;
intervalFilterIntervalRulePrefix : LPAREN intervalFilterRulePrefix RPAREN;
intervalFilterIntervalRuleWildcard : LPAREN intervalFilterRuleWildcard RPAREN;
intervalFilterIntervalRuleFuzzy : LPAREN intervalFilterRuleFuzzy RPAREN;

// matcF
// match part begin
//match
filterMatch : MATCH COLON LPAREN fieldFilter* RPAREN;
//match_bool
filterMatchBoolPrefix : MATCH_BOOL_PREFIX COLON LPAREN fieldFilter* RPAREN;
//match_phrase
filterMatchPhrase : MATCH_PHRASE COLON LPAREN fieldFilter* RPAREN;
//match_phrase_prefix
filterMatchPhrasePrefix : MATCH_PHRASE_PREFIX COLON LPAREN fieldFilter* RPAREN;
//combined_fields
filterCombinedFields: COMBINED_FIELDS COLON LPAREN fieldFilter*  RPAREN;
//mult_match
filterMultiMatch: MULTI_MATCH COLON LPAREN fieldFilter* RPAREN;
//common
filterCommon: COMMON COLON LPAREN fieldFilter* RPAREN;
//query_string
filterQueryString: QUERY_STRING COLON LPAREN fieldFilter* RPAREN { addRegexTree($ctx);  };
//simple_query_string
filterSimpleQueryString: SIMPLE_QUERY_STRING COLON LPAREN fieldQueryFilter* RPAREN;
// match part end


// LEAF TERM FILTER
leafTermFilter: filterExists
                | filterFuzzy
                | filterTermFilter
                | filterPrefix
                | filterIds
                | rangeFilter
                | regexpFilter
                | termsFilter
                | termsetFilter
                | termTypeFilter
                | wildcardFilter
                ;

// term part begin
// term exists
filterExists: EXISTS COLON LPAREN FIELD COLON fieldName=string  RPAREN   { $ctx.addField($ctx.fieldName); };
// term fuzzy
filterFuzzy: FUZZY COLON LPAREN fieldFuzzyExactFilter RPAREN;
fieldFuzzyExactFilter: fieldName=string COLON LPAREN fieldValueFilter RPAREN   { $ctx.addField($ctx.fieldName); };
// term term
filterTermFilter:  TERM COLON LPAREN fieldFilter* RPAREN;
// term ids
filterIds: IDS COLON LPAREN VALUES COLON filterValue=arr {  $ctx.addValue($ctx.filterValue);  } RPAREN;
// term prefix
filterPrefix: PREFIX COLON LPAREN fieldValueFilter RPAREN;
// term range
rangeFilter: RANGE COLON LPAREN fieldName=string COLON LPAREN (rangeFilterGT|rangeFilterLT|option=pairs)*  RPAREN RPAREN   { $ctx.addField($ctx.fieldName); };
rangeFilterGT : (GT|GTE) COLON fieldValue = jvalue { $ctx.addValue($ctx.fieldValue);  };
rangeFilterLT : (LT|LTE) COLON fieldValue = jvalue { $ctx.addValue($ctx.fieldValue);  };
// term regexp
regexpFilter: REGEXP COLON LPAREN fieldValueFilter RPAREN { addRegexTree($ctx); };
// term terms
termsFilter: TERMS COLON (termsFilterFieldN | termsFilterField1)  ;
termsFilterField1 : LPAREN termsFilterField+ RPAREN;
termsFilterFieldN : LSQUARE termsFilterFieldNItem+ RSQUARE ;
termsFilterFieldNItem : LPAREN (fieldNameExpr|option=pairs) + RPAREN ;
termsFilterField : (termsFilterFieldItem1|termsFilterFieldItem | option=pairs)+;
termsFilterFieldItem1 : ( fieldNameExpr |termsFilterFieldNameArray| option=pairs) +;
termsFilterFieldItem : fieldName=string   { $ctx.addField($ctx.fieldName); } COLON (termsFilterFieldValueArray | termsFilterFieldValueString | termsFilterFieldValueLookup);
termsFilterFieldValueString: fieldValue=string  { $ctx.addValue($ctx.fieldValue);  };
termsFilterFieldValueArray: fieldValue=arr      { $ctx.addValue($ctx.fieldValue);  };
termsFilterFieldValueLookup : LPAREN (pathExpr | idExpr | indexExpr | option=pairs)+ RPAREN;
termsFilterFieldNameArray : fieldName = string { $ctx.addField($ctx.fieldName); } COLON LSQUARE fieldValue = string+ { $ctx.addValue($ctx.fieldValue);  } RSQUARE;

indexExpr : INDEX COLON indexName=string;
pathExpr : PATH COLON pathName=string;
idExpr : ID2 COLON idName=string;
// term term_set
termsetFilter: TERMS_SET COLON LPAREN (termsetFilterItem) + RPAREN;
termsetFilterItem:  fieldName=string   { $ctx.addField($ctx.fieldName); } COLON LPAREN termsetFilterTerms+ RPAREN;
termsetFilterTerms : (TERMS COLON fielValues=arr) | option=pairs;

// term type
termTypeFilter: TYPE2 COLON LPAREN fieldFilter*  RPAREN;

// term wildcard
wildcardFilter : WILDCARD COLON LPAREN fieldFilter* RPAREN;

// term part end

// geo part begin
leafGeoFilter: geoBoundingBoxFilter
             | geoDistanceFilter
             | geoPolygonFilter
             | geoShapeFilter
             ;
// geo bounding box
geoBoundingBoxFilter: GEO_BOUNDING_BOX COLON LPAREN geoBoundingBoxFilterField  RPAREN;
geoBoundingBoxFilterField: (fieldName=string   { $ctx.addField($ctx.fieldName); } COLON LPAREN option=pairs+ RPAREN);

// geo distance
geoDistanceFilter: GEO_DISTANCE COLON LPAREN geoDistanceFilterField RPAREN;
//geoDistanceFilterField:  (DISTANCE COLON v1=string) | (DISTANCE_TYPE COLON v2=string) | (NAME1 COLON v3=string) | (VALIDATION_METHOD COLON v4=string) | (fieldName=string COLON filterValue=jvalue) ;
geoDistanceFilterField: (fieldNameExpr | option=pairs) +;
// geo polygon
geoPolygonFilter: GEO_POLYGON COLON LPAREN geoPolygonFilterField+  RPAREN;
geoPolygonFilterField: (NAME1 COLON v1=string) | (VALIDATION_METHOD COLON v2=string) | (fieldName=string COLON filterValue=jvalue   { $ctx.addFieldValue($ctx.fieldName,$ctx.filterValue); }) ;
// geo shape
geoShapeFilter: GEO_SHAPE COLON LPAREN geoShapeFilterField+  RPAREN;
geoShapeFilterField:  ((NAME1 COLON fieldName=string) | (fieldName=string  COLON fieldValue=jvalue) |(INDEX COLON indexName = string))   { $ctx.addField($ctx.fieldName);  $ctx.addValue($ctx.fieldValue); };
// geo part end


// shape part begin
// LEAF SHAPE
leafShapeFilter : shapeFilter;
// shape query
shapeFilter: SHAPE COLON LPAREN option=pairs+ RPAREN;
// shape part end

// JOIN QUERY PART BEGIN
// JOIN QUERY PART END

// span query
spanQuery: QUERY COLON LPAREN spanFilter RPAREN;
/// span part begin
spanFilter : spanNearFilter
            | spanNotFilter
            | spanOrFilter
            | spanWithinFilter
            | spanContainingFilter
            | spanFiledMaskingFilter
            | spanFirstFilter
            | spanMultiFilter
            | spanTermFilter
            ;

// span_near
spanNearFilter: SPAN_NEAR COLON LPAREN ( (spanNearFilterClausesPart) | option=pairs) + RPAREN;
spanNearFilterClausesPart : CLAUSES COLON LSQUARE spanNearFilterClausesPartItem+  RSQUARE;
spanNearFilterClausesPartItem : LPAREN spanFilter RPAREN;
// span_not
spanNotFilter : SPAN_NOT COLON LPAREN (((spanNotFilterIncludePart | spanNotFilterExcludePart)) | option=pairs) + RPAREN;
spanNotFilterIncludePart : INCLUDE COLON LPAREN spanFilter RPAREN;
spanNotFilterExcludePart : EXCLUDE COLON LPAREN spanFilter RPAREN;
// span_or
spanOrFilter : SPAN_OR COLON LPAREN ( spanOrFilterClausesPart | option=pairs) RPAREN;
spanOrFilterClausesPart : CLAUSES COLON LSQUARE (LPAREN spanTermFilter RPAREN)+  RSQUARE;
// span_term
spanTermFilter: SPAN_TERM COLON LPAREN (fieldSimpleFilter |  fieldExactFilter)  RPAREN;
// span_within
spanWithinFilter : SPAN_WITHIN COLON LPAREN (spanWithinFilterPart) + RPAREN;
spanWithinFilterPart : clauseName=string COLON LPAREN spanFilter RPAREN;
// span_containing
spanContainingFilter : SPAN_CONTAINING COLON LPAREN  (spanContainingFilterPart) +  RPAREN;
spanContainingFilterPart : clauseName=string COLON LPAREN spanFilter RPAREN;
// span_filedmasking
spanFiledMaskingFilter : SPAN_FIELD_MASKING COLON LPAREN  ((spanQuery) | fieldSimpleFilter | option=pairs)+ RPAREN;
// span_first
spanFirstFilter : SPAN_FIRST COLON LPAREN (spanFirstFilterPart | option=pairs) +  RPAREN;
spanFirstFilterPart : MATCH COLON LPAREN spanFilter RPAREN;
// span_multi
spanMultiFilter : SPAN_MULTI COLON LPAREN MATCH COLON LPAREN ( spanMultiFilterPart | option=pairs) + RPAREN RPAREN;
spanMultiFilterPart : name=(WILDCARD | FUZZY | PREFIX | RANGE | REGEXP) COLON LPAREN fieldExactFilter RPAREN;
/// span part end

//other filter
leafOtherFilter : distanceFeatureFilter
                | moreLikeThisFilter
                | percolateFilter
                | rankFeatureFilter
                | scriptFilter
                | scriptScoreFilter
                | pinnedFilter
                ;

//distance query
distanceFeatureFilter : DISTANCE_FEATURE COLON LPAREN (fieldNameExpr | option=pairs)+ RPAREN;
moreLikeThisFilter : MORE_LIKE_THIS COLON LPAREN (fieldsNamesExpr | fieldLikeExpr | option=pairs)+ RPAREN;
percolateFilter : PERCOLATE COLON LPAREN (fieldNameExpr | fieldDocuments | fieldDocument | fieldIndex1 | fieldId1 | option=pairs)+ RPAREN;
rankFeatureFilter : RANK_FEATURE COLON LPAREN (fieldNameExpr | fieldDocuments | fieldDocument | fieldIndex1 | fieldId1 | option=pairs)+ RPAREN;
//script filter
scriptFilter : SCRIPT COLON LPAREN SCRIPT COLON  (scriptFilterScriptSimple | scriptFilterSourceValue | option=pairs) + RPAREN;
scriptFilterScriptSimple :  script=string ;
scriptFilterSourceValue : LPAREN( (SOURCE2 COLON script=string) | option=pairs)+   RPAREN ;
//script score
scriptScoreFilter : SCRIPT_SCORE COLON  LPAREN ( (SCRIPT COLON  (  scriptFilterScriptSimple | scriptFilterSourceValue | option=pairs) ) | queryBody )+ RPAREN;
pinnedFilter : PINNED COLON  LPAREN  (pinnedFilterDocs | pinnedFilterOrganic | pinnedFilterIds | option=pairs ) + RPAREN;
pinnedFilterOrganic : ORGANIC COLON  LPAREN  queryFilter + RPAREN;
pinnedFilterDocs : DOCS COLON LSQUARE pinnedFilterDocsItem+ RSQUARE;
pinnedFilterDocsItem : LPAREN (fieldId | fieldIndex | option=pairs)+ RPAREN;
pinnedFilterIds : IDS COLON ids=arr;


// agg
//adjacency_matrix
aggs : bucketAggs
      | metricsAggs
      | pipeLineAggs
      ;

//BUCKET AGGS
bucketAggs :  adjacencyMatrixAgg
           | autoDateHistogramAgg
           | categorizeTextAgg
           | childrenAgg
           | compositeAgg
           | dateHistogramAgg
           | dateRangeAgg
           | diversifiedSamplerAgg
           | filterAgg
           | filtersAgg
           | geoDistanceAgg
           | geoHashGridAgg
           | geoTileGridAgg
           | histogramAgg
           | ipRangeAgg
           | missingAgg
           | multiTermsAgg
           | nestedAgg
           | parentAgg
           | rangeAgg
           | rareTermsAgg
           | reverseNestedAgg
           | samplerAgg
           | significantCrimeTypesAgg
           | significantTextAgg
           | significantTermsAgg
           | termsAgg
           | variableWidthHistogramAgg
           ;

//_reindex
reindexStatement :  httpMethod=POST SLASH? REINDEX SLASH? uriFragments? reindexStatementBody;
reindexStatementBody : LPAREN  (reindexStatementSection | option=pairs)+ RPAREN;
reindexStatementSection : string COLON LPAREN (reindexStatementSectionIndex | option=pairs)+ RPAREN ;
reindexStatementSectionIndex : INDEX COLON (indexName=string | indexNames=stringArr);

//_termvectors
termvectorsStatement : termvectorsStaticStatement | termvectorsDynamicStatement;
termvectorsStaticStatement : httpMethod=GET s1=SLASH? indexName=uriSegIndex SLASH TERMVECTORS SLASH id=uriSeg s2=SLASH? uriFragments? termvectorsStatementBody?;
termvectorsDynamicStatement : httpMethod=GET s1=SLASH? indexName=uriSegIndex SLASH TERMVECTORS s2=SLASH? uriFragments? termvectorsStatementBody;
termvectorsStatementBody : LPAREN (termvectorsStatementBodyFields|option=pairs)+ RPAREN;
termvectorsStatementBodyFields : FIELDS COLON fieldNames=stringArr   { $ctx.addField($ctx.fieldNames); };

//_mtermvectors
mtermvecotrsStatement :  httpMethod=POST (SLASH? indexName=uriSegIndex)? s1=SLASH? MTERMVECTORS s2=SLASH? uriFragments? (mtermvectorsStatementBody | mtermvectorsStatementBody1);
mtermvectorsStatementBody : LPAREN (string COLON LSQUARE mtermvectorsStatementBodyItem+ RSQUARE) RPAREN;
mtermvectorsStatementBodyItem : LPAREN  (mtermvectorsStatementBodyIndex|mtermvectorsStatementBodyFields|mtermvectorsStatementBodyId|option=pairs)+ RPAREN;
mtermvectorsStatementBodyFields : FIELDS COLON fieldNames=stringArr   { $ctx.addField($ctx.fieldNames); };
mtermvectorsStatementBodyIndex : INDEX1 COLON indexName=string;
mtermvectorsStatementBodyId : ID1 COLON documentId=string;
mtermvectorsStatementBody1 :  LPAREN  ( mtermvectorsStatementBody1Item | option=pairs )+    RPAREN;
mtermvectorsStatementBody1Item: mtermvectorsStatementBody1Fields | mtermvectorsStatementBody1Ids;
mtermvectorsStatementBody1Ids : IDS COLON fieldNames=stringArr   { $ctx.addField($ctx.fieldNames); };
mtermvectorsStatementBody1Fields :  PARAMETERS COLON LPAREN ((FIELDS COLON fieldNames=stringArr { $ctx.addField($ctx.fieldNames); }) | option=pairs)+  RPAREN ;


// create _enrich
createEnrichStatement : httpMethod=PUT s1=SLASH? ENRICH SLASH POLICY SLASH myPolicy=uriSeg s2=SLASH? uriFragments? createEnrichStatementBody ;
createEnrichStatementBody : LPAREN policyType=string COLON LPAREN (createEnrichStatementPolicyTypeIndices|createEnrichStatementPolicyTypeMatchField|createEnrichStatementPolicyTypeEnrichFields | queryBody) + RPAREN RPAREN ;
createEnrichStatementPolicyTypeIndices :  INDICES COLON (indexName=string | indexNames=stringArr);
createEnrichStatementPolicyTypeMatchField : MATCH_FIELD COLON fieldName=string   { $ctx.addField($ctx.fieldName); };
createEnrichStatementPolicyTypeEnrichFields : ENRICH_FIELDS COLON fieldNames=stringArr   { $ctx.addField($ctx.fieldNames); };

// delete _enrich
deleteEnrichStatement : httpMethod=DELETE s1=SLASH? ENRICH SLASH POLICY SLASH myPolicy=uriSeg s2=SLASH? uriFragments? ;

// get _enrich
getEnrichStatement : httpMethod=GET s1=SLASH? ENRICH SLASH POLICY (SLASH myPolicy=uriSeg)? s2=SLASH? uriFragments? ;

// execute _enrich
executeEnrichStatement : httpMethod=(PUT|POST) s1=SLASH? ENRICH SLASH POLICY SLASH myPolicy=uriSeg SLASH EXECUTE s2=SLASH? uriFragments? ;

// enrich stats
statsEnrichStatement : httpMethod=GET s1=SLASH? ENRICH SLASH STATS1 s2=SLASH? uriFragments? ;

// create or update _autoscaling
autoScalingCreateOrUpdateStatement : httpMethod=(PUT|POST) s1=SLASH? AUTO_SCALING SLASH POLICY SLASH name=uriSeg s2=SLASH?  uriFragments? obj;
// get autosaling
autoScalingGetStatement :  httpMethod=GET s1=SLASH? AUTO_SCALING SLASH uriSeg  uriFragments? obj?;
autoScalingGetPolicyStatement : httpMethod=GET s1=SLASH? AUTO_SCALING SLASH POLICY SLASH uriSeg s2=SLASH?  uriFragments? obj?;
// delee autoscaling
autoScalingDeleteStatement : httpMethod=DELETE s1=SLASH? AUTO_SCALING SLASH POLICY SLASH name=uriSeg s2=SLASH?  uriFragments? obj?;

//cat
catStatement : httpMethod=GET s1=SLASH? CAT uriAppendixExpr s2=SLASH? uriFragments? obj?;
//cluster
clusterStatement : httpMethod=(GET|POST|PUT|DELETE) s1=SLASH? name=(CLUSTER|NODES|REMOTE|TASKS) uriAppendixExpr s2=SLASH? uriFragments? obj?;
//crossClusterRP
clusterClusterReplicationStatement :  httpMethod=(GET|POST|PUT|DELETE)   ((s1=SLASH? CCR) | ( SLASH uriSeg  (s1=SLASH? CCR))) uriAppendixExpr?  s2=SLASH? uriFragments obj?;
// data stream statement
dataStreamStatement :  httpMethod=(GET|POST|PUT|DELETE)  (s1=SLASH? DATA_STREAM) uriAppendixExpr  s2=SLASH? uriFragments? obj?;
// _reatures
featuresStatement :  httpMethod=(GET|POST|PUT|DELETE) uriPrefixExpr (s1=SLASH? FEATURES) uriAppendixExpr  s2=SLASH? uriFragments? obj?;
// _fleet
fleetStatement : httpMethod=(GET|POST|PUT|DELETE) uriPrefixExpr (s1=SLASH? FLEET) uriAppendixExpr  s2=SLASH? uriFragments? obj?;

uriPrefixExpr : (SLASH uriSeg)* ;
uriAppendixExpr :  (SLASH uriSeg)*;

graphStatement :  httpMethod=POST s1=SLASH? indexName=uriSegIndex s2=SLASH GRAPH s3=SLASH other=uriSeg  s4=SLASH? uriFragments? graphStatementBody;
graphStatementBody : LPAREN (queryBody|graphStatementVertices|graphStatementConnections)+ RPAREN ;
graphStatementConnections : CONNECTIONS COLON LPAREN  (graphStatementVertices | queryBody | option=pairs+)+ RPAREN;
graphStatementVertices : VERTICES COLON LSQUARE graphStatementVertice+ RSQUARE;
graphStatementVertice : LPAREN (graphStatementVerticeField|graphStatementVerticeInclude|graphStatementVerticeExclude|option=pairs)+   RPAREN;
graphStatementVerticeField : FIELD COLON fieldName=string   { $ctx.addField($ctx.fieldName); };
graphStatementVerticeInclude : INCLUDE COLON jvalue;
graphStatementVerticeExclude : EXCLUDE COLON jvalue;

// bucket agg begin
//adjacency_matrix
adjacencyMatrixAgg : ADJACENCY_MATRIX COLON LPAREN FILTERS COLON LPAREN adjacencyMatrixAggPart RPAREN RPAREN;
adjacencyMatrixAggPart : (groupName=string COLON LPAREN queryFilter RPAREN) +;
//auto_date_histogram
autoDateHistogramAgg : AUTO_DATE_HISTOGRAM COLON LPAREN aggCommonPart RPAREN ;
//categorize_text
categorizeTextAgg : CATEGORY_TEXT COLON LPAREN aggCommonPart RPAREN ;
//children
childrenAgg : CHILDREN COLON LPAREN  option=pairs + RPAREN ;
//composite
compositeAgg : COMPOSITE COLON LPAREN ((SOURCES COLON LSQUARE compositeAggItem+ RSQUARE) | (option=pairs))+ RPAREN;
compositeAggItem : LPAREN sourceName=string COLON LPAREN (aggs | queryFilter) RPAREN RPAREN;
// date_histogram
dateHistogramAgg : DATE_HISTOGRAM COLON LPAREN aggCommonPart RPAREN;
// date_range
dateRangeAgg : DATE_RANGE COLON LPAREN aggCommonPart RPAREN;
//diversified_sampler
diversifiedSamplerAgg : DIVERSIFIED_SAMPLER COLON LPAREN aggCommonPart RPAREN;
//filter
filterAgg : queryFilter;
//filters
filtersAgg : FILTERS COLON LPAREN ((filtersAgg | filtersAggBody | filtersAggBodyN) | option=pairs ) + RPAREN;
filtersAggBody :  (name=string COLON LPAREN queryFilter RPAREN )+;
filtersAggBodyN : (name=string COLON LSQUARE filtersAggBodyNItem+  RSQUARE);
filtersAggBodyNItem : LPAREN queryFilter RPAREN;
//geo_distance
geoDistanceAgg : GEO_DISTANCE COLON LPAREN aggCommonPart RPAREN ;
//geohash_grid
geoHashGridAgg : GEO_HASH_GRID COLON LPAREN aggCommonPart RPAREN;
//geotile_grid
geoTileGridAgg : GEO_TILE_GRID COLON LPAREN aggCommonPart RPAREN;
//histogram
histogramAgg : HISTOGRAM COLON LPAREN aggCommonPart RPAREN;
//ip_range
ipRangeAgg : IP_RANGE COLON LPAREN aggCommonPart RPAREN;
//missing
missingAgg : MISSING COLON LPAREN aggCommonPart RPAREN;
//multi_terms
multiTermsAgg : MULTI_TERMS COLON LPAREN (termsFilter|option=pairs)+ RPAREN;
// netsted
nestedAgg :  NESTED COLON LPAREN option=pairs+ RPAREN;
// parent
parentAgg : PARENT COLON LPAREN option=pairs + RPAREN;
//range
rangeAgg : RANGE COLON rangeAggItem;
rangeAggItem : LPAREN (fieldNameExpr|option=pairs)+ RPAREN;
//rare_terms
rareTermsAgg : RARE_TERMS COLON LPAREN aggCommonPart RPAREN;
//reverse_nested
reverseNestedAgg : REVERSE_NESTED COLON LPAREN aggCommonPart RPAREN;
//sampler
samplerAgg : SAMPLER COLON LPAREN aggCommonPart RPAREN;
//significant_crime_types
significantCrimeTypesAgg : SIGNIFICANT_CRIME_TYPES COLON LPAREN aggCommonPart RPAREN;
//significant_text
significantTextAgg : SIGNIFICANT_TEXT COLON LPAREN (fieldNameExpr|aggBackgroundFilter|sourceFieldsExpr|option=pairs)+ RPAREN;
//significant_terms
significantTermsAgg : SIGNIFICANT_TERMS COLON LPAREN (fieldNameExpr|aggBackgroundFilter|option=pairs) + RPAREN;
aggBackgroundFilter :  BACKGROUND_FILTER COLON LPAREN queryFilter RPAREN;
//terms
termsAgg : termsFilter;
//variable_width_histogram
variableWidthHistogramAgg : VARIABLE_WIDTH_HSITOGRAM COLON LPAREN aggCommonPart RPAREN;
// bucket agg end

//METRICS AGGS
metricsAggs : avgAggs
            | boxplotAggs
            | cardinalityAggs
            | extendedStatsAggs
            | geoBoundsAggs
            | geoCentroidAggs
            | geoLineAggs
            | matrixStatsAggs
            | maxAggs
            | medianAbsoluteDeviationAggs
            | minAggs
            | percentileRanksAggs
            | percentilesAggs
            | rateAggs
            | scriptedMetricAggs
            | statsAggs
            | stringStatsAggs
            | sumAggs
            | tTestAggs
            | topHitsAggs
            | topMetricsAggs
            | valueCountAggs
            | typesCountAggs
            | weightedAvgAggs
            ;

//avg
avgAggs : AVG COLON LPAREN aggCommonPart RPAREN;
//boxplot
boxplotAggs : BOXPLOT COLON LPAREN aggCommonPart RPAREN;
//cardinality
cardinalityAggs : CARDINALITY COLON LPAREN aggCommonPart RPAREN;
//cardinality
extendedStatsAggs : EXTENDED_STATS COLON LPAREN aggCommonPart RPAREN;
//geo_bounds
geoBoundsAggs : GEO_BOUNDS COLON LPAREN aggCommonPart RPAREN;
//geo_centroid
geoCentroidAggs : GEO_CENTROID COLON LPAREN aggCommonPart RPAREN;
//geo_line
geoLineAggs : GEO_LINE COLON LPAREN aggCommonPart RPAREN;
//matrix_stats
matrixStatsAggs : MATRIX_STATS COLON LPAREN matrixStatsAggsPart RPAREN;
matrixStatsAggsPart : ((FIELDS COLON fieldNames=stringArr   { $ctx.addField($ctx.fieldNames); } ) | option=pairs)+;
//max
maxAggs : MAX COLON LPAREN aggCommonPart RPAREN;
//median_absolute_deviation
medianAbsoluteDeviationAggs :  MEDIAN_ABSOLUTE_DEVIATION COLON LPAREN aggCommonPart RPAREN;
//min
minAggs : MIN COLON LPAREN aggCommonPart RPAREN;
//percentile_ranks
percentileRanksAggs : PERCENTILE_RANKS COLON LPAREN aggCommonPart RPAREN;
//percentiles
percentilesAggs : PERCENTILES COLON LPAREN aggCommonPart RPAREN;
//rate
rateAggs : RATE COLON LPAREN rateAggsItem+ RPAREN;
rateAggsItem : fieldNameExpr | option=pairs ;
//scripted_metric
scriptedMetricAggs : SCRIPTED_METRIC COLON LPAREN aggCommonPart RPAREN;
//stats
statsAggs : STATS COLON LPAREN aggCommonPart RPAREN;
//string_stats
stringStatsAggs : STRING_STATS COLON LPAREN aggCommonPart RPAREN;
//sum
sumAggs : SUM COLON LPAREN aggCommonPart RPAREN;
//t_test
tTestAggs : T_TEST COLON LPAREN (tTestAggsItem|option=pairs)+ RPAREN;
tTestAggsItem : string COLON LPAREN (fieldNameExpr | queryFilter)+ RPAREN ;
//top_hits
topHitsAggs : TOP_HITS COLON LPAREN aggCommonPart RPAREN;
//top_metrics
topMetricsAggs : TOP_METRICS COLON LPAREN (topMetricsAggsItem |option=pairs)+ RPAREN;
topMetricsAggsItem : (topMetricsAggSort | topMetricsAggsMetrics) +;
topMetricsAggSort : sortExpr;
topMetricsAggsMetrics : METRICS COLON (topMetricsAggsMetricsItems|topMetricsAggsMetricsItem);
topMetricsAggsMetricsItems : LSQUARE topMetricsAggsMetricsItem+ RSQUARE;
topMetricsAggsMetricsItem : LPAREN fieldNameExpr RPAREN;


//types_count
typesCountAggs : TYPES_COUNT COLON LPAREN aggCommonPart RPAREN;
//weighted_avg
weightedAvgAggs : WEIGHTED_AVG COLON LPAREN weightedAvgAggsItem RPAREN;
weightedAvgAggsItem : (weightedAvgAggsItemValue | weightedAvgAggsItemWeight | option=pairs )+;
weightedAvgAggsItemValue: VALUE COLON LPAREN aggCommonPart RPAREN;
weightedAvgAggsItemWeight: WEIGHT COLON LPAREN aggCommonPart RPAREN;

//value_count
valueCountAggs : VALUE_COUNT COLON LPAREN fieldNameExpr RPAREN;

// pipe line aggs
pipeLineAggs : averageBucketAggs
              | bucketScriptAggs
              | bucketCountKsTestAggs
              | bucketCorreationAggs
              | bucketSelectorAggs
              | bucketSortAggs
              | cumulativeCardinalityAggs
              | cumulativeSumAggs
              | derivativeAggs
              | extendedStatsBucketAggs
              | maxBucketAggs
              | minBucketAggs
              | movingAvgAggs
              | movingFnAggs
              | movingPercentilesAggs
              | normalizeAggs
              | percentilesBucketAggs
              | serialDiffAggs
              | statsBucketAggs
              | sumBucketAggs
              | inferenceAggs
              ;

//avg_bucket
averageBucketAggs : AVERAGE_BUCKET COLON LPAREN aggCommonPart RPAREN;
//bucket_script
bucketScriptAggs : BUCKET_SCRIPT COLON LPAREN aggCommonPart RPAREN;
//bucket_count_ks_test
bucketCountKsTestAggs : BUCKET_COUNT_KS_TEST COLON LPAREN aggCommonPart RPAREN;
//bucket_correlation
bucketCorreationAggs : BUCKET_CORRELATION COLON LPAREN aggCommonPart RPAREN;
//bucket_selector
bucketSelectorAggs : BUCKET_SELECTOR COLON LPAREN aggCommonPart RPAREN;
//bucket_sort
bucketSortAggs : BUCKET_SORT COLON LPAREN aggCommonPart RPAREN;
//cumulative_cardinality
cumulativeCardinalityAggs : CUMULATIVE_CARDINALITY COLON LPAREN aggCommonPart RPAREN;
//cumulative_sum
cumulativeSumAggs : CUMULATIVE_SUM COLON LPAREN aggCommonPart RPAREN;
//derivative
derivativeAggs : DERIVATIVE COLON LPAREN aggCommonPart RPAREN;
//extended_stats_bucket
extendedStatsBucketAggs : EXTENDED_STATS_BUCKET COLON LPAREN aggCommonPart RPAREN;
//max_bucket
maxBucketAggs : MAX_BUCKET COLON LPAREN aggCommonPart RPAREN;
//min_bucket
minBucketAggs : MIN_BUCKET COLON LPAREN aggCommonPart RPAREN;
//moving_avg
movingAvgAggs : MOVING_AVG COLON LPAREN aggCommonPart RPAREN;
//moving_fn
movingFnAggs : MOMVING_FN COLON LPAREN aggCommonPart RPAREN;
//moving_percentiles
movingPercentilesAggs : MOMVING_PERCENTILES COLON LPAREN aggCommonPart RPAREN;
//normalize
normalizeAggs : NORMALIZE COLON LPAREN aggCommonPart RPAREN;
//percentiles_bucket
percentilesBucketAggs : PERCENTILES_BUCKET COLON LPAREN aggCommonPart RPAREN;
//serial_diff
serialDiffAggs : SERIAL_DIFF COLON LPAREN aggCommonPart RPAREN;
//stats_bucket
statsBucketAggs : STATS_BUCKET COLON LPAREN aggCommonPart RPAREN;
//sum_bucket
sumBucketAggs : SUM_BUCKET COLON LPAREN aggCommonPart RPAREN;
//inference
inferenceAggs : INFERENCE COLON LPAREN aggCommonPart RPAREN;
//agg common part
aggCommonPart :  (fieldNameExpr | scriptExpr | sortExpr | option=pairs) +;

// end agg

// common part begin
// field filter begin
fieldFilter : fieldSimpleFilter
            | fieldExactFilter
            | fieldQueryFilter
            | fieldNameExpr
            | fieldLikeExpr
//            | fieldValueFilter
            ;

// xxx_field=xxx_value
fieldSimpleFilter: fieldName=string COLON fieldValue=string  { $ctx.addFieldValue($ctx.fieldName,$ctx.fieldValue);  };
fieldExactFilter: fieldName=string COLON LPAREN (((queryExpr|valueExpr |operatorExpr|fieldsNamesExpr)) | option=pairs)+ RPAREN  { $ctx.addField($ctx.fieldName); };
fieldQueryFilter: (((queryExpr|valueExpr|fieldNames=fieldsNamesExpr { $ctx.addField($ctx.fieldNames);  }|filterQueryFieldValue|fieldValueExpr|defaultExpr)) |option=pairs)+ ;
//fieldValueFilter: ((valueExpr) | option=pairs)+; //与 fieldQueryFilter合并
fieldValueFilter: fieldQueryFilter;
filterQueryFieldValue : fieldName=string COLON fieldValue = string{ $ctx.addFieldValue($ctx.fieldName,$ctx.fieldValue); };

//field : [ "a","b" ]
fieldsNamesExpr : FIELDS COLON fieldNames=stringArr { $ctx.addField($ctx.fieldNames);  };
//query : "ssssss"
fieldValueExpr : fieldName = string COLON LPAREN (fieldValueExpr1|option=pairs)+ RPAREN;
fieldValueExpr1 : VALUE COLON fieldValue = string;
queryExpr: QUERY COLON filterValue=string {  $ctx.addValue($ctx.filterValue);  };
valueExpr: VALUE COLON filterValue=string {  $ctx.addValue($ctx.filterValue);  };
fieldNameExpr : FIELD COLON fieldName=string    { $ctx.addField($ctx.fieldName);  };
operatorExpr: OPERATOR COLON operator=string;
defaultExpr : DEFAULT_FIELD COLON fieldName=string  { $ctx.addField($ctx.fieldName);  };
sourceFieldsExpr : SOURCE_FIELDS COLON fieldNames=stringArr { $ctx.addField($ctx.fieldNames);  };
sortExpr : SORT COLON (sortItems | sortItem);
sortItems : LSQUARE sortItem+ RSQUARE;
sortItem : LPAREN fieldName=string COLON sortExprOptions RPAREN { $ctx.addField($ctx.fieldName);  };
sortExprOptions : jvalue;
scriptExpr : SCRIPT COLON string;

//like unlike
fieldLikeExpr: (LIKE|UNLIKE) COLON (fieldLikeExprN | fieldLikeExpr1);
fieldLikeExprN: LSQUARE fieldLikeExprValue+ RSQUARE ;
fieldLikeExpr1: fieldLikeExprValue;
fieldLikeExprValue : fieldLikeExprValueObj | fieldLikeExprValueSimple;
fieldLikeExprValueObj : LPAREN (fieldIndex | fieldId | option=pairs)+  RPAREN;
fieldLikeExprValueSimple : fieldValue=string {  $ctx.addValue($ctx.fieldValue);  };
fieldDocuments : DOCUMENTS COLON LSQUARE fieldDocumentValue+ RSQUARE;
fieldDocument : DOCUMENT COLON fieldDocumentValue;
fieldDocumentValue : LPAREN fieldName=string COLON fieldValue=string RPAREN { $ctx.addFieldValue($ctx.fieldName,$ctx.fieldValue);  };
fieldIndex1 : INDEX COLON indexName=string;
fieldId1 : ID2 COLON id=string;

fieldIndex : INDEX1 COLON indexName=string;
fieldId : ID1 COLON id=string;

pairs: pair;
// common part end

uriSeg :   uriSeg  uriSeg
          |NUMBER
          |GET
          |PUT
          |POST
          |DELETE
          |HEAD
          |OPTIONS
          |BOOLEAN_TRUE
          |BOOLEAN_FALSE
          |NULL
          |ENRICH
          |POLICY
          |CREATE
          |UPDATE
          |SEARCH_SHARDS
          |SEARCH
          |MAPPING1
          |DELETE_BY_QUERY
          |UPDATE_BY_QUERY
          |MGET
          |BULK
          |REINDEX
          |TERMVECTORS
          |MTERMVECTORS
          |EXECUTE
          |STATS1
          |AUTO_SCALING
          |CAT
          |CLUSTER
          |NODES
          |REMOTE
          |TASKS
          |CCR
          |DATA_STREAM
          |FEATURES
          |FLEET
          |FIND_STRUCTURE
          |GRAPH
          |CLOSE
          |OPEN
          |SHRINK
          |CLONE
          |ROLLOVER
          |UNFREEZE
          |FREEZE
          |RESLOVE
          |MSEARCH
          |RENDER
          |COUNT
          |TERMS_ENUM
          |ASYNC_SEARCH
          |EXPLAIN
          |FIELD_CAPS
          |RANK_EVAL
          |CID
          |DOC1
          |PID
          |COLON
          ;


uriSegIndex :  uriIndexAtom  uriSeg*;

uriIndexAtom :   NUMBER
                 |GET
                 |PUT
                 |POST
                 |DELETE
                 |HEAD
                 |OPTIONS
                 |BOOLEAN_TRUE
                 |BOOLEAN_FALSE
                 |NULL
                 |POLICY
                 |PID
                 |DOC1
                 ;



string : STRING
        |CONNECTIONS
        |VERTICES
        |MATCH_FIELD
        |ENRICH_FIELDS
        |CREATE1
        |DELETE1
        |UPDATE1
        |INDEX1
        |DOCS
        |OPERATOR
        |IDS
        |EXISTS
        |REVERSE_NESTED
        |NESTED
        |PATH
        |SCORE1
        |STORED_FIELDS1
        |STORED_FIELDS
        |DOCVALUE_FIELDS
        |DOC
        |VALUES
        |VALUE_COUNT
        |VALUE
        |COLLAPSE
        |SCRIPT_SCORE
        |SCRIPT
        |RUNTIME
        |SIMPLE_QUERY_STRING
        |QUERY_STRING
        |QUERY
        |FUZZY
        |FIELDS
        |FIELD
        |SHOULD
        |MUST_NOT
        |MUST
        |FILTERS
        |FILTER
        |SETTINGS
        |INDICES
        |INDEX
        |SOURCES
        |SOURCE1
        |SOURCE2
        |TYPE1
        |TYPE2
        |CLASS
        |COMMON
        |MATCH_ALL
        |MATCH_NONE
        |MULTI_MATCH
        |COMBINED_FIELDS
        |MATCH_PHRASE_PREFIX
        |MATCH_PHRASE
        |MATCH_BOOL_PREFIX
        |MATCH
        |AGGREGATIONS
        |AGGS
        |AGG
        |INCLUDES
        |EXCLUDES
        |SOURCE_INCLUDE
        |SOURCE_EXCLUDE
        |INCLUDE
        |EXCLUDE
        |RUNTIME_MAPPINGS
        |RUNTIME_MAPPINGS1
        |MAPPINGS1
        |MAPPINGS2
        |PROPERTIES
        |LANG
        |IGNORED
        |META
        |ID1
        |ID2
        |SORT
        |TERMS_SET
        |TERMS
        |TERM
        |DYNAMIC
        |FORMAT
        |PREFIX
        |REGEXP
        |WILDCARD
        |GEO_BOUNDING_BOX
        |GEO_DISTANCE
        |GEO_POLYGON
        |GEO_SHAPE
        |DISTANCE_TYPE
        |DISTANCE
        |NAME1
        |VALIDATION_METHOD
        |SHAPE
        |SPAN_NEAR
        |SPAN_NOT
        |SPAN_OR
        |SPAN_AND
        |SPAN_TERM
        |SPAN_CONTAINING
        |SPAN_FIELD_MASKING
        |SPAN_FIRST
        |SPAN_MULTI
        |SPAN_WITHIN
        |CLAUSES
        |BOOL
        |ADJACENCY_MATRIX
        |AUTO_DATE_HISTOGRAM
        |DATE_HISTOGRAM
        |HISTOGRAM
        |CATEGORY_TEXT
        |CHILDREN
        |COMPOSITE
        |DATE_RANGE
        |DIVERSIFIED_SAMPLER
        |GEO_HASH_GRID
        |GEO_TILE_GRID
        |IP_RANGE
        |MISSING
        |MULTI_TERMS
        |PARENT
        |RANGE
        |RARE_TERMS
        |SAMPLER
        |SIGNIFICANT_CRIME_TYPES
        |SIGNIFICANT_TEXT
        |VARIABLE_WIDTH_HSITOGRAM
        |PARAMETERS
        |AVG
        |BOXPLOT
        |CARDINALITY
        |EXTENDED_STATS
        |GEO_BOUNDS
        |GEO_CENTROID
        |GEO_LINE
        |MATRIX_STATS
        |MAX
        |MIN
        |MEDIAN_ABSOLUTE_DEVIATION
        |PERCENTILE_RANKS
        |PERCENTILES
        |RATE
        |SCRIPTED_METRIC
        |STRING_STATS
        |STATS
        |SUM
        |T_TEST
        |TOP_HITS
        |TOP_METRICS
        |METRICS
        |TYPES_COUNT
        |WEIGHTED_AVG
        |WEIGHT
        |INFERENCE
        |AVERAGE_BUCKET
        |BUCKET_SCRIPT
        |BUCKET_COUNT_KS_TEST
        |BUCKET_CORRELATION
        |BUCKET_SELECTOR
        |BUCKET_SORT
        |CUMULATIVE_CARDINALITY
        |CUMULATIVE_SUM
        |DERIVATIVE
        |EXTENDED_STATS_BUCKET
        |MAX_BUCKET
        |MIN_BUCKET
        |MOVING_AVG
        |MOMVING_FN
        |MOMVING_PERCENTILES
        |NORMALIZE
        |PERCENTILES_BUCKET
        |SERIAL_DIFF
        |STATS_BUCKET
        |SUM_BUCKET
        |STRING1
        |INDEX_FILTER
        |REQUESTS
        |REQUEST
        |RATINGS
        |BOOSTING
        |CONSTANT_SCORE
        |DIS_MAX
        |QUERIES
        |FUNCTION_SCORE
        |DEFAULT_FIELD
        |HAS_CHILD
        |HAS_PARENT
        |PARENT_ID
        |DISTANCE_FEATURE
        |MORE_LIKE_THIS
        |LIKE
        |UNLIKE
        |PERCOLATE
        |DOCUMENTS
        |DOCUMENT
        |RANK_FEATURE
        |PINNED
        |ORGANIC
        |SIGNIFICANT_TERMS
        |BACKGROUND_FILTER
        |SOURCE_FIELDS
        |ALIASES
        |DYNAMIC_TEMPLATES
        |DEFINE_ALL
        |HITS
        ;


mappingString : STRING
        |CONNECTIONS
        |VERTICES
        |MATCH_FIELD
        |ENRICH_FIELDS
        |CREATE1
        |DELETE1
        |UPDATE1
        |INDEX1
        |DOCS
        |OPERATOR
        |IDS
        |EXISTS
        |REVERSE_NESTED
        |NESTED
        |PATH
        |SCORE1
        |STORED_FIELDS1
        |STORED_FIELDS
        |DOCVALUE_FIELDS
        |DOC
        |VALUES
        |VALUE_COUNT
        |VALUE
        |COLLAPSE
        |SCRIPT_SCORE
        |SCRIPT
        |RUNTIME
        |SIMPLE_QUERY_STRING
        |QUERY_STRING
        |QUERY
        |FUZZY
        |FIELDS
        |FIELD
        |SHOULD
        |MUST_NOT
        |MUST
        |FILTERS
        |FILTER
        |SETTINGS
        |INDICES
        |INDEX
        |SOURCES
        |SOURCE1
        |SOURCE2
        |TYPE1
        |TYPE2
        |CLASS
        |COMMON
        |MATCH_ALL
        |MATCH_NONE
        |MULTI_MATCH
        |COMBINED_FIELDS
        |MATCH_PHRASE_PREFIX
        |MATCH_PHRASE
        |MATCH_BOOL_PREFIX
        |MATCH
        |AGGREGATIONS
        |AGGS
        |AGG
        |INCLUDES
        |EXCLUDES
        |SOURCE_INCLUDE
        |SOURCE_EXCLUDE
        |INCLUDE
        |EXCLUDE
        |RUNTIME_MAPPINGS
        |RUNTIME_MAPPINGS1
        |MAPPINGS1
        |MAPPINGS2
        |LANG
        |IGNORED
        |META
        |ID1
        |ID2
        |SORT
        |TERMS_SET
        |TERMS
        |TERM
        |DYNAMIC
        |FORMAT
        |PREFIX
        |REGEXP
        |WILDCARD
        |GEO_BOUNDING_BOX
        |GEO_DISTANCE
        |GEO_POLYGON
        |GEO_SHAPE
        |DISTANCE_TYPE
        |DISTANCE
        |NAME1
        |VALIDATION_METHOD
        |SHAPE
        |SPAN_NEAR
        |SPAN_NOT
        |SPAN_OR
        |SPAN_AND
        |SPAN_TERM
        |SPAN_CONTAINING
        |SPAN_FIELD_MASKING
        |SPAN_FIRST
        |SPAN_MULTI
        |SPAN_WITHIN
        |CLAUSES
        |BOOL
        |ADJACENCY_MATRIX
        |AUTO_DATE_HISTOGRAM
        |DATE_HISTOGRAM
        |HISTOGRAM
        |CATEGORY_TEXT
        |CHILDREN
        |COMPOSITE
        |DATE_RANGE
        |DIVERSIFIED_SAMPLER
        |GEO_HASH_GRID
        |GEO_TILE_GRID
        |IP_RANGE
        |MISSING
        |MULTI_TERMS
        |PARENT
        |RANGE
        |RARE_TERMS
        |SAMPLER
        |SIGNIFICANT_CRIME_TYPES
        |SIGNIFICANT_TEXT
        |VARIABLE_WIDTH_HSITOGRAM
        |PARAMETERS
        |AVG
        |BOXPLOT
        |CARDINALITY
        |EXTENDED_STATS
        |GEO_BOUNDS
        |GEO_CENTROID
        |GEO_LINE
        |MATRIX_STATS
        |MAX
        |MIN
        |MEDIAN_ABSOLUTE_DEVIATION
        |PERCENTILE_RANKS
        |PERCENTILES
        |RATE
        |SCRIPTED_METRIC
        |STRING_STATS
        |STATS
        |SUM
        |T_TEST
        |TOP_HITS
        |TOP_METRICS
        |METRICS
        |TYPES_COUNT
        |WEIGHTED_AVG
        |WEIGHT
        |INFERENCE
        |AVERAGE_BUCKET
        |BUCKET_SCRIPT
        |BUCKET_COUNT_KS_TEST
        |BUCKET_CORRELATION
        |BUCKET_SELECTOR
        |BUCKET_SORT
        |CUMULATIVE_CARDINALITY
        |CUMULATIVE_SUM
        |DERIVATIVE
        |EXTENDED_STATS_BUCKET
        |MAX_BUCKET
        |MIN_BUCKET
        |MOVING_AVG
        |MOMVING_FN
        |MOMVING_PERCENTILES
        |NORMALIZE
        |PERCENTILES_BUCKET
        |SERIAL_DIFF
        |STATS_BUCKET
        |SUM_BUCKET
        |STRING1
        |INDEX_FILTER
        |REQUESTS
        |REQUEST
        |RATINGS
        |BOOSTING
        |CONSTANT_SCORE
        |DIS_MAX
        |QUERIES
        |FUNCTION_SCORE
        |DEFAULT_FIELD
        |HAS_CHILD
        |HAS_PARENT
        |PARENT_ID
        |DISTANCE_FEATURE
        |MORE_LIKE_THIS
        |LIKE
        |UNLIKE
        |PERCOLATE
        |DOCUMENTS
        |DOCUMENT
        |RANK_FEATURE
        |PINNED
        |ORGANIC
        |SIGNIFICANT_TERMS
        |BACKGROUND_FILTER
        |SOURCE_FIELDS
        |ALIASES
        |DYNAMIC_TEMPLATES
        |DEFINE_ALL
        |HITS
        ;

obj
   : LPAREN pair (pair)* RPAREN
   | LPAREN RPAREN
   ;

pair : string COLON jvalue ;

stringArr : LSQUARE string (string) * RSQUARE
          | LSQUARE RSQUARE
          ;

arr
   : LSQUARE jvalue (jvalue)* RSQUARE
   | LSQUARE RSQUARE
   ;

bool : BOOLEAN_TRUE | BOOLEAN_FALSE;
jvalue : obj
       | arr
       | string
       | NUMBER
       | bool
       | NULL
        ;

uriFragments: URI_QUESTION? uriFragmentSegments;
uriFragmentSegments: uriFragmentSegment (URI_AND uriFragmentSegment)*;
uriFragmentSegment: (URI_ID|PID) URI_EQ? (URI_SIGN|URI_ID|NUMBER|PID|COLON)*;

/******************************************************
    以下部分为响应体
    不同响应体的规则独立
*******************************************************/
// reponse part
// mapping response
mappingResponse : LPAREN mappingResponseMapping+ RPAREN;
mappingResponseMapping : string COLON createIndexStatementBody;

//_search response
searchResponse : LPAREN searchResponseItem RPAREN;
searchResponseItem : (searchResponseItemHits| searchResponseItemAgregations | pairs)+;
searchResponseItemHits : HITS COLON LPAREN (searchResponseHitsHits | pairs)+ RPAREN;
searchResponseItemAgregations : AGGREGATIONS COLON jvalue;
searchResponseHitsHits : HITS COLON LSQUARE (searchResponseHitsHitsMemo|searchResponseHitsHitsFields|pairs)+ RSQUARE;
searchResponseHitsHitsMemo : LPAREN (searchResponseHitsHitsIndex|searchResponseHitsHitsType|searchResponseHitsHitsSource|searchResponseHitsHitsId|pairs)+ RPAREN;
searchResponseHitsHitsIndex : INDEX1 COLON string ;
searchResponseHitsHitsType : TYPE1 COLON string ;
searchResponseHitsHitsSource : SOURCE1 COLON data=jvalue;
searchResponseHitsHitsId : ID1 COLON data=jvalue;
searchResponseHitsHitsFields : FIELDS COLON data=jvalue;

//_get response
getResponse : searchResponseHitsHitsMemo;
