ParseTree

 */
/// An interface to access the tree of _org.antlr.v4.runtime.RuleContext_ objects created
/// during a parse that makes the data structure look like a simple parse tree.
/// This node represents both internal nodes, rule invocations,
/// and leaf nodes, token matches.
///
/// The payload is either a _org.antlr.v4.runtime.Token_ or a _org.antlr.v4.runtime.RuleContext_ object.
///
public protocol ParseTree: SyntaxTree, CustomStringConvertible, CustomDebugStringConvertible {
    /// Set the parent for this leaf node.
    func setParent(_ parent: RuleContext)
    /// The _org.antlr.v4.runtime.tree.ParseTreeVisitor_ needs a double dispatch method.
    func accept<T>(_ visitor: ParseTreeVisitor<T>) -> T?
    /// Return the combined text of all leaf nodes. Does not get any
    /// off-channel tokens (if any) so won't return whitespace and
    /// comments if they are sent to parser on hidden channel.
    func getText() -> String
    /// Specialize toStringTree so that it can print out more information
    /// based upon the parser.
    func toStringTree(_ parser: Parser) -> String
    /// Equivalent to `getChild(index)! as! ParseTree`
    subscript(index: Int) -> ParseTree { get }
}


Tree

 */
/// The basic notion of a tree has a parent, a payload, and a list of children.
/// It is the most abstract interface for all the trees used by ANTLR.
///
public protocol Tree: AnyObject {
    /// The parent of this node. If the return value is null, then this
    /// node is the root of the tree.
    ///
    func getParent() -> Tree?
    ///
    /// This method returns whatever object represents the data at this note. For
    /// example, for parse trees, the payload can be a _org.antlr.v4.runtime.Token_ representing
    /// a leaf node or a _org.antlr.v4.runtime.RuleContext_ object representing a rule
    /// invocation. For abstract syntax trees (ASTs), this is a _org.antlr.v4.runtime.Token_
    /// object.
    ///
    func getPayload() -> AnyObject
    /// If there are children, get the `i`th value indexed from 0.
    func getChild(_ i: Int) -> Tree?
    /// How many children are there? If there is none, then this
    /// node represents a leaf node.
    ///
    func getChildCount() -> Int
    /// Print out a whole tree, not just a node, in LISP format
    /// `(root child1 .. childN)`. Print just a node if this is a leaf.
    ///
    func toStringTree() -> String
}


ParseTreeListener

 */
/// This interface describes the minimal core of methods triggered
/// by _org.antlr.v4.runtime.tree.ParseTreeWalker_. E.g.,
///
/// ParseTreeWalker walker = new ParseTreeWalker();
/// walker.walk(myParseTreeListener, myParseTree); <-- triggers events in your listener
///
/// If you want to trigger events in multiple listeners during a single
/// tree walk, you can use the ParseTreeDispatcher object available at
///
/// https://github.com/antlr/antlr4/issues/841
///
public protocol ParseTreeListener: AnyObject {
    func visitTerminal(_ node: TerminalNode)
    func visitErrorNode(_ node: ErrorNode)
    func enterEveryRule(_ ctx: ParserRuleContext) throws
    func exitEveryRule(_ ctx: ParserRuleContext) throws
}


ParseTreeProperty

 */
import Foundation
public class ParseTreeProperty<V> {
  var annotations = Dictionary<ObjectIdentifier, V>()

  public init() {}

  open func get(_ node: ParseTree) -> V? { return annotations[ObjectIdentifier(node)] }
  open func put(_ node: ParseTree, _ value: V) { annotations[ObjectIdentifier(node)] = value }
  open func removeFrom(_ node: ParseTree) { annotations.removeValue(forKey: ObjectIdentifier(node)) }
}


ErrorNode

 */
/// Represents a token that was consumed during resynchronization
/// rather than during a valid match operation. For example,
/// we will create this kind of a node during single token insertion
/// and deletion as well as during "consume until error recovery set"
/// upon no viable alternative exceptions.
///
public class ErrorNode: TerminalNodeImpl {
    public override init(_ token: Token) {
        super.init(token)
    }
    override
    public func accept<T>(_ visitor: ParseTreeVisitor<T>) -> T? {
        return visitor.visitErrorNode(self)
    }
}


ParseTreeVisitor

 */
