// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// 
// Autogenerated from Pigeon (v7.0.2), do not edit directly.
// See also: https://pub.dev/packages/pigeon

import Foundation
#if os(iOS)
import Flutter
#elseif os(macOS)
import FlutterMacOS
#else
#error("Unsupported platform.")
#endif



private func wrapResult(_ result: Any?) -> [Any?] {
  return [result]
}

private func wrapError(_ error: FlutterError) -> [Any?] {
  return [
    error.code,
    error.message,
    error.details
  ]
}

enum AnEnum: Int {
  case one = 0
  case two = 1
  case three = 2
}

/// Generated class from Pigeon that represents data sent in messages.
struct AllTypes {
  var aBool: Bool
  var anInt: Int32
  var aDouble: Double
  var aByteArray: FlutterStandardTypedData
  var a4ByteArray: FlutterStandardTypedData
  var a8ByteArray: FlutterStandardTypedData
  var aFloatArray: FlutterStandardTypedData
  var aList: [Any?]
  var aMap: [AnyHashable: Any?]
  var anEnum: AnEnum
  var aString: String

  static func fromList(_ list: [Any?]) -> AllTypes? {
    let aBool = list[0] as! Bool
    let anInt = list[1] as! Int32
    let aDouble = list[2] as! Double
    let aByteArray = list[3] as! FlutterStandardTypedData
    let a4ByteArray = list[4] as! FlutterStandardTypedData
    let a8ByteArray = list[5] as! FlutterStandardTypedData
    let aFloatArray = list[6] as! FlutterStandardTypedData
    let aList = list[7] as! [Any?]
    let aMap = list[8] as! [AnyHashable: Any?]
    let anEnum = AnEnum(rawValue: list[9] as! Int)!
    let aString = list[10] as! String

    return AllTypes(
      aBool: aBool,
      anInt: anInt,
      aDouble: aDouble,
      aByteArray: aByteArray,
      a4ByteArray: a4ByteArray,
      a8ByteArray: a8ByteArray,
      aFloatArray: aFloatArray,
      aList: aList,
      aMap: aMap,
      anEnum: anEnum,
      aString: aString
    )
  }
  func toList() -> [Any?] {
    return [
      aBool,
      anInt,
      aDouble,
      aByteArray,
      a4ByteArray,
      a8ByteArray,
      aFloatArray,
      aList,
      aMap,
      anEnum.rawValue,
      aString,
    ]
  }
}

/// Generated class from Pigeon that represents data sent in messages.
struct AllNullableTypes {
  var aNullableBool: Bool? = nil
  var aNullableInt: Int32? = nil
  var aNullableDouble: Double? = nil
  var aNullableByteArray: FlutterStandardTypedData? = nil
  var aNullable4ByteArray: FlutterStandardTypedData? = nil
  var aNullable8ByteArray: FlutterStandardTypedData? = nil
  var aNullableFloatArray: FlutterStandardTypedData? = nil
  var aNullableList: [Any?]? = nil
  var aNullableMap: [AnyHashable: Any?]? = nil
  var nullableNestedList: [[Bool?]?]? = nil
  var nullableMapWithAnnotations: [String?: String?]? = nil
  var nullableMapWithObject: [String?: Any?]? = nil
  var aNullableEnum: AnEnum? = nil
  var aNullableString: String? = nil

