// 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.1.0), 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 echo(_ everything: AllTypes) -> AllTypes
  /// Returns the passed object, to test serialization and deserialization.
  func echo(_ everything: AllNullableTypes?) -> AllNullableTypes?
  /// Returns an error, to test error handling.
  func throwError()
  /// Returns passed in int.
  func echo(_ anInt: Int32) -> Int32
  /// Returns passed in double.
  func echo(_ aDouble: Double) -> Double
  /// Returns the passed in boolean.
  func echo(_ aBool: Bool) -> Bool
  /// Returns the passed in string.
  func echo(_ aString: String) -> String
  /// Returns the passed in Uint8List.
  func echo(_ aUint8List: FlutterStandardTypedData) -> FlutterStandardTypedData
  /// Returns the passed in generic Object.
  func echo(_ anObject: Any) -> Any
  /// Returns the inner `aString` value from the wrapped object, to test
  /// sending of nested objects.
  func extractNestedNullableString(from wrapper: AllNullableTypesWrapper) -> String?
  /// Returns the inner `aString` value from the wrapped object, to test
  /// sending of nested objects.
  func createNestedObject(with nullableString: String?) -> AllNullableTypesWrapper
  /// Returns passed in arguments of multiple types.
  func sendMultipleNullableTypes(aBool aNullableBool: Bool?, anInt aNullableInt: Int32?, aString aNullableString: String?) -> AllNullableTypes
  /// Returns passed in int.
  func echo(_ aNullableInt: Int32?) -> Int32?
  /// Returns passed in double.
  func echo(_ aNullableDouble: Double?) -> Double?
  /// Returns the passed in boolean.
  func echo(_ aNullableBool: Bool?) -> Bool?
  /// Returns the passed in string.
  func echo(_ aNullableString: String?) -> String?
  /// Returns the passed in Uint8List.
  func echo(_ aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData?
  /// Returns the passed in generic Object.
  func echo(_ 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 echoAsync(_ aString: String, completion: @escaping (String) -> Void)
  func callFlutterNoop(completion: @escaping () -> Void)
  func callFlutterEcho(_ everything: AllTypes, completion: @escaping (AllTypes) -> Void)
  func callFlutterSendMultipleNullableTypes(aBool aNullableBool: Bool?, anInt aNullableInt: Int32?, aString aNullableString: String?, completion: @escaping (AllNullableTypes) -> Void)
  func callFlutterEcho(_ aBool: Bool, completion: @escaping (Bool) -> Void)
  func callFlutterEcho(_ anInt: Int32, completion: @escaping (Int32) -> Void)
  func callFlutterEcho(_ aDouble: Double, completion: @escaping (Double) -> Void)
  func callFlutterEcho(_ aString: String, completion: @escaping (String) -> Void)
  func callFlutterEcho(_ aList: FlutterStandardTypedData, completion: @escaping (FlutterStandardTypedData) -> Void)
  func callFlutterEcho(_ aList: [Any?], completion: @escaping ([Any?]) -> Void)
  func callFlutterEcho(_ aMap: [String?: Any?], completion: @escaping ([String?: Any?]) -> Void)
  func callFlutterEchoNullable(_ aBool: Bool?, completion: @escaping (Bool?) -> Void)
  func callFlutterEchoNullable(_ anInt: Int32?, completion: @escaping (Int32?) -> Void)
  func callFlutterEchoNullable(_ aDouble: Double?, completion: @escaping (Double?) -> Void)
  func callFlutterEchoNullable(_ aString: String?, completion: @escaping (String?) -> Void)
  func callFlutterEchoNullable(_ aList: FlutterStandardTypedData?, completion: @escaping (FlutterStandardTypedData?) -> Void)
  func callFlutterEchoNullable(_ aList: [Any?]?, completion: @escaping ([Any?]?) -> Void)
  func callFlutterEchoNullable(_ 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.echo(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.echo(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.echo(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.echo(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.echo(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.echo(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.echo(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.echo(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(from: 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.createNestedObject(with: 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(aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: 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.echo(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.echo(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.echo(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.echo(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.echo(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.echo(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.echoAsync(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.callFlutterEcho(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(aBool: aNullableBoolArg, anInt: aNullableIntArg, aString: 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.callFlutterEcho(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.callFlutterEcho(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.callFlutterEcho(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.callFlutterEcho(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.callFlutterEcho(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.callFlutterEcho(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.callFlutterEcho(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.callFlutterEchoNullable(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.callFlutterEchoNullable(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.callFlutterEchoNullable(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.callFlutterEchoNullable(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.callFlutterEchoNullable(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.callFlutterEchoNullable(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.callFlutterEchoNullable(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 echo(_ 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 echoNullable(_ 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(aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int32?, aString 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 echo(_ 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 echo(_ 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 echo(_ 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 echo(_ 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 echo(_ 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 echo(_ 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 echo(_ 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 echoNullable(_ 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 echoNullable(_ 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 echoNullable(_ 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 echoNullable(_ 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 echoNullable(_ 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 echoNullable(_ 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 echoNullable(_ 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)
    }
  }
}