///
/// This interface defines the basic notion of a parse tree visitor. Generated
/// visitors implement this interface and the `XVisitor` interface for
/// grammar `X`.
///
/// - Parameter <T>: The return type of the visit operation. Use _Void_ for
/// operations with no return type.
///
open class ParseTreeVisitor<T> {
    public init() {
    }
    // typealias T
    ///
    /// Visit a parse tree, and return a user-defined result of the operation.
    ///
    /// - Parameter tree: The _org.antlr.v4.runtime.tree.ParseTree_ to visit.
    /// - Returns: The result of visiting the parse tree.
    ///
    open func visit(_ tree: ParseTree) -> T? {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Visit the children of a node, and return a user-defined result of the
    /// operation.
    ///
    /// - Parameter node: The _org.antlr.v4.runtime.tree.RuleNode_ whose children should be visited.
    /// - Returns: The result of visiting the children of the node.
    ///
    open func visitChildren(_ node: RuleNode) -> T? {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Visit a terminal node, and return a user-defined result of the operation.
    ///
    /// - Parameter node: The _org.antlr.v4.runtime.tree.TerminalNode_ to visit.
    /// - Returns: The result of visiting the node.
    ///
    open func visitTerminal(_ node: TerminalNode) -> T? {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Visit an error node, and return a user-defined result of the operation.
    ///
    /// - Parameter node: The _org.antlr.v4.runtime.tree.ErrorNode_ to visit.
    /// - Returns: The result of visiting the node.
    ///
    open func visitErrorNode(_ node: ErrorNode) -> T? {
        fatalError(#function + " must be overridden")
    }
}


ParseTreeWalker

 */
public class ParseTreeWalker {
    public static let DEFAULT = ParseTreeWalker()
    public init() {
    }
    /**
	 * Performs a walk on the given parse tree starting at the root and going down recursively
	 * with depth-first search. On each node, ParseTreeWalker.enterRule is called before
	 * recursively walking down into child nodes, then
	 * ParseTreeWalker.exitRule is called after the recursive call to wind up.
	 * - Parameter listener: The listener used by the walker to process grammar rules
	 * - Parameter t: The parse tree to be walked on
	 */
    public func walk(_ listener: ParseTreeListener, _ t: ParseTree) throws {
        if let errNode = t as? ErrorNode {
            listener.visitErrorNode(errNode)
        }
        else if let termNode = t as? TerminalNode {
            listener.visitTerminal(termNode)
        }
        else if let r = t as? RuleNode {
            try enterRule(listener, r)
            let n = r.getChildCount()
            for i in 0..<n {
                try walk(listener, r[i])
            }
            try exitRule(listener, r)
        }
        else {
            preconditionFailure()
        }
    }
    /**
	 * Enters a grammar rule by first triggering the generic event ParseTreeListener.enterEveryRule
	 * then by triggering the event specific to the given parse tree node
	 * - Parameter listener: The listener responding to the trigger events
	 * - Parameter r: The grammar rule containing the rule context
	 */
    internal func enterRule(_ listener: ParseTreeListener, _ r: RuleNode) throws {
        let ctx = r.getRuleContext() as! ParserRuleContext
        try listener.enterEveryRule(ctx)
        ctx.enterRule(listener)
    }
    /**
	 * Exits a grammar rule by first triggering the event specific to the given parse tree node
	 * then by triggering the generic event ParseTreeListener.exitEveryRule
	 * - Parameter listener: The listener responding to the trigger events
	 * - Parameter r: The grammar rule containing the rule context
	 */
    internal func exitRule(_ listener: ParseTreeListener, _ r: RuleNode) throws {
        let ctx = r.getRuleContext() as! ParserRuleContext
        ctx.exitRule(listener)
        try listener.exitEveryRule(ctx)
    }
}


TerminalNodeImpl

 */
public class TerminalNodeImpl: TerminalNode {
    public var symbol: Token
    public weak var parent: ParseTree?
    public init(_ symbol: Token) {
        self.symbol = symbol
    }
    public func getChild(_ i: Int) -> Tree? {
        return nil
    }
    open subscript(index: Int) -> ParseTree {
        preconditionFailure("Index out of range (TerminalNode never has children)")
    }
    public func getSymbol() -> Token? {
        return symbol
    }
    public func getParent() -> Tree? {
        return parent
    }
    public func setParent(_ parent: RuleContext) {
        self.parent = parent
    }
    public func getPayload() -> AnyObject {
        return symbol
    }
    public func getSourceInterval() -> Interval {
        //if   symbol == nil   { return Interval.INVALID; }
        let tokenIndex: Int = symbol.getTokenIndex()
        return Interval(tokenIndex, tokenIndex)
    }
    public func getChildCount() -> Int {
        return 0
    }
    public func accept<T>(_ visitor: ParseTreeVisitor<T>) -> T? {
        return visitor.visitTerminal(self)
    }
    public func getText() -> String {
        return (symbol.getText())!
    }
    public func toStringTree(_ parser: Parser) -> String {
        return description
    }
    public var description: String {
        //TODO: symbol == nil?
        //if    symbol == nil   {return "<nil>"; }
        if symbol.getType() == CommonToken.EOF {
            return "<EOF>"
        }
        return symbol.getText()!
    }
    public var debugDescription: String {
        return description
    }
    public func toStringTree() -> String {
        return description
    }
}


ParseTreePatternMatcher

 */
///
/// A tree pattern matching mechanism for ANTLR _org.antlr.v4.runtime.tree.ParseTree_s.
///
/// Patterns are strings of source input text with special tags representing
/// token or rule references such as:
///
/// `<ID> = <expr>;`
///
/// Given a pattern start rule such as `statement`, this object constructs
/// a _org.antlr.v4.runtime.tree.ParseTree_ with placeholders for the `ID` and `expr`
/// subtree. Then the _#match_ routines can compare an actual
/// _org.antlr.v4.runtime.tree.ParseTree_ from a parse with this pattern. Tag `<ID>` matches
/// any `ID` token and tag `<expr>` references the result of the
/// `expr` rule (generally an instance of `ExprContext`.
///
/// Pattern `x = 0;` is a similar pattern that matches the same pattern
/// except that it requires the identifier to be `x` and the expression to
/// be `0`.
///
/// The _#matches_ routines return `true` or `false` based
/// upon a match for the tree rooted at the parameter sent in. The
/// _#match_ routines return a _org.antlr.v4.runtime.tree.pattern.ParseTreeMatch_ object that
/// contains the parse tree, the parse tree pattern, and a map from tag name to
/// matched nodes (more below). A subtree that fails to match, returns with
/// _org.antlr.v4.runtime.tree.pattern.ParseTreeMatch#mismatchedNode_ set to the first tree node that did not
/// match.
///
/// For efficiency, you can compile a tree pattern in string form to a
/// _org.antlr.v4.runtime.tree.pattern.ParseTreePattern_ object.
///
/// See `TestParseTreeMatcher` for lots of examples.
/// _org.antlr.v4.runtime.tree.pattern.ParseTreePattern_ has two static helper methods:
/// _org.antlr.v4.runtime.tree.pattern.ParseTreePattern#findAll_ and _org.antlr.v4.runtime.tree.pattern.ParseTreePattern#match_ that
/// are easy to use but not super efficient because they create new
/// _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher_ objects each time and have to compile the
/// pattern in string form before using it.
///
/// The lexer and parser that you pass into the _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher_
/// constructor are used to parse the pattern in string form. The lexer converts
/// the `<ID> = <expr>;` into a sequence of four tokens (assuming lexer
/// throws out whitespace or puts it on a hidden channel). Be aware that the
/// input stream is reset for the lexer (but not the parser; a
/// _org.antlr.v4.runtime.ParserInterpreter_ is created to parse the input.). Any user-defined
/// fields you have put into the lexer might get changed when this mechanism asks
/// it to scan the pattern string.
///
/// Normally a parser does not accept token `<expr>` as a valid
/// `expr` but, from the parser passed in, we create a special version of
/// the underlying grammar representation (an _org.antlr.v4.runtime.atn.ATN_) that allows imaginary
/// tokens representing rules (`<expr>`) to match entire rules. We call
/// these __bypass alternatives__.
///
/// Delimiters are `<` and `>`, with `\` as the escape string
/// by default, but you can set them to whatever you want using
/// _#setDelimiters_. You must escape both start and stop strings
/// `\<` and `\>`.
///
public class ParseTreePatternMatcher {
    ///
    /// This is the backing field for _#getLexer()_.
    ///
    private final let lexer: Lexer
    ///
    /// This is the backing field for _#getParser()_.
    ///
    private final let parser: Parser
    internal var start: String = "<"
    internal var stop: String = ">"
    internal var escape: String = "\\"
    ///
    /// Constructs a _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher_ or from a _org.antlr.v4.runtime.Lexer_ and
    /// _org.antlr.v4.runtime.Parser_ object. The lexer input stream is altered for tokenizing
    /// the tree patterns. The parser is used as a convenient mechanism to get
    /// the grammar name, plus token, rule names.
    ///
    public init(_ lexer: Lexer, _ parser: Parser) {
        self.lexer = lexer
        self.parser = parser
    }
    ///
    /// Set the delimiters used for marking rule and token tags within concrete
    /// syntax used by the tree pattern parser.
    ///
    /// - Parameter start: The start delimiter.
    /// - Parameter stop: The stop delimiter.
    /// - Parameter escapeLeft: The escape sequence to use for escaping a start or stop delimiter.
    ///
    /// - Throws: ANTLRError.ilegalArgument if `start` is `null` or empty.
    /// - Throws: ANTLRError.ilegalArgument if `stop` is `null` or empty.
    ///
    public func setDelimiters(_ start: String, _ stop: String, _ escapeLeft: String) throws {
        if start.isEmpty {
            throw ANTLRError.illegalArgument(msg: "start cannot be null or empty")
        }
        if stop.isEmpty {
            throw ANTLRError.illegalArgument(msg: "stop cannot be null or empty")
        }
        self.start = start
        self.stop = stop
        self.escape = escapeLeft
    }
    ///
    /// Does `pattern` matched as rule `patternRuleIndex` match `tree`?
    ///
    public func matches(_ tree: ParseTree, _ pattern: String, _ patternRuleIndex: Int) throws -> Bool {
        let p: ParseTreePattern = try compile(pattern, patternRuleIndex)
        return try matches(tree, p)
    }
    ///
    /// Does `pattern` matched as rule patternRuleIndex match tree? Pass in a
    /// compiled pattern instead of a string representation of a tree pattern.
    ///
    public func matches(_ tree: ParseTree, _ pattern: ParseTreePattern) throws -> Bool {
        let labels: MultiMap<String, ParseTree> = MultiMap<String, ParseTree>()
        let mismatchedNode: ParseTree? = try matchImpl(tree, pattern.getPatternTree(), labels)
        return mismatchedNode == nil
    }
    ///
    /// Compare `pattern` matched as rule `patternRuleIndex` against
    /// `tree` and return a _org.antlr.v4.runtime.tree.pattern.ParseTreeMatch_ object that contains the
    /// matched elements, or the node at which the match failed.
    ///
    public func match(_ tree: ParseTree, _ pattern: String, _ patternRuleIndex: Int) throws -> ParseTreeMatch {
        let p: ParseTreePattern = try compile(pattern, patternRuleIndex)
        return try match(tree, p)
    }
    ///
    /// Compare `pattern` matched against `tree` and return a
    /// _org.antlr.v4.runtime.tree.pattern.ParseTreeMatch_ object that contains the matched elements, or the
    /// node at which the match failed. Pass in a compiled pattern instead of a
    /// string representation of a tree pattern.
    ///
    public func match(_ tree: ParseTree, _ pattern: ParseTreePattern) throws -> ParseTreeMatch {
        let labels: MultiMap<String, ParseTree> = MultiMap<String, ParseTree>()
        let mismatchedNode: ParseTree? = try matchImpl(tree, pattern.getPatternTree(), labels)
        return ParseTreeMatch(tree, pattern, labels, mismatchedNode)
    }
    ///
    /// For repeated use of a tree pattern, compile it to a
    /// _org.antlr.v4.runtime.tree.pattern.ParseTreePattern_ using this method.
    ///
    public func compile(_ pattern: String, _ patternRuleIndex: Int) throws -> ParseTreePattern {
        let tokenList = try tokenize(pattern)
        let tokenSrc = ListTokenSource(tokenList)
        let tokens = CommonTokenStream(tokenSrc)
        let parserInterp = try ParserInterpreter(parser.getGrammarFileName(),
                parser.getVocabulary(),
                parser.getRuleNames(),
                parser.getATNWithBypassAlts(),
                tokens)
        parserInterp.setErrorHandler(BailErrorStrategy())
        let tree = try parserInterp.parse(patternRuleIndex)
        // Make sure tree pattern compilation checks for a complete parse
        if try tokens.LA(1) != CommonToken.EOF {
            throw ANTLRError.illegalState(msg: "Tree pattern compilation doesn't check for a complete parse")
        }
        return ParseTreePattern(self, pattern, patternRuleIndex, tree)
    }
    ///
    /// Used to convert the tree pattern string into a series of tokens. The
    /// input stream is reset.
    ///
    public func getLexer() -> Lexer {
        return lexer
    }
    ///
    /// Used to collect to the grammar file name, token names, rule names for
    /// used to parse the pattern into a parse tree.
    ///
    public func getParser() -> Parser {
        return parser
    }
    // ---- SUPPORT CODE ----
    ///
    /// Recursively walk `tree` against `patternTree`, filling
    /// `match.`_org.antlr.v4.runtime.tree.pattern.ParseTreeMatch#labels labels_.
    ///
    /// - Returns: the first node encountered in `tree` which does not match
    /// a corresponding node in `patternTree`, or `null` if the match
    /// was successful. The specific node returned depends on the matching
    /// algorithm used by the implementation, and may be overridden.
    ///
    internal func matchImpl(_ tree: ParseTree,
                            _ patternTree: ParseTree,
                            _ labels: MultiMap<String, ParseTree>) throws -> ParseTree? {
        // x and <ID>, x and y, or x and x; or could be mismatched types
        if tree is TerminalNode && patternTree is TerminalNode {
            let t1 = tree as! TerminalNode
            let t2 = patternTree as! TerminalNode
            var mismatchedNode: ParseTree? = nil
            // both are tokens and they have same type
            if t1.getSymbol()!.getType() == t2.getSymbol()!.getType() {
                if t2.getSymbol() is TokenTagToken {
                    // x and <ID>
                    let tokenTagToken: TokenTagToken = t2.getSymbol() as! TokenTagToken
                    // track label->list-of-nodes for both token name and label (if any)
                    labels.map(tokenTagToken.getTokenName(), tree)
                    if let label = tokenTagToken.getLabel() {
                        labels.map(label, tree)
                    }
                } else {
                    if t1.getText() == t2.getText() {
                        // x and x
                    } else {
                        // x and y
                        if mismatchedNode == nil {
                            mismatchedNode = t1
                        }
                    }
                }
            } else {
                if mismatchedNode == nil {
                    mismatchedNode = t1
                }
            }
            return mismatchedNode
        }
        if tree is ParserRuleContext && patternTree is ParserRuleContext {
            let r1: ParserRuleContext = tree as! ParserRuleContext
            let r2: ParserRuleContext = patternTree as! ParserRuleContext
            var mismatchedNode: ParseTree? = nil
            // (expr ...) and <expr>
            if let ruleTagToken = getRuleTagToken(r2) {
                if r1.getRuleContext().getRuleIndex() == r2.getRuleContext().getRuleIndex() {
                    // track label->list-of-nodes for both rule name and label (if any)
                    labels.map(ruleTagToken.getRuleName(), tree)
                    if let label = ruleTagToken.getLabel() {
                        labels.map(label, tree)
                    }
                } else {
                    if mismatchedNode == nil {
                        mismatchedNode = r1
                    }
                }
                return mismatchedNode
            }
            // (expr ...) and (expr ...)
            if r1.getChildCount() != r2.getChildCount() {
                if mismatchedNode == nil {
                    mismatchedNode = r1
                }
                return mismatchedNode
            }
            for i in 0 ..< r1.getChildCount() {
                if let childMatch = try matchImpl(r1[i], patternTree[i], labels) {
                    return childMatch
                }
            }
            return mismatchedNode
        }
        // if nodes aren't both tokens or both rule nodes, can't match
        return tree
    }
    /// Is `t` `(expr <expr>)` subtree?
    internal func getRuleTagToken(_ t: ParseTree) -> RuleTagToken? {
        if let ruleNode = t as? RuleNode,
            ruleNode.getChildCount() == 1,
            let terminalNode = ruleNode[0] as? TerminalNode,
            let ruleTag = terminalNode.getSymbol() as? RuleTagToken {
//            print("rule tag subtree "+t.toStringTree(parser));
            return ruleTag
        }
        return nil
    }
    public func tokenize(_ pattern: String) throws -> Array<Token> {
        // split pattern into chunks: sea (raw input) and islands (<ID>, <expr>)
        let chunks = try split(pattern)
        // create token stream from text and tags
        var tokens = [Token]()
        for chunk in chunks {
            if let tagChunk = chunk as? TagChunk {
                // add special rule token or conjure up new token from name
                let firstStr = String(tagChunk.getTag().first!)
                if firstStr.lowercased() != firstStr {
                    let ttype = parser.getTokenType(tagChunk.getTag())
                    if ttype == CommonToken.INVALID_TYPE {
                        throw ANTLRError.illegalArgument(msg: "Unknown token " + tagChunk.getTag() + " in pattern: " + pattern)
                    }
                    let t = TokenTagToken(tagChunk.getTag(), ttype, tagChunk.getLabel())
                    tokens.append(t)
                } else {
                    if firstStr.uppercased() != firstStr {
                        let ruleIndex: Int = parser.getRuleIndex(tagChunk.getTag())
                        if ruleIndex == -1 {
                            throw ANTLRError.illegalArgument(msg: "Unknown rule " + tagChunk.getTag() + " in pattern: " + pattern)
                        }
                        let ruleImaginaryTokenType: Int = parser.getATNWithBypassAlts().ruleToTokenType[ruleIndex]
                        tokens.append(RuleTagToken(tagChunk.getTag(), ruleImaginaryTokenType, tagChunk.getLabel()))
                    } else {
                        throw ANTLRError.illegalArgument(msg: "invalid tag: " + tagChunk.getTag() + " in pattern: " + pattern)
                    }
                }
            } else {
                let textChunk = chunk as! TextChunk
                let inputStream = ANTLRInputStream(textChunk.getText())
                try lexer.setInputStream(inputStream)
                var t = try lexer.nextToken()
                while t.getType() != CommonToken.EOF {
                    tokens.append(t)
                    t = try lexer.nextToken()
                }
            }
        }
//		print("tokens="+tokens);
        return tokens
    }
    ///
    /// Split `<ID> = <e:expr> ;` into 4 chunks for tokenizing by _#tokenize_.
    ///
    public func split(_ pattern: String) throws -> [Chunk] {
        var p = pattern.startIndex
        let n = pattern.endIndex
        var chunks = [Chunk]()
        // find all start and stop indexes first, then collect
        var starts = [Range<String.Index>]()
        var stops = [Range<String.Index>]()
        let escapedStart = escape + start
        let escapedStop = escape + stop
        while p < n {
            let slice = pattern[p...]
            if slice.hasPrefix(escapedStart) {
                p = pattern.index(p, offsetBy: escapedStart.count)
            }
            else if slice.hasPrefix(escapedStop) {
                p = pattern.index(p, offsetBy: escapedStop.count)
            }
            else if slice.hasPrefix(start) {
                let upperBound = pattern.index(p, offsetBy: start.count)
                starts.append(p ..< upperBound)
                p = upperBound
            }
            else if slice.hasPrefix(stop) {
                let upperBound = pattern.index(p, offsetBy: stop.count)
                stops.append(p ..< upperBound)
                p = upperBound
            }
            else {
                p = pattern.index(after: p)
            }
        }
        if starts.count > stops.count {
            throw ANTLRError.illegalArgument(msg: "unterminated tag in pattern: " + pattern)
        }
        if starts.count < stops.count {
            throw ANTLRError.illegalArgument(msg: "missing start tag in pattern: " + pattern)
        }
        let ntags = starts.count
        for i in 0..<ntags {
            if starts[i].lowerBound >= stops[i].lowerBound {
                throw ANTLRError.illegalArgument(msg: "tag delimiters out of order in pattern: " + pattern)
            }
        }
        // collect into chunks now
        if ntags == 0 {
            let text = String(pattern[..<n])
            chunks.append(TextChunk(text))
        }
        if ntags > 0 && starts[0].lowerBound > pattern.startIndex {
            // copy text up to first tag into chunks
            let text = pattern[pattern.startIndex ..< starts[0].lowerBound]
            chunks.append(TextChunk(String(text)))
        }
        for i in 0 ..< ntags {
            // copy inside of <tag>
            let tag = pattern[starts[i].upperBound ..< stops[i].lowerBound]
            let ruleOrToken: String
            let label: String?
            let bits = tag.split(separator: ":", maxSplits: 1)
            if bits.count == 2 {
                label = String(bits[0])
                ruleOrToken = String(bits[1])
            }
            else {
                label = nil
                ruleOrToken = String(tag)
            }
            chunks.append(try TagChunk(label, ruleOrToken))
            if i + 1 < ntags {
                // copy from end of <tag> to start of next
                let text = pattern[stops[i].upperBound ..< starts[i + 1].lowerBound]
                chunks.append(TextChunk(String(text)))
            }
        }
        if ntags > 0 {
            let afterLastTag = stops[ntags - 1].upperBound
            if afterLastTag < n {
                // copy text from end of last tag to end
                let text = pattern[afterLastTag ..< n]
                chunks.append(TextChunk(String(text)))
            }
        }
        // strip out the escape sequences from text chunks but not tags
        for i in 0 ..< chunks.count {
            let c = chunks[i]
            if let tc = c as? TextChunk {
                let unescaped = tc.getText().replacingOccurrences(of: escape, with: "")
                if unescaped.count < tc.getText().count {
                    chunks[i] = TextChunk(unescaped)
                }
            }
        }
        return chunks
    }
}


TokenTagToken

 */
///
/// A _org.antlr.v4.runtime.Token_ object representing a token of a particular type; e.g.,
/// `<ID>`. These tokens are created for _org.antlr.v4.runtime.tree.pattern.TagChunk_ chunks where the
/// tag corresponds to a lexer rule or token type.
///
public class TokenTagToken: CommonToken {
    ///
    /// This is the backing field for _#getTokenName_.
    ///
    private let tokenName: String
    ///
    /// This is the backing field for _#getLabel_.
    ///
    private let label: String?
    ///
    /// Constructs a new instance of _org.antlr.v4.runtime.tree.pattern.TokenTagToken_ for an unlabeled tag
    /// with the specified token name and type.
    ///
    /// - Parameter tokenName: The token name.
    /// - Parameter type: The token type.
    ///
    public convenience init(_ tokenName: String, _ type: Int) {
        self.init(tokenName, type, nil)
    }
    ///
    /// Constructs a new instance of _org.antlr.v4.runtime.tree.pattern.TokenTagToken_ with the specified
    /// token name, type, and label.
    ///
    /// - Parameter tokenName: The token name.
    /// - Parameter type: The token type.
    /// - Parameter label: The label associated with the token tag, or `null` if
    /// the token tag is unlabeled.
    ///
    public init(_ tokenName: String, _ type: Int, _ label: String?) {
        self.tokenName = tokenName
        self.label = label
        super.init(type)
    }
    ///
    /// Gets the token name.
    /// - Returns: The token name.
    ///
    public final func getTokenName() -> String {
        return tokenName
    }
    ///
    /// Gets the label associated with the rule tag.
    ///
    /// - Returns: The name of the label associated with the rule tag, or
    /// `null` if this is an unlabeled rule tag.
    ///
    public final func getLabel() -> String? {
        return label
    }
    ///
    ///
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.TokenTagToken_ returns the token tag
    /// formatted with `<` and `>` delimiters.
    ///
    override
    public func getText() -> String {
        if let label = label {
            return "<" + label + ":" + tokenName + ">"
        }
        return "<" + tokenName + ">"
    }
    ///
    ///
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.TokenTagToken_ returns a string of the form
    /// `tokenName:type`.
    ///
    override
    public var description: String {
        return tokenName + ":" + String(type)
    }
}


ParseTreeMatch

 */
///
/// Represents the result of matching a _org.antlr.v4.runtime.tree.ParseTree_ against a tree pattern.
///
public class ParseTreeMatch: CustomStringConvertible {
    ///
    /// This is the backing field for _#getTree()_.
    ///
    private let tree: ParseTree
    ///
    /// This is the backing field for _#getPattern()_.
    ///
    private let pattern: ParseTreePattern
    ///
    /// This is the backing field for _#getLabels()_.
    ///
    private let labels: MultiMap<String, ParseTree>
    ///
    /// This is the backing field for _#getMismatchedNode()_.
    ///
    private let mismatchedNode: ParseTree?
    ///
    /// Constructs a new instance of _org.antlr.v4.runtime.tree.pattern.ParseTreeMatch_ from the specified
    /// parse tree and pattern.
    ///
    /// - Parameter tree: The parse tree to match against the pattern.
    /// - Parameter pattern: The parse tree pattern.
    /// - Parameter labels: A mapping from label names to collections of
    /// _org.antlr.v4.runtime.tree.ParseTree_ objects located by the tree pattern matching process.
    /// - Parameter mismatchedNode: The first node which failed to match the tree
    /// pattern during the matching process.
    ///
    /// - Throws: ANTLRError.ilegalArgument if `tree` is `null`
    /// - Throws: ANTLRError.ilegalArgument if `pattern` is `null`
    /// - Throws: ANTLRError.ilegalArgument if `labels` is `null`
    ///
    public init(_ tree: ParseTree, _ pattern: ParseTreePattern, _ labels: MultiMap<String, ParseTree>, _ mismatchedNode: ParseTree?) {
        self.tree = tree
        self.pattern = pattern
        self.labels = labels
        self.mismatchedNode = mismatchedNode
    }
    ///
    /// Get the last node associated with a specific `label`.
    ///
    /// For example, for pattern `<id:ID>`, `get("id")` returns the
    /// node matched for that `ID`. If more than one node
    /// matched the specified label, only the last is returned. If there is
    /// no node associated with the label, this returns `null`.
    ///
    /// Pattern tags like `<ID>` and `<expr>` without labels are
    /// considered to be labeled with `ID` and `expr`, respectively.
    ///
    /// - Parameter label: The label to check.
    ///
    /// - Returns: The last _org.antlr.v4.runtime.tree.ParseTree_ to match a tag with the specified
    /// label, or `null` if no parse tree matched a tag with the label.
    ///
    public func get(_ label: String) -> ParseTree? {
        if let parseTrees = labels.get(label) , parseTrees.count > 0 {
            return parseTrees[parseTrees.count - 1]   // return last if multiple
        } else {
            return nil
        }
    }
    ///
    /// Return all nodes matching a rule or token tag with the specified label.
    ///
    /// If the `label` is the name of a parser rule or token in the
    /// grammar, the resulting list will contain both the parse trees matching
    /// rule or tags explicitly labeled with the label and the complete set of
    /// parse trees matching the labeled and unlabeled tags in the pattern for
    /// the parser rule or token. For example, if `label` is `"foo"`,
    /// the result will contain __all__ of the following.
    ///
    /// * Parse tree nodes matching tags of the form `<foo:anyRuleName>` and
    /// `<foo:AnyTokenName>`.
    /// * Parse tree nodes matching tags of the form `<anyLabel:foo>`.
    /// * Parse tree nodes matching tags of the form `<foo>`.
    ///
    /// - Parameter label: The label.
    ///
    /// - Returns: A collection of all _org.antlr.v4.runtime.tree.ParseTree_ nodes matching tags with
    /// the specified `label`. If no nodes matched the label, an empty list
    /// is returned.
    ///
    public func getAll(_ label: String) -> Array<ParseTree> {
        return labels.get(label) ?? []
    }
    ///
    /// Return a mapping from label → [list of nodes].
    ///
    /// The map includes special entries corresponding to the names of rules and
    /// tokens referenced in tags in the original pattern. For additional
    /// information, see the description of _#getAll(String)_.
    ///
    /// - Returns: A mapping from labels to parse tree nodes. If the parse tree
    /// pattern did not contain any rule or token tags, this map will be empty.
    ///
    public func getLabels() -> MultiMap<String, ParseTree> {
        return labels
    }
    ///
    /// Get the node at which we first detected a mismatch.
    ///
    /// - Returns: the node at which we first detected a mismatch, or `null`
    /// if the match was successful.
    ///
    public func getMismatchedNode() -> ParseTree? {
        return mismatchedNode
    }
    ///
    /// Gets a value indicating whether the match operation succeeded.
    ///
    /// - Returns: `true` if the match operation succeeded; otherwise,
    /// `false`.
    ///
    public func succeeded() -> Bool {
        return mismatchedNode == nil
    }
    ///
    /// Get the tree pattern we are matching against.
    ///
    /// - Returns: The tree pattern we are matching against.
    ///
    public func getPattern() -> ParseTreePattern {
        return pattern
    }
    ///
    /// Get the parse tree we are trying to match to a pattern.
    ///
    /// - Returns: The _org.antlr.v4.runtime.tree.ParseTree_ we are trying to match to a pattern.
    ///
    public func getTree() -> ParseTree {
        return tree
    }
    public var description: String {
        let info = succeeded() ? "succeeded" : "failed"
        return "Match \(info); found \(getLabels().size()) labels"
    }
}


TagChunk

 */
///
/// Represents a placeholder tag in a tree pattern. A tag can have any of the
/// following forms.
///
/// * `expr`: An unlabeled placeholder for a parser rule `expr`.
/// * `ID`: An unlabeled placeholder for a token of type `ID`.
/// * `e:expr`: A labeled placeholder for a parser rule `expr`.
/// * `id:ID`: A labeled placeholder for a token of type `ID`.
///
/// This class does not perform any validation on the tag or label names aside
/// from ensuring that the tag is a non-null, non-empty string.
///
public class TagChunk: Chunk, CustomStringConvertible {
    ///
    /// This is the backing field for _#getTag_.
    ///
    private let tag: String
    ///
    /// This is the backing field for _#getLabel_.
    ///
    private let label: String?
    ///
    /// Construct a new instance of _org.antlr.v4.runtime.tree.pattern.TagChunk_ using the specified tag and
    /// no label.
    ///
    /// - Parameter tag: The tag, which should be the name of a parser rule or token
    /// type.
    ///
    /// - Throws: ANTLRError.illegalArgument if `tag` is `null` or
    /// empty.
    ///
    public convenience init(_ tag: String) throws {
        try self.init(nil, tag)
    }
    ///
    /// Construct a new instance of _org.antlr.v4.runtime.tree.pattern.TagChunk_ using the specified label
    /// and tag.
    ///
    /// - Parameter label: The label for the tag. If this is `null`, the
    /// _org.antlr.v4.runtime.tree.pattern.TagChunk_ represents an unlabeled tag.
    /// - Parameter tag: The tag, which should be the name of a parser rule or token
    /// type.
    ///
    /// - Throws: ANTLRError.illegalArgument if `tag` is `null` or
    /// empty.
    ///
    public init(_ label: String?, _ tag: String) throws {
        self.label = label
        self.tag = tag
        super.init()
        if tag.isEmpty {
            throw ANTLRError.illegalArgument(msg: "tag cannot be null or empty")
        }
    }
    ///
    /// Get the tag for this chunk.
    ///
    /// - Returns: The tag for the chunk.
    ///
    public final func getTag() -> String {
        return tag
    }
    ///
    /// Get the label, if any, assigned to this chunk.
    ///
    /// - Returns: The label assigned to this chunk, or `null` if no label is
    /// assigned to the chunk.
    ///
    public final func getLabel() -> String? {
        return label
    }
    ///
    /// This method returns a text representation of the tag chunk. Labeled tags
    /// are returned in the form `label:tag`, and unlabeled tags are
    /// returned as just the tag name.
    ///
    public var description: String {
        if let label = label {
            return "\(label):\(tag)"
        }
        else {
            return tag
        }
    }
    override public func isEqual(_ other: Chunk) -> Bool {
        guard let other = other as? TagChunk else {
            return false
        }
        return tag == other.tag && label == other.label
    }
}


RuleTagToken

 */
///
/// A _org.antlr.v4.runtime.Token_ object representing an entire subtree matched by a parser
/// rule; e.g., `<expr>`. These tokens are created for _org.antlr.v4.runtime.tree.pattern.TagChunk_
/// chunks where the tag corresponds to a parser rule.
///
public class RuleTagToken: Token, CustomStringConvertible {
    ///
    /// This is the backing field for _#getRuleName_.
    ///
    private let ruleName: String
    ///
    /// The token type for the current token. This is the token type assigned to
    /// the bypass alternative for the rule during ATN deserialization.
    ///
    private let bypassTokenType: Int
    ///
    /// This is the backing field for _#getLabel_.
    ///
    private let label: String?
    public var visited = false
    ///
    /// Constructs a new instance of _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ with the specified rule
    /// name and bypass token type and no label.
    ///
    /// - Parameter ruleName: The name of the parser rule this rule tag matches.
    /// - Parameter bypassTokenType: The bypass token type assigned to the parser rule.
    ///
    /// - Throws: ANTLRError.illegalArgument if `ruleName` is `null`
    /// or empty.
    ///
    public convenience init(_ ruleName: String, _ bypassTokenType: Int) {
        self.init(ruleName, bypassTokenType, nil)
    }
    ///
    /// Constructs a new instance of _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ with the specified rule
    /// name, bypass token type, and label.
    ///
    /// - Parameter ruleName: The name of the parser rule this rule tag matches.
    /// - Parameter bypassTokenType: The bypass token type assigned to the parser rule.
    /// - Parameter label: The label associated with the rule tag, or `null` if
    /// the rule tag is unlabeled.
    ///
    /// - Throws: ANTLRError.illegalArgument if `ruleName` is `null`
    /// or empty.
    ///
    public init(_ ruleName: String, _ bypassTokenType: Int, _ label: String?) {
        self.ruleName = ruleName
        self.bypassTokenType = bypassTokenType
        self.label = label
    }
    ///
    /// Gets the name of the rule associated with this rule tag.
    ///
    /// - Returns: The name of the parser rule associated with this rule tag.
    ///
    public final func getRuleName() -> String {
        return ruleName
    }
    ///
    /// Gets the label associated with the rule tag.
    ///
    /// - Returns: The name of the label associated with the rule tag, or
    /// `null` if this is an unlabeled rule tag.
    ///
    public final func getLabel() -> String? {
        return label
    }
    ///
    /// Rule tag tokens are always placed on the _#DEFAULT_CHANNEL_.
    ///
    public func getChannel() -> Int {
        return RuleTagToken.DEFAULT_CHANNEL
    }
    ///
    /// This method returns the rule tag formatted with `<` and `>`
    /// delimiters.
    ///
    public func getText() -> String? {
        if let label = label {
            return "<\(label):\(ruleName)>"
        }
        return "<\(ruleName)>"
    }
    ///
    /// Rule tag tokens have types assigned according to the rule bypass
    /// transitions created during ATN deserialization.
    ///
    public func getType() -> Int {
        return bypassTokenType
    }
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ always returns 0.
    ///
    public func getLine() -> Int {
        return 0
    }
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ always returns -1.
    ///
    public func getCharPositionInLine() -> Int {
        return -1
    }
    ///
    ///
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ always returns -1.
    ///
    public func getTokenIndex() -> Int {
        return -1
    }
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ always returns -1.
    ///
    public func getStartIndex() -> Int {
        return -1
    }
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ always returns -1.
    ///
    public func getStopIndex() -> Int {
        return -1
    }
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ always returns `null`.
    ///
    public func getTokenSource() -> TokenSource? {
        return nil
    }
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ always returns `null`.
    ///
    public func getInputStream() -> CharStream? {
        return nil
    }
    public func getTokenSourceAndStream() -> TokenSourceAndStream {
        return TokenSourceAndStream.EMPTY
    }
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ returns a string of the form
    /// `ruleName:bypassTokenType`.
    ///
    public var description: String {
        return ruleName + ":" + String(bypassTokenType)
    }
}


Chunk

 */
///
/// A chunk is either a token tag, a rule tag, or a span of literal text within a
/// tree pattern.
///
/// The method _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher#split(String)_ returns a list of
/// chunks in preparation for creating a token stream by
/// _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher#tokenize(String)_. From there, we get a parse
/// tree from with _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher#compile(String, int)_. These
/// chunks are converted to _org.antlr.v4.runtime.tree.pattern.RuleTagToken_, _org.antlr.v4.runtime.tree.pattern.TokenTagToken_, or the
/// regular tokens of the text surrounding the tags.
///
public class Chunk: Equatable {
    public static func ==(lhs: Chunk, rhs: Chunk) -> Bool {
        return lhs.isEqual(rhs)
    }
    public func isEqual(_ other: Chunk) -> Bool {
        return self === other
    }
}


ParseTreePattern

 */
///
/// A pattern like `<ID> = <expr>;` converted to a _org.antlr.v4.runtime.tree.ParseTree_ by
/// _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher#compile(String, int)_.
///
public class ParseTreePattern {
    ///
    /// This is the backing field for _#getPatternRuleIndex()_.
    ///
    private let patternRuleIndex: Int
    ///
    /// This is the backing field for _#getPattern()_.
    ///
    private let pattern: String
    ///
    /// This is the backing field for _#getPatternTree()_.
    ///
    private let patternTree: ParseTree
    ///
    /// This is the backing field for _#getMatcher()_.
    ///
    private let matcher: ParseTreePatternMatcher
    ///
    /// Construct a new instance of the _org.antlr.v4.runtime.tree.pattern.ParseTreePattern_ class.
    ///
    /// - Parameter matcher: The _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher_ which created this
    /// tree pattern.
    /// - Parameter pattern: The tree pattern in concrete syntax form.
    /// - Parameter patternRuleIndex: The parser rule which serves as the root of the
    /// tree pattern.
    /// - Parameter patternTree: The tree pattern in _org.antlr.v4.runtime.tree.ParseTree_ form.
    ///
    public init(_ matcher: ParseTreePatternMatcher,
                _ pattern: String, _ patternRuleIndex: Int, _ patternTree: ParseTree) {
        self.matcher = matcher
        self.patternRuleIndex = patternRuleIndex
        self.pattern = pattern
        self.patternTree = patternTree
    }
    ///
    /// Match a specific parse tree against this tree pattern.
    ///
    /// - Parameter tree: The parse tree to match against this tree pattern.
    /// - Returns: A _org.antlr.v4.runtime.tree.pattern.ParseTreeMatch_ object describing the result of the
    /// match operation. The _org.antlr.v4.runtime.tree.pattern.ParseTreeMatch#succeeded()_ method can be
    /// used to determine whether or not the match was successful.
    ///
    public func match(_ tree: ParseTree) throws -> ParseTreeMatch {
        return try matcher.match(tree, self)
    }
    ///
    /// Determine whether or not a parse tree matches this tree pattern.
    ///
    /// - Parameter tree: The parse tree to match against this tree pattern.
    /// - Returns: `true` if `tree` is a match for the current tree
    /// pattern; otherwise, `false`.
    ///
    public func matches(_ tree: ParseTree) throws -> Bool {
        return try matcher.match(tree, self).succeeded()
    }
    ///
    /// Find all nodes using XPath and then try to match those subtrees against
    /// this tree pattern.
    ///
    /// - Parameter tree: The _org.antlr.v4.runtime.tree.ParseTree_ to match against this pattern.
    /// - Parameter xpath: An expression matching the nodes
    ///
    /// - Returns: A collection of _org.antlr.v4.runtime.tree.pattern.ParseTreeMatch_ objects describing the
    /// successful matches. Unsuccessful matches are omitted from the result,
    /// regardless of the reason for the failure.
    ///
    /*public func findAll(tree : ParseTree, _ xpath : String) -> Array<ParseTreeMatch> {
        var subtrees : Array<ParseTree> = XPath.findAll(tree, xpath, matcher.getParser());
        var matches : Array<ParseTreeMatch> = Array<ParseTreeMatch>();
        for t : ParseTree in subtrees {
            var match : ParseTreeMatch = match(t);
            if ( match.succeeded() ) {
                matches.add(match);
            }
        }
        return matches;
    }*/
    ///
    /// Get the _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher_ which created this tree pattern.
    ///
    /// - Returns: The _org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher_ which created this tree
    /// pattern.
    ///
    public func getMatcher() -> ParseTreePatternMatcher {
        return matcher
    }
    ///
    /// Get the tree pattern in concrete syntax form.
    ///
    /// - Returns: The tree pattern in concrete syntax form.
    ///
    public func getPattern() -> String {
        return pattern
    }
    ///
    /// Get the parser rule which serves as the outermost rule for the tree
    /// pattern.
    ///
    /// - Returns: The parser rule which serves as the outermost rule for the tree
    /// pattern.
    ///
    public func getPatternRuleIndex() -> Int {
        return patternRuleIndex
    }
    ///
    /// Get the tree pattern as a _org.antlr.v4.runtime.tree.ParseTree_. The rule and token tags from
    /// the pattern are present in the parse tree as terminal nodes with a symbol
    /// of type _org.antlr.v4.runtime.tree.pattern.RuleTagToken_ or _org.antlr.v4.runtime.tree.pattern.TokenTagToken_.
    ///
    /// - Returns: The tree pattern as a _org.antlr.v4.runtime.tree.ParseTree_.
    ///
    public func getPatternTree() -> ParseTree {
        return patternTree
    }
}


TextChunk

 */
///
/// Represents a span of raw text (concrete syntax) between tags in a tree
/// pattern string.
///
public class TextChunk: Chunk, CustomStringConvertible {
    ///
    /// This is the backing field for _#getText_.
    ///
    private let text: String
    ///
    /// Constructs a new instance of _org.antlr.v4.runtime.tree.pattern.TextChunk_ with the specified text.
    ///
    /// - Parameter text: The text of this chunk.
    /// - Throws: ANTLRError.illegalArgument if `text` is `null`.
    ///
    public init(_ text: String) {
        self.text = text
    }
    ///
    /// Gets the raw text of this chunk.
    ///
    /// - Returns: The text of the chunk.
    ///
    public final func getText() -> String {
        return text
    }
    ///
    /// The implementation for _org.antlr.v4.runtime.tree.pattern.TextChunk_ returns the result of
    /// _#getText()_ in single quotes.
    ///
    public var description: String {
        return "'\(text)'"
    }
    override public func isEqual(_ other: Chunk) -> Bool {
        guard let other = other as? TextChunk else {
            return false
        }
        return text == other.text
    }
}


DFASerializer

///
///
///
/// A DFA walker that knows how to dump them to serialized strings.
///
public class DFASerializer: CustomStringConvertible {
    private let dfa: DFA
    private let vocabulary: Vocabulary
    public init(_ dfa: DFA, _ vocabulary: Vocabulary) {
        self.dfa = dfa
        self.vocabulary = vocabulary
    }
    public var description: String {
        if dfa.s0 == nil {
            return ""
        }
        var buf = ""
        let states = dfa.getStates()
        for s in states {
            guard let edges = s.edges else {
                continue
            }
            for (i, t) in edges.enumerated() {
                guard let t = t, t.stateNumber != Int.max else {
                    continue
                }
                let edgeLabel = getEdgeLabel(i)
                buf += getStateString(s)
                buf += "-\(edgeLabel)->"
                buf += getStateString(t)
                buf += "\n"
            }
        }
        return buf
    }
    internal func getEdgeLabel(_ i: Int) -> String {
        return vocabulary.getDisplayName(i - 1)
    }
    internal func getStateString(_ s: DFAState) -> String {
        let n = s.stateNumber
        let s1 = s.isAcceptState ? ":" : ""
        let s2 = s.requiresFullContext ? "^" : ""
        let baseStateStr = s1 + "s" + String(n) + s2
        if s.isAcceptState {
            if let predicates = s.predicates {
                return baseStateStr + "=>\(predicates)"
            } else {
                return baseStateStr + "=>\(s.prediction)"
            }
        } else {
            return baseStateStr
        }
    }
}


LexerDFASerializer

///
///
public class LexerDFASerializer: DFASerializer {
    public init(_ dfa: DFA) {
        super.init(dfa, Vocabulary.EMPTY_VOCABULARY)
    }
    override
    internal func getEdgeLabel(_ i: Int) -> String {
        return "'\(Character(integerLiteral: i))'"
    }
}


DFA

///
///
public class DFA: CustomStringConvertible {
    ///
    /// A set of all DFA states.
    ///
    public var states = [DFAState: DFAState]()
    public var s0: DFAState?
    public let decision: Int
    ///
    /// From which ATN state did we create this DFA?
    ///
    public let atnStartState: DecisionState
    ///
    /// `true` if this DFA is for a precedence decision; otherwise,
    /// `false`. This is the backing field for _#isPrecedenceDfa_.
    ///
    private let precedenceDfa: Bool

    ///
    /// mutex for states changes.
    ///
    internal private(set) var statesMutex = Mutex()
    public convenience init(_ atnStartState: DecisionState) {
        self.init(atnStartState, 0)
    }
    public init(_ atnStartState: DecisionState, _ decision: Int) {
        self.atnStartState = atnStartState
        self.decision = decision
        if let starLoopState = atnStartState as? StarLoopEntryState, starLoopState.precedenceRuleDecision {
            let precedenceState = DFAState(ATNConfigSet())
            precedenceState.edges = [DFAState]()
            precedenceState.isAcceptState = false
            precedenceState.requiresFullContext = false
            precedenceDfa = true
            s0 = precedenceState
        }
        else {
            precedenceDfa = false
            s0 = nil
        }
    }
    ///
    /// Gets whether this DFA is a precedence DFA. Precedence DFAs use a special
    /// start state _#s0_ which is not stored in _#states_. The
    /// _org.antlr.v4.runtime.dfa.DFAState#edges_ array for this start state contains outgoing edges
    /// supplying individual start states corresponding to specific precedence
    /// values.
    ///
    /// - returns: `true` if this is a precedence DFA; otherwise,
    /// `false`.
    /// - seealso: org.antlr.v4.runtime.Parser#getPrecedence()
    ///
    public final func isPrecedenceDfa() -> Bool {
        return precedenceDfa
    }
    ///
    /// Get the start state for a specific precedence value.
    ///
    /// - parameter precedence: The current precedence.
    /// - returns: The start state corresponding to the specified precedence, or
    /// `null` if no start state exists for the specified precedence.
    ///
    /// - throws: _ANTLRError.illegalState_ if this is not a precedence DFA.
    /// - seealso: #isPrecedenceDfa()
    ///
    public final func getPrecedenceStartState(_ precedence: Int) throws -> DFAState? {
        if !isPrecedenceDfa() {
            throw ANTLRError.illegalState(msg: "Only precedence DFAs may contain a precedence start state.")
        }
        guard let s0 = s0, let edges = s0.edges, precedence >= 0, precedence < edges.count else {
            return nil
        }
        return edges[precedence]
    }
    ///
    /// Set the start state for a specific precedence value.
    ///
    /// - parameter precedence: The current precedence.
    /// - parameter startState: The start state corresponding to the specified
    /// precedence.
    ///
    /// - throws: _ANTLRError.illegalState_ if this is not a precedence DFA.
    /// - seealso: #isPrecedenceDfa()
    ///
    public final func setPrecedenceStartState(_ precedence: Int, _ startState: DFAState) throws {
        if !isPrecedenceDfa() {
            throw ANTLRError.illegalState(msg: "Only precedence DFAs may contain a precedence start state.")
        }
        guard let s0 = s0, let edges = s0.edges, precedence >= 0 else {
            return
        }
        // synchronization on s0 here is ok. when the DFA is turned into a
        // precedence DFA, s0 will be initialized once and not updated again
        s0.mutex.synchronized {
            // s0.edges is never null for a precedence DFA
            if precedence >= edges.count {
                let increase = [DFAState?](repeating: nil, count: (precedence + 1 - edges.count))
                s0.edges = edges + increase
            }
            s0.edges[precedence] = startState
        }
    }
    ///
    /// Return a list of all states in this DFA, ordered by state number.
    ///
    public func getStates() -> [DFAState] {
        var result = [DFAState](states.keys)
        result = result.sorted {
            $0.stateNumber < $1.stateNumber
        }
        return result
    }
    public var description: String {
        return toString(Vocabulary.EMPTY_VOCABULARY)
    }
    public func toString(_ vocabulary: Vocabulary) -> String {
        if s0 == nil {
            return ""
        }
        let serializer = DFASerializer(self, vocabulary)
        return serializer.description
    }
    public func toLexerString() -> String {
        if s0 == nil {
            return ""
        }
        let serializer = LexerDFASerializer(self)
        return serializer.description
    }
}


DFAState

///
///
///
/// A DFA state represents a set of possible ATN configurations.
/// As Aho, Sethi, Ullman p. 117 says "The DFA uses its state
/// to keep track of all possible states the ATN can be in after
/// reading each input symbol.  That is to say, after reading
/// input a1a2..an, the DFA is in a state that represents the
/// subset T of the states of the ATN that are reachable from the
/// ATN's start state along some path labeled a1a2..an."
/// In conventional NFA→DFA conversion, therefore, the subset T
/// would be a bitset representing the set of states the
/// ATN could be in.  We need to track the alt predicted by each
/// state as well, however.  More importantly, we need to maintain
/// a stack of states, tracking the closure operations as they
/// jump from rule to rule, emulating rule invocations (method calls).
/// I have to add a stack to simulate the proper lookahead sequences for
/// the underlying LL grammar from which the ATN was derived.
///
/// I use a set of ATNConfig objects not simple states.  An ATNConfig
/// is both a state (ala normal conversion) and a RuleContext describing
/// the chain of rules (if any) followed to arrive at that state.
///
/// A DFA state may have multiple references to a particular state,
/// but with different ATN contexts (with same or different alts)
/// meaning that state was reached via a different set of rule invocations.
///
public final class DFAState: Hashable, CustomStringConvertible {
    public internal(set) var stateNumber = ATNState.INVALID_STATE_NUMBER
    public internal(set) var configs: ATNConfigSet
    ///
    /// `edges[symbol]` points to target of symbol. Shift up by 1 so (-1)
    /// _org.antlr.v4.runtime.Token#EOF_ maps to `edges[0]`.
    ///
    public internal(set) var edges: [DFAState?]!
    public internal(set) var isAcceptState = false
    ///
    /// if accept state, what ttype do we match or alt do we predict?
    /// This is set to _org.antlr.v4.runtime.atn.ATN#INVALID_ALT_NUMBER_ when _#predicates_`!=null` or
    /// _#requiresFullContext_.
    ///
    public internal(set) var prediction = ATN.INVALID_ALT_NUMBER
    public internal(set) var lexerActionExecutor: LexerActionExecutor?
    ///
    /// Indicates that this state was created during SLL prediction that
    /// discovered a conflict between the configurations in the state. Future
    /// _org.antlr.v4.runtime.atn.ParserATNSimulator#execATN_ invocations immediately jumped doing
    /// full context prediction if this field is true.
    ///
    public internal(set) var requiresFullContext = false
    ///
    /// During SLL parsing, this is a list of predicates associated with the
    /// ATN configurations of the DFA state. When we have predicates,
    /// _#requiresFullContext_ is `false` since full context prediction evaluates predicates
    /// on-the-fly. If this is not null, then _#prediction_ is
    /// _org.antlr.v4.runtime.atn.ATN#INVALID_ALT_NUMBER_.
    ///
    /// We only use these for non-_#requiresFullContext_ but conflicting states. That
    /// means we know from the context (it's $ or we don't dip into outer
    /// context) that it's an ambiguity not a conflict.
    ///
    /// This list is computed by _org.antlr.v4.runtime.atn.ParserATNSimulator#predicateDFAState_.
    ///
    public internal(set) var predicates: [PredPrediction]?
    ///
    /// mutex for states changes.
    ///
    internal private(set) var mutex = Mutex()
    ///
    /// Map a predicate to a predicted alternative.
    ///
    public final class PredPrediction: CustomStringConvertible {
        public let pred: SemanticContext
        // never null; at least SemanticContext.Empty.Instance
        public let alt: Int
        public init(_ pred: SemanticContext, _ alt: Int) {
            self.alt = alt
            self.pred = pred
        }
        public var description: String {
            return "(\(pred),\(alt))"
        }
    }
    public init(_ configs: ATNConfigSet) {
        self.configs = configs
    }
    ///
    /// Get the set of all alts mentioned by all ATN configurations in this
    /// DFA state.
    ///
    public func getAltSet() -> Set<Int>? {
        return configs.getAltSet()
    }
    public func hash(into hasher: inout Hasher) {
        hasher.combine(configs)
    }
    public var description: String {
        var buf = "\(stateNumber):\(configs)"
        if isAcceptState {
            buf += "=>"
            if let predicates = predicates {
                buf += String(describing: predicates)
            }
            else {
                buf += String(prediction)
            }
        }
        return buf
    }
}
///
/// Two _org.antlr.v4.runtime.dfa.DFAState_ instances are equal if their ATN configuration sets
/// are the same. This method is used to see if a state already exists.
///
/// Because the number of alternatives and number of ATN configurations are
/// finite, there is a finite number of DFA states that can be processed.
/// This is necessary to show that the algorithm terminates.
///
/// Cannot test the DFA state numbers here because in
/// _org.antlr.v4.runtime.atn.ParserATNSimulator#addDFAState_ we need to know if any other state
/// exists that has this exact set of ATN configurations. The
/// _#stateNumber_ is irrelevant.
///
public func ==(lhs: DFAState, rhs: DFAState) -> Bool {
    if lhs === rhs {
        return true
    }
    return (lhs.configs == rhs.configs)
}


DoubleKeyMap

///
    public mutating func put(_ k1: Key1, _ k2: Key2, _ v: Value) -> Value? {
        let prev: Value?
        if var data2 = data[k1] {
            prev = data2[k2]
            data2[k2] = v
            data[k1] = data2
        }
        else {
            prev = nil
            let data2 = [
                k2: v
            ]
            data[k1] = data2
        }
        return prev
    }
    public func get(_ k1: Key1, _ k2: Key2) -> Value? {
        return data[k1]?[k2]
    }
    public func get(_ k1: Key1) -> [Key2: Value]? {
        return data[k1]
    }
}


Interval

///
///
///
/// An immutable inclusive interval a..b
///
public struct Interval: Hashable {
   public static let INVALID: Interval = Interval(-1, -2)
    public var a: Int
    public var b: Int
    public init(_ a: Int, _ b: Int) {
        self.a = a
        self.b = b
    }
    ///
    /// Interval objects are used readonly so share all with the
    /// same single value a==b up to some max size.  Use an array as a perfect hash.
    /// Return shared object for 0..INTERVAL_POOL_MAX_VALUE or a new
    /// Interval object with a..a in it.  On Java.g4, 218623 IntervalSets
    /// have a..a (set with 1 element).
    ///
    public static func of(_ a: Int, _ b: Int) -> Interval {
        return Interval(a, b)
    }
    ///
    /// return number of elements between a and b inclusively. x..x is length 1.
    /// if b < a, then length is 0.  9..10 has length 2.
    ///
    public func length() -> Int {
        if b < a {
            return 0
        }
        return b - a + 1
    }
    public func hash(into hasher: inout Hasher) {
        hasher.combine(a)
        hasher.combine(b)
    }
    ///
    /// Does this start completely before other? Disjoint
    ///
    public func startsBeforeDisjoint(_ other: Interval) -> Bool {
        return self.a < other.a && self.b < other.a
    }
    ///
    /// Does this start at or before other? Nondisjoint
    ///
    public func startsBeforeNonDisjoint(_ other: Interval) -> Bool {
        return self.a <= other.a && self.b >= other.a
    }
    ///
    /// Does this.a start after other.b? May or may not be disjoint
    ///
    public func startsAfter(_ other: Interval) -> Bool {
        return self.a > other.a
    }
    ///
    /// Does this start completely after other? Disjoint
    ///
    public func startsAfterDisjoint(_ other: Interval) -> Bool {
        return self.a > other.b
    }
    ///
    /// Does this start after other? NonDisjoint
    ///
    public func startsAfterNonDisjoint(_ other: Interval) -> Bool {
        return self.a > other.a && self.a <= other.b // this.b>=other.b implied
    }
    ///
    /// Are both ranges disjoint? I.e., no overlap?
    ///
    public func disjoint(_ other: Interval) -> Bool {
        return startsBeforeDisjoint(other) || startsAfterDisjoint(other)
    }
    ///
    /// Are two intervals adjacent such as 0..41 and 42..42?
    ///
    public func adjacent(_ other: Interval) -> Bool {
        return self.a == other.b + 1 || self.b == other.a - 1
    }
    public func properlyContains(_ other: Interval) -> Bool {
        return other.a >= self.a && other.b <= self.b
    }
    ///
    /// Return the interval computed from combining this and other
    ///
    public func union(_ other: Interval) -> Interval {
        return Interval.of(min(a, other.a), max(b, other.b))
    }
    ///
    /// Return the interval in common between this and o
    ///
    public func intersection(_ other: Interval) -> Interval {
        return Interval.of(max(a, other.a), min(b, other.b))
    }
    ///
    /// Return the interval with elements from this not in other;
    /// other must not be totally enclosed (properly contained)
    /// within this, which would result in two disjoint intervals
    /// instead of the single one returned by this method.
    ///
    public func differenceNotProperlyContained(_ other: Interval) -> Interval? {
        var diff: Interval? = nil
        // other.a to left of this.a (or same)
        if other.startsBeforeNonDisjoint(self) {
            diff = Interval.of(max(self.a, other.b + 1),
                    self.b)
        }
                // other.a to right of this.a
        else {
            if other.startsAfterNonDisjoint(self) {
                diff = Interval.of(self.a, other.a - 1)
            }
        }
        return diff
    }
   public var description: String {
        return "\(a)..\(b)"
    }
}
public func ==(lhs: Interval, rhs: Interval) -> Bool {
    return lhs.a == rhs.a && lhs.b == rhs.b
}


Utils

///
///
import Foundation
public class Utils {
    public static func escapeWhitespace(_ s: String, _ escapeSpaces: Bool) -> String {
        var buf = ""
        for c in s {
            if c == " " && escapeSpaces {
                buf += "\u{00B7}"
            }
            else if c == "\t" {
                    buf += "\\t"
            }
            else if c == "\n" {
                buf += "\\n"
            }
            else if c == "\r" {
                buf += "\\r"
            }
            else {
            }
        }
        return buf
    }
    public static func toMap(_ keys: [String]) -> [String: Int] {
        var m = [String: Int]()
        for (index, v) in keys.enumerated() {
            m[v] = index
        }
        return m
    }
}


InterpreterDataReader

// A class to read plain text interpreter data produced by ANTLR.
public class InterpreterDataReader {

    let filePath:String,
        atn:ATN,
        vocabulary:Vocabulary,
        ruleNames:[String],
        channelNames:[String], // Only valid for lexer grammars.
        modeNames:[String] // ditto

    /**
     * The structure of the data file is line based with empty lines
     * separating the different parts. For lexers the layout is:
     * token literal names:
     * ...
     *
     * token symbolic names:
     * ...
     *
     * rule names:
     * ...
     *
     * channel names:
     * ...
     *
     * mode names:
     * ...
     *
     * atn:
     * <a single line with comma separated int values> enclosed in a pair of squared brackets.
     *
     * Data for a parser does not contain channel and mode names.
     */
    enum Part {
        case partName
        case tokenLiteralNames
        case tokenSymbolicNames
        case ruleNames
        case channelNames
        case modeNames
        case atn
    }
    enum Error: Swift.Error {
        case dataError(String)
    }

    public init(_ filePath:String) throws {
        self.filePath = filePath
        let contents = try String(contentsOfFile: filePath, encoding: String.Encoding.utf8)
        var part = Part.partName,
            literalNames = [String](),
            symbolicNames = [String](),
            ruleNames = [String](),
            channelNames = [String](),
            modeNames = [String](),
            atnText = [Substring](),
            fail:Error?
        contents.enumerateLines { (line,stop) in
            // throws have to be moved outside the enumerateLines block
            if line == "" {
                part = .partName
            }
            switch part {
            case .partName:
                switch line {
                case "token literal names:":
                    part = .tokenLiteralNames
                case "token symbolic names:":
                    part = .tokenSymbolicNames
                case "rule names:":
                    part = .ruleNames
                case "channel names:":
                    part = .channelNames
                case "mode names:":
                    part = .modeNames
                case "atn:":
                    part = .atn
                case "":
                    break
                default:
                    fail = Error.dataError("Unrecognized interpreter data part at "+line)
                }
            case .tokenLiteralNames:
                literalNames.append((line == "null") ? "" : line)
            case .tokenSymbolicNames:
                symbolicNames.append((line == "null") ? "" : line)
            case .ruleNames:
                ruleNames.append(line)
            case .channelNames:
                channelNames.append(line)
            case .modeNames:
                modeNames.append(line)
            case .atn:
                if line.prefix(1) == "[" && line.suffix(1) == "]" {
                    atnText = line.dropFirst().dropLast().split(separator:",")
                } else {
                    fail = Error.dataError("Missing bracket(s) at "+line)
                }
                part = .partName
            }
        }
        if let fail = fail { throw fail }
        vocabulary = Vocabulary(literalNames, symbolicNames)
        self.ruleNames = ruleNames
        self.channelNames = channelNames
        self.modeNames = modeNames
        let atnSerialized = atnText.map{Int($0.trimmingCharacters(in:.whitespaces))!}
        atn = try ATNDeserializer().deserialize(atnSerialized)
    }

    public func createLexer(input: CharStream)throws->LexerInterpreter {
        return try LexerInterpreter(filePath,
                                    vocabulary,
                                    ruleNames,
                                    channelNames,
                                    modeNames,
                                    atn,
                                    input)
    }

    public func createParser(input: TokenStream)throws->ParserInterpreter {
        return try ParserInterpreter(filePath,
                                    vocabulary,
                                    ruleNames,
                                    atn,
                                    input)
    }
}


IntervalSet

///
///
///
/// This class implements the _org.antlr.v4.runtime.misc.IntSet_ backed by a sorted array of
/// non-overlapping intervals. It is particularly efficient for representing
/// large collections of numbers, where the majority of elements appear as part
/// of a sequential range of numbers that are all part of the set. For example,
/// the set { 1, 2, 3, 4, 7, 8 } may be represented as { [1, 4], [7, 8] }.
///
///
/// This class is able to represent sets containing any combination of values in
/// the range _Integer#MIN_VALUE_ to _Integer#MAX_VALUE_
/// (inclusive).
///
public class IntervalSet: IntSet, Hashable, CustomStringConvertible {
    public static let COMPLETE_CHAR_SET: IntervalSet =
    {
        let set = IntervalSet.of(Lexer.MIN_CHAR_VALUE, Lexer.MAX_CHAR_VALUE)
        set.makeReadonly()
        return set
    }()
    public static let EMPTY_SET: IntervalSet = {
        let set = IntervalSet()
        set.makeReadonly()
        return set
    }()
    ///
    /// The list of sorted, disjoint intervals.
    ///
    internal var intervals: [Interval]
    internal var readonly = false
    public init(_ intervals: [Interval]) {
        self.intervals = intervals
    }
    public convenience init(_ set: IntervalSet) {
        self.init()
        try! addAll(set)
    }
    public init(_ els: Int...) {
        if els.isEmpty {
            intervals = [Interval]() // most sets are 1 or 2 elements
        } else {
            intervals = [Interval]()
            for e in els {
                try! add(e)
            }
        }
    }
    ///
    /// Create a set with all ints within range [a..b] (inclusive)
    ///
    public static func of(_ a: Int, _ b: Int) -> IntervalSet {
        let s = IntervalSet()
        try! s.add(a, b)
        return s
    }
    public func clear() throws {
        if readonly {
            throw ANTLRError.illegalState(msg: "can't alter readonly IntervalSet")
        }
        intervals.removeAll()
    }
    ///
    /// Add a single element to the set.  An isolated element is stored
    /// as a range el..el.
    ///
    public func add(_ el: Int) throws {
        if readonly {
            throw ANTLRError.illegalState(msg: "can't alter readonly IntervalSet")
        }
        try! add(el, el)
    }
    ///
    /// Add interval; i.e., add all integers from a to b to set.
    /// If b<a, do nothing.
    /// Keep list in sorted order (by left range value).
    /// If overlap, combine ranges.  For example,
    /// If this is {1..5, 10..20}, adding 6..7 yields
    /// {1..5, 6..7, 10..20}.  Adding 4..8 yields {1..8, 10..20}.
    ///
    public func add(_ a: Int, _ b: Int) throws {
        try add(Interval.of(a, b))
    }
    // copy on write so we can cache a..a intervals and sets of that
    internal func add(_ addition: Interval) throws {
        if readonly {
            throw ANTLRError.illegalState(msg: "can't alter readonly IntervalSet")
        }
        if addition.b < addition.a {
            return
        }
        // find position in list
        // Use iterators as we modify list in place
        var i = 0
        while i < intervals.count {
            let r = intervals[i]
            if addition == r {
                return
            }
            if addition.adjacent(r) || !addition.disjoint(r) {
                // next to each other, make a single larger interval
                let bigger = addition.union(r)
                //iter.set(bigger);
                intervals[i] = bigger
                // make sure we didn't just create an interval that
                // should be merged with next interval in list
                while i < intervals.count - 1 {
                    i += 1
                    let next = intervals[i]
                    if !bigger.adjacent(next) && bigger.disjoint(next) {
                        break
                    }
                    // if we bump up against or overlap next, merge
                    ///
                    /// iter.remove();   // remove this one
                    /// iter.previous(); // move backwards to what we just set
                    /// iter.set(bigger.union(next)); // set to 3 merged ones
                    /// iter.next(); // first call to next after previous duplicates the resul
                    ///
                    intervals.remove(at: i)
                    i -= 1
                    intervals[i] = bigger.union(next)
                }
                return
            }
            if addition.startsBeforeDisjoint(r) {
                // insert before r
                intervals.insert(addition, at: i)
                return
            }
            // if disjoint and after r, a future iteration will handle it
            i += 1
        }
        // ok, must be after last interval (and disjoint from last interval)
        // just add it
        intervals.append(addition)
    }
    ///
    /// combine all sets in the array returned the or'd value
    ///
    public func or(_ sets: [IntervalSet]) -> IntSet {
        let r = IntervalSet()
        for s in sets {
            try! r.addAll(s)
        }
        return r
    }
    public func addAll(_ set: IntSet?) throws -> IntSet {
        guard let set = set else {
             return self
        }
        if let other = set as? IntervalSet {
            // walk set and add each interval
            for interval in other.intervals {
                try add(interval)
            }
        } else {
            let setList = set.toList()
            for value in setList {
                try add(value)
            }
        }
        return self
    }
    public func complement(_ minElement: Int, _ maxElement: Int) -> IntSet? {
        return complement(IntervalSet.of(minElement, maxElement))
    }
    ///
    ///
    ///
    public func complement(_ vocabulary: IntSet?) -> IntSet? {
        guard let vocabulary = vocabulary, !vocabulary.isNil() else {
            return nil  // nothing in common with null set
        }
        var vocabularyIS: IntervalSet
        if let vocabulary = vocabulary as? IntervalSet {
            vocabularyIS = vocabulary
        } else {
            vocabularyIS = IntervalSet()
            try! vocabularyIS.addAll(vocabulary)
        }
        return vocabularyIS.subtract(self)
    }
    public func subtract(_ a: IntSet?) -> IntSet {
        guard let a = a, !a.isNil() else {
            return IntervalSet(self)
        }
        if let a = a as? IntervalSet {
            return subtract(self, a)
        }
        let other = IntervalSet()
        try! other.addAll(a)
        return subtract(self, other)
    }
    ///
    /// Compute the set difference between two interval sets. The specific
    /// operation is `left - right`. If either of the input sets is
    /// `null`, it is treated as though it was an empty set.
    ///
    public func subtract(_ left: IntervalSet?, _ right: IntervalSet?) -> IntervalSet {
        guard let left = left, !left.isNil() else {
            return IntervalSet()
        }
        let result = IntervalSet(left)
        guard let right = right, !right.isNil() else {
            // right set has no elements; just return the copy of the current set
            return result
        }
        var resultI = 0
        var rightI = 0
        while resultI < result.intervals.count && rightI < right.intervals.count {
            let resultInterval = result.intervals[resultI]
            let rightInterval = right.intervals[rightI]
            // operation: (resultInterval - rightInterval) and update indexes
            if rightInterval.b < resultInterval.a {
                rightI += 1
                continue
            }
            if rightInterval.a > resultInterval.b {
                resultI += 1
                continue
            }
            var beforeCurrent: Interval? = nil
            var afterCurrent: Interval? = nil
            if rightInterval.a > resultInterval.a {
                beforeCurrent = Interval(resultInterval.a, rightInterval.a - 1)
            }
            if rightInterval.b < resultInterval.b {
                afterCurrent = Interval(rightInterval.b + 1, resultInterval.b)
            }
            if let beforeCurrent = beforeCurrent {
                if let afterCurrent = afterCurrent {
                    // split the current interval into two
                    result.intervals[resultI] = beforeCurrent
                    result.intervals.insert(afterCurrent, at: resultI + 1)
                    resultI += 1
                    rightI += 1
                    continue
                } else {
                    // replace the current interval
                    result.intervals[resultI] = beforeCurrent
                    resultI += 1
                    continue
                }
            } else {
                if let afterCurrent = afterCurrent {
                    // replace the current interval
                    result.intervals[resultI] = afterCurrent
                    rightI += 1
                    continue
                } else {
                    // remove the current interval (thus no need to increment resultI)
                    result.intervals.remove(at: resultI)
                    //result.intervals.remove(resultI);
                    continue
                }
            }
        }
        // If rightI reached right.intervals.size(), no more intervals to subtract from result.
        // If resultI reached result.intervals.size(), we would be subtracting from an empty set.
        // Either way, we are done.
        return result
    }
    public func or(_ a: IntSet) -> IntSet {
        let o = IntervalSet()
        try! o.addAll(self)
        try! o.addAll(a)
        return o
    }
    ///
    ///
    ///
    public func and(_ other: IntSet?) -> IntSet? {
        if other == nil {
            return nil // nothing in common with null set
        }
        let myIntervals = self.intervals
        let theirIntervals = (other as! IntervalSet).intervals
        var intersection: IntervalSet? = nil
        let mySize = myIntervals.count
        let theirSize = theirIntervals.count
        var i = 0
        var j = 0
        // iterate down both interval lists looking for nondisjoint intervals
        while i < mySize && j < theirSize {
            let mine = myIntervals[i]
            let theirs = theirIntervals[j]
            if mine.startsBeforeDisjoint(theirs) {
                // move this iterator looking for interval that might overlap
                i += 1
            } else {
                if theirs.startsBeforeDisjoint(mine) {
                    // move other iterator looking for interval that might overlap
                    j += 1
                } else {
                    if mine.properlyContains(theirs) {
                        // overlap, add intersection, get next theirs
                        if intersection == nil {
                            intersection = IntervalSet()
                        }
                        try! intersection!.add(mine.intersection(theirs))
                        j += 1
                    } else {
                        if theirs.properlyContains(mine) {
                            // overlap, add intersection, get next mine
                            if intersection == nil {
                                intersection = IntervalSet()
                            }
                            try! intersection!.add(mine.intersection(theirs))
                            i += 1
                        } else {
                            if !mine.disjoint(theirs) {
                                // overlap, add intersection
                                if intersection == nil {
                                    intersection = IntervalSet()
                                }
                                try! intersection!.add(mine.intersection(theirs))
                                // Move the iterator of lower range [a..b], but not
                                // the upper range as it may contain elements that will collide
                                // with the next iterator. So, if mine=[0..115] and
                                // theirs=[115..200], then intersection is 115 and move mine
                                // but not theirs as theirs may collide with the next range
                                // in thisIter.
                                // move both iterators to next ranges
                                if mine.startsAfterNonDisjoint(theirs) {
                                    j += 1
                                } else {
                                    if theirs.startsAfterNonDisjoint(mine) {
                                        i += 1
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        if intersection == nil {
            return IntervalSet()
        }
        return intersection
    }
    ///
    ///
    ///
    public func contains(_ el: Int) -> Bool {
        for interval in intervals {
            let a = interval.a
            let b = interval.b
            if el < a {
                break // list is sorted and el is before this interval; not here
            }
            if el >= a && el <= b {
                return true // found in this interval
            }
        }
        return false
    }
    ///
    ///
    ///
    public func isNil() -> Bool {
        return intervals.isEmpty
    }
    ///
    ///
    ///
    public func getSingleElement() -> Int {
        if intervals.count == 1 {
            let interval = intervals[0]
            if interval.a == interval.b {
                return interval.a
            }
        }
        return CommonToken.INVALID_TYPE
    }
    ///
    /// Returns the maximum value contained in the set.
    ///
    /// - returns: the maximum value contained in the set. If the set is empty, this
    /// method returns _org.antlr.v4.runtime.Token#INVALID_TYPE_.
    ///
    public func getMaxElement() -> Int {
        if isNil() {
            return CommonToken.INVALID_TYPE
        }
        let last = intervals[intervals.count - 1]
        return last.b
    }
    ///
    /// Returns the minimum value contained in the set.
    ///
    /// - returns: the minimum value contained in the set. If the set is empty, this
    /// method returns _org.antlr.v4.runtime.Token#INVALID_TYPE_.
    ///
    public func getMinElement() -> Int {
        if isNil() {
            return CommonToken.INVALID_TYPE
        }
        return intervals[0].a
    }
    ///
    /// Return a list of Interval objects.
    ///
    public func getIntervals() -> [Interval] {
        return intervals
    }
    public func hash(into hasher: inout Hasher) {
        for interval in intervals {
            hasher.combine(interval.a)
            hasher.combine(interval.b)
        }
    }
    ///
    /// Are two IntervalSets equal?  Because all intervals are sorted
    /// and disjoint, equals is a simple linear walk over both lists
    /// to make sure they are the same.  Interval.equals() is used
    /// by the List.equals() method to check the ranges.
    ///
    ///
    /// public func equals(obj : AnyObject) -> Bool {
    /// if ( obj==nil || !(obj is IntervalSet) ) {
    /// return false;
    /// }
    /// var other : IntervalSet = obj as! IntervalSet;
    /// return self.intervals.equals(other.intervals);
    ///
    public var description: String {
        return toString(false)
    }
    public func toString(_ elemAreChar: Bool) -> String {
        if intervals.isEmpty {
            return "{}"
        }
        let selfSize = size()
        var buf = ""
        if selfSize > 1 {
            buf += "{"
        }
        var first = true
        for interval in intervals {
            if !first {
                buf += ", "
            }
            first = false
            let a = interval.a
            let b = interval.b
            if a == b {
                if a == CommonToken.EOF {
                    buf += "<EOF>"
                }
                else if elemAreChar {
                    buf += "'\(a)'"
                }
                else {
                    buf += "\(a)"
                }
            }
            else if elemAreChar {
                buf += "'\(a)'..'\(b)'"
            }
            else {
                buf += "\(a)..\(b)"
            }
        }
        if selfSize > 1 {
            buf += "}"
        }
        return buf
    }
    public func toString(_ vocabulary: Vocabulary) -> String {
        if intervals.isEmpty {
            return "{}"
        }
        let selfSize = size()
        var buf = ""
        if selfSize > 1 {
            buf += "{"
        }
        var first = true
        for interval in intervals {
            if !first {
                buf += ", "
            }
            first = false
            let a = interval.a
            let b = interval.b
            if a == b {
                buf += elementName(vocabulary, a)
            }
            else {
                for i in a...b {
                    if i > a {
                        buf += ", "
                    }
                    buf += elementName(vocabulary, i)
                }
            }
        }
        if selfSize > 1 {
            buf += "}"
        }
        return buf
    }
    internal func elementName(_ vocabulary: Vocabulary, _ a: Int) -> String {
        if a == CommonToken.EOF {
            return "<EOF>"
        }
        else if a == CommonToken.EPSILON {
            return "<EPSILON>"
        }
        else {
            return vocabulary.getDisplayName(a)
        }
    }
    public func size() -> Int {
        var n = 0
        for interval in intervals {
            n += (interval.b - interval.a + 1)
        }
        return n
    }
    public func toList() -> [Int] {
        var values = [Int]()
        for interval in intervals {
            let a = interval.a
            let b = interval.b
            values.append(contentsOf: a...b)
        }
        return values
    }
    public func toSet() -> Set<Int> {
        var s = Set<Int>()
        for interval in intervals {
            let a = interval.a
            let b = interval.b
            for v in a...b  {
                s.insert(v)
            }
        }
        return s
    }
    ///
    /// Get the ith element of ordered set.  Used only by RandomPhrase so
    /// don't bother to implement if you're not doing that for a new
    /// ANTLR code gen target.
    ///
    public func get(_ i: Int) -> Int {
        var index = 0
        for interval in intervals {
            let a = interval.a
            let b = interval.b
            for v in a...b  {
                if index == i {
                    return v
                }
                index += 1
            }
        }
        return -1
    }
    public func remove(_ el: Int) throws {
        if readonly {
            throw ANTLRError.illegalState(msg: "can't alter readonly IntervalSet")
        }
        var idx = intervals.startIndex
        while idx < intervals.endIndex {
            defer { intervals.formIndex(after: &idx) }
            var interval: Interval {
                get {
                    return intervals[idx]
                }
                set {
                    intervals[idx] = newValue
                }
            }
            let a = interval.a
            let b = interval.b
            if el < a {
                break // list is sorted and el is before this interval; not here
            }
            // if whole interval x..x, rm
            if el == a && el == b {
                intervals.remove(at: idx)
                break
            }
            // if on left edge x..b, adjust left
            if el == a {
                interval.a += 1
                break
            }
            // if on right edge a..x, adjust right
            if el == b {
                interval.b -= 1
                break
            }
            // if in middle a..x..b, split interval
            if el > a && el < b {
                // found in this interval
                let oldb = interval.b
                interval.b = el - 1      // [a..x-1]
                try add(el + 1, oldb) // add [x+1..b]
            }
        }
    }
    public func isReadonly() -> Bool {
        return readonly
    }
    public func makeReadonly() {
        readonly = true
    }
}
public func ==(lhs: IntervalSet, rhs: IntervalSet) -> Bool {
    return lhs.intervals == rhs.intervals
}


IntSet

///
///
///
/// A generic set of integers.
///
/// - seealso: org.antlr.v4.runtime.misc.IntervalSet
///
public protocol IntSet {
    ///
    /// Adds the specified value to the current set.
    ///
    /// - parameter el: the value to add
    ///
    /// - throws: _ANTLRError.illegalState_ if the current set is read-only
    ///
    func add(_ el: Int) throws
    ///
    /// Modify the current _org.antlr.v4.runtime.misc.IntSet_ object to contain all elements that are
    /// present in itself, the specified `set`, or both.
    ///
    /// - parameter set: The set to add to the current set. A `null` argument is
    /// treated as though it were an empty set.
    /// - returns: `this` (to support chained calls)
    ///
    /// - throws: _ANTLRError.illegalState_ if the current set is read-only
    ///
    func addAll(_ set: IntSet?) throws -> IntSet
    ///
    /// Return a new _org.antlr.v4.runtime.misc.IntSet_ object containing all elements that are
    /// present in both the current set and the specified set `a`.
    ///
    /// - parameter a: The set to intersect with the current set. A `null`
    /// argument is treated as though it were an empty set.
    /// - returns: A new _org.antlr.v4.runtime.misc.IntSet_ instance containing the intersection of the
    /// current set and `a`. The value `null` may be returned in
    /// place of an empty result set.
    ///
    func and(_ a: IntSet?) -> IntSet?
    ///
    /// Return a new _org.antlr.v4.runtime.misc.IntSet_ object containing all elements that are
    /// present in `elements` but not present in the current set. The
    /// following expressions are equivalent for input non-null _org.antlr.v4.runtime.misc.IntSet_
    /// instances `x` and `y`.
    ///
    /// * `x.complement(y)`
    /// *`y.subtract(x)`
    ///
    /// - parameter elements: The set to compare with the current set. A `null`
    /// argument is treated as though it were an empty set.
    /// - returns: A new _org.antlr.v4.runtime.misc.IntSet_ instance containing the elements present in
    /// `elements` but not present in the current set. The value
    /// `null` may be returned in place of an empty result set.
    ///
    func complement(_ elements: IntSet?) -> IntSet?
    ///
    /// Return a new _org.antlr.v4.runtime.misc.IntSet_ object containing all elements that are
    /// present in the current set, the specified set `a`, or both.
    ///
    ///
    /// This method is similar to _#addAll(org.antlr.v4.runtime.misc.IntSet)_, but returns a new
    /// _org.antlr.v4.runtime.misc.IntSet_ instance instead of modifying the current set.
    ///
    /// - parameter a: The set to union with the current set. A `null` argument
    /// is treated as though it were an empty set.
    /// - returns: A new _org.antlr.v4.runtime.misc.IntSet_ instance containing the union of the current
    /// set and `a`. The value `null` may be returned in place of an
    /// empty result set.
    ///
    func or(_ a: IntSet) -> IntSet
    ///
    /// Return a new _org.antlr.v4.runtime.misc.IntSet_ object containing all elements that are
    /// present in the current set but not present in the input set `a`.
    /// The following expressions are equivalent for input non-null
    /// _org.antlr.v4.runtime.misc.IntSet_ instances `x` and `y`.
    ///
    /// * `y.subtract(x)`
    /// * `x.complement(y)`
    ///
    /// - parameter a: The set to compare with the current set. A `null`
    /// argument is treated as though it were an empty set.
    /// - returns: A new _org.antlr.v4.runtime.misc.IntSet_ instance containing the elements present in
    /// `elements` but not present in the current set. The value
    /// `null` may be returned in place of an empty result set.
    ///
    func subtract(_ a: IntSet?) -> IntSet
    ///
    /// Return the total number of elements represented by the current set.
    ///
    /// - returns: the total number of elements represented by the current set,
    /// regardless of the manner in which the elements are stored.
    ///
    func size() -> Int
    ///
    /// Returns `true` if this set contains no elements.
    ///
    /// - returns: `true` if the current set contains no elements; otherwise,
    /// `false`.
    ///
    func isNil() -> Bool
    ///
    /// Returns the single value contained in the set, if _#size_ is 1;
    /// otherwise, returns _org.antlr.v4.runtime.Token#INVALID_TYPE_.
    ///
    /// - returns: the single value contained in the set, if _#size_ is 1;
    /// otherwise, returns _org.antlr.v4.runtime.Token#INVALID_TYPE_.
    ///
    func getSingleElement() -> Int
    ///
    /// Returns `true` if the set contains the specified element.
    ///
    /// - parameter el: The element to check for.
    /// - returns: `true` if the set contains `el`; otherwise `false`.
    ///
    func contains(_ el: Int) -> Bool
    ///
    /// Removes the specified value from the current set. If the current set does
    /// not contain the element, no changes are made.
    ///
    /// - parameter el: the value to remove
    ///
    /// - throws: _ANTLRError.illegalState_ if the current set is read-only
    ///
    func remove(_ el: Int) throws
    ///
    /// Return a list containing the elements represented by the current set. The
    /// list is returned in ascending numerical order.
    ///
    /// - returns: A list containing all element present in the current set, sorted
    /// in ascending numerical order.
    ///
    func toList() -> [Int]
}