  static func fromList(_ list: [Any?]) -> AllNullableTypes? {
    let aNullableBool = list[0] as? Bool 
    let aNullableInt = list[1] as? Int32 
    let aNullableDouble = list[2] as? Double 
    let aNullableByteArray = list[3] as? FlutterStandardTypedData 
    let aNullable4ByteArray = list[4] as? FlutterStandardTypedData 
    let aNullable8ByteArray = list[5] as? FlutterStandardTypedData 
    let aNullableFloatArray = list[6] as? FlutterStandardTypedData 
    let aNullableList = list[7] as? [Any?] 
    let aNullableMap = list[8] as? [AnyHashable: Any?] 
    let nullableNestedList = list[9] as? [[Bool?]?] 
    let nullableMapWithAnnotations = list[10] as? [String?: String?] 
    let nullableMapWithObject = list[11] as? [String?: Any?] 
    var aNullableEnum: AnEnum? = nil
    if let aNullableEnumRawValue = list[12] as? Int {
      aNullableEnum = AnEnum(rawValue: aNullableEnumRawValue)
    }
    let aNullableString = list[13] as? String 

    return AllNullableTypes(
      aNullableBool: aNullableBool,
      aNullableInt: aNullableInt,
      aNullableDouble: aNullableDouble,
      aNullableByteArray: aNullableByteArray,
      aNullable4ByteArray: aNullable4ByteArray,
      aNullable8ByteArray: aNullable8ByteArray,
      aNullableFloatArray: aNullableFloatArray,
      aNullableList: aNullableList,
      aNullableMap: aNullableMap,
      nullableNestedList: nullableNestedList,
      nullableMapWithAnnotations: nullableMapWithAnnotations,
      nullableMapWithObject: nullableMapWithObject,
      aNullableEnum: aNullableEnum,
      aNullableString: aNullableString
    )
  }
  func toList() -> [Any?] {
    return [
      aNullableBool,
      aNullableInt,
      aNullableDouble,
      aNullableByteArray,
      aNullable4ByteArray,
      aNullable8ByteArray,
      aNullableFloatArray,
      aNullableList,
      aNullableMap,
      nullableNestedList,
      nullableMapWithAnnotations,
      nullableMapWithObject,
      aNullableEnum?.rawValue,
      aNullableString,
    ]
  }
}

/// Generated class from Pigeon that represents data sent in messages.
struct AllNullableTypesWrapper {
  var values: AllNullableTypes

  static func fromList(_ list: [Any?]) -> AllNullableTypesWrapper? {
    let values = AllNullableTypes.fromList(list[0] as! [Any?])!

    return AllNullableTypesWrapper(
      values: values
    )
  }
  func toList() -> [Any?] {
    return [
      values.toList(),
    ]
  }
}

private class HostIntegrationCoreApiCodecReader: FlutterStandardReader {
  override func readValue(ofType type: UInt8) -> Any? {
    switch type {
      case 128:
        return AllNullableTypes.fromList(self.readValue() as! [Any])
      case 129:
        return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])
      case 130:
        return AllTypes.fromList(self.readValue() as! [Any])
      default:
        return super.readValue(ofType: type)
    }
  }
}

private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter {
  override func writeValue(_ value: Any) {
    if let value = value as? AllNullableTypes {
      super.writeByte(128)
      super.writeValue(value.toList())
    } else if let value = value as? AllNullableTypesWrapper {
      super.writeByte(129)
      super.writeValue(value.toList())
    } else if let value = value as? AllTypes {
      super.writeByte(130)
      super.writeValue(value.toList())
    } else {
      super.writeValue(value)
    }
  }
}

private class HostIntegrationCoreApiCodecReaderWriter: FlutterStandardReaderWriter {
  override func reader(with data: Data) -> FlutterStandardReader {
    return HostIntegrationCoreApiCodecReader(data: data)
  }

  override func writer(with data: NSMutableData) -> FlutterStandardWriter {
    return HostIntegrationCoreApiCodecWriter(data: data)
  }
}

class HostIntegrationCoreApiCodec: FlutterStandardMessageCodec {
  static let shared = HostIntegrationCoreApiCodec(readerWriter: HostIntegrationCoreApiCodecReaderWriter())
}

