GPBSwiftTests

// Protocol Buffers - Google's data interchange format
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
import Foundation
import XCTest
// Test some usage of the ObjC library from Swift.
class GPBBridgeTests: XCTestCase {
  func testProto2Basics() {
    let msg = Message2()
    let msg2 = Message2()
    let msg3 = Message2_OptionalGroup()
    msg.optionalInt32 = 100
    msg.optionalString = "abc"
    msg.optionalEnum = .bar
    msg2.optionalString = "other"
    msg.optional = msg2
    msg3.a = 200
    msg.optionalGroup = msg3
    msg.repeatedInt32Array.addValue(300)
    msg.repeatedInt32Array.addValue(301)
    msg.repeatedStringArray.add("mno")
    msg.repeatedStringArray.add("pqr")
    msg.repeatedEnumArray.addValue(Message2_Enum.bar.rawValue)
    msg.repeatedEnumArray.addValue(Message2_Enum.baz.rawValue)
    msg.mapInt32Int32.setInt32(400, forKey:500)
    msg.mapInt32Int32.setInt32(401, forKey:501)
    msg.mapStringString.setObject("foo", forKey:"bar" as NSString)
    msg.mapStringString.setObject("abc", forKey:"xyz" as NSString)
    msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey:600)
    msg.mapInt32Enum.setEnum(Message2_Enum.baz.rawValue, forKey:601)
    // Check has*.
    XCTAssertTrue(msg.hasOptionalInt32)
    XCTAssertTrue(msg.hasOptionalString)
    XCTAssertTrue(msg.hasOptionalEnum)
    XCTAssertTrue(msg2.hasOptionalString)
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertTrue(msg3.hasA)
    XCTAssertTrue(msg.hasOptionalGroup)
    XCTAssertFalse(msg.hasOptionalInt64)
    XCTAssertFalse(msg.hasOptionalFloat)
    // Check values.
    XCTAssertEqual(msg.optionalInt32, Int32(100))
    XCTAssertEqual(msg.optionalString, "abc")
    XCTAssertEqual(msg2.optionalString, "other")
    XCTAssertTrue(msg.optional === msg2)
    XCTAssertEqual(msg.optionalEnum, Message2_Enum.bar)
    XCTAssertEqual(msg3.a, Int32(200))
    XCTAssertTrue(msg.optionalGroup === msg3)
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(2))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 0), Int32(300))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 1), Int32(301))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
    XCTAssertEqual(msg.repeatedStringArray.object(at: 0) as? String, "mno")
    XCTAssertEqual(msg.repeatedStringArray.object(at: 1) as? String, "pqr")
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(2))
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 0), Message2_Enum.bar.rawValue)
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 1), Message2_Enum.baz.rawValue)
    XCTAssertEqual(msg.repeatedInt64Array.count, UInt(0))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
    var intValue: Int32 = 0
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 500))
    XCTAssertEqual(intValue, Int32(400))
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 501))
    XCTAssertEqual(intValue, Int32(401))
    XCTAssertEqual(msg.mapStringString.count, Int(2))
    XCTAssertEqual(msg.mapStringString.object(forKey: "bar") as? String, "foo")
    XCTAssertEqual(msg.mapStringString.object(forKey: "xyz") as? String, "abc")
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600))
    XCTAssertEqual(intValue, Message2_Enum.bar.rawValue)
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601))
    XCTAssertEqual(intValue, Message2_Enum.baz.rawValue)
    // Clearing a string with nil.
    msg2.optionalString = nil
    XCTAssertFalse(msg2.hasOptionalString)
    XCTAssertEqual(msg2.optionalString, "")
    // Clearing a message with nil.
    msg.optionalGroup = nil
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertTrue(msg.optionalGroup !== msg3)  // New instance
    // Clear.
    msg.clear()
    XCTAssertFalse(msg.hasOptionalInt32)
    XCTAssertFalse(msg.hasOptionalString)
    XCTAssertFalse(msg.hasOptionalEnum)
    XCTAssertFalse(msg.hasOptionalMessage)
    XCTAssertFalse(msg.hasOptionalInt64)
    XCTAssertFalse(msg.hasOptionalFloat)
    XCTAssertEqual(msg.optionalInt32, Int32(0))
    XCTAssertEqual(msg.optionalString, "")
    XCTAssertTrue(msg.optional !== msg2)  // New instance
    XCTAssertEqual(msg.optionalEnum, Message2_Enum.foo)  // Default
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(0))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(0))
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(0))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(0))
    XCTAssertEqual(msg.mapStringString.count, Int(0))
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(0))
  }
  func testProto3Basics() {
    let msg = Message3()
    let msg2 = Message3()
    msg.optionalInt32 = 100
    msg.optionalString = "abc"
    msg.optionalEnum = .bar
    msg2.optionalString = "other"
    msg.optional = msg2
    msg.repeatedInt32Array.addValue(300)
    msg.repeatedInt32Array.addValue(301)
    msg.repeatedStringArray.add("mno")
    msg.repeatedStringArray.add("pqr")
    // "proto3" syntax lets enum get unknown values.
    msg.repeatedEnumArray.addValue(Message3_Enum.bar.rawValue)
    msg.repeatedEnumArray.addRawValue(666)
    SetMessage3_OptionalEnum_RawValue(msg2, 666)
    msg.mapInt32Int32.setInt32(400, forKey:500)
    msg.mapInt32Int32.setInt32(401, forKey:501)
    msg.mapStringString.setObject("foo", forKey:"bar" as NSString)
    msg.mapStringString.setObject("abc", forKey:"xyz" as NSString)
    msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey:600)
    // "proto3" syntax lets enum get unknown values.
    msg.mapInt32Enum.setRawValue(666, forKey:601)
    // Has only exists on for message fields.
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertFalse(msg2.hasOptionalMessage)
    // Check values.
    XCTAssertEqual(msg.optionalInt32, Int32(100))
    XCTAssertEqual(msg.optionalString, "abc")
    XCTAssertEqual(msg2.optionalString, "other")
    XCTAssertTrue(msg.optional === msg2)
    XCTAssertEqual(msg.optionalEnum, Message3_Enum.bar)
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(2))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 0), Int32(300))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 1), Int32(301))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
    XCTAssertEqual(msg.repeatedStringArray.object(at: 0) as? String, "mno")
    XCTAssertEqual(msg.repeatedStringArray.object(at: 1) as? String, "pqr")
    XCTAssertEqual(msg.repeatedInt64Array.count, UInt(0))
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(2))
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 0), Message3_Enum.bar.rawValue)
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 1), Message3_Enum.gpbUnrecognizedEnumeratorValue.rawValue)
    XCTAssertEqual(msg.repeatedEnumArray.rawValue(at: 1), 666)
    XCTAssertEqual(msg2.optionalEnum, Message3_Enum.gpbUnrecognizedEnumeratorValue)
    XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Int32(666))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
    var intValue: Int32 = 0
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:500))
    XCTAssertEqual(intValue, Int32(400))
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:501))
    XCTAssertEqual(intValue, Int32(401))
    XCTAssertEqual(msg.mapStringString.count, Int(2))
    XCTAssertEqual(msg.mapStringString.object(forKey: "bar") as? String, "foo")
    XCTAssertEqual(msg.mapStringString.object(forKey: "xyz") as? String, "abc")
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600))
    XCTAssertEqual(intValue, Message2_Enum.bar.rawValue)
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601))
    XCTAssertEqual(intValue, Message3_Enum.gpbUnrecognizedEnumeratorValue.rawValue)
    XCTAssertTrue(msg.mapInt32Enum.getRawValue(&intValue, forKey:601))
    XCTAssertEqual(intValue, 666)
    // Clearing a string with nil.
    msg2.optionalString = nil
    XCTAssertEqual(msg2.optionalString, "")
    // Clearing a message with nil.
    msg.optional = nil
    XCTAssertFalse(msg.hasOptionalMessage)
    XCTAssertTrue(msg.optional !== msg2)  // New instance
    // Clear.
    msg.clear()
    XCTAssertFalse(msg.hasOptionalMessage)
    XCTAssertEqual(msg.optionalInt32, Int32(0))
    XCTAssertEqual(msg.optionalString, "")
    XCTAssertTrue(msg.optional !== msg2)  // New instance
    XCTAssertEqual(msg.optionalEnum, Message3_Enum.foo)  // Default
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(0))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(0))
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(0))
    msg2.clear()
    XCTAssertEqual(msg2.optionalEnum, Message3_Enum.foo)  // Default
    XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Message3_Enum.foo.rawValue)
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(0))
    XCTAssertEqual(msg.mapStringString.count, Int(0))
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(0))
  }
  func testAutoCreation() {
    let msg = Message2()
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertFalse(msg.hasOptionalMessage)
    // Access shouldn't result in has* but should return objects.
    let msg2 = msg.optionalGroup
    let msg3 = msg.optional.optional
    let msg4 = msg.optional
    XCTAssertNotNil(msg2)
    XCTAssertNotNil(msg3)
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertFalse(msg.optional.hasOptionalMessage)
    XCTAssertFalse(msg.hasOptionalMessage)
    // Setting things should trigger has* getting set.
    msg.optionalGroup.a = 10
    msg.optional.optional.optionalInt32 = 100
    XCTAssertTrue(msg.hasOptionalGroup)
    XCTAssertTrue(msg.optional.hasOptionalMessage)
    XCTAssertTrue(msg.hasOptionalMessage)
    // And they should be the same pointer as before.
    XCTAssertTrue(msg2 === msg.optionalGroup)
    XCTAssertTrue(msg3 === msg.optional.optional)
    XCTAssertTrue(msg4 === msg.optional)
    // Clear gets us new objects next time around.
    msg.clear()
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertFalse(msg.optional.hasOptionalMessage)
    XCTAssertFalse(msg.hasOptionalMessage)
    msg.optionalGroup.a = 20
    msg.optional.optional.optionalInt32 = 200
    XCTAssertTrue(msg.hasOptionalGroup)
    XCTAssertTrue(msg.optional.hasOptionalMessage)
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertTrue(msg2 !== msg.optionalGroup)
    XCTAssertTrue(msg3 !== msg.optional.optional)
    XCTAssertTrue(msg4 !== msg.optional)
    // Explicit set of a message, means autocreated object doesn't bind.
    msg.clear()
    let autoCreated = msg.optional
    XCTAssertFalse(msg.hasOptionalMessage)
    let msg5 = Message2()
    msg5.optionalInt32 = 123
    msg.optional = msg5
    XCTAssertTrue(msg.hasOptionalMessage)
    // Modifying the autocreated doesn't replaced the explicit set one.
    autoCreated?.optionalInt32 = 456
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertTrue(msg.optional === msg5)
    XCTAssertEqual(msg.optional.optionalInt32, Int32(123))
  }
  func testProto2OneOfSupport() {
    let msg = Message2()
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    let autoCreated = msg.oneof  // Default create one.
    XCTAssertNotNil(autoCreated)
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofInt32)
    msg.oneofFloat = 20.0
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(20.0))
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofFloat)
    msg.oneofEnum = .bar
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.bar)
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofEnum)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 200
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(200))
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofMessage)
    // Clear the oneof.
    Message2_ClearOOneOfCase(msg)
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    let autoCreated2 = msg.oneof  // Default create one
    XCTAssertNotNil(autoCreated2)
    XCTAssertTrue(autoCreated2 !== autoCreated)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofInt32)
    // Confirm Message.clear() handles the oneof correctly.
    msg.clear()
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 300
    XCTAssertTrue(msg.oneof !== autoCreated)  // New instance
    XCTAssertTrue(msg.oneof !== autoCreated2)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(300))
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofMessage)
    // Set message to nil clears the oneof.
    msg.oneof = nil
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
  }
  func testProto3OneOfSupport() {
    let msg = Message3()
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    let autoCreated = msg.oneof  // Default create one.
    XCTAssertNotNil(autoCreated)
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofInt32)
    msg.oneofFloat = 20.0
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(20.0))
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofFloat)
    msg.oneofEnum = .bar
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.bar)
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofEnum)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 200
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(200))
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofMessage)
    // Clear the oneof.
    Message3_ClearOOneOfCase(msg)
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    let autoCreated2 = msg.oneof  // Default create one
    XCTAssertNotNil(autoCreated2)
    XCTAssertTrue(autoCreated2 !== autoCreated)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofInt32)
    // Confirm Message.clear() handles the oneof correctly.
    msg.clear()
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 300
    XCTAssertTrue(msg.oneof !== autoCreated)  // New instance
    XCTAssertTrue(msg.oneof !== autoCreated2)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(300))
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofMessage)
    // Set message to nil clears the oneof.
    msg.oneof = nil
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
  }
  func testSerialization() {
    let msg = Message2()
    msg.optionalInt32 = 100
    msg.optionalInt64 = 101
    msg.optionalGroup.a = 102
    msg.repeatedStringArray.add("abc")
    msg.repeatedStringArray.add("def")
    msg.mapInt32Int32.setInt32(200, forKey:300)
    msg.mapInt32Int32.setInt32(201, forKey:201)
    msg.mapStringString.setObject("foo", forKey:"bar" as NSString)
    msg.mapStringString.setObject("abc", forKey:"xyz" as NSString)
    let data = msg.data()
    let msg2 = try! Message2(data: data!)
    XCTAssertTrue(msg2 !== msg)  // New instance
    XCTAssertEqual(msg.optionalInt32, Int32(100))
    XCTAssertEqual(msg.optionalInt64, Int64(101))
    XCTAssertEqual(msg.optionalGroup.a, Int32(102))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
    XCTAssertEqual(msg.mapStringString.count, Int(2))
    XCTAssertEqual(msg2, msg)
  }
}


