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

#undef _HAS_EXCEPTIONS

#include "core_tests.gen.h"

#include <flutter/basic_message_channel.h>
#include <flutter/binary_messenger.h>
#include <flutter/encodable_value.h>
#include <flutter/standard_message_codec.h>

#include <map>
#include <optional>
#include <string>

namespace core_tests_pigeontest {
using flutter::BasicMessageChannel;
using flutter::CustomEncodableValue;
using flutter::EncodableList;
using flutter::EncodableMap;
using flutter::EncodableValue;

// AllTypes

bool AllTypes::a_bool() const { return a_bool_; }
void AllTypes::set_a_bool(bool value_arg) { a_bool_ = value_arg; }

int64_t AllTypes::an_int() const { return an_int_; }
void AllTypes::set_an_int(int64_t value_arg) { an_int_ = value_arg; }

double AllTypes::a_double() const { return a_double_; }
void AllTypes::set_a_double(double value_arg) { a_double_ = value_arg; }

const std::vector<uint8_t>& AllTypes::a_byte_array() const {
  return a_byte_array_;
}
void AllTypes::set_a_byte_array(const std::vector<uint8_t>& value_arg) {
  a_byte_array_ = value_arg;
}

const std::vector<int32_t>& AllTypes::a4_byte_array() const {
  return a4_byte_array_;
}
void AllTypes::set_a4_byte_array(const std::vector<int32_t>& value_arg) {
  a4_byte_array_ = value_arg;
}

const std::vector<int64_t>& AllTypes::a8_byte_array() const {
  return a8_byte_array_;
}
void AllTypes::set_a8_byte_array(const std::vector<int64_t>& value_arg) {
  a8_byte_array_ = value_arg;
}

const std::vector<double>& AllTypes::a_float_array() const {
  return a_float_array_;
}
void AllTypes::set_a_float_array(const std::vector<double>& value_arg) {
  a_float_array_ = value_arg;
}

const EncodableList& AllTypes::a_list() const { return a_list_; }
void AllTypes::set_a_list(const EncodableList& value_arg) {
  a_list_ = value_arg;
}

const EncodableMap& AllTypes::a_map() const { return a_map_; }
void AllTypes::set_a_map(const EncodableMap& value_arg) { a_map_ = value_arg; }

const AnEnum& AllTypes::an_enum() const { return an_enum_; }
void AllTypes::set_an_enum(const AnEnum& value_arg) { an_enum_ = value_arg; }

const std::string& AllTypes::a_string() const { return a_string_; }
void AllTypes::set_a_string(std::string_view value_arg) {
  a_string_ = value_arg;
}

EncodableList AllTypes::ToEncodableList() const {
  EncodableList list;
  list.reserve(11);
  list.push_back(EncodableValue(a_bool_));
  list.push_back(EncodableValue(an_int_));
  list.push_back(EncodableValue(a_double_));
  list.push_back(EncodableValue(a_byte_array_));
  list.push_back(EncodableValue(a4_byte_array_));
  list.push_back(EncodableValue(a8_byte_array_));
  list.push_back(EncodableValue(a_float_array_));
  list.push_back(EncodableValue(a_list_));
  list.push_back(EncodableValue(a_map_));
  list.push_back(EncodableValue((int)an_enum_));
  list.push_back(EncodableValue(a_string_));
  return list;
}

AllTypes::AllTypes() {}

AllTypes::AllTypes(const EncodableList& list) {
  auto& encodable_a_bool = list[0];
  if (const bool* pointer_a_bool = std::get_if<bool>(&encodable_a_bool)) {
    a_bool_ = *pointer_a_bool;
  }
  auto& encodable_an_int = list[1];
  if (const int32_t* pointer_an_int = std::get_if<int32_t>(&encodable_an_int))
    an_int_ = *pointer_an_int;
  else if (const int64_t* pointer_an_int_64 =
               std::get_if<int64_t>(&encodable_an_int))
    an_int_ = *pointer_an_int_64;
  auto& encodable_a_double = list[2];
  if (const double* pointer_a_double =
          std::get_if<double>(&encodable_a_double)) {
    a_double_ = *pointer_a_double;
  }
  auto& encodable_a_byte_array = list[3];
  if (const std::vector<uint8_t>* pointer_a_byte_array =
          std::get_if<std::vector<uint8_t>>(&encodable_a_byte_array)) {
    a_byte_array_ = *pointer_a_byte_array;
  }
  auto& encodable_a4_byte_array = list[4];
  if (const std::vector<int32_t>* pointer_a4_byte_array =
          std::get_if<std::vector<int32_t>>(&encodable_a4_byte_array)) {
    a4_byte_array_ = *pointer_a4_byte_array;
  }
  auto& encodable_a8_byte_array = list[5];
  if (const std::vector<int64_t>* pointer_a8_byte_array =
          std::get_if<std::vector<int64_t>>(&encodable_a8_byte_array)) {
    a8_byte_array_ = *pointer_a8_byte_array;
  }
  auto& encodable_a_float_array = list[6];
  if (const std::vector<double>* pointer_a_float_array =
          std::get_if<std::vector<double>>(&encodable_a_float_array)) {
    a_float_array_ = *pointer_a_float_array;
  }
  auto& encodable_a_list = list[7];
  if (const EncodableList* pointer_a_list =
          std::get_if<EncodableList>(&encodable_a_list)) {
    a_list_ = *pointer_a_list;
  }
  auto& encodable_a_map = list[8];
  if (const EncodableMap* pointer_a_map =
          std::get_if<EncodableMap>(&encodable_a_map)) {
    a_map_ = *pointer_a_map;
  }
  auto& encodable_an_enum = list[9];
  if (const int32_t* pointer_an_enum = std::get_if<int32_t>(&encodable_an_enum))
    an_enum_ = (AnEnum)*pointer_an_enum;
  auto& encodable_a_string = list[10];
  if (const std::string* pointer_a_string =
          std::get_if<std::string>(&encodable_a_string)) {
    a_string_ = *pointer_a_string;
  }
}

// AllNullableTypes

const bool* AllNullableTypes::a_nullable_bool() const {
  return a_nullable_bool_ ? &(*a_nullable_bool_) : nullptr;
}
void AllNullableTypes::set_a_nullable_bool(const bool* value_arg) {
  a_nullable_bool_ = value_arg ? std::optional<bool>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_bool(bool value_arg) {
  a_nullable_bool_ = value_arg;
}

const int64_t* AllNullableTypes::a_nullable_int() const {
  return a_nullable_int_ ? &(*a_nullable_int_) : nullptr;
}
void AllNullableTypes::set_a_nullable_int(const int64_t* value_arg) {
  a_nullable_int_ =
      value_arg ? std::optional<int64_t>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_int(int64_t value_arg) {
  a_nullable_int_ = value_arg;
}

const double* AllNullableTypes::a_nullable_double() const {
  return a_nullable_double_ ? &(*a_nullable_double_) : nullptr;
}
void AllNullableTypes::set_a_nullable_double(const double* value_arg) {
  a_nullable_double_ =
      value_arg ? std::optional<double>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_double(double value_arg) {
  a_nullable_double_ = value_arg;
}

const std::vector<uint8_t>* AllNullableTypes::a_nullable_byte_array() const {
  return a_nullable_byte_array_ ? &(*a_nullable_byte_array_) : nullptr;
}
void AllNullableTypes::set_a_nullable_byte_array(
    const std::vector<uint8_t>* value_arg) {
  a_nullable_byte_array_ = value_arg
                               ? std::optional<std::vector<uint8_t>>(*value_arg)
                               : std::nullopt;
}
void AllNullableTypes::set_a_nullable_byte_array(
    const std::vector<uint8_t>& value_arg) {
  a_nullable_byte_array_ = value_arg;
}

const std::vector<int32_t>* AllNullableTypes::a_nullable4_byte_array() const {
  return a_nullable4_byte_array_ ? &(*a_nullable4_byte_array_) : nullptr;
}
void AllNullableTypes::set_a_nullable4_byte_array(
    const std::vector<int32_t>* value_arg) {
  a_nullable4_byte_array_ =
      value_arg ? std::optional<std::vector<int32_t>>(*value_arg)
                : std::nullopt;
}
void AllNullableTypes::set_a_nullable4_byte_array(
    const std::vector<int32_t>& value_arg) {
  a_nullable4_byte_array_ = value_arg;
}

const std::vector<int64_t>* AllNullableTypes::a_nullable8_byte_array() const {
  return a_nullable8_byte_array_ ? &(*a_nullable8_byte_array_) : nullptr;
}
void AllNullableTypes::set_a_nullable8_byte_array(
    const std::vector<int64_t>* value_arg) {
  a_nullable8_byte_array_ =
      value_arg ? std::optional<std::vector<int64_t>>(*value_arg)
                : std::nullopt;
}
void AllNullableTypes::set_a_nullable8_byte_array(
    const std::vector<int64_t>& value_arg) {
  a_nullable8_byte_array_ = value_arg;
}

const std::vector<double>* AllNullableTypes::a_nullable_float_array() const {
  return a_nullable_float_array_ ? &(*a_nullable_float_array_) : nullptr;
}
void AllNullableTypes::set_a_nullable_float_array(
    const std::vector<double>* value_arg) {
  a_nullable_float_array_ =
      value_arg ? std::optional<std::vector<double>>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_float_array(
    const std::vector<double>& value_arg) {
  a_nullable_float_array_ = value_arg;
}

const EncodableList* AllNullableTypes::a_nullable_list() const {
  return a_nullable_list_ ? &(*a_nullable_list_) : nullptr;
}
void AllNullableTypes::set_a_nullable_list(const EncodableList* value_arg) {
  a_nullable_list_ =
      value_arg ? std::optional<EncodableList>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_list(const EncodableList& value_arg) {
  a_nullable_list_ = value_arg;
}

const EncodableMap* AllNullableTypes::a_nullable_map() const {
  return a_nullable_map_ ? &(*a_nullable_map_) : nullptr;
}
void AllNullableTypes::set_a_nullable_map(const EncodableMap* value_arg) {
  a_nullable_map_ =
      value_arg ? std::optional<EncodableMap>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_map(const EncodableMap& value_arg) {
  a_nullable_map_ = value_arg;
}

const EncodableList* AllNullableTypes::nullable_nested_list() const {
  return nullable_nested_list_ ? &(*nullable_nested_list_) : nullptr;
}
void AllNullableTypes::set_nullable_nested_list(
    const EncodableList* value_arg) {
  nullable_nested_list_ =
      value_arg ? std::optional<EncodableList>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_nullable_nested_list(
    const EncodableList& value_arg) {
  nullable_nested_list_ = value_arg;
}

const EncodableMap* AllNullableTypes::nullable_map_with_annotations() const {
  return nullable_map_with_annotations_ ? &(*nullable_map_with_annotations_)
                                        : nullptr;
}
void AllNullableTypes::set_nullable_map_with_annotations(
    const EncodableMap* value_arg) {
  nullable_map_with_annotations_ =
      value_arg ? std::optional<EncodableMap>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_nullable_map_with_annotations(
    const EncodableMap& value_arg) {
  nullable_map_with_annotations_ = value_arg;
}

const EncodableMap* AllNullableTypes::nullable_map_with_object() const {
  return nullable_map_with_object_ ? &(*nullable_map_with_object_) : nullptr;
}
void AllNullableTypes::set_nullable_map_with_object(
    const EncodableMap* value_arg) {
  nullable_map_with_object_ =
      value_arg ? std::optional<EncodableMap>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_nullable_map_with_object(
    const EncodableMap& value_arg) {
  nullable_map_with_object_ = value_arg;
}

const AnEnum* AllNullableTypes::a_nullable_enum() const {
  return a_nullable_enum_ ? &(*a_nullable_enum_) : nullptr;
}
void AllNullableTypes::set_a_nullable_enum(const AnEnum* value_arg) {
  a_nullable_enum_ =
      value_arg ? std::optional<AnEnum>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_enum(const AnEnum& value_arg) {
  a_nullable_enum_ = value_arg;
}

const std::string* AllNullableTypes::a_nullable_string() const {
  return a_nullable_string_ ? &(*a_nullable_string_) : nullptr;
}
void AllNullableTypes::set_a_nullable_string(
    const std::string_view* value_arg) {
  a_nullable_string_ =
      value_arg ? std::optional<std::string>(*value_arg) : std::nullopt;
}
void AllNullableTypes::set_a_nullable_string(std::string_view value_arg) {
  a_nullable_string_ = value_arg;
}

EncodableList AllNullableTypes::ToEncodableList() const {
  EncodableList list;
  list.reserve(14);
  list.push_back(a_nullable_bool_ ? EncodableValue(*a_nullable_bool_)
                                  : EncodableValue());
  list.push_back(a_nullable_int_ ? EncodableValue(*a_nullable_int_)
                                 : EncodableValue());
  list.push_back(a_nullable_double_ ? EncodableValue(*a_nullable_double_)
                                    : EncodableValue());
  list.push_back(a_nullable_byte_array_
                     ? EncodableValue(*a_nullable_byte_array_)
                     : EncodableValue());
  list.push_back(a_nullable4_byte_array_
                     ? EncodableValue(*a_nullable4_byte_array_)
                     : EncodableValue());
  list.push_back(a_nullable8_byte_array_
                     ? EncodableValue(*a_nullable8_byte_array_)
                     : EncodableValue());
  list.push_back(a_nullable_float_array_
                     ? EncodableValue(*a_nullable_float_array_)
                     : EncodableValue());
  list.push_back(a_nullable_list_ ? EncodableValue(*a_nullable_list_)
                                  : EncodableValue());
  list.push_back(a_nullable_map_ ? EncodableValue(*a_nullable_map_)
                                 : EncodableValue());
  list.push_back(nullable_nested_list_ ? EncodableValue(*nullable_nested_list_)
                                       : EncodableValue());
  list.push_back(nullable_map_with_annotations_
                     ? EncodableValue(*nullable_map_with_annotations_)
                     : EncodableValue());
  list.push_back(nullable_map_with_object_
                     ? EncodableValue(*nullable_map_with_object_)
                     : EncodableValue());
  list.push_back(a_nullable_enum_ ? EncodableValue((int)(*a_nullable_enum_))
                                  : EncodableValue());
  list.push_back(a_nullable_string_ ? EncodableValue(*a_nullable_string_)
                                    : EncodableValue());
  return list;
}

AllNullableTypes::AllNullableTypes() {}

AllNullableTypes::AllNullableTypes(const EncodableList& list) {
  auto& encodable_a_nullable_bool = list[0];
  if (const bool* pointer_a_nullable_bool =
          std::get_if<bool>(&encodable_a_nullable_bool)) {
    a_nullable_bool_ = *pointer_a_nullable_bool;
  }
  auto& encodable_a_nullable_int = list[1];
  if (const int32_t* pointer_a_nullable_int =
          std::get_if<int32_t>(&encodable_a_nullable_int))
    a_nullable_int_ = *pointer_a_nullable_int;
  else if (const int64_t* pointer_a_nullable_int_64 =
               std::get_if<int64_t>(&encodable_a_nullable_int))
    a_nullable_int_ = *pointer_a_nullable_int_64;
  auto& encodable_a_nullable_double = list[2];
  if (const double* pointer_a_nullable_double =
          std::get_if<double>(&encodable_a_nullable_double)) {
    a_nullable_double_ = *pointer_a_nullable_double;
  }
  auto& encodable_a_nullable_byte_array = list[3];
  if (const std::vector<uint8_t>* pointer_a_nullable_byte_array =
          std::get_if<std::vector<uint8_t>>(&encodable_a_nullable_byte_array)) {
    a_nullable_byte_array_ = *pointer_a_nullable_byte_array;
  }
  auto& encodable_a_nullable4_byte_array = list[4];
  if (const std::vector<int32_t>* pointer_a_nullable4_byte_array =
          std::get_if<std::vector<int32_t>>(
              &encodable_a_nullable4_byte_array)) {
    a_nullable4_byte_array_ = *pointer_a_nullable4_byte_array;
  }
  auto& encodable_a_nullable8_byte_array = list[5];
  if (const std::vector<int64_t>* pointer_a_nullable8_byte_array =
          std::get_if<std::vector<int64_t>>(
              &encodable_a_nullable8_byte_array)) {
    a_nullable8_byte_array_ = *pointer_a_nullable8_byte_array;
  }
  auto& encodable_a_nullable_float_array = list[6];
  if (const std::vector<double>* pointer_a_nullable_float_array =
          std::get_if<std::vector<double>>(&encodable_a_nullable_float_array)) {
    a_nullable_float_array_ = *pointer_a_nullable_float_array;
  }
  auto& encodable_a_nullable_list = list[7];
  if (const EncodableList* pointer_a_nullable_list =
          std::get_if<EncodableList>(&encodable_a_nullable_list)) {
    a_nullable_list_ = *pointer_a_nullable_list;
  }
  auto& encodable_a_nullable_map = list[8];
  if (const EncodableMap* pointer_a_nullable_map =
          std::get_if<EncodableMap>(&encodable_a_nullable_map)) {
    a_nullable_map_ = *pointer_a_nullable_map;
  }
  auto& encodable_nullable_nested_list = list[9];
  if (const EncodableList* pointer_nullable_nested_list =
          std::get_if<EncodableList>(&encodable_nullable_nested_list)) {
    nullable_nested_list_ = *pointer_nullable_nested_list;
  }
  auto& encodable_nullable_map_with_annotations = list[10];
  if (const EncodableMap* pointer_nullable_map_with_annotations =
          std::get_if<EncodableMap>(&encodable_nullable_map_with_annotations)) {
    nullable_map_with_annotations_ = *pointer_nullable_map_with_annotations;
  }
  auto& encodable_nullable_map_with_object = list[11];
  if (const EncodableMap* pointer_nullable_map_with_object =
          std::get_if<EncodableMap>(&encodable_nullable_map_with_object)) {
    nullable_map_with_object_ = *pointer_nullable_map_with_object;
  }
  auto& encodable_a_nullable_enum = list[12];
  if (const int32_t* pointer_a_nullable_enum =
          std::get_if<int32_t>(&encodable_a_nullable_enum))
    a_nullable_enum_ = (AnEnum)*pointer_a_nullable_enum;
  auto& encodable_a_nullable_string = list[13];
  if (const std::string* pointer_a_nullable_string =
          std::get_if<std::string>(&encodable_a_nullable_string)) {
    a_nullable_string_ = *pointer_a_nullable_string;
  }
}

// AllNullableTypesWrapper

const AllNullableTypes& AllNullableTypesWrapper::values() const {
  return values_;
}
void AllNullableTypesWrapper::set_values(const AllNullableTypes& value_arg) {
  values_ = value_arg;
}

EncodableList AllNullableTypesWrapper::ToEncodableList() const {
  EncodableList list;
  list.reserve(1);
  list.push_back(EncodableValue(values_.ToEncodableList()));
  return list;
}

AllNullableTypesWrapper::AllNullableTypesWrapper() {}

AllNullableTypesWrapper::AllNullableTypesWrapper(const EncodableList& list) {
  auto& encodable_values = list[0];
  if (const EncodableList* pointer_values =
          std::get_if<EncodableList>(&encodable_values)) {
    values_ = AllNullableTypes(*pointer_values);
  }
}

HostIntegrationCoreApiCodecSerializer::HostIntegrationCoreApiCodecSerializer() {
}
EncodableValue HostIntegrationCoreApiCodecSerializer::ReadValueOfType(
    uint8_t type, flutter::ByteStreamReader* stream) const {
  switch (type) {
    case 128:
      return CustomEncodableValue(
          AllNullableTypes(std::get<EncodableList>(ReadValue(stream))));
    case 129:
      return CustomEncodableValue(
          AllNullableTypesWrapper(std::get<EncodableList>(ReadValue(stream))));
    case 130:
      return CustomEncodableValue(
          AllTypes(std::get<EncodableList>(ReadValue(stream))));
    default:
      return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
  }
}

void HostIntegrationCoreApiCodecSerializer::WriteValue(
    const EncodableValue& value, flutter::ByteStreamWriter* stream) const {
  if (const CustomEncodableValue* custom_value =
          std::get_if<CustomEncodableValue>(&value)) {
    if (custom_value->type() == typeid(AllNullableTypes)) {
      stream->WriteByte(128);
      WriteValue(
          EncodableValue(
              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
          stream);
      return;
    }
    if (custom_value->type() == typeid(AllNullableTypesWrapper)) {
      stream->WriteByte(129);
      WriteValue(
          EncodableValue(std::any_cast<AllNullableTypesWrapper>(*custom_value)
                             .ToEncodableList()),
          stream);
      return;
    }
    if (custom_value->type() == typeid(AllTypes)) {
      stream->WriteByte(130);
      WriteValue(EncodableValue(
                     std::any_cast<AllTypes>(*custom_value).ToEncodableList()),
                 stream);
      return;
    }
  }
  flutter::StandardCodecSerializer::WriteValue(value, stream);
}

/// The codec used by HostIntegrationCoreApi.
const flutter::StandardMessageCodec& HostIntegrationCoreApi::GetCodec() {
  return flutter::StandardMessageCodec::GetInstance(
      &HostIntegrationCoreApiCodecSerializer::GetInstance());
}

// Sets up an instance of `HostIntegrationCoreApi` to handle messages through
// the `binary_messenger`.
void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger,
                                   HostIntegrationCoreApi* api) {
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noop",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              std::optional<FlutterError> output = api->Noop();
              if (output.has_value()) {
                reply(WrapError(output.value()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(EncodableValue());
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_everything_arg = args.at(0);
              if (encodable_everything_arg.IsNull()) {
                reply(WrapError("everything_arg unexpectedly null."));
                return;
              }
              const auto& everything_arg = std::any_cast<const AllTypes&>(
                  std::get<CustomEncodableValue>(encodable_everything_arg));
              ErrorOr<AllTypes> output = api->EchoAllTypes(everything_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(
                  CustomEncodableValue(std::move(output).TakeValue()));
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_everything_arg = args.at(0);
              const auto* everything_arg =
                  &(std::any_cast<const AllNullableTypes&>(
                      std::get<CustomEncodableValue>(
                          encodable_everything_arg)));
              ErrorOr<std::optional<AllNullableTypes>> output =
                  api->EchoAllNullableTypes(everything_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(
                    CustomEncodableValue(std::move(output_optional).value()));
              } else {
                wrapped.push_back(EncodableValue());
              }
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.throwError", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              std::optional<FlutterError> output = api->ThrowError();
              if (output.has_value()) {
                reply(WrapError(output.value()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(EncodableValue());
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_an_int_arg = args.at(0);
              if (encodable_an_int_arg.IsNull()) {
                reply(WrapError("an_int_arg unexpectedly null."));
                return;
              }
              const int64_t an_int_arg = encodable_an_int_arg.LongValue();
              ErrorOr<int64_t> output = api->EchoInt(an_int_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(EncodableValue(std::move(output).TakeValue()));
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_double_arg = args.at(0);
              if (encodable_a_double_arg.IsNull()) {
                reply(WrapError("a_double_arg unexpectedly null."));
                return;
              }
              const auto& a_double_arg =
                  std::get<double>(encodable_a_double_arg);
              ErrorOr<double> output = api->EchoDouble(a_double_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(EncodableValue(std::move(output).TakeValue()));
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_bool_arg = args.at(0);
              if (encodable_a_bool_arg.IsNull()) {
                reply(WrapError("a_bool_arg unexpectedly null."));
                return;
              }
              const auto& a_bool_arg = std::get<bool>(encodable_a_bool_arg);
              ErrorOr<bool> output = api->EchoBool(a_bool_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(EncodableValue(std::move(output).TakeValue()));
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoString", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_string_arg = args.at(0);
              if (encodable_a_string_arg.IsNull()) {
                reply(WrapError("a_string_arg unexpectedly null."));
                return;
              }
              const auto& a_string_arg =
                  std::get<std::string>(encodable_a_string_arg);
              ErrorOr<std::string> output = api->EchoString(a_string_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(EncodableValue(std::move(output).TakeValue()));
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_uint8_list_arg = args.at(0);
              if (encodable_a_uint8_list_arg.IsNull()) {
                reply(WrapError("a_uint8_list_arg unexpectedly null."));
                return;
              }
              const auto& a_uint8_list_arg =
                  std::get<std::vector<uint8_t>>(encodable_a_uint8_list_arg);
              ErrorOr<std::vector<uint8_t>> output =
                  api->EchoUint8List(a_uint8_list_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(EncodableValue(std::move(output).TakeValue()));
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_an_object_arg = args.at(0);
              if (encodable_an_object_arg.IsNull()) {
                reply(WrapError("an_object_arg unexpectedly null."));
                return;
              }
              const auto& an_object_arg = encodable_an_object_arg;
              ErrorOr<EncodableValue> output = api->EchoObject(an_object_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(EncodableValue(std::move(output).TakeValue()));
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_wrapper_arg = args.at(0);
              if (encodable_wrapper_arg.IsNull()) {
                reply(WrapError("wrapper_arg unexpectedly null."));
                return;
              }
              const auto& wrapper_arg =
                  std::any_cast<const AllNullableTypesWrapper&>(
                      std::get<CustomEncodableValue>(encodable_wrapper_arg));
              ErrorOr<std::optional<std::string>> output =
                  api->ExtractNestedNullableString(wrapper_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(
                    EncodableValue(std::move(output_optional).value()));
              } else {
                wrapped.push_back(EncodableValue());
              }
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_nullable_string_arg = args.at(0);
              const auto* nullable_string_arg =
                  std::get_if<std::string>(&encodable_nullable_string_arg);
              ErrorOr<AllNullableTypesWrapper> output =
                  api->CreateNestedNullableString(nullable_string_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(
                  CustomEncodableValue(std::move(output).TakeValue()));
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_nullable_bool_arg = args.at(0);
              const auto* a_nullable_bool_arg =
                  std::get_if<bool>(&encodable_a_nullable_bool_arg);
              const auto& encodable_a_nullable_int_arg = args.at(1);
              const int64_t a_nullable_int_arg_value =
                  encodable_a_nullable_int_arg.IsNull()
                      ? 0
                      : encodable_a_nullable_int_arg.LongValue();
              const auto* a_nullable_int_arg =
                  encodable_a_nullable_int_arg.IsNull()
                      ? nullptr
                      : &a_nullable_int_arg_value;
              const auto& encodable_a_nullable_string_arg = args.at(2);
              const auto* a_nullable_string_arg =
                  std::get_if<std::string>(&encodable_a_nullable_string_arg);
              ErrorOr<AllNullableTypes> output = api->SendMultipleNullableTypes(
                  a_nullable_bool_arg, a_nullable_int_arg,
                  a_nullable_string_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(
                  CustomEncodableValue(std::move(output).TakeValue()));
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_nullable_int_arg = args.at(0);
              const int64_t a_nullable_int_arg_value =
                  encodable_a_nullable_int_arg.IsNull()
                      ? 0
                      : encodable_a_nullable_int_arg.LongValue();
              const auto* a_nullable_int_arg =
                  encodable_a_nullable_int_arg.IsNull()
                      ? nullptr
                      : &a_nullable_int_arg_value;
              ErrorOr<std::optional<int64_t>> output =
                  api->EchoNullableInt(a_nullable_int_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(
                    EncodableValue(std::move(output_optional).value()));
              } else {
                wrapped.push_back(EncodableValue());
              }
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_nullable_double_arg = args.at(0);
              const auto* a_nullable_double_arg =
                  std::get_if<double>(&encodable_a_nullable_double_arg);
              ErrorOr<std::optional<double>> output =
                  api->EchoNullableDouble(a_nullable_double_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(
                    EncodableValue(std::move(output_optional).value()));
              } else {
                wrapped.push_back(EncodableValue());
              }
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_nullable_bool_arg = args.at(0);
              const auto* a_nullable_bool_arg =
                  std::get_if<bool>(&encodable_a_nullable_bool_arg);
              ErrorOr<std::optional<bool>> output =
                  api->EchoNullableBool(a_nullable_bool_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(
                    EncodableValue(std::move(output_optional).value()));
              } else {
                wrapped.push_back(EncodableValue());
              }
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_nullable_string_arg = args.at(0);
              const auto* a_nullable_string_arg =
                  std::get_if<std::string>(&encodable_a_nullable_string_arg);
              ErrorOr<std::optional<std::string>> output =
                  api->EchoNullableString(a_nullable_string_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(
                    EncodableValue(std::move(output_optional).value()));
              } else {
                wrapped.push_back(EncodableValue());
              }
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_nullable_uint8_list_arg = args.at(0);
              const auto* a_nullable_uint8_list_arg =
                  std::get_if<std::vector<uint8_t>>(
                      &encodable_a_nullable_uint8_list_arg);
              ErrorOr<std::optional<std::vector<uint8_t>>> output =
                  api->EchoNullableUint8List(a_nullable_uint8_list_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(
                    EncodableValue(std::move(output_optional).value()));
              } else {
                wrapped.push_back(EncodableValue());
              }
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_nullable_object_arg = args.at(0);
              const auto* a_nullable_object_arg =
                  &encodable_a_nullable_object_arg;
              ErrorOr<std::optional<EncodableValue>> output =
                  api->EchoNullableObject(a_nullable_object_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(
                    EncodableValue(std::move(output_optional).value()));
              } else {
                wrapped.push_back(EncodableValue());
              }
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              api->NoopAsync([reply](std::optional<FlutterError>&& output) {
                if (output.has_value()) {
                  reply(WrapError(output.value()));
                  return;
                }
                EncodableList wrapped;
                wrapped.push_back(EncodableValue());
                reply(EncodableValue(std::move(wrapped)));
              });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_string_arg = args.at(0);
              if (encodable_a_string_arg.IsNull()) {
                reply(WrapError("a_string_arg unexpectedly null."));
                return;
              }
              const auto& a_string_arg =
                  std::get<std::string>(encodable_a_string_arg);
              api->EchoAsyncString(
                  a_string_arg, [reply](ErrorOr<std::string>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        EncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.throwAsyncError",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              api->ThrowAsyncError(
                  [reply](ErrorOr<std::optional<EncodableValue>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(
                          EncodableValue(std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(EncodableValue());
                    }
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.throwAsyncErrorFromVoid",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              api->ThrowAsyncErrorFromVoid(
                  [reply](std::optional<FlutterError>&& output) {
                    if (output.has_value()) {
                      reply(WrapError(output.value()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(EncodableValue());
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              api->CallFlutterNoop(
                  [reply](std::optional<FlutterError>&& output) {
                    if (output.has_value()) {
                      reply(WrapError(output.value()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(EncodableValue());
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoAllTypes",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_everything_arg = args.at(0);
              if (encodable_everything_arg.IsNull()) {
                reply(WrapError("everything_arg unexpectedly null."));
                return;
              }
              const auto& everything_arg = std::any_cast<const AllTypes&>(
                  std::get<CustomEncodableValue>(encodable_everything_arg));
              api->CallFlutterEchoAllTypes(
                  everything_arg, [reply](ErrorOr<AllTypes>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        CustomEncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi."
        "callFlutterSendMultipleNullableTypes",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_nullable_bool_arg = args.at(0);
              const auto* a_nullable_bool_arg =
                  std::get_if<bool>(&encodable_a_nullable_bool_arg);
              const auto& encodable_a_nullable_int_arg = args.at(1);
              const int64_t a_nullable_int_arg_value =
                  encodable_a_nullable_int_arg.IsNull()
                      ? 0
                      : encodable_a_nullable_int_arg.LongValue();
              const auto* a_nullable_int_arg =
                  encodable_a_nullable_int_arg.IsNull()
                      ? nullptr
                      : &a_nullable_int_arg_value;
              const auto& encodable_a_nullable_string_arg = args.at(2);
              const auto* a_nullable_string_arg =
                  std::get_if<std::string>(&encodable_a_nullable_string_arg);
              api->CallFlutterSendMultipleNullableTypes(
                  a_nullable_bool_arg, a_nullable_int_arg,
                  a_nullable_string_arg,
                  [reply](ErrorOr<AllNullableTypes>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        CustomEncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoBool",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_bool_arg = args.at(0);
              if (encodable_a_bool_arg.IsNull()) {
                reply(WrapError("a_bool_arg unexpectedly null."));
                return;
              }
              const auto& a_bool_arg = std::get<bool>(encodable_a_bool_arg);
              api->CallFlutterEchoBool(
                  a_bool_arg, [reply](ErrorOr<bool>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        EncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoInt",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_an_int_arg = args.at(0);
              if (encodable_an_int_arg.IsNull()) {
                reply(WrapError("an_int_arg unexpectedly null."));
                return;
              }
              const int64_t an_int_arg = encodable_an_int_arg.LongValue();
              api->CallFlutterEchoInt(
                  an_int_arg, [reply](ErrorOr<int64_t>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        EncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoDouble",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_double_arg = args.at(0);
              if (encodable_a_double_arg.IsNull()) {
                reply(WrapError("a_double_arg unexpectedly null."));
                return;
              }
              const auto& a_double_arg =
                  std::get<double>(encodable_a_double_arg);
              api->CallFlutterEchoDouble(
                  a_double_arg, [reply](ErrorOr<double>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        EncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_string_arg = args.at(0);
              if (encodable_a_string_arg.IsNull()) {
                reply(WrapError("a_string_arg unexpectedly null."));
                return;
              }
              const auto& a_string_arg =
                  std::get<std::string>(encodable_a_string_arg);
              api->CallFlutterEchoString(
                  a_string_arg, [reply](ErrorOr<std::string>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        EncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoUint8List",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_list_arg = args.at(0);
              if (encodable_a_list_arg.IsNull()) {
                reply(WrapError("a_list_arg unexpectedly null."));
                return;
              }
              const auto& a_list_arg =
                  std::get<std::vector<uint8_t>>(encodable_a_list_arg);
              api->CallFlutterEchoUint8List(
                  a_list_arg, [reply](ErrorOr<std::vector<uint8_t>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        EncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoList",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_list_arg = args.at(0);
              if (encodable_a_list_arg.IsNull()) {
                reply(WrapError("a_list_arg unexpectedly null."));
                return;
              }
              const auto& a_list_arg =
                  std::get<EncodableList>(encodable_a_list_arg);
              api->CallFlutterEchoList(
                  a_list_arg, [reply](ErrorOr<EncodableList>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        EncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoMap",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_map_arg = args.at(0);
              if (encodable_a_map_arg.IsNull()) {
                reply(WrapError("a_map_arg unexpectedly null."));
                return;
              }
              const auto& a_map_arg =
                  std::get<EncodableMap>(encodable_a_map_arg);
              api->CallFlutterEchoMap(
                  a_map_arg, [reply](ErrorOr<EncodableMap>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    wrapped.push_back(
                        EncodableValue(std::move(output).TakeValue()));
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableBool",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_bool_arg = args.at(0);
              const auto* a_bool_arg = std::get_if<bool>(&encodable_a_bool_arg);
              api->CallFlutterEchoNullableBool(
                  a_bool_arg, [reply](ErrorOr<std::optional<bool>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(
                          EncodableValue(std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(EncodableValue());
                    }
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableInt",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_an_int_arg = args.at(0);
              const int64_t an_int_arg_value =
                  encodable_an_int_arg.IsNull()
                      ? 0
                      : encodable_an_int_arg.LongValue();
              const auto* an_int_arg =
                  encodable_an_int_arg.IsNull() ? nullptr : &an_int_arg_value;
              api->CallFlutterEchoNullableInt(
                  an_int_arg,
                  [reply](ErrorOr<std::optional<int64_t>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(
                          EncodableValue(std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(EncodableValue());
                    }
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi."
        "callFlutterEchoNullableDouble",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_double_arg = args.at(0);
              const auto* a_double_arg =
                  std::get_if<double>(&encodable_a_double_arg);
              api->CallFlutterEchoNullableDouble(
                  a_double_arg,
                  [reply](ErrorOr<std::optional<double>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(
                          EncodableValue(std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(EncodableValue());
                    }
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi."
        "callFlutterEchoNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_string_arg = args.at(0);
              const auto* a_string_arg =
                  std::get_if<std::string>(&encodable_a_string_arg);
              api->CallFlutterEchoNullableString(
                  a_string_arg,
                  [reply](ErrorOr<std::optional<std::string>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(
                          EncodableValue(std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(EncodableValue());
                    }
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi."
        "callFlutterEchoNullableUint8List",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_list_arg = args.at(0);
              const auto* a_list_arg =
                  std::get_if<std::vector<uint8_t>>(&encodable_a_list_arg);
              api->CallFlutterEchoNullableUint8List(
                  a_list_arg,
                  [reply](
                      ErrorOr<std::optional<std::vector<uint8_t>>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(
                          EncodableValue(std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(EncodableValue());
                    }
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableList",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_list_arg = args.at(0);
              const auto* a_list_arg =
                  std::get_if<EncodableList>(&encodable_a_list_arg);
              api->CallFlutterEchoNullableList(
                  a_list_arg,
                  [reply](ErrorOr<std::optional<EncodableList>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(
                          EncodableValue(std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(EncodableValue());
                    }
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableMap",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              const auto& args = std::get<EncodableList>(message);
              const auto& encodable_a_map_arg = args.at(0);
              const auto* a_map_arg =
                  std::get_if<EncodableMap>(&encodable_a_map_arg);
              api->CallFlutterEchoNullableMap(
                  a_map_arg,
                  [reply](ErrorOr<std::optional<EncodableMap>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(
                          EncodableValue(std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(EncodableValue());
                    }
                    reply(EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
}

EncodableValue HostIntegrationCoreApi::WrapError(
    std::string_view error_message) {
  return EncodableValue(
      EncodableList{EncodableValue(std::string(error_message)),
                    EncodableValue("Error"), EncodableValue()});
}
EncodableValue HostIntegrationCoreApi::WrapError(const FlutterError& error) {
  return EncodableValue(EncodableList{EncodableValue(error.message()),
                                      EncodableValue(error.code()),
                                      error.details()});
}

FlutterIntegrationCoreApiCodecSerializer::
    FlutterIntegrationCoreApiCodecSerializer() {}
EncodableValue FlutterIntegrationCoreApiCodecSerializer::ReadValueOfType(
    uint8_t type, flutter::ByteStreamReader* stream) const {
  switch (type) {
    case 128:
      return CustomEncodableValue(
          AllNullableTypes(std::get<EncodableList>(ReadValue(stream))));
    case 129:
      return CustomEncodableValue(
          AllNullableTypesWrapper(std::get<EncodableList>(ReadValue(stream))));
    case 130:
      return CustomEncodableValue(
          AllTypes(std::get<EncodableList>(ReadValue(stream))));
    default:
      return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
  }
}

void FlutterIntegrationCoreApiCodecSerializer::WriteValue(
    const EncodableValue& value, flutter::ByteStreamWriter* stream) const {
  if (const CustomEncodableValue* custom_value =
          std::get_if<CustomEncodableValue>(&value)) {
    if (custom_value->type() == typeid(AllNullableTypes)) {
      stream->WriteByte(128);
      WriteValue(
          EncodableValue(
              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
          stream);
      return;
    }
    if (custom_value->type() == typeid(AllNullableTypesWrapper)) {
      stream->WriteByte(129);
      WriteValue(
          EncodableValue(std::any_cast<AllNullableTypesWrapper>(*custom_value)
                             .ToEncodableList()),
          stream);
      return;
    }
    if (custom_value->type() == typeid(AllTypes)) {
      stream->WriteByte(130);
      WriteValue(EncodableValue(
                     std::any_cast<AllTypes>(*custom_value).ToEncodableList()),
                 stream);
      return;
    }
  }
  flutter::StandardCodecSerializer::WriteValue(value, stream);
}

// Generated class from Pigeon that represents Flutter messages that can be
// called from C++.
FlutterIntegrationCoreApi::FlutterIntegrationCoreApi(
    flutter::BinaryMessenger* binary_messenger) {
  this->binary_messenger_ = binary_messenger;
}

const flutter::StandardMessageCodec& FlutterIntegrationCoreApi::GetCodec() {
  return flutter::StandardMessageCodec::GetInstance(
      &FlutterIntegrationCoreApiCodecSerializer::GetInstance());
}

void FlutterIntegrationCoreApi::Noop(
    std::function<void(void)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_, "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue();
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) { on_success(); });
}
void FlutterIntegrationCoreApi::EchoAllTypes(
    const AllTypes& everything_arg,
    std::function<void(const AllTypes&)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes", &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      EncodableValue(everything_arg.ToEncodableList()),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value = std::any_cast<const AllTypes&>(
            std::get<CustomEncodableValue>(encodable_return_value));
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoAllNullableTypes(
    const AllNullableTypes& everything_arg,
    std::function<void(const AllNullableTypes&)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      EncodableValue(everything_arg.ToEncodableList()),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value = std::any_cast<const AllNullableTypes&>(
            std::get<CustomEncodableValue>(encodable_return_value));
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::SendMultipleNullableTypes(
    const bool* a_nullable_bool_arg, const int64_t* a_nullable_int_arg,
    const std::string* a_nullable_string_arg,
    std::function<void(const AllNullableTypes&)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      a_nullable_bool_arg ? EncodableValue(*a_nullable_bool_arg)
                          : EncodableValue(),
      a_nullable_int_arg ? EncodableValue(*a_nullable_int_arg)
                         : EncodableValue(),
      a_nullable_string_arg ? EncodableValue(*a_nullable_string_arg)
                            : EncodableValue(),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value = std::any_cast<const AllNullableTypes&>(
            std::get<CustomEncodableValue>(encodable_return_value));
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoBool(
    bool a_bool_arg, std::function<void(bool)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool", &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      EncodableValue(a_bool_arg),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value = std::get<bool>(encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoInt(
    int64_t an_int_arg, std::function<void(int64_t)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      EncodableValue(an_int_arg),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const int64_t return_value = encodable_return_value.LongValue();
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoDouble(
    double a_double_arg, std::function<void(double)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble", &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      EncodableValue(a_double_arg),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value = std::get<double>(encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoString(
    const std::string& a_string_arg,
    std::function<void(const std::string&)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString", &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      EncodableValue(a_string_arg),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value =
            std::get<std::string>(encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoUint8List(
    const std::vector<uint8_t>& a_list_arg,
    std::function<void(const std::vector<uint8_t>&)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      EncodableValue(a_list_arg),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value =
            std::get<std::vector<uint8_t>>(encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoList(
    const EncodableList& a_list_arg,
    std::function<void(const EncodableList&)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList", &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      EncodableValue(a_list_arg),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value =
            std::get<EncodableList>(encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoMap(
    const EncodableMap& a_map_arg,
    std::function<void(const EncodableMap&)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      EncodableValue(a_map_arg),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value =
            std::get<EncodableMap>(encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoNullableBool(
    const bool* a_bool_arg, std::function<void(const bool*)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      a_bool_arg ? EncodableValue(*a_bool_arg) : EncodableValue(),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto* return_value = std::get_if<bool>(&encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoNullableInt(
    const int64_t* an_int_arg, std::function<void(const int64_t*)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      an_int_arg ? EncodableValue(*an_int_arg) : EncodableValue(),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const int64_t return_value_value =
            encodable_return_value.IsNull()
                ? 0
                : encodable_return_value.LongValue();
        const auto* return_value =
            encodable_return_value.IsNull() ? nullptr : &return_value_value;
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoNullableDouble(
    const double* a_double_arg, std::function<void(const double*)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      a_double_arg ? EncodableValue(*a_double_arg) : EncodableValue(),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto* return_value = std::get_if<double>(&encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoNullableString(
    const std::string* a_string_arg,
    std::function<void(const std::string*)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      a_string_arg ? EncodableValue(*a_string_arg) : EncodableValue(),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto* return_value =
            std::get_if<std::string>(&encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoNullableUint8List(
    const std::vector<uint8_t>* a_list_arg,
    std::function<void(const std::vector<uint8_t>*)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      a_list_arg ? EncodableValue(*a_list_arg) : EncodableValue(),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto* return_value =
            std::get_if<std::vector<uint8_t>>(&encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoNullableList(
    const EncodableList* a_list_arg,
    std::function<void(const EncodableList*)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      a_list_arg ? EncodableValue(*a_list_arg) : EncodableValue(),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto* return_value =
            std::get_if<EncodableList>(&encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoNullableMap(
    const EncodableMap* a_map_arg,
    std::function<void(const EncodableMap*)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap",
      &GetCodec());
  EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
      a_map_arg ? EncodableValue(*a_map_arg) : EncodableValue(),
  });
  channel->Send(
      encoded_api_arguments,
      [on_success = std::move(on_success), on_error = std::move(on_error)](
          const uint8_t* reply, size_t reply_size) {
        std::unique_ptr<EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto* return_value =
            std::get_if<EncodableMap>(&encodable_return_value);
        on_success(return_value);
      });
}
/// The codec used by HostTrivialApi.
const flutter::StandardMessageCodec& HostTrivialApi::GetCodec() {
  return flutter::StandardMessageCodec::GetInstance(
      &flutter::StandardCodecSerializer::GetInstance());
}

// Sets up an instance of `HostTrivialApi` to handle messages through the
// `binary_messenger`.
void HostTrivialApi::SetUp(flutter::BinaryMessenger* binary_messenger,
                           HostTrivialApi* api) {
  {
    auto channel = std::make_unique<BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostTrivialApi.noop",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const EncodableValue& message,
                const flutter::MessageReply<EncodableValue>& reply) {
            try {
              std::optional<FlutterError> output = api->Noop();
              if (output.has_value()) {
                reply(WrapError(output.value()));
                return;
              }
              EncodableList wrapped;
              wrapped.push_back(EncodableValue());
              reply(EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
}

EncodableValue HostTrivialApi::WrapError(std::string_view error_message) {
  return EncodableValue(
      EncodableList{EncodableValue(std::string(error_message)),
                    EncodableValue("Error"), EncodableValue()});
}
EncodableValue HostTrivialApi::WrapError(const FlutterError& error) {
  return EncodableValue(EncodableList{EncodableValue(error.message()),
                                      EncodableValue(error.code()),
                                      error.details()});
}

}  // namespace core_tests_pigeontest
