// 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.5), do not edit directly.
// See also: https://pub.dev/packages/pigeon

#import "CoreTests.gen.h"
#import <Flutter/Flutter.h>

#if !__has_feature(objc_arc)
#error File requires ARC to be enabled.
#endif

static NSArray *wrapResult(id result, FlutterError *error) {
  if (error) {
    return @[
      error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null]
    ];
  }
  return @[ result ?: [NSNull null] ];
}
static id GetNullableObject(NSDictionary *dict, id key) {
  id result = dict[key];
  return (result == [NSNull null]) ? nil : result;
}
static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
  id result = array[key];
  return (result == [NSNull null]) ? nil : result;
}

@interface AllTypes ()
+ (AllTypes *)fromList:(NSArray *)list;
+ (nullable AllTypes *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end

@interface AllNullableTypes ()
+ (AllNullableTypes *)fromList:(NSArray *)list;
+ (nullable AllNullableTypes *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end

@interface AllNullableTypesWrapper ()
+ (AllNullableTypesWrapper *)fromList:(NSArray *)list;
+ (nullable AllNullableTypesWrapper *)nullableFromList:(NSArray *)list;
- (NSArray *)toList;
@end

@implementation AllTypes
+ (instancetype)makeWithABool:(NSNumber *)aBool
                        anInt:(NSNumber *)anInt
                      aDouble:(NSNumber *)aDouble
                   aByteArray:(FlutterStandardTypedData *)aByteArray
                  a4ByteArray:(FlutterStandardTypedData *)a4ByteArray
                  a8ByteArray:(FlutterStandardTypedData *)a8ByteArray
                  aFloatArray:(FlutterStandardTypedData *)aFloatArray
                        aList:(NSArray *)aList
                         aMap:(NSDictionary *)aMap
                       anEnum:(AnEnum)anEnum
                      aString:(NSString *)aString {
  AllTypes *pigeonResult = [[AllTypes alloc] init];
  pigeonResult.aBool = aBool;
  pigeonResult.anInt = anInt;
  pigeonResult.aDouble = aDouble;
  pigeonResult.aByteArray = aByteArray;
  pigeonResult.a4ByteArray = a4ByteArray;
  pigeonResult.a8ByteArray = a8ByteArray;
  pigeonResult.aFloatArray = aFloatArray;
  pigeonResult.aList = aList;
  pigeonResult.aMap = aMap;
  pigeonResult.anEnum = anEnum;
  pigeonResult.aString = aString;
  return pigeonResult;
}
+ (AllTypes *)fromList:(NSArray *)list {
  AllTypes *pigeonResult = [[AllTypes alloc] init];
  pigeonResult.aBool = GetNullableObjectAtIndex(list, 0);
  NSAssert(pigeonResult.aBool != nil, @"");
  pigeonResult.anInt = GetNullableObjectAtIndex(list, 1);
  NSAssert(pigeonResult.anInt != nil, @"");
  pigeonResult.aDouble = GetNullableObjectAtIndex(list, 2);
  NSAssert(pigeonResult.aDouble != nil, @"");
  pigeonResult.aByteArray = GetNullableObjectAtIndex(list, 3);
  NSAssert(pigeonResult.aByteArray != nil, @"");
  pigeonResult.a4ByteArray = GetNullableObjectAtIndex(list, 4);
  NSAssert(pigeonResult.a4ByteArray != nil, @"");
  pigeonResult.a8ByteArray = GetNullableObjectAtIndex(list, 5);
  NSAssert(pigeonResult.a8ByteArray != nil, @"");
  pigeonResult.aFloatArray = GetNullableObjectAtIndex(list, 6);
  NSAssert(pigeonResult.aFloatArray != nil, @"");
  pigeonResult.aList = GetNullableObjectAtIndex(list, 7);
  NSAssert(pigeonResult.aList != nil, @"");
  pigeonResult.aMap = GetNullableObjectAtIndex(list, 8);
  NSAssert(pigeonResult.aMap != nil, @"");
  pigeonResult.anEnum = [GetNullableObjectAtIndex(list, 9) integerValue];
  pigeonResult.aString = GetNullableObjectAtIndex(list, 10);
  NSAssert(pigeonResult.aString != nil, @"");
  return pigeonResult;
}
+ (nullable AllTypes *)nullableFromList:(NSArray *)list {
  return (list) ? [AllTypes fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.aBool ?: [NSNull null]),
    (self.anInt ?: [NSNull null]),
    (self.aDouble ?: [NSNull null]),
    (self.aByteArray ?: [NSNull null]),
    (self.a4ByteArray ?: [NSNull null]),
    (self.a8ByteArray ?: [NSNull null]),
    (self.aFloatArray ?: [NSNull null]),
    (self.aList ?: [NSNull null]),
    (self.aMap ?: [NSNull null]),
    @(self.anEnum),
    (self.aString ?: [NSNull null]),
  ];
}
@end

@implementation AllNullableTypes
+ (instancetype)makeWithANullableBool:(nullable NSNumber *)aNullableBool
                         aNullableInt:(nullable NSNumber *)aNullableInt
                      aNullableDouble:(nullable NSNumber *)aNullableDouble
                   aNullableByteArray:(nullable FlutterStandardTypedData *)aNullableByteArray
                  aNullable4ByteArray:(nullable FlutterStandardTypedData *)aNullable4ByteArray
                  aNullable8ByteArray:(nullable FlutterStandardTypedData *)aNullable8ByteArray
                  aNullableFloatArray:(nullable FlutterStandardTypedData *)aNullableFloatArray
                        aNullableList:(nullable NSArray *)aNullableList
                         aNullableMap:(nullable NSDictionary *)aNullableMap
                   nullableNestedList:(nullable NSArray<NSArray<NSNumber *> *> *)nullableNestedList
           nullableMapWithAnnotations:
               (nullable NSDictionary<NSString *, NSString *> *)nullableMapWithAnnotations
                nullableMapWithObject:(nullable NSDictionary<NSString *, id> *)nullableMapWithObject
                        aNullableEnum:(AnEnum)aNullableEnum
                      aNullableString:(nullable NSString *)aNullableString {
  AllNullableTypes *pigeonResult = [[AllNullableTypes alloc] init];
  pigeonResult.aNullableBool = aNullableBool;
  pigeonResult.aNullableInt = aNullableInt;
  pigeonResult.aNullableDouble = aNullableDouble;
  pigeonResult.aNullableByteArray = aNullableByteArray;
  pigeonResult.aNullable4ByteArray = aNullable4ByteArray;
  pigeonResult.aNullable8ByteArray = aNullable8ByteArray;
  pigeonResult.aNullableFloatArray = aNullableFloatArray;
  pigeonResult.aNullableList = aNullableList;
  pigeonResult.aNullableMap = aNullableMap;
  pigeonResult.nullableNestedList = nullableNestedList;
  pigeonResult.nullableMapWithAnnotations = nullableMapWithAnnotations;
  pigeonResult.nullableMapWithObject = nullableMapWithObject;
  pigeonResult.aNullableEnum = aNullableEnum;
  pigeonResult.aNullableString = aNullableString;
  return pigeonResult;
}
+ (AllNullableTypes *)fromList:(NSArray *)list {
  AllNullableTypes *pigeonResult = [[AllNullableTypes alloc] init];
  pigeonResult.aNullableBool = GetNullableObjectAtIndex(list, 0);
  pigeonResult.aNullableInt = GetNullableObjectAtIndex(list, 1);
  pigeonResult.aNullableDouble = GetNullableObjectAtIndex(list, 2);
  pigeonResult.aNullableByteArray = GetNullableObjectAtIndex(list, 3);
  pigeonResult.aNullable4ByteArray = GetNullableObjectAtIndex(list, 4);
  pigeonResult.aNullable8ByteArray = GetNullableObjectAtIndex(list, 5);
  pigeonResult.aNullableFloatArray = GetNullableObjectAtIndex(list, 6);
  pigeonResult.aNullableList = GetNullableObjectAtIndex(list, 7);
  pigeonResult.aNullableMap = GetNullableObjectAtIndex(list, 8);
  pigeonResult.nullableNestedList = GetNullableObjectAtIndex(list, 9);
  pigeonResult.nullableMapWithAnnotations = GetNullableObjectAtIndex(list, 10);
  pigeonResult.nullableMapWithObject = GetNullableObjectAtIndex(list, 11);
  pigeonResult.aNullableEnum = [GetNullableObjectAtIndex(list, 12) integerValue];
  pigeonResult.aNullableString = GetNullableObjectAtIndex(list, 13);
  return pigeonResult;
}
+ (nullable AllNullableTypes *)nullableFromList:(NSArray *)list {
  return (list) ? [AllNullableTypes fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.aNullableBool ?: [NSNull null]),
    (self.aNullableInt ?: [NSNull null]),
    (self.aNullableDouble ?: [NSNull null]),
    (self.aNullableByteArray ?: [NSNull null]),
    (self.aNullable4ByteArray ?: [NSNull null]),
    (self.aNullable8ByteArray ?: [NSNull null]),
    (self.aNullableFloatArray ?: [NSNull null]),
    (self.aNullableList ?: [NSNull null]),
    (self.aNullableMap ?: [NSNull null]),
    (self.nullableNestedList ?: [NSNull null]),
    (self.nullableMapWithAnnotations ?: [NSNull null]),
    (self.nullableMapWithObject ?: [NSNull null]),
    @(self.aNullableEnum),
    (self.aNullableString ?: [NSNull null]),
  ];
}
@end