TFLBertTokenizerTest

class TFLBertTokenizerTest: XCTestCase {
  static let bundle = Bundle(for: TFLBertTokenizerTest.self)
  static let mobileBertVocabPath = bundle.path(forResource: "mobilebert_vocab", ofType: "txt")!
  func testInitBertTokenizerFromPath() {
    let bertTokenizer = TFLBertTokenizer(vocabPath: TFLBertTokenizerTest.mobileBertVocabPath)
    XCTAssertNotNil(bertTokenizer)
    let tokens = bertTokenizer.tokens(fromInput: "i'm questionansweraskask")
    XCTAssertEqual(tokens, ["i", "'", "m", "question", "##ans", "##wer", "##ask", "##ask"])
    let ids = bertTokenizer.ids(fromTokens: tokens)
    XCTAssertEqual(ids, [1045, 1005, 1049, 3160, 6962, 13777, 19895, 19895])
  }
  func testInitBertTokenizerFromVocab() {
    let bertTokenizer = TFLBertTokenizer(vocab: ["hell", "##o", "wor", "##ld", "there"])
    XCTAssertNotNil(bertTokenizer)
    let tokens = bertTokenizer.tokens(fromInput: "hello there hello world")
    XCTAssertEqual(tokens, ["hell", "##o", "there", "hell", "##o", "wor", "##ld"])
    let ids = bertTokenizer.ids(fromTokens: tokens)
    XCTAssertEqual(ids, [0, 1, 4, 0, 1, 2, 3])
  }
}


TFLSentencepieceTokenizerTest

class TFLSentencepieceTokenizerTest: XCTestCase {
  static let bundle = Bundle(for: TFLSentencepieceTokenizerTest.self)
  static let spModelPath = bundle.path(forResource: "30k-clean", ofType: "model")!
  func testInitSentenpieceTokenizerFromPath() {
    let spTokenizer = TFLSentencepieceTokenizer(
      modelPath: TFLSentencepieceTokenizerTest.spModelPath)
    XCTAssertNotNil(spTokenizer)
    let tokens = spTokenizer.tokens(fromInput: "good morning, i'm your teacher.\n")
    XCTAssertEqual(tokens, ["▁good", "▁morning", ",", "▁i", "'", "m", "▁your", "▁teacher", "."])
    let ids = spTokenizer.ids(fromTokens: tokens)
    XCTAssertEqual(ids, [254, 959, 15, 31, 22, 79, 154, 2197, 9])
  }
}


TFLAudioClassifierTests