/// The core interface that each host language plugin must implement in
/// platform_test integration tests.
///
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol HostIntegrationCoreApi {
  /// A no-op function taking no arguments and returning no value, to sanity
  /// test basic calling.
  func noop()
  /// Returns the passed object, to test serialization and deserialization.
  func echoAllTypes(everything: AllTypes) -> AllTypes
  /// Returns the passed object, to test serialization and deserialization.
  func echoAllNullableTypes(everything: AllNullableTypes?) -> AllNullableTypes?
  /// Returns an error, to test error handling.
  func throwError()
  /// Returns passed in int.
  func echoInt(anInt: Int32) -> Int32
  /// Returns passed in double.
  func echoDouble(aDouble: Double) -> Double
  /// Returns the passed in boolean.
  func echoBool(aBool: Bool) -> Bool
  /// Returns the passed in string.
  func echoString(aString: String) -> String
  /// Returns the passed in Uint8List.
  func echoUint8List(aUint8List: FlutterStandardTypedData) -> FlutterStandardTypedData
  /// Returns the passed in generic Object.
  func echoObject(anObject: Any) -> Any
  /// Returns the inner `aString` value from the wrapped object, to test
  /// sending of nested objects.
  func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String?
  /// Returns the inner `aString` value from the wrapped object, to test
  /// sending of nested objects.
  func createNestedNullableString(nullableString: String?) -> AllNullableTypesWrapper
  /// Returns passed in arguments of multiple types.
  func sendMultipleNullableTypes(aNullableBool: Bool?, aNullableInt: Int32?, aNullableString: String?) -> AllNullableTypes
  /// Returns passed in int.
  func echoNullableInt(aNullableInt: Int32?) -> Int32?
  /// Returns passed in double.
  func echoNullableDouble(aNullableDouble: Double?) -> Double?
  /// Returns the passed in boolean.
  func echoNullableBool(aNullableBool: Bool?) -> Bool?
  /// Returns the passed in string.
  func echoNullableString(aNullableString: String?) -> String?
  /// Returns the passed in Uint8List.
  func echoNullableUint8List(aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData?
  /// Returns the passed in generic Object.
  func echoNullableObject(aNullableObject: Any?) -> Any?
  /// A no-op function taking no arguments and returning no value, to sanity
  /// test basic asynchronous calling.
  func noopAsync(completion: @escaping () -> Void)
  /// Returns the passed string asynchronously.
  func echoAsyncString(aString: String, completion: @escaping (String) -> Void)
  func callFlutterNoop(completion: @escaping () -> Void)
  func callFlutterEchoAllTypes(everything: AllTypes, completion: @escaping (AllTypes) -> Void)
  func callFlutterSendMultipleNullableTypes(aNullableBool: Bool?, aNullableInt: Int32?, aNullableString: String?, completion: @escaping (AllNullableTypes) -> Void)
  func callFlutterEchoBool(aBool: Bool, completion: @escaping (Bool) -> Void)
  func callFlutterEchoInt(anInt: Int32, completion: @escaping (Int32) -> Void)
  func callFlutterEchoDouble(aDouble: Double, completion: @escaping (Double) -> Void)
  func callFlutterEchoString(aString: String, completion: @escaping (String) -> Void)
  func callFlutterEchoUint8List(aList: FlutterStandardTypedData, completion: @escaping (FlutterStandardTypedData) -> Void)
  func callFlutterEchoList(aList: [Any?], completion: @escaping ([Any?]) -> Void)
  func callFlutterEchoMap(aMap: [String?: Any?], completion: @escaping ([String?: Any?]) -> Void)
  func callFlutterEchoNullableBool(aBool: Bool?, completion: @escaping (Bool?) -> Void)
  func callFlutterEchoNullableInt(anInt: Int32?, completion: @escaping (Int32?) -> Void)
  func callFlutterEchoNullableDouble(aDouble: Double?, completion: @escaping (Double?) -> Void)
  func callFlutterEchoNullableString(aString: String?, completion: @escaping (String?) -> Void)
  func callFlutterEchoNullableUint8List(aList: FlutterStandardTypedData?, completion: @escaping (FlutterStandardTypedData?) -> Void)
  func callFlutterEchoNullableList(aList: [Any?]?, completion: @escaping ([Any?]?) -> Void)
  func callFlutterEchoNullableMap(aMap: [String?: Any?]?, completion: @escaping ([String?: Any?]?) -> Void)
}

/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
class HostIntegrationCoreApiSetup {
  /// The codec used by HostIntegrationCoreApi.
  static var codec: FlutterStandardMessageCodec { HostIntegrationCoreApiCodec.shared }
  /// Sets up an instance of `HostIntegrationCoreApi` to handle messages through the `binaryMessenger`.
  static func setUp(binaryMessenger: FlutterBinaryMessenger, api: HostIntegrationCoreApi?) {
    /// A no-op function taking no arguments and returning no value, to sanity
    /// test basic calling.
    let noopChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noop", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      noopChannel.setMessageHandler { _, reply in
        api.noop()
        reply(wrapResult(nil))
      }
    } else {
      noopChannel.setMessageHandler(nil)
    }
    /// Returns the passed object, to test serialization and deserialization.
    let echoAllTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoAllTypesChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let everythingArg = args[0] as! AllTypes
        let result = api.echoAllTypes(everything: everythingArg)
        reply(wrapResult(result))
      }
    } else {
      echoAllTypesChannel.setMessageHandler(nil)
    }
    /// Returns the passed object, to test serialization and deserialization.
    let echoAllNullableTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoAllNullableTypesChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let everythingArg = args[0] as? AllNullableTypes
        let result = api.echoAllNullableTypes(everything: everythingArg)
        reply(wrapResult(result))
      }
    } else {
      echoAllNullableTypesChannel.setMessageHandler(nil)
    }
    /// Returns an error, to test error handling.
    let throwErrorChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.throwError", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      throwErrorChannel.setMessageHandler { _, reply in
        api.throwError()
        reply(wrapResult(nil))
      }
    } else {
      throwErrorChannel.setMessageHandler(nil)
    }
    /// Returns passed in int.
    let echoIntChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoIntChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let anIntArg = args[0] as! Int32
        let result = api.echoInt(anInt: anIntArg)
        reply(wrapResult(result))
      }
    } else {
      echoIntChannel.setMessageHandler(nil)
    }
    /// Returns passed in double.
    let echoDoubleChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoDoubleChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aDoubleArg = args[0] as! Double
        let result = api.echoDouble(aDouble: aDoubleArg)
        reply(wrapResult(result))
      }
    } else {
      echoDoubleChannel.setMessageHandler(nil)
    }
    /// Returns the passed in boolean.
    let echoBoolChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoBoolChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aBoolArg = args[0] as! Bool
        let result = api.echoBool(aBool: aBoolArg)
        reply(wrapResult(result))
      }
    } else {
      echoBoolChannel.setMessageHandler(nil)
    }
    /// Returns the passed in string.
    let echoStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoString", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoStringChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aStringArg = args[0] as! String
        let result = api.echoString(aString: aStringArg)
        reply(wrapResult(result))
      }
    } else {
      echoStringChannel.setMessageHandler(nil)
    }
    /// Returns the passed in Uint8List.
    let echoUint8ListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoUint8ListChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aUint8ListArg = args[0] as! FlutterStandardTypedData
        let result = api.echoUint8List(aUint8List: aUint8ListArg)
        reply(wrapResult(result))
      }
    } else {
      echoUint8ListChannel.setMessageHandler(nil)
    }
    /// Returns the passed in generic Object.
    let echoObjectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoObjectChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let anObjectArg = args[0]!
        let result = api.echoObject(anObject: anObjectArg)
        reply(wrapResult(result))
      }
    } else {
      echoObjectChannel.setMessageHandler(nil)
    }
    /// Returns the inner `aString` value from the wrapped object, to test
    /// sending of nested objects.
    let extractNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      extractNestedNullableStringChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let wrapperArg = args[0] as! AllNullableTypesWrapper
        let result = api.extractNestedNullableString(wrapper: wrapperArg)
        reply(wrapResult(result))
      }
    } else {
      extractNestedNullableStringChannel.setMessageHandler(nil)
    }
    /// Returns the inner `aString` value from the wrapped object, to test
    /// sending of nested objects.
    let createNestedNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      createNestedNullableStringChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let nullableStringArg = args[0] as? String
        let result = api.createNestedNullableString(nullableString: nullableStringArg)
        reply(wrapResult(result))
      }
    } else {
      createNestedNullableStringChannel.setMessageHandler(nil)
    }
    /// Returns passed in arguments of multiple types.
    let sendMultipleNullableTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      sendMultipleNullableTypesChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aNullableBoolArg = args[0] as? Bool
        let aNullableIntArg = args[1] as? Int32
        let aNullableStringArg = args[2] as? String
        let result = api.sendMultipleNullableTypes(aNullableBool: aNullableBoolArg, aNullableInt: aNullableIntArg, aNullableString: aNullableStringArg)
        reply(wrapResult(result))
      }
    } else {
      sendMultipleNullableTypesChannel.setMessageHandler(nil)
    }
    /// Returns passed in int.
    let echoNullableIntChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoNullableIntChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aNullableIntArg = args[0] as? Int32
        let result = api.echoNullableInt(aNullableInt: aNullableIntArg)
        reply(wrapResult(result))
      }
    } else {
      echoNullableIntChannel.setMessageHandler(nil)
    }
    /// Returns passed in double.
    let echoNullableDoubleChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoNullableDoubleChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aNullableDoubleArg = args[0] as? Double
        let result = api.echoNullableDouble(aNullableDouble: aNullableDoubleArg)
        reply(wrapResult(result))
      }
    } else {
      echoNullableDoubleChannel.setMessageHandler(nil)
    }
    /// Returns the passed in boolean.
    let echoNullableBoolChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoNullableBoolChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aNullableBoolArg = args[0] as? Bool
        let result = api.echoNullableBool(aNullableBool: aNullableBoolArg)
        reply(wrapResult(result))
      }
    } else {
      echoNullableBoolChannel.setMessageHandler(nil)
    }
    /// Returns the passed in string.
    let echoNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoNullableStringChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aNullableStringArg = args[0] as? String
        let result = api.echoNullableString(aNullableString: aNullableStringArg)
        reply(wrapResult(result))
      }
    } else {
      echoNullableStringChannel.setMessageHandler(nil)
    }
    /// Returns the passed in Uint8List.
    let echoNullableUint8ListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoNullableUint8ListChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aNullableUint8ListArg = args[0] as? FlutterStandardTypedData
        let result = api.echoNullableUint8List(aNullableUint8List: aNullableUint8ListArg)
        reply(wrapResult(result))
      }
    } else {
      echoNullableUint8ListChannel.setMessageHandler(nil)
    }
    /// Returns the passed in generic Object.
    let echoNullableObjectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoNullableObjectChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aNullableObjectArg = args[0]
        let result = api.echoNullableObject(aNullableObject: aNullableObjectArg)
        reply(wrapResult(result))
      }
    } else {
      echoNullableObjectChannel.setMessageHandler(nil)
    }
    /// A no-op function taking no arguments and returning no value, to sanity
    /// test basic asynchronous calling.
    let noopAsyncChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      noopAsyncChannel.setMessageHandler { _, reply in
        api.noopAsync() {
          reply(wrapResult(nil))
        }
      }
    } else {
      noopAsyncChannel.setMessageHandler(nil)
    }
    /// Returns the passed string asynchronously.
    let echoAsyncStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      echoAsyncStringChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aStringArg = args[0] as! String
        api.echoAsyncString(aString: aStringArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      echoAsyncStringChannel.setMessageHandler(nil)
    }
    let callFlutterNoopChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterNoopChannel.setMessageHandler { _, reply in
        api.callFlutterNoop() {
          reply(wrapResult(nil))
        }
      }
    } else {
      callFlutterNoopChannel.setMessageHandler(nil)
    }
    let callFlutterEchoAllTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoAllTypes", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoAllTypesChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let everythingArg = args[0] as! AllTypes
        api.callFlutterEchoAllTypes(everything: everythingArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoAllTypesChannel.setMessageHandler(nil)
    }
    let callFlutterSendMultipleNullableTypesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterSendMultipleNullableTypesChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aNullableBoolArg = args[0] as? Bool
        let aNullableIntArg = args[1] as? Int32
        let aNullableStringArg = args[2] as? String
        api.callFlutterSendMultipleNullableTypes(aNullableBool: aNullableBoolArg, aNullableInt: aNullableIntArg, aNullableString: aNullableStringArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterSendMultipleNullableTypesChannel.setMessageHandler(nil)
    }
    let callFlutterEchoBoolChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoBool", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoBoolChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aBoolArg = args[0] as! Bool
        api.callFlutterEchoBool(aBool: aBoolArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoBoolChannel.setMessageHandler(nil)
    }
    let callFlutterEchoIntChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoInt", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoIntChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let anIntArg = args[0] as! Int32
        api.callFlutterEchoInt(anInt: anIntArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoIntChannel.setMessageHandler(nil)
    }
    let callFlutterEchoDoubleChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoDouble", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoDoubleChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aDoubleArg = args[0] as! Double
        api.callFlutterEchoDouble(aDouble: aDoubleArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoDoubleChannel.setMessageHandler(nil)
    }
    let callFlutterEchoStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoStringChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aStringArg = args[0] as! String
        api.callFlutterEchoString(aString: aStringArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoStringChannel.setMessageHandler(nil)
    }
    let callFlutterEchoUint8ListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoUint8List", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoUint8ListChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aListArg = args[0] as! FlutterStandardTypedData
        api.callFlutterEchoUint8List(aList: aListArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoUint8ListChannel.setMessageHandler(nil)
    }
    let callFlutterEchoListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoList", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoListChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aListArg = args[0] as! [Any?]
        api.callFlutterEchoList(aList: aListArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoListChannel.setMessageHandler(nil)
    }
    let callFlutterEchoMapChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoMap", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoMapChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aMapArg = args[0] as! [String?: Any?]
        api.callFlutterEchoMap(aMap: aMapArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoMapChannel.setMessageHandler(nil)
    }
    let callFlutterEchoNullableBoolChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableBool", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoNullableBoolChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aBoolArg = args[0] as? Bool
        api.callFlutterEchoNullableBool(aBool: aBoolArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoNullableBoolChannel.setMessageHandler(nil)
    }
    let callFlutterEchoNullableIntChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableInt", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoNullableIntChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let anIntArg = args[0] as? Int32
        api.callFlutterEchoNullableInt(anInt: anIntArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoNullableIntChannel.setMessageHandler(nil)
    }
    let callFlutterEchoNullableDoubleChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableDouble", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoNullableDoubleChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aDoubleArg = args[0] as? Double
        api.callFlutterEchoNullableDouble(aDouble: aDoubleArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoNullableDoubleChannel.setMessageHandler(nil)
    }
    let callFlutterEchoNullableStringChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableString", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoNullableStringChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aStringArg = args[0] as? String
        api.callFlutterEchoNullableString(aString: aStringArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoNullableStringChannel.setMessageHandler(nil)
    }
    let callFlutterEchoNullableUint8ListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableUint8List", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoNullableUint8ListChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aListArg = args[0] as? FlutterStandardTypedData
        api.callFlutterEchoNullableUint8List(aList: aListArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoNullableUint8ListChannel.setMessageHandler(nil)
    }
    let callFlutterEchoNullableListChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableList", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoNullableListChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aListArg = args[0] as? [Any?]
        api.callFlutterEchoNullableList(aList: aListArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoNullableListChannel.setMessageHandler(nil)
    }
    let callFlutterEchoNullableMapChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableMap", binaryMessenger: binaryMessenger, codec: codec)
    if let api = api {
      callFlutterEchoNullableMapChannel.setMessageHandler { message, reply in
        let args = message as! [Any?]
        let aMapArg = args[0] as? [String?: Any?]
        api.callFlutterEchoNullableMap(aMap: aMapArg) { result in
          reply(wrapResult(result))
        }
      }
    } else {
      callFlutterEchoNullableMapChannel.setMessageHandler(nil)
    }
  }
}
private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader {
  override func readValue(ofType type: UInt8) -> Any? {
    switch type {
      case 128:
        return AllNullableTypes.fromList(self.readValue() as! [Any])
      case 129:
        return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])
      case 130:
        return AllTypes.fromList(self.readValue() as! [Any])
      default:
        return super.readValue(ofType: type)
    }
  }
}