@implementation AllNullableTypesWrapper
+ (instancetype)makeWithValues:(AllNullableTypes *)values {
  AllNullableTypesWrapper *pigeonResult = [[AllNullableTypesWrapper alloc] init];
  pigeonResult.values = values;
  return pigeonResult;
}
+ (AllNullableTypesWrapper *)fromList:(NSArray *)list {
  AllNullableTypesWrapper *pigeonResult = [[AllNullableTypesWrapper alloc] init];
  pigeonResult.values = [AllNullableTypes nullableFromList:(GetNullableObjectAtIndex(list, 0))];
  NSAssert(pigeonResult.values != nil, @"");
  return pigeonResult;
}
+ (nullable AllNullableTypesWrapper *)nullableFromList:(NSArray *)list {
  return (list) ? [AllNullableTypesWrapper fromList:list] : nil;
}
- (NSArray *)toList {
  return @[
    (self.values ? [self.values toList] : [NSNull null]),
  ];
}
@end

@interface HostIntegrationCoreApiCodecReader : FlutterStandardReader
@end
@implementation HostIntegrationCoreApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [AllNullableTypes fromList:[self readValue]];
    case 129:
      return [AllNullableTypesWrapper fromList:[self readValue]];
    case 130:
      return [AllTypes fromList:[self readValue]];
    default:
      return [super readValueOfType:type];
  }
}
@end