class AudioClassifierTests: XCTestCase {
  static let bundle = Bundle(for: AudioClassifierTests.self)
  static let modelPath = bundle.path(
    forResource: "yamnet_audio_classifier_with_metadata",
    ofType: "tflite")
  func verifyError(
    _ error: Error,
    expectedLocalizedDescription: String
  ) {
    XCTAssertEqual(
      error.localizedDescription,
      expectedLocalizedDescription)
  }
  func verifyCategory(
    _ category: ClassificationCategory,
    expectedIndex: NSInteger,
    expectedScore: Float,
    expectedLabel: String,
    expectedDisplayName: String?
  ) {
    XCTAssertEqual(
      category.index,
      expectedIndex)
    XCTAssertEqual(
      category.score,
      expectedScore,
      accuracy: 1e-6)
    XCTAssertEqual(
      category.label,
      expectedLabel)
    XCTAssertEqual(
      category.displayName,
      expectedDisplayName)
  }
  func verifyClassifications(
    _ classifications: Classifications,
    expectedHeadIndex: NSInteger,
    expectedCategoryCount: NSInteger
  ) {
    XCTAssertEqual(
      classifications.headIndex,
      expectedHeadIndex)
    XCTAssertEqual(
      classifications.categories.count,
      expectedCategoryCount)
  }
  func verifyClassificationResult(
    _ classificationResult: ClassificationResult,
    expectedClassificationsCount: NSInteger
  ) {
    XCTAssertEqual(
      classificationResult.classifications.count,
      expectedClassificationsCount)
  }
  func bufferFromFile(
    withName name: String,
    fileExtension: String,
    audioFormat: AudioFormat
  ) -> AVAudioPCMBuffer? {
    guard
      let filePath = AudioClassifierTests.bundle.path(
        forResource: name,
        ofType: fileExtension)
    else {
      return nil
    }
    return AVAudioPCMBuffer.loadPCMBufferFromFile(
      withPath: filePath,
      audioFormat: audioFormat)
  }
  func createAudioClassifierOptions(
    modelPath: String?
  ) throws -> AudioClassifierOptions? {
    let modelPath = try XCTUnwrap(modelPath)
    let options = AudioClassifierOptions(modelPath: modelPath)
    return options
  }
  func createAudioClassifier(
    withModelPath modelPath: String?
  ) throws -> AudioClassifier? {
    let options = try XCTUnwrap(
      self.createAudioClassifierOptions(
        modelPath: AudioClassifierTests.modelPath))
    let audioClassifier = try XCTUnwrap(
      AudioClassifier.classifier(
        options: options))
    return audioClassifier
  }
  func createAudioTensor(
    withAudioClassifier audioClassifier: AudioClassifier
  ) -> AudioTensor {
    let audioTensor = audioClassifier.createInputAudioTensor()
    return audioTensor
  }
  func loadAudioTensor(
    _ audioTensor: AudioTensor,
    fromWavFileWithName fileName: String
  ) throws {
    // Load pcm buffer from file.
    let buffer = try XCTUnwrap(
      self.bufferFromFile(
        withName: fileName,
        fileExtension: "wav",
        audioFormat: audioTensor.audioFormat))
    // Get float buffer from pcm buffer.
    let floatBuffer = try XCTUnwrap(buffer.floatBuffer)
    // Load float buffer into the audio tensor.
    try audioTensor.load(
      buffer: floatBuffer,
      offset: 0,
      size: floatBuffer.size)
  }
  func classify(
    audioTensor: AudioTensor,
    usingAudioClassifier audioClassifier: AudioClassifier
  ) throws -> ClassificationResult? {
    let classificationResult = try XCTUnwrap(
      audioClassifier.classify(
        audioTensor: audioTensor))
    let expectedClassificationsCount = 1
    self.verifyClassificationResult(
      classificationResult,
      expectedClassificationsCount: expectedClassificationsCount)
    let expectedCategoryCount = 521
    let expectedHeadIndex = 0
    self.verifyClassifications(
      classificationResult.classifications[0],
      expectedHeadIndex: expectedHeadIndex,
      expectedCategoryCount: expectedCategoryCount)
    return classificationResult
  }
  func validateForInferenceWithFloatBuffer(
    categories: [ClassificationCategory]
  ) {
    self.verifyCategory(
      categories[0],
      expectedIndex: 0,
      expectedScore: 0.957031,
      expectedLabel: "Speech",
      expectedDisplayName: nil)
    self.verifyCategory(
      categories[1],
      expectedIndex: 500,
      0.019531,               // expectedScore
      expectedLabel: "Inside, small room",
      expectedDisplayName: nil)
  }
  func testInferenceWithFloatBufferSucceeds() throws {
    let audioClassifier = try XCTUnwrap(
      self.createAudioClassifier(
        withModelPath: AudioClassifierTests.modelPath))
    let audioTensor = self.createAudioTensor(
      withAudioClassifier: audioClassifier)
    try self.loadAudioTensor(
      audioTensor, fromWavFileWithName: "speech")
    let classificationResult = try XCTUnwrap(
      self.classify(
        audioTensor: audioTensor,
        usingAudioClassifier: audioClassifier))
    self.validateForInferenceWithFloatBuffer(
      categories: classificationResult.classifications[0].categories)
  }
  func testInferenceWithNoModelPathFails() throws {
    let options = AudioClassifierOptions()
    do {
      let audioClassifier = try AudioClassifier.classifier(
        options: options)
      XCTAssertNil(audioClassifier)
    } catch {
      self.verifyError(
        error,
        expectedLocalizedDescription:
          "INVALID_ARGUMENT: Missing mandatory `model_file` field in `base_options`")
    }
  }
}


TFLImageSegmenterTests

class ImageSegmenterTests: XCTestCase {
  static let bundle = Bundle(for: ImageSegmenterTests.self)
  static let modelPath = bundle.path(
    forResource: "deeplabv3",
    ofType: "tflite")
  // The maximum fraction of pixels in the candidate mask that can have a
  // different class than the golden mask for the test to pass.
  let kGoldenMaskTolerance: Float = 1e-2
  // Magnification factor used when creating the golden category masks to make
  // them more human-friendly. Each pixel in the golden masks has its value
  // multiplied by this factor, i.e. a value of 10 means class index 1, a value of
  // 20 means class index 2, etc.
  let kGoldenMaskMagnificationFactor: UInt8 = 10
  let deepLabV3SegmentationWidth = 257
  let deepLabV3SegmentationHeight = 257
  func verifyDeeplabV3PartialSegmentationResult(_ coloredLabels: [ColoredLabel]) {
    self.verifyColoredLabel(
      coloredLabels[0],
      expectedR: 0,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "background")
    self.verifyColoredLabel(
      coloredLabels[1],
      expectedR: 128,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "aeroplane")
    self.verifyColoredLabel(
      coloredLabels[2],
      expectedR: 0,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "bicycle")
    self.verifyColoredLabel(
      coloredLabels[3],
      expectedR: 128,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "bird")
    self.verifyColoredLabel(
      coloredLabels[4],
      expectedR: 0,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "boat")
    self.verifyColoredLabel(
      coloredLabels[5],
      expectedR: 128,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "bottle")
    self.verifyColoredLabel(
      coloredLabels[6],
      expectedR: 0,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "bus")
    self.verifyColoredLabel(
      coloredLabels[7],
      expectedR: 128,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "car")
    self.verifyColoredLabel(
      coloredLabels[8],
      expectedR: 64,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "cat")
    self.verifyColoredLabel(
      coloredLabels[9],
      expectedR: 192,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "chair")
    self.verifyColoredLabel(
      coloredLabels[10],
      expectedR: 64,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "cow")
    self.verifyColoredLabel(
      coloredLabels[11],
      expectedR: 192,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "dining table")
    self.verifyColoredLabel(
      coloredLabels[12],
      expectedR: 64,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "dog")
    self.verifyColoredLabel(
      coloredLabels[13],
      expectedR: 192,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "horse")
    self.verifyColoredLabel(
      coloredLabels[14],
      expectedR: 64,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "motorbike")
    self.verifyColoredLabel(
      coloredLabels[15],
      expectedR: 192,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "person")
    self.verifyColoredLabel(
      coloredLabels[16],
      expectedR: 0,
      expectedG: 64,
      expectedB: 0,
      expectedLabel: "potted plant")
    self.verifyColoredLabel(
      coloredLabels[17],
      expectedR: 128,
      expectedG: 64,
      expectedB: 0,
      expectedLabel: "sheep")
    self.verifyColoredLabel(
      coloredLabels[18],
      expectedR: 0,
      expectedG: 192,
      expectedB: 0,
      expectedLabel: "sofa")
    self.verifyColoredLabel(
      coloredLabels[19],
      expectedR: 128,
      expectedG: 192,
      expectedB: 0,
      expectedLabel: "train")
    self.verifyColoredLabel(
      coloredLabels[20],
      expectedR: 0,
      expectedG: 64,
      expectedB: 128,
      expectedLabel: "tv")
  }
  func verifyColoredLabel(
    _ coloredLabel: ColoredLabel,
    expectedR: UInt,
    expectedG: UInt,
    expectedB: UInt,
    expectedLabel: String
  ) {
    XCTAssertEqual(
      coloredLabel.r,
      expectedR)
    XCTAssertEqual(
      coloredLabel.g,
      expectedG)
    XCTAssertEqual(
      coloredLabel.b,
      expectedB)
    XCTAssertEqual(
      coloredLabel.label,
      expectedLabel)
  }
  func testSuccessfullInferenceOnMLImageWithUIImage() throws {
    let modelPath = try XCTUnwrap(ImageSegmenterTests.modelPath)
    let imageSegmenterOptions = ImageSegmenterOptions(modelPath: modelPath)
    let imageSegmenter =
      try ImageSegmenter.segmenter(options: imageSegmenterOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "segmentation_input_rotation0",
        type: "jpg"))
    let segmentationResult: SegmentationResult =
      try XCTUnwrap(imageSegmenter.segment(mlImage: gmlImage))
    XCTAssertEqual(segmentationResult.segmentations.count, 1)
    let coloredLabels = try XCTUnwrap(segmentationResult.segmentations[0].coloredLabels)
    verifyDeeplabV3PartialSegmentationResult(coloredLabels)
    let categoryMask = try XCTUnwrap(segmentationResult.segmentations[0].categoryMask)
    XCTAssertEqual(deepLabV3SegmentationWidth, categoryMask.width)
    XCTAssertEqual(deepLabV3SegmentationHeight, categoryMask.height)
    let goldenMaskImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "segmentation_golden_rotation0",
        type: "png"))
    let pixelBuffer = goldenMaskImage.grayScalePixelBuffer().takeRetainedValue()
    CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.readOnly)
    let pixelBufferBaseAddress = (try XCTUnwrap(CVPixelBufferGetBaseAddress(pixelBuffer)))
      .assumingMemoryBound(to: UInt8.self)
    let numPixels = deepLabV3SegmentationWidth * deepLabV3SegmentationHeight
    let mask = try XCTUnwrap(categoryMask.mask)
    var inconsistentPixels: Float = 0.0
    for i in 0..<numPixels {
      if mask[i] * kGoldenMaskMagnificationFactor != pixelBufferBaseAddress[i] {
        inconsistentPixels += 1
      }
    }
    CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.readOnly)
    XCTAssertLessThan(inconsistentPixels / Float(numPixels), kGoldenMaskTolerance)
  }
}


