QueryBuilder is a state machine used internally by QueryEngine to assemble the words and tags of a SearchQuery while scanning the raw query string. It maintains multiple buffers and flags to determine how the next characters should be interpreted.
| Field | Purpose |
|---|---|
current : StringBuffer |
Accumulates characters for the current term. When a splitter or end of input is reached, the buffer is flushed into the appropriate list. |
optional : List<PointedWord> |
Stores optional words along with their points. |
require : List<PointedWord> |
Stores required words. |
cannot : List<PointedWord> |
Stores forbidden words. |
tags : Map<String, List<PointedWord>> |
Stores tag words keyed by tag name. |
ignoreSpecial : bool |
When true, treat special patterns as literals. Set by ignoreNextPattern (escape). |
ignoreChar : bool |
When true, skip the current character entirely. Set by ignoreNextChar (escape). |
add : QueryType |
Indicates whether the next word should be optional, required or forbidden. |
holding : bool |
Indicates quote mode; special characters are ignored while holding except escapes and wildcard replacements. |
holdingAsTag : bool |
Indicates that the current quoted block should be treated as a tag name rather than text. |
tagName : String? |
Temporary storage for the name of a tag being parsed. |
void onChar(QueryEngine engine, int charCode)Called for each code unit in the query string. It performs the following steps:
ignoreChar is true, clear the flag and return (skip the character).PatternItem for charCode in the engine.ignoreSpecial is true, treat the pattern as a literal and append its character to current; clear the flag.holding), only ignoreNextPattern and ignoreNextChar patterns are handled. Wildcards (*) are appended as special sentinel characters; other patterns are treated as literals. When encountering another collector pattern (e.g. closing quote), flush the current term and exit quote mode.current to the appropriate bucket; if definesTag, set holdingAsTag and flush current; if definesRequired or definesNotAllowed, set add accordingly; if ignoreNextPattern or ignoreNextChar, set ignoreSpecial or ignoreChar; if it has a charReplacement and regExpChar, append the replacement; otherwise, treat as a literal.void append(QueryEngine engine)Flushes the current buffer into the correct bucket based on the state flags:
current is empty, return.QueryType from add and holdingAsTag flags.holdingAsTag, add, tagName) and clear current.SearchQuery build(QueryEngine engine, List<int> codeUnits)Iterates through all characters with onChar() and then calls append() to flush any remaining term. Finally, constructs and returns a SearchQuery with the populated lists and tag map.
QueryBuilder is not intended for external use. Instead, use QueryEngine.buildQuery() or SearchQuery.from() to parse queries. Understanding its internals can help you modify the query syntax by creating custom PatternItems and adjusting state transitions.