private class FlutterIntegrationCoreApiCodecWriter: FlutterStandardWriter {
  override func writeValue(_ value: Any) {
    if let value = value as? AllNullableTypes {
      super.writeByte(128)
      super.writeValue(value.toList())
    } else if let value = value as? AllNullableTypesWrapper {
      super.writeByte(129)
      super.writeValue(value.toList())
    } else if let value = value as? AllTypes {
      super.writeByte(130)
      super.writeValue(value.toList())
    } else {
      super.writeValue(value)
    }
  }
}

private class FlutterIntegrationCoreApiCodecReaderWriter: FlutterStandardReaderWriter {
  override func reader(with data: Data) -> FlutterStandardReader {
    return FlutterIntegrationCoreApiCodecReader(data: data)
  }

  override func writer(with data: NSMutableData) -> FlutterStandardWriter {
    return FlutterIntegrationCoreApiCodecWriter(data: data)
  }
}

class FlutterIntegrationCoreApiCodec: FlutterStandardMessageCodec {
  static let shared = FlutterIntegrationCoreApiCodec(readerWriter: FlutterIntegrationCoreApiCodecReaderWriter())
}

/// The core interface that the Dart platform_test code implements for host
/// integration tests to call into.
///
/// Generated class from Pigeon that represents Flutter messages that can be called from Swift.
class FlutterIntegrationCoreApi {
  private let binaryMessenger: FlutterBinaryMessenger
  init(binaryMessenger: FlutterBinaryMessenger){
    self.binaryMessenger = binaryMessenger
  }
  var codec: FlutterStandardMessageCodec {
    return FlutterIntegrationCoreApiCodec.shared
  }
  /// A no-op function taking no arguments and returning no value, to sanity
  /// test basic calling.
  func noop(completion: @escaping () -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage(nil) { _ in
      completion()
    }
  }
  /// Returns the passed object, to test serialization and deserialization.
  func echoAllTypes(everything everythingArg: AllTypes, completion: @escaping (AllTypes) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([everythingArg] as [Any?]) { response in
      let result = response as! AllTypes
      completion(result)
    }
  }
  /// Returns the passed object, to test serialization and deserialization.
  func echoAllNullableTypes(everything everythingArg: AllNullableTypes, completion: @escaping (AllNullableTypes) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([everythingArg] as [Any?]) { response in
      let result = response as! AllNullableTypes
      completion(result)
    }
  }
  /// Returns passed in arguments of multiple types.
  ///
  /// Tests multiple-arity FlutterApi handling.
  func sendMultipleNullableTypes(aNullableBool aNullableBoolArg: Bool?, aNullableInt aNullableIntArg: Int32?, aNullableString aNullableStringArg: String?, completion: @escaping (AllNullableTypes) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { response in
      let result = response as! AllNullableTypes
      completion(result)
    }
  }
  /// Returns the passed boolean, to test serialization and deserialization.
  func echoBool(aBool aBoolArg: Bool, completion: @escaping (Bool) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aBoolArg] as [Any?]) { response in
      let result = response as! Bool
      completion(result)
    }
  }
  /// Returns the passed int, to test serialization and deserialization.
  func echoInt(anInt anIntArg: Int32, completion: @escaping (Int32) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([anIntArg] as [Any?]) { response in
      let result = response as! Int32
      completion(result)
    }
  }
  /// Returns the passed double, to test serialization and deserialization.
  func echoDouble(aDouble aDoubleArg: Double, completion: @escaping (Double) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aDoubleArg] as [Any?]) { response in
      let result = response as! Double
      completion(result)
    }
  }
  /// Returns the passed string, to test serialization and deserialization.
  func echoString(aString aStringArg: String, completion: @escaping (String) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aStringArg] as [Any?]) { response in
      let result = response as! String
      completion(result)
    }
  }
  /// Returns the passed byte list, to test serialization and deserialization.
  func echoUint8List(aList aListArg: FlutterStandardTypedData, completion: @escaping (FlutterStandardTypedData) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aListArg] as [Any?]) { response in
      let result = response as! FlutterStandardTypedData
      completion(result)
    }
  }
  /// Returns the passed list, to test serialization and deserialization.
  func echoList(aList aListArg: [Any?], completion: @escaping ([Any?]) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aListArg] as [Any?]) { response in
      let result = response as! [Any?]
      completion(result)
    }
  }
  /// Returns the passed map, to test serialization and deserialization.
  func echoMap(aMap aMapArg: [String?: Any?], completion: @escaping ([String?: Any?]) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aMapArg] as [Any?]) { response in
      let result = response as! [String?: Any?]
      completion(result)
    }
  }
  /// Returns the passed boolean, to test serialization and deserialization.
  func echoNullableBool(aBool aBoolArg: Bool?, completion: @escaping (Bool?) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aBoolArg] as [Any?]) { response in
      let result = response as? Bool
      completion(result)
    }
  }
  /// Returns the passed int, to test serialization and deserialization.
  func echoNullableInt(anInt anIntArg: Int32?, completion: @escaping (Int32?) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([anIntArg] as [Any?]) { response in
      let result = response as? Int32
      completion(result)
    }
  }
  /// Returns the passed double, to test serialization and deserialization.
  func echoNullableDouble(aDouble aDoubleArg: Double?, completion: @escaping (Double?) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aDoubleArg] as [Any?]) { response in
      let result = response as? Double
      completion(result)
    }
  }
  /// Returns the passed string, to test serialization and deserialization.
  func echoNullableString(aString aStringArg: String?, completion: @escaping (String?) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aStringArg] as [Any?]) { response in
      let result = response as? String
      completion(result)
    }
  }
  /// Returns the passed byte list, to test serialization and deserialization.
  func echoNullableUint8List(aList aListArg: FlutterStandardTypedData?, completion: @escaping (FlutterStandardTypedData?) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aListArg] as [Any?]) { response in
      let result = response as? FlutterStandardTypedData
      completion(result)
    }
  }
  /// Returns the passed list, to test serialization and deserialization.
  func echoNullableList(aList aListArg: [Any?]?, completion: @escaping ([Any?]?) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aListArg] as [Any?]) { response in
      let result = response as? [Any?]
      completion(result)
    }
  }
  /// Returns the passed map, to test serialization and deserialization.
  func echoNullableMap(aMap aMapArg: [String?: Any?]?, completion: @escaping ([String?: Any?]?) -> Void) {
    let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap", binaryMessenger: binaryMessenger, codec: codec)
    channel.sendMessage([aMapArg] as [Any?]) { response in
      let result = response as? [String?: Any?]
      completion(result)
    }
  }
}
/// An API that can be implemented for minimal, compile-only tests.
///
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol HostTrivialApi {
  func noop()
}

/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
class HostTrivialApiSetup {
  /// The codec used by HostTrivialApi.
  /// Sets up an instance of `HostTrivialApi` to handle messages through the `binaryMessenger`.
  static func setUp(binaryMessenger: FlutterBinaryMessenger, api: HostTrivialApi?) {
    let noopChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostTrivialApi.noop", binaryMessenger: binaryMessenger)
    if let api = api {
      noopChannel.setMessageHandler { _, reply in
        api.noop()
        reply(wrapResult(nil))
      }
    } else {
      noopChannel.setMessageHandler(nil)
    }
  }
}