TFLObjectDetectorTests

class ObjectDetectorTests: XCTestCase {
  static let bundle = Bundle(for: ObjectDetectorTests.self)
  static let modelPath = bundle.path(
    forResource: "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29",
    ofType: "tflite")
  func verifyDetectionResult(_ detectionResult: DetectionResult) {
    XCTAssertGreaterThan(detectionResult.detections.count, 0)
    self.verifyDetection(
      detectionResult.detections[0],
      expectedBoundingBox: CGRect(x: 54, y: 396, width: 393, height: 199),
      expectedFirstScore: 0.632812,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[1],
      expectedBoundingBox: CGRect(x: 602, y: 157, width: 394, height: 447),
      expectedFirstScore: 0.609375,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[2],
      expectedBoundingBox: CGRect(x: 260, y: 394, width: 179, height: 209),
      expectedFirstScore: 0.5625,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[3],
      expectedBoundingBox: CGRect(x: 387, y: 197, width: 281, height: 409),
      expectedFirstScore: 0.488281,
      expectedFirstLabel: "dog")
  }
  func verifyDetection(
    _ detection: Detection, expectedBoundingBox: CGRect,
    expectedFirstScore: Float,
    expectedFirstLabel: String
  ) {
    XCTAssertGreaterThan(detection.categories.count, 0)
    XCTAssertEqual(
      detection.boundingBox.origin.x,
      expectedBoundingBox.origin.x)
    XCTAssertEqual(
      detection.boundingBox.origin.y,
      expectedBoundingBox.origin.y)
    XCTAssertEqual(
      detection.boundingBox.size.width,
      expectedBoundingBox.size.width)
    XCTAssertEqual(
      detection.boundingBox.size.height,
      expectedBoundingBox.size.height)
    XCTAssertEqual(
      detection.categories[0].label,
      expectedFirstLabel)
    XCTAssertEqual(
      detection.categories[0].score,
      expectedFirstScore, accuracy: 0.001)
  }
  func testSuccessfullInferenceOnMLImageWithUIImage() throws {
    let modelPath = try XCTUnwrap(ObjectDetectorTests.modelPath)
    let objectDetectorOptions = ObjectDetectorOptions(modelPath: modelPath)
    let objectDetector =
      try ObjectDetector.detector(options: objectDetectorOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "cats_and_dogs",
        type: "jpg"))
    let detectionResults: DetectionResult =
      try objectDetector.detect(mlImage: gmlImage)
    self.verifyDetectionResult(detectionResults)
  }
  func testModelOptionsWithMaxResults() throws {
    let modelPath = try XCTUnwrap(ObjectDetectorTests.modelPath)
    let objectDetectorOptions = ObjectDetectorOptions(modelPath: modelPath)
    let maxResults = 3
    objectDetectorOptions.classificationOptions.maxResults = maxResults
    let objectDetector =
      try ObjectDetector.detector(options: objectDetectorOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "cats_and_dogs",
        type: "jpg"))
    let detectionResult: DetectionResult = try objectDetector.detect(
      mlImage: gmlImage)
    XCTAssertLessThanOrEqual(detectionResult.detections.count, maxResults)
    self.verifyDetection(
      detectionResult.detections[0],
      expectedBoundingBox: CGRect(x: 54, y: 396, width: 393, height: 199),
      expectedFirstScore: 0.632812,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[1],
      expectedBoundingBox: CGRect(x: 602, y: 157, width: 394, height: 447),
      expectedFirstScore: 0.609375,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[2],
      expectedBoundingBox: CGRect(x: 260, y: 394, width: 179, height: 209),
      expectedFirstScore: 0.5625,
      expectedFirstLabel: "cat")
  }
}


TFLImageClassifierTests

class ImageClassifierTests: XCTestCase {
  static let bundle = Bundle(for: ImageClassifierTests.self)
  static let modelPath = bundle.path(
    forResource: "mobilenet_v2_1.0_224",
    ofType: "tflite")
  func testSuccessfullInferenceOnMLImageWithUIImage() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "burger",
        type: "jpg"))
    let classificationResults: ClassificationResult =
      try imageClassifier.classify(mlImage: gmlImage)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertGreaterThan(classificationResults.classifications[0].categories.count, 0)
    // TODO: match the score as image_classifier_test.cc
    let category = classificationResults.classifications[0].categories[0]
    XCTAssertEqual(category.label, "cheeseburger")
    XCTAssertEqual(category.score, 0.748976, accuracy: 0.001)
  }
  func testModelOptionsWithMaxResults() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let maxResults = 3
    imageClassifierOptions.classificationOptions.maxResults = maxResults
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "burger",
        type: "jpg"))
    let classificationResults: ClassificationResult = try imageClassifier.classify(
      mlImage: gmlImage)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertLessThanOrEqual(classificationResults.classifications[0].categories.count, maxResults)
    // TODO: match the score as image_classifier_test.cc
    let category = classificationResults.classifications[0].categories[0]
    XCTAssertEqual(category.label, "cheeseburger")
    XCTAssertEqual(category.score, 0.748976, accuracy: 0.001)
  }
  func testInferenceWithBoundingBox() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "multi_objects",
        type: "jpg"))
    let roi = CGRect(x: 406, y: 110, width: 148, height: 153)
    let classificationResults =
      try imageClassifier.classify(mlImage: gmlImage, regionOfInterest: roi)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertGreaterThan(classificationResults.classifications[0].categories.count, 0)
    // TODO: match the label and score as image_classifier_test.cc
    // let category = classificationResults.classifications[0].categories[0]
    // XCTAssertEqual(category.label, "soccer ball")
    // XCTAssertEqual(category.score, 0.256512, accuracy:0.001);
  }
  func testInferenceWithRGBAImage() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "sparrow",
        type: "png"))
    let classificationResults =
      try imageClassifier.classify(mlImage: gmlImage)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertGreaterThan(classificationResults.classifications[0].categories.count, 0)
    let category = classificationResults.classifications[0].categories[0]
    XCTAssertEqual(category.label, "junco")
    XCTAssertEqual(category.score, 0.253016, accuracy: 0.001)
  }
}


TFLNLClassifierTest

class TFLNLClassifierTest: XCTestCase {
  static let bundle = Bundle(for: TFLNLClassifierTest.self)
  static let modelPath = bundle.path(
    forResource: "test_model_nl_classifier_with_regex_tokenizer",
    ofType: "tflite")!
  var modelOptions:TFLNLClassifierOptions!;
  override func setUp() {
    modelOptions = TFLNLClassifierOptions()
    modelOptions.inputTensorName = "input_text"
    modelOptions.outputScoreTensorName = "probability"
  }
  func testClassifyPositiveResult() {
    let nlClassifier = TFLNLClassifier.nlClassifier(
      modelPath: TFLNLClassifierTest.modelPath,
      options: modelOptions)
    XCTAssertNotNil(nlClassifier)
    let categories = nlClassifier.classify(
      text: "This is the best movie I’ve seen in recent years. Strongly recommend it!")
    XCTAssertGreaterThan(categories["Positive"]!.doubleValue, categories["Negative"]!.doubleValue)
  }
   func testClassifyNegativeResult() {
     let nlClassifier = TFLNLClassifier.nlClassifier(
       modelPath: TFLNLClassifierTest.modelPath,
       options: modelOptions)
     XCTAssertNotNil(nlClassifier)
     let categories = nlClassifier.classify(text: "What a waste of my time.")
     XCTAssertGreaterThan(categories["Negative"]!.doubleValue, categories["Positive"]!.doubleValue)
   }
}