@interface HostIntegrationCoreApiCodecWriter : FlutterStandardWriter
@end
@implementation HostIntegrationCoreApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[AllNullableTypes class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) {
    [self writeByte:129];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[AllTypes class]]) {
    [self writeByte:130];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface HostIntegrationCoreApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation HostIntegrationCoreApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[HostIntegrationCoreApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[HostIntegrationCoreApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *HostIntegrationCoreApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    HostIntegrationCoreApiCodecReaderWriter *readerWriter =
        [[HostIntegrationCoreApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

void HostIntegrationCoreApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                                 NSObject<HostIntegrationCoreApi> *api) {
  /// A no-op function taking no arguments and returning no value, to sanity
  /// test basic calling.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.noop"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(noopWithError:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(noopWithError:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        FlutterError *error;
        [api noopWithError:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed object, to test serialization and deserialization.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(echoAllTypes:error:)],
          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoAllTypes:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        AllTypes *arg_everything = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        AllTypes *output = [api echoAllTypes:arg_everything error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed object, to test serialization and deserialization.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoAllNullableTypes:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(echoAllNullableTypes:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        AllNullableTypes *arg_everything = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        AllNullableTypes *output = [api echoAllNullableTypes:arg_everything error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns an error, to test error handling.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.throwError"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(throwErrorWithError:)],
          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(throwErrorWithError:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        FlutterError *error;
        [api throwErrorWithError:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns passed in int.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoInt"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoInt:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoInt:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api echoInt:arg_anInt error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns passed in double.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoDouble:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoDouble:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api echoDouble:arg_aDouble error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed in boolean.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoBool"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoBool:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoBool:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api echoBool:arg_aBool error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed in string.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoString"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoString:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoString:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSString *arg_aString = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSString *output = [api echoString:arg_aString error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed in Uint8List.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(echoUint8List:error:)],
          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoUint8List:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        FlutterStandardTypedData *arg_aUint8List = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        FlutterStandardTypedData *output = [api echoUint8List:arg_aUint8List error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed in generic Object.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoObject"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoObject:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoObject:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        id arg_anObject = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        id output = [api echoObject:arg_anObject error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the inner `aString` value from the wrapped object, to test
  /// sending of nested objects.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(extractNestedNullableStringFrom:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(extractNestedNullableStringFrom:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        AllNullableTypesWrapper *arg_wrapper = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSString *output = [api extractNestedNullableStringFrom:arg_wrapper error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the inner `aString` value from the wrapped object, to test
  /// sending of nested objects.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(createNestedObjectWithNullableString:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(createNestedObjectWithNullableString:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSString *arg_nullableString = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        AllNullableTypesWrapper *output =
            [api createNestedObjectWithNullableString:arg_nullableString error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns passed in arguments of multiple types.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(sendMultipleNullableTypesABool:
                                                                           anInt:aString:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(sendMultipleNullableTypesABool:anInt:aString:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1);
        NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2);
        FlutterError *error;
        AllNullableTypes *output = [api sendMultipleNullableTypesABool:arg_aNullableBool
                                                                 anInt:arg_aNullableInt
                                                               aString:arg_aNullableString
                                                                 error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns passed in int.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(echoNullableInt:error:)],
          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoNullableInt:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api echoNullableInt:arg_aNullableInt error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns passed in double.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoNullableDouble:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(echoNullableDouble:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aNullableDouble = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api echoNullableDouble:arg_aNullableDouble error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed in boolean.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(echoNullableBool:error:)],
          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(echoNullableBool:error:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSNumber *output = [api echoNullableBool:arg_aNullableBool error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed in string.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoNullableString:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(echoNullableString:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        NSString *output = [api echoNullableString:arg_aNullableString error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed in Uint8List.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoNullableUint8List:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(echoNullableUint8List:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        FlutterStandardTypedData *arg_aNullableUint8List = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        FlutterStandardTypedData *output = [api echoNullableUint8List:arg_aNullableUint8List
                                                                error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed in generic Object.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoNullableObject:error:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(echoNullableObject:error:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        id arg_aNullableObject = GetNullableObjectAtIndex(args, 0);
        FlutterError *error;
        id output = [api echoNullableObject:arg_aNullableObject error:&error];
        callback(wrapResult(output, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// A no-op function taking no arguments and returning no value, to sanity
  /// test basic asynchronous calling.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert(
          [api respondsToSelector:@selector(noopAsyncWithCompletion:)],
          @"HostIntegrationCoreApi api (%@) doesn't respond to @selector(noopAsyncWithCompletion:)",
          api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        [api noopAsyncWithCompletion:^(FlutterError *_Nullable error) {
          callback(wrapResult(nil, error));
        }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  /// Returns the passed string asynchronously.
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(echoAsyncString:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(echoAsyncString:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSString *arg_aString = GetNullableObjectAtIndex(args, 0);
        [api echoAsyncString:arg_aString
                  completion:^(NSString *_Nullable output, FlutterError *_Nullable error) {
                    callback(wrapResult(output, error));
                  }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterNoopWithCompletion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterNoopWithCompletion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        [api callFlutterNoopWithCompletion:^(FlutterError *_Nullable error) {
          callback(wrapResult(nil, error));
        }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoAllTypes"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoAllTypes:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoAllTypes:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        AllTypes *arg_everything = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoAllTypes:arg_everything
                          completion:^(AllTypes *_Nullable output, FlutterError *_Nullable error) {
                            callback(wrapResult(output, error));
                          }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:
               @"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterSendMultipleNullableTypes"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector
                     (callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterSendMultipleNullableTypesABool:anInt:aString:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aNullableBool = GetNullableObjectAtIndex(args, 0);
        NSNumber *arg_aNullableInt = GetNullableObjectAtIndex(args, 1);
        NSString *arg_aNullableString = GetNullableObjectAtIndex(args, 2);
        [api callFlutterSendMultipleNullableTypesABool:arg_aNullableBool
                                                 anInt:arg_aNullableInt
                                               aString:arg_aNullableString
                                            completion:^(AllNullableTypes *_Nullable output,
                                                         FlutterError *_Nullable error) {
                                              callback(wrapResult(output, error));
                                            }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoBool"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoBool:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoBool:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoBool:arg_aBool
                      completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) {
                        callback(wrapResult(output, error));
                      }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoInt"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoInt:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoInt:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoInt:arg_anInt
                     completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) {
                       callback(wrapResult(output, error));
                     }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoDouble"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoDouble:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoDouble:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoDouble:arg_aDouble
                        completion:^(NSNumber *_Nullable output, FlutterError *_Nullable error) {
                          callback(wrapResult(output, error));
                        }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoString:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoString:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSString *arg_aString = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoString:arg_aString
                        completion:^(NSString *_Nullable output, FlutterError *_Nullable error) {
                          callback(wrapResult(output, error));
                        }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoUint8List"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoUint8List:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoUint8List:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        FlutterStandardTypedData *arg_aList = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoUint8List:arg_aList
                           completion:^(FlutterStandardTypedData *_Nullable output,
                                        FlutterError *_Nullable error) {
                             callback(wrapResult(output, error));
                           }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoList"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoList:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoList:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSArray<id> *arg_aList = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoList:arg_aList
                      completion:^(NSArray<id> *_Nullable output, FlutterError *_Nullable error) {
                        callback(wrapResult(output, error));
                      }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoMap"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoMap:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoMap:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSDictionary<NSString *, id> *arg_aMap = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoMap:arg_aMap
                     completion:^(NSDictionary<NSString *, id> *_Nullable output,
                                  FlutterError *_Nullable error) {
                       callback(wrapResult(output, error));
                     }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableBool"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableBool:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoNullableBool:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aBool = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoNullableBool:arg_aBool
                              completion:^(NSNumber *_Nullable output,
                                           FlutterError *_Nullable error) {
                                callback(wrapResult(output, error));
                              }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableInt"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableInt:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoNullableInt:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_anInt = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoNullableInt:arg_anInt
                             completion:^(NSNumber *_Nullable output,
                                          FlutterError *_Nullable error) {
                               callback(wrapResult(output, error));
                             }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableDouble"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableDouble:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoNullableDouble:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSNumber *arg_aDouble = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoNullableDouble:arg_aDouble
                                completion:^(NSNumber *_Nullable output,
                                             FlutterError *_Nullable error) {
                                  callback(wrapResult(output, error));
                                }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableString"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableString:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoNullableString:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSString *arg_aString = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoNullableString:arg_aString
                                completion:^(NSString *_Nullable output,
                                             FlutterError *_Nullable error) {
                                  callback(wrapResult(output, error));
                                }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:
               @"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableUint8List"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableUint8List:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoNullableUint8List:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        FlutterStandardTypedData *arg_aList = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoNullableUint8List:arg_aList
                                   completion:^(FlutterStandardTypedData *_Nullable output,
                                                FlutterError *_Nullable error) {
                                     callback(wrapResult(output, error));
                                   }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableList"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableList:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoNullableList:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSArray<id> *arg_aList = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoNullableList:arg_aList
                              completion:^(NSArray<id> *_Nullable output,
                                           FlutterError *_Nullable error) {
                                callback(wrapResult(output, error));
                              }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
  {
    FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc]
           initWithName:@"dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableMap"
        binaryMessenger:binaryMessenger
                  codec:HostIntegrationCoreApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(callFlutterEchoNullableMap:completion:)],
                @"HostIntegrationCoreApi api (%@) doesn't respond to "
                @"@selector(callFlutterEchoNullableMap:completion:)",
                api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        NSArray *args = message;
        NSDictionary<NSString *, id> *arg_aMap = GetNullableObjectAtIndex(args, 0);
        [api callFlutterEchoNullableMap:arg_aMap
                             completion:^(NSDictionary<NSString *, id> *_Nullable output,
                                          FlutterError *_Nullable error) {
                               callback(wrapResult(output, error));
                             }];
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
@interface FlutterIntegrationCoreApiCodecReader : FlutterStandardReader
@end
@implementation FlutterIntegrationCoreApiCodecReader
- (nullable id)readValueOfType:(UInt8)type {
  switch (type) {
    case 128:
      return [AllNullableTypes fromList:[self readValue]];
    case 129:
      return [AllNullableTypesWrapper fromList:[self readValue]];
    case 130:
      return [AllTypes fromList:[self readValue]];
    default:
      return [super readValueOfType:type];
  }
}
@end

@interface FlutterIntegrationCoreApiCodecWriter : FlutterStandardWriter
@end
@implementation FlutterIntegrationCoreApiCodecWriter
- (void)writeValue:(id)value {
  if ([value isKindOfClass:[AllNullableTypes class]]) {
    [self writeByte:128];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[AllNullableTypesWrapper class]]) {
    [self writeByte:129];
    [self writeValue:[value toList]];
  } else if ([value isKindOfClass:[AllTypes class]]) {
    [self writeByte:130];
    [self writeValue:[value toList]];
  } else {
    [super writeValue:value];
  }
}
@end

@interface FlutterIntegrationCoreApiCodecReaderWriter : FlutterStandardReaderWriter
@end
@implementation FlutterIntegrationCoreApiCodecReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
  return [[FlutterIntegrationCoreApiCodecWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
  return [[FlutterIntegrationCoreApiCodecReader alloc] initWithData:data];
}
@end

NSObject<FlutterMessageCodec> *FlutterIntegrationCoreApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  static dispatch_once_t sPred = 0;
  dispatch_once(&sPred, ^{
    FlutterIntegrationCoreApiCodecReaderWriter *readerWriter =
        [[FlutterIntegrationCoreApiCodecReaderWriter alloc] init];
    sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
  });
  return sSharedObject;
}

@interface FlutterIntegrationCoreApi ()
@property(nonatomic, strong) NSObject<FlutterBinaryMessenger> *binaryMessenger;
@end

@implementation FlutterIntegrationCoreApi

- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
  self = [super init];
  if (self) {
    _binaryMessenger = binaryMessenger;
  }
  return self;
}
- (void)noopWithCompletion:(void (^)(NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.noop"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:nil
                 reply:^(id reply) {
                   completion(nil);
                 }];
}
- (void)echoAllTypes:(AllTypes *)arg_everything
          completion:(void (^)(AllTypes *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_everything ?: [NSNull null] ]
                 reply:^(id reply) {
                   AllTypes *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoAllNullableTypes:(AllNullableTypes *)arg_everything
                  completion:(void (^)(AllNullableTypes *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_everything ?: [NSNull null] ]
                 reply:^(id reply) {
                   AllNullableTypes *output = reply;
                   completion(output, nil);
                 }];
}
- (void)sendMultipleNullableTypesABool:(nullable NSNumber *)arg_aNullableBool
                                 anInt:(nullable NSNumber *)arg_aNullableInt
                               aString:(nullable NSString *)arg_aNullableString
                            completion:(void (^)(AllNullableTypes *_Nullable,
                                                 NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:
          @"dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[
    arg_aNullableBool ?: [NSNull null], arg_aNullableInt ?: [NSNull null],
    arg_aNullableString ?: [NSNull null]
  ]
                 reply:^(id reply) {
                   AllNullableTypes *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoBool:(NSNumber *)arg_aBool
      completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aBool ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSNumber *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoInt:(NSNumber *)arg_anInt
     completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_anInt ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSNumber *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoDouble:(NSNumber *)arg_aDouble
        completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aDouble ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSNumber *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoString:(NSString *)arg_aString
        completion:(void (^)(NSString *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aString ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSString *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoUint8List:(FlutterStandardTypedData *)arg_aList
           completion:
               (void (^)(FlutterStandardTypedData *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aList ?: [NSNull null] ]
                 reply:^(id reply) {
                   FlutterStandardTypedData *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoList:(NSArray<id> *)arg_aList
      completion:(void (^)(NSArray<id> *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aList ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSArray<id> *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoMap:(NSDictionary<NSString *, id> *)arg_aMap
     completion:(void (^)(NSDictionary<NSString *, id> *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aMap ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSDictionary<NSString *, id> *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoNullableBool:(nullable NSNumber *)arg_aBool
              completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aBool ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSNumber *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoNullableInt:(nullable NSNumber *)arg_anInt
             completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_anInt ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSNumber *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoNullableDouble:(nullable NSNumber *)arg_aDouble
                completion:(void (^)(NSNumber *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aDouble ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSNumber *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoNullableString:(nullable NSString *)arg_aString
                completion:(void (^)(NSString *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aString ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSString *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoNullableUint8List:(nullable FlutterStandardTypedData *)arg_aList
                   completion:(void (^)(FlutterStandardTypedData *_Nullable,
                                        NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aList ?: [NSNull null] ]
                 reply:^(id reply) {
                   FlutterStandardTypedData *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoNullableList:(nullable NSArray<id> *)arg_aList
              completion:(void (^)(NSArray<id> *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aList ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSArray<id> *output = reply;
                   completion(output, nil);
                 }];
}
- (void)echoNullableMap:(nullable NSDictionary<NSString *, id> *)arg_aMap
             completion:
                 (void (^)(NSDictionary<NSString *, id> *_Nullable, NSError *_Nullable))completion {
  FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
      messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap"
             binaryMessenger:self.binaryMessenger
                       codec:FlutterIntegrationCoreApiGetCodec()];
  [channel sendMessage:@[ arg_aMap ?: [NSNull null] ]
                 reply:^(id reply) {
                   NSDictionary<NSString *, id> *output = reply;
                   completion(output, nil);
                 }];
}
@end

NSObject<FlutterMessageCodec> *HostTrivialApiGetCodec() {
  static FlutterStandardMessageCodec *sSharedObject = nil;
  sSharedObject = [FlutterStandardMessageCodec sharedInstance];
  return sSharedObject;
}

void HostTrivialApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
                         NSObject<HostTrivialApi> *api) {
  {
    FlutterBasicMessageChannel *channel =
        [[FlutterBasicMessageChannel alloc] initWithName:@"dev.flutter.pigeon.HostTrivialApi.noop"
                                         binaryMessenger:binaryMessenger
                                                   codec:HostTrivialApiGetCodec()];
    if (api) {
      NSCAssert([api respondsToSelector:@selector(noopWithError:)],
                @"HostTrivialApi api (%@) doesn't respond to @selector(noopWithError:)", api);
      [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
        FlutterError *error;
        [api noopWithError:&error];
        callback(wrapResult(nil, error));
      }];
    } else {
      [channel setMessageHandler:nil];
    }
  }
}