TFLBertNLClassifierTest

class TFLBertNLClassifierTest: XCTestCase {
  static let bundle = Bundle(for: TFLBertNLClassifierTest.self)
  static let bertModelPath = bundle.path(forResource: "bert_nl_classifier", ofType: "tflite")!
  func testClassifyPositiveResult() {
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "it's a charming and often affecting journey")
    XCTAssertGreaterThan(categories["positive"]!.doubleValue, categories["negative"]!.doubleValue)
  }
  func testClassifyNegativeResult() {
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "unflinchingly bleak and desperate")
    XCTAssertGreaterThan(categories["negative"]!.doubleValue, categories["positive"]!.doubleValue)
  }
  func testCreateFromOptionsClassifyPositiveResult() {
    let modelOptions = TFLBertNLClassifierOptions()
    modelOptions.maxSeqLen = 128
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath,
      options: modelOptions)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "it's a charming and often affecting journey")
    XCTAssertGreaterThan(categories["positive"]!.doubleValue, categories["negative"]!.doubleValue)
  }
  func testCreateFromOptionsClassifyNegativeResult() {
    let modelOptions = TFLBertNLClassifierOptions()
    modelOptions.maxSeqLen = 128
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath,
      options: modelOptions)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "unflinchingly bleak and desperate")
    XCTAssertGreaterThan(categories["negative"]!.doubleValue, categories["positive"]!.doubleValue)
  }
}


TFLBertQuestionAnswererTest

class TFLBertQuestionAnswererTest: XCTestCase {
  static let bundle = Bundle(for: TFLBertQuestionAnswererTest.self)
  static let mobileBertModelPath = bundle.path(forResource: "mobilebert_with_metadata", ofType: "tflite")!
  static let albertModelPath = bundle.path(forResource: "albert_with_metadata", ofType: "tflite")!
  static let context = """
    The role of teacher is often formal and ongoing, carried out at a school or other place of
    formal education. In many countries, a person who wishes to become a teacher must first obtain
     specified professional qualifications or credentials from a university or college. These
    professional qualifications may include the study of pedagogy, the science of teaching.
    Teachers, like other professionals, may have to continue their education after they qualify,
    a process known as continuing professional development. Teachers may use a lesson plan to
    facilitate student learning, providing a course of study which is called the curriculum.
    """
  static let question = "What is a course of study called?"
  static let answer = "the curriculum."
  func testInitMobileBert() {
    let mobileBertAnswerer = TFLBertQuestionAnswerer.questionAnswerer(
      modelPath: TFLBertQuestionAnswererTest.mobileBertModelPath)
    XCTAssertNotNil(mobileBertAnswerer)
    let answers = mobileBertAnswerer.answer(
      context: TFLBertQuestionAnswererTest.context, question: TFLBertQuestionAnswererTest.question)
    XCTAssertNotNil(answers)
    XCTAssertEqual(answers[0].text, TFLBertQuestionAnswererTest.answer)
  }
  func testInitAlbert() {
    let albertAnswerer = TFLBertQuestionAnswerer.questionAnswerer(
      modelPath: TFLBertQuestionAnswererTest.albertModelPath)
    XCTAssertNotNil(albertAnswerer)
    let answers = albertAnswerer.answer(
      context: TFLBertQuestionAnswererTest.context, question: TFLBertQuestionAnswererTest.question)
    XCTAssertNotNil(answers)
    XCTAssertEqual(answers[0].text, TFLBertQuestionAnswererTest.answer)
  }
}


file

import Foundation

public class GypSwiftTest {
  let myProperty = false

  init() {
    self.myProperty = true
  }
}


Package

// swift-tools-version:5.6

import PackageDescription

let package = Package(
    name: "Antlr4",
    products: [
        .library(
            name: "Antlr4",
            targets: ["Antlr4"]),
        .library(
            name: "Antlr4Static",
            type: .static,
            targets: ["Antlr4"]),
    ],
    targets: [
        .target(
            name: "Antlr4",
            dependencies: [],
            path: "./runtime/Swift/Sources/Antlr4"),
        .testTarget(
            name: "Antlr4Tests",
            dependencies: ["Antlr4"],
            path: "./runtime/Swift/Tests/Antlr4Tests",
            exclude: [
                "./runtime/Swift/Tests/VisitorBasic.g4",
                "./runtime/Swift/Tests/VisitorCalc.g4",
                "./runtime/Swift/Tests/LexerA.g4",
                "./runtime/Swift/Tests/LexerB.g4",
                "./runtime/Swift/Tests/Threading.g4"
            ]
        )
    ]
)


InterpreterRuleContext

///
///
///
/// This class extends _org.antlr.v4.runtime.ParserRuleContext_ by allowing the value of
/// _#getRuleIndex_ to be explicitly set for the context.
///
///
/// _org.antlr.v4.runtime.ParserRuleContext_ does not include field storage for the rule index
/// since the context classes created by the code generator override the
/// _#getRuleIndex_ method to return the correct value for that context.
/// Since the parser interpreter does not use the context classes generated for a
/// parser, this class (with slightly more memory overhead per node) is used to
/// provide equivalent functionality.
///
public class InterpreterRuleContext: ParserRuleContext {
    ///
    /// This is the backing field for _#getRuleIndex_.
    ///
    private var ruleIndex: Int = -1
    public override init() {
        super.init()
    }
    ///
    /// Constructs a new _org.antlr.v4.runtime.InterpreterRuleContext_ with the specified
    /// parent, invoking state, and rule index.
    ///
    /// - parameter parent: The parent context.
    /// - parameter invokingStateNumber: The invoking state number.
    /// - parameter ruleIndex: The rule index for the current context.
    ///
    public init(_ parent: ParserRuleContext?,
                _ invokingStateNumber: Int,
                _ ruleIndex: Int) {
        self.ruleIndex = ruleIndex
        super.init(parent, invokingStateNumber)
    }
    override
    public func getRuleIndex() -> Int {
        return ruleIndex
    }
    ///
    /// Copy a _org.antlr.v4.runtime.ParserRuleContext_ or _org.antlr.v4.runtime.InterpreterRuleContext_
    /// stack to a _org.antlr.v4.runtime.InterpreterRuleContext_ tree.
    /// Return _null_ if `ctx` is null.
    ///
    public static func fromParserRuleContext(_ ctx: ParserRuleContext?) -> InterpreterRuleContext? {
        guard let ctx = ctx else {
             return nil
        }
        let dup: InterpreterRuleContext = InterpreterRuleContext()
        dup.copyFrom(ctx)
        dup.ruleIndex = ctx.getRuleIndex()
        dup.parent = fromParserRuleContext(ctx.getParent() as? ParserRuleContext)
        return dup
    }
}


WritableToken

 */
public protocol WritableToken: Token {
    func setText(_ text: String)
    func setType(_ ttype: Int)
    func setLine(_ line: Int)
    func setCharPositionInLine(_ pos: Int)
    func setChannel(_ channel: Int)
    func setTokenIndex(_ index: Int)
}


TokenFactory

 */
/// The default mechanism for creating tokens. It's used by default in Lexer and
/// the error handling strategy (to create missing tokens).  Notifying the parser
/// of a new factory means that it notifies it's token source and error strategy.
///
public protocol TokenFactory {
    //typealias Symbol
    /// This is the method used to create tokens in the lexer and in the
    /// error handling strategy. If text!=null, than the start and stop positions
    /// are wiped to -1 in the text override is set in the CommonToken.
    ///
    func create(_ source: TokenSourceAndStream, _ type: Int, _ text: String?,
                _ channel: Int, _ start: Int, _ stop: Int,
                _ line: Int, _ charPositionInLine: Int) -> Token
    /// Generically useful
    func create(_ type: Int, _ text: String) -> Token
}
/**
 Holds the references to the TokenSource and CharStream used to create a Token.
 These are together to reduce memory footprint by having one instance of
 TokenSourceAndStream shared across many tokens.  The references here are weak
 to avoid retain cycles.
 */
public class TokenSourceAndStream {
    ///
    /// An empty TokenSourceAndStream which is used as the default value of
    /// _#source_ for tokens that do not have a source.
    ///
    public static let EMPTY = TokenSourceAndStream()
    public weak var tokenSource: TokenSource?
    public weak var stream: CharStream?
    public init(_ tokenSource: TokenSource? = nil, _ stream: CharStream? = nil) {
        self.tokenSource = tokenSource
        self.stream = stream
    }
}


ProxyErrorListener

 */
///
/// This implementation of _org.antlr.v4.runtime.ANTLRErrorListener_ dispatches all calls to a
/// collection of delegate listeners. This reduces the effort required to support multiple
/// listeners.
///
/// - Author: Sam Harwell
///
public class ProxyErrorListener: ANTLRErrorListener {
    private final var delegates: [ANTLRErrorListener]
    public init(_ delegates: [ANTLRErrorListener]) {
        self.delegates = delegates
    }
    public func syntaxError<T>(_ recognizer: Recognizer<T>,
                               _ offendingSymbol: AnyObject?,
                               _ line: Int,
                               _ charPositionInLine: Int,
                               _ msg: String,
                               _ e: AnyObject?)
    {
        for listener in delegates {
            listener.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e)
        }
    }
    public func reportAmbiguity(_ recognizer: Parser,
                                _ dfa: DFA,
                                _ startIndex: Int,
                                _ stopIndex: Int,
                                _ exact: Bool,
                                _ ambigAlts: BitSet,
                                _ configs: ATNConfigSet) {
        for listener in delegates {
            listener.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs)
        }
    }
    public func reportAttemptingFullContext(_ recognizer: Parser,
                                            _ dfa: DFA,
                                            _ startIndex: Int,
                                            _ stopIndex: Int,
                                            _ conflictingAlts: BitSet?,
                                            _ configs: ATNConfigSet) {
        for listener in delegates {
            listener.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs)
        }
    }
    public func reportContextSensitivity(_ recognizer: Parser,
                                         _ dfa: DFA,
                                         _ startIndex: Int,
                                         _ stopIndex: Int,
                                         _ prediction: Int,
                                         _ configs: ATNConfigSet) {
        for listener in delegates {
            listener.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs)
        }
    }
}


ANTLRFileStream

///
/// This is an _org.antlr.v4.runtime.ANTLRInputStream_ that is loaded from a file all at once
/// when you construct the object.
///
import Foundation
public class ANTLRFileStream: ANTLRInputStream {
    private let fileName: String
    public init(_ fileName: String, _ encoding: String.Encoding? = nil) throws {
        self.fileName = fileName
        let fileContents = try String(contentsOfFile: fileName, encoding: encoding ?? .utf8)
        let data = Array(fileContents.unicodeScalars)
        super.init(data, data.count)
    }
    override
    public func getSourceName() -> String {
        return fileName
    }
}


BaseErrorListener

///
///
///
/// Provides an empty default implementation of _org.antlr.v4.runtime.ANTLRErrorListener_. The
/// default implementation of each method does nothing, but can be overridden as
/// necessary.
///
/// -  Sam Harwell
///
open class BaseErrorListener: ANTLRErrorListener {
    public init() {
    }
    open func syntaxError<T>(_ recognizer: Recognizer<T>,
                             _ offendingSymbol: AnyObject?,
                             _ line: Int,
                             _ charPositionInLine: Int,
                             _ msg: String,
                             _ e: AnyObject?
    ) {
    }
    open func reportAmbiguity(_ recognizer: Parser,
                                _ dfa: DFA,
                                _ startIndex: Int,
                                _ stopIndex: Int,
                                _ exact: Bool,
                                _ ambigAlts: BitSet,
                                _ configs: ATNConfigSet) {
    }
    open func reportAttemptingFullContext(_ recognizer: Parser,
                                            _ dfa: DFA,
                                            _ startIndex: Int,
                                            _ stopIndex: Int,
                                            _ conflictingAlts: BitSet?,
                                            _ configs: ATNConfigSet) {
    }
    open func reportContextSensitivity(_ recognizer: Parser,
                                         _ dfa: DFA,
                                         _ startIndex: Int,
                                         _ stopIndex: Int,
                                         _ prediction: Int,
                                         _ configs: ATNConfigSet) {
    }
}


CommonTokenStream

///
///
///
/// This class extends _org.antlr.v4.runtime.BufferedTokenStream_ with functionality to filter
/// token streams to tokens on a particular channel (tokens where
/// _org.antlr.v4.runtime.Token#getChannel_ returns a particular value).
///
///
/// This token stream provides access to all tokens by index or when calling
/// methods like _#getText_. The channel filtering is only used for code
/// accessing tokens via the lookahead methods _#LA_, _#LT_, and
/// _#LB_.
///
///
/// By default, tokens are placed on the default channel
/// (_org.antlr.v4.runtime.Token#DEFAULT_CHANNEL_), but may be reassigned by using the
/// `->channel(HIDDEN)` lexer command, or by using an embedded action to
/// call _org.antlr.v4.runtime.Lexer#setChannel_.
///
///
///
/// Note: lexer rules which use the `->skip` lexer command or call
/// _org.antlr.v4.runtime.Lexer#skip_ do not produce tokens at all, so input text matched by
/// such a rule will not be available as part of the token stream, regardless of
/// channel.
///
public class CommonTokenStream: BufferedTokenStream {
    ///
    /// Specifies the channel to use for filtering tokens.
    ///
    ///
    /// The default value is _org.antlr.v4.runtime.Token#DEFAULT_CHANNEL_, which matches the
    /// default channel assigned to tokens created by the lexer.
    ///
    internal var channel = CommonToken.DEFAULT_CHANNEL
    ///
    /// Constructs a new _org.antlr.v4.runtime.CommonTokenStream_ using the specified token
    /// source and the default token channel (_org.antlr.v4.runtime.Token#DEFAULT_CHANNEL_).
    ///
    /// - parameter tokenSource: The token source.
    ///
    public override init(_ tokenSource: TokenSource) {
        super.init(tokenSource)
    }
    ///
    /// Constructs a new _org.antlr.v4.runtime.CommonTokenStream_ using the specified token
    /// source and filtering tokens to the specified channel. Only tokens whose
    /// _org.antlr.v4.runtime.Token#getChannel_ matches `channel` or have the
    /// _org.antlr.v4.runtime.Token#getType_ equal to _org.antlr.v4.runtime.Token#EOF_ will be returned by the
    /// token stream lookahead methods.
    ///
    /// - parameter tokenSource: The token source.
    /// - parameter channel: The channel to use for filtering tokens.
    ///
    public convenience init(_ tokenSource: TokenSource, _ channel: Int) {
        self.init(tokenSource)
        self.channel = channel
    }
    override
    internal func adjustSeekIndex(_ i: Int) throws -> Int {
        return try nextTokenOnChannel(i, channel)
    }
    override
    internal func LB(_ k: Int) throws -> Token? {
        if k == 0 || (p - k) < 0 {
            return nil
        }
        var i = p
        var n = 1
        // find k good tokens looking backwards
        while n <= k {
            // skip off-channel tokens
            try i = previousTokenOnChannel(i - 1, channel)
            n += 1
        }
        if i < 0 {
            return nil
        }
        return tokens[i]
    }
    override
    public func LT(_ k: Int) throws -> Token? {
        //System.out.println("enter LT("+k+")");
        try lazyInit()
        if k == 0 {
            return nil
        }
        if k < 0 {
            return try LB(-k)
        }
        var i = p
        var n = 1 // we know tokens[p] is a good one
        // find k good tokens
        while n < k {
            // skip off-channel tokens, but make sure to not look past EOF
            if try sync(i + 1) {
                i = try nextTokenOnChannel(i + 1, channel)
            }
            n += 1
        }
//		if ( i>range ) range = i;
        return tokens[i]
    }
    ///
    /// Count EOF just once.
    ///
    public func getNumberOfOnChannelTokens() throws -> Int {
        var n = 0
        try fill()
        for t in tokens {
            if t.getChannel() == channel {
                n += 1
            }
            if t.getType() == CommonToken.EOF {
                break
            }
        }
        return n
    }
}


ANTLRErrorListener

///
/// How to emit recognition errors.
///
public protocol ANTLRErrorListener: AnyObject {
    ///
    /// Upon syntax error, notify any interested parties. This is not how to
    /// recover from errors or compute error messages. _org.antlr.v4.runtime.ANTLRErrorStrategy_
    /// specifies how to recover from syntax errors and how to compute error
    /// messages. This listener's job is simply to emit a computed message,
    /// though it has enough information to create its own message in many cases.
    ///
    /// The _RecognitionException_ is non-null for all syntax errors except
    /// when we discover mismatched token errors that we can recover from
    /// in-line, without returning from the surrounding rule (via the single
    /// token insertion and deletion mechanism).
    ///
    /// - parameter recognizer:
    /// What parser got the error. From this
    /// object, you can access the context as well
    /// as the input stream.
    /// - parameter offendingSymbol:
    /// The offending token in the input token
    /// stream, unless recognizer is a lexer (then it's null). If
    /// no viable alternative error, `e` has token at which we
    /// started production for the decision.
    /// - parameter line:
    /// The line number in the input where the error occurred.
    /// - parameter charPositionInLine:
    /// The character position within that line where the error occurred.
    /// - parameter msg:
    /// The message to emit.
    /// - parameter e:
    /// The exception generated by the parser that led to
    /// the reporting of an error. It is null in the case where
    /// the parser was able to recover in line without exiting the
    /// surrounding rule.
    ///
    func syntaxError<T>(_ recognizer: Recognizer<T>,
                        _ offendingSymbol: AnyObject?,
                        _ line: Int,
                        _ charPositionInLine: Int,
                        _ msg: String,
                        _ e: AnyObject?
    )
    ///
    /// This method is called by the parser when a full-context prediction
    /// results in an ambiguity.
    ///
    /// Each full-context prediction which does not result in a syntax error
    /// will call either _#reportContextSensitivity_ or
    /// _#reportAmbiguity_.
    ///
    /// When `ambigAlts` is not null, it contains the set of potentially
    /// viable alternatives identified by the prediction algorithm. When
    /// `ambigAlts` is null, use _org.antlr.v4.runtime.atn.ATNConfigSet#getAlts_ to obtain the
    /// represented alternatives from the `configs` argument.
    ///
    /// When `exact` is `true`, __all__ of the potentially
    /// viable alternatives are truly viable, i.e. this is reporting an exact
    /// ambiguity. When `exact` is `false`, __at least two__ of
    /// the potentially viable alternatives are viable for the current input, but
    /// the prediction algorithm terminated as soon as it determined that at
    /// least the __minimum__ potentially viable alternative is truly
    /// viable.
    ///
    /// When the _org.antlr.v4.runtime.atn.PredictionMode#LL_EXACT_AMBIG_DETECTION_ prediction
    /// mode is used, the parser is required to identify exact ambiguities so
    /// `exact` will always be `true`.
    ///
    /// This method is not used by lexers.
    ///
    /// - parameter recognizer: the parser instance
    /// - parameter dfa: the DFA for the current decision
    /// - parameter startIndex: the input index where the decision started
    /// - parameter stopIndex: the input input where the ambiguity was identified
    /// - parameter exact: `true` if the ambiguity is exactly known, otherwise
    /// `false`. This is always `true` when
    /// _org.antlr.v4.runtime.atn.PredictionMode#LL_EXACT_AMBIG_DETECTION_ is used.
    /// - parameter ambigAlts: the potentially ambiguous alternatives, or `null`
    /// to indicate that the potentially ambiguous alternatives are the complete
    /// set of represented alternatives in `configs`
    /// - parameter configs: the ATN configuration set where the ambiguity was
    /// identified
    ///
    func reportAmbiguity(_ recognizer: Parser,
                         _ dfa: DFA,
                         _ startIndex: Int,
                         _ stopIndex: Int,
                         _ exact: Bool,
                         _ ambigAlts: BitSet,
                         _ configs: ATNConfigSet)
    ///
    /// This method is called when an SLL conflict occurs and the parser is about
    /// to use the full context information to make an LL decision.
    ///
    /// If one or more configurations in `configs` contains a semantic
    /// predicate, the predicates are evaluated before this method is called. The
    /// subset of alternatives which are still viable after predicates are
    /// evaluated is reported in `conflictingAlts`.
    ///
    /// This method is not used by lexers.
    ///
    /// - parameter recognizer: the parser instance
    /// - parameter dfa: the DFA for the current decision
    /// - parameter startIndex: the input index where the decision started
    /// - parameter stopIndex: the input index where the SLL conflict occurred
    /// - parameter conflictingAlts: The specific conflicting alternatives. If this is
    /// `null`, the conflicting alternatives are all alternatives
    /// represented in `configs`. At the moment, conflictingAlts is non-null
    /// (for the reference implementation, but Sam's optimized version can see this
    /// as null).
    /// - parameter configs: the ATN configuration set where the SLL conflict was
    /// detected
    ///
    func reportAttemptingFullContext(_ recognizer: Parser,
                                     _ dfa: DFA,
                                     _ startIndex: Int,
                                     _ stopIndex: Int,
                                     _ conflictingAlts: BitSet?,
                                     _ configs: ATNConfigSet)
    ///
    /// This method is called by the parser when a full-context prediction has a
    /// unique result.
    ///
    /// Each full-context prediction which does not result in a syntax error
    /// will call either _#reportContextSensitivity_ or
    /// _#reportAmbiguity_.
    ///
    /// For prediction implementations that only evaluate full-context
    /// predictions when an SLL conflict is found (including the default
    /// _org.antlr.v4.runtime.atn.ParserATNSimulator_ implementation), this method reports cases
    /// where SLL conflicts were resolved to unique full-context predictions,
    /// i.e. the decision was context-sensitive. This report does not necessarily
    /// indicate a problem, and it may appear even in completely unambiguous
    /// grammars.
    ///
    /// `configs` may have more than one represented alternative if the
    /// full-context prediction algorithm does not evaluate predicates before
    /// beginning the full-context prediction. In all cases, the final prediction
    /// is passed as the `prediction` argument.
    ///
    /// Note that the definition of "context sensitivity" in this method
    /// differs from the concept in _org.antlr.v4.runtime.atn.DecisionInfo#contextSensitivities_.
    /// This method reports all instances where an SLL conflict occurred but LL
    /// parsing produced a unique result, whether or not that unique result
    /// matches the minimum alternative in the SLL conflicting set.
    ///
    /// This method is not used by lexers.
    ///
    /// - parameter recognizer: the parser instance
    /// - parameter dfa: the DFA for the current decision
    /// - parameter startIndex: the input index where the decision started
    /// - parameter stopIndex: the input index where the context sensitivity was
    /// finally determined
    /// - parameter prediction: the unambiguous result of the full-context prediction
    /// - parameter configs: the ATN configuration set where the unambiguous prediction
    /// was determined
    ///
    func reportContextSensitivity(_ recognizer: Parser,
                                  _ dfa: DFA,
                                  _ startIndex: Int,
                                  _ stopIndex: Int,
                                  _ prediction: Int,
                                  _ configs: ATNConfigSet)
}


ConsoleErrorListener

///
///
///
///
/// -  Sam Harwell
///
public class ConsoleErrorListener: BaseErrorListener {
    ///
    /// Provides a default instance of _org.antlr.v4.runtime.ConsoleErrorListener_.
    ///
    public static let INSTANCE: ConsoleErrorListener = ConsoleErrorListener()
    ///
    ///
    /// This implementation prints messages to _System#err_ containing the
    /// values of `line`, `charPositionInLine`, and `msg` using
    /// the following format.
    ///
    /// line __line__:__charPositionInLine__ __msg__
    ///
    ///
    override public func syntaxError<T>(_ recognizer: Recognizer<T>,
                                        _ offendingSymbol: AnyObject?,
                                        _ line: Int,
                                        _ charPositionInLine: Int,
                                        _ msg: String,
                                        _ e: AnyObject?
    ) {
        if Parser.ConsoleError {
            errPrint("line \(line):\(charPositionInLine) \(msg)")
        }
    }
}


Recognizer

 */
import Foundation
public protocol RecognizerProtocol {
    func getATN() -> ATN
    func getGrammarFileName() -> String
    func getParseInfo() -> ParseInfo?
    func getRuleNames() -> [String]
    func getSerializedATN() -> [Int]
    func getState() -> Int
    func getTokenType(_ tokenName: String) -> Int
    func getVocabulary() -> Vocabulary
}
open class Recognizer<ATNInterpreter: ATNSimulator>: RecognizerProtocol {
    private var _listeners: [ANTLRErrorListener] = [ConsoleErrorListener.INSTANCE]
    public var _interp: ATNInterpreter!
    private var _stateNumber = ATNState.INVALID_STATE_NUMBER
    open func getRuleNames() -> [String] {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Get the vocabulary used by the recognizer.
    ///
    /// - Returns: A _org.antlr.v4.runtime.Vocabulary_ instance providing information about the
    /// vocabulary used by the grammar.
    ///
    open func getVocabulary() -> Vocabulary {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Get a map from token names to token types.
    ///
    /// Used for XPath and tree pattern compilation.
    ///
    public func getTokenTypeMap() -> [String: Int] {
        return tokenTypeMap
    }
    public lazy var tokenTypeMap: [String: Int] = {
        let vocabulary = getVocabulary()
        var result = [String: Int]()
        let length = getATN().maxTokenType
        for i in 0...length {
            if let literalName = vocabulary.getLiteralName(i) {
                result[literalName] = i
            }
            if let symbolicName = vocabulary.getSymbolicName(i) {
                result[symbolicName] = i
            }
        }
        result["EOF"] = CommonToken.EOF
        return result
    }()
    ///
    /// Get a map from rule names to rule indexes.
    ///
    /// Used for XPath and tree pattern compilation.
    ///
    public func getRuleIndexMap() -> [String : Int] {
        return ruleIndexMap
    }
    public lazy var ruleIndexMap: [String: Int] = {
        let ruleNames = getRuleNames()
        return Utils.toMap(ruleNames)
    }()
    public func getTokenType(_ tokenName: String) -> Int {
        return getTokenTypeMap()[tokenName] ?? CommonToken.INVALID_TYPE
    }
    ///
    /// If this recognizer was generated, it will have a serialized ATN
    /// representation of the grammar.
    ///
    /// For interpreters, we don't know their serialized ATN despite having
    /// created the interpreter from it.
    ///
    open func getSerializedATN() -> [Int] {
        fatalError("there is no serialized ATN")
    }
    /// For debugging and other purposes, might want the grammar name.
    /// Have ANTLR generate an implementation for this method.
    ///
    open func getGrammarFileName() -> String {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Get the _org.antlr.v4.runtime.atn.ATN_ used by the recognizer for prediction.
    ///
    /// - Returns: The _org.antlr.v4.runtime.atn.ATN_ used by the recognizer for prediction.
    ///
    open func getATN() -> ATN {
        fatalError(#function + " must be overridden")
    }
    ///
    /// Get the ATN interpreter used by the recognizer for prediction.
    ///
    /// - Returns: The ATN interpreter used by the recognizer for prediction.
    ///
    open func getInterpreter() -> ATNInterpreter {
        return _interp
    }
    /// If profiling during the parse/lex, this will return DecisionInfo records
    /// for each decision in recognizer in a ParseInfo object.
    ///
    /// - Since: 4.3
    ///
    open func getParseInfo() -> ParseInfo? {
        return nil
    }
    ///
    /// Set the ATN interpreter used by the recognizer for prediction.
    ///
    /// - Parameter interpreter: The ATN interpreter used by the recognizer for
    /// prediction.
    ///
    open func setInterpreter(_ interpreter: ATNInterpreter) {
        _interp = interpreter
    }
    ///
    /// What is the error header, normally line/character position information?
    ///
    open func getErrorHeader(_ e: RecognitionException) -> String {
        let offending = e.getOffendingToken()
        let line = offending.getLine()
        let charPositionInLine = offending.getCharPositionInLine()
        return "line \(line):\(charPositionInLine)"
    }
    open func addErrorListener(_ listener: ANTLRErrorListener) {
        _listeners.append(listener)
    }
    open func removeErrorListener(_ listener: ANTLRErrorListener) {
        _listeners = _listeners.filter() {
            $0 !== listener
        }
    }
    open func removeErrorListeners() {
        _listeners.removeAll()
    }
    open func getErrorListeners() -> [ANTLRErrorListener] {
        return _listeners
    }
    open func getErrorListenerDispatch() -> ANTLRErrorListener {
        return ProxyErrorListener(getErrorListeners())
    }
    // subclass needs to override these if there are sempreds or actions
    // that the ATN interp needs to execute
    open func sempred(_ _localctx: RuleContext?, _ ruleIndex: Int, _ actionIndex: Int) throws -> Bool {
        return true
    }
    open func precpred(_ localctx: RuleContext?, _ precedence: Int) -> Bool {
        return true
    }
    open func action(_ _localctx: RuleContext?, _ ruleIndex: Int, _ actionIndex: Int) throws {
    }
    public final func getState() -> Int {
        return _stateNumber
    }
    /// Indicate that the recognizer has changed internal state that is
    /// consistent with the ATN state passed in.  This way we always know
    /// where we are in the ATN as the parser goes along. The rule
    /// context objects form a stack that lets us see the stack of
    /// invoking rules. Combine this and we have complete ATN
    /// configuration information.
    ///
    public final func setState(_ atnState: Int) {
//		System.err.println("setState "+atnState);
        _stateNumber = atnState
//		if ( traceATNStates ) _ctx.trace(atnState);
    }
    open func getInputStream() -> IntStream? {
        fatalError(#function + " must be overridden")
    }
    open func setInputStream(_ input: IntStream) throws {
        fatalError(#function + " must be overridden")
    }
    open func getTokenFactory() -> TokenFactory {
        fatalError(#function + " must be overridden")
    }
    open func setTokenFactory(_ input: TokenFactory) {
        fatalError(#function + " must be overridden")
    }
}


ANTLRErrorStrategy

///
///
///
///
///
///
/// The interface for defining strategies to deal with syntax errors
/// encountered during a parse by ANTLR-generated parsers. We distinguish between three
/// different kinds of errors:
///
/// * The parser could not figure out which path to take in the ATN (none of
/// the available alternatives could possibly match)
/// * The current input does not match what we were looking for
/// * A predicate evaluated to false
///
/// Implementations of this interface report syntax errors by calling
/// _org.antlr.v4.runtime.Parser#notifyErrorListeners_.
///
/// TODO: what to do about lexers
///
public protocol ANTLRErrorStrategy {
    ///
    /// Reset the error handler state for the specified `recognizer`.
    /// - parameter recognizer: the parser instance
    ///
    func reset(_ recognizer: Parser)
    ///
    /// This method is called when an unexpected symbol is encountered during an
    /// inline match operation, such as _org.antlr.v4.runtime.Parser#match_. If the error
    /// strategy successfully recovers from the match failure, this method
    /// returns the _org.antlr.v4.runtime.Token_ instance which should be treated as the
    /// successful result of the match.
    ///
    /// This method handles the consumption of any tokens - the caller should
    /// __not__ call _org.antlr.v4.runtime.Parser#consume_ after a successful recovery.
    ///
    /// Note that the calling code will not report an error if this method
    /// returns successfully. The error strategy implementation is responsible
    /// for calling _org.antlr.v4.runtime.Parser#notifyErrorListeners_ as appropriate.
    ///
    /// - parameter recognizer: the parser instance
    /// - throws: _RecognitionException_ if the error strategy was not able to
    /// recover from the unexpected input symbol
    ///
    func recoverInline(_ recognizer: Parser) throws -> Token
    ///
    /// This method is called to recover from exception `e`. This method is
    /// called after _#reportError_ by the default exception handler
    /// generated for a rule method.
    ///
    /// - seealso: #reportError
    ///
    /// - parameter recognizer: the parser instance
    /// - parameter e: the recognition exception to recover from
    /// - throws: _RecognitionException_ if the error strategy could not recover from
    /// the recognition exception
    ///
    func recover(_ recognizer: Parser, _ e: RecognitionException) throws
    ///
    /// This method provides the error handler with an opportunity to handle
    /// syntactic or semantic errors in the input stream before they result in a
    /// _org.antlr.v4.runtime.RecognitionException_.
    ///
    /// The generated code currently contains calls to _#sync_ after
    /// entering the decision state of a closure block (`(...)*` or
    /// `(...)+`).
    ///
    /// For an implementation based on Jim Idle's "magic sync" mechanism, see
    /// _org.antlr.v4.runtime.DefaultErrorStrategy#sync_.
    ///
    /// - seealso: org.antlr.v4.runtime.DefaultErrorStrategy#sync
    ///
    /// - parameter recognizer: the parser instance
    /// - throws: _RecognitionException_ if an error is detected by the error
    /// strategy but cannot be automatically recovered at the current state in
    /// the parsing process
    ///
    func sync(_ recognizer: Parser) throws
    ///
    /// Tests whether or not recognizer} is in the process of recovering
    /// from an error. In error recovery mode, _org.antlr.v4.runtime.Parser#consume_ adds
    /// symbols to the parse tree by calling
    /// _Parser#createErrorNode(ParserRuleContext, Token)_ then
    /// _ParserRuleContext#addErrorNode(ErrorNode)_ instead of
    /// _Parser#createTerminalNode(ParserRuleContext, Token)_.
    ///
    /// - parameter recognizer: the parser instance
    /// - returns: `true` if the parser is currently recovering from a parse
    /// error, otherwise `false`
    ///
    func inErrorRecoveryMode(_ recognizer: Parser) -> Bool
    ///
    /// This method is called by when the parser successfully matches an input
    /// symbol.
    ///
    /// - parameter recognizer: the parser instance
    ///
    func reportMatch(_ recognizer: Parser)
    ///
    /// Report any kind of _org.antlr.v4.runtime.RecognitionException_. This method is called by
    /// the default exception handler generated for a rule method.
    ///
    /// - parameter recognizer: the parser instance
    /// - parameter e: the recognition exception to report
    ///
    func reportError(_ recognizer: Parser, _ e: RecognitionException)
}