// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Autogenerated from Pigeon (v7.0.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 {

// 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 flutter::EncodableList& AllTypes::a_list() const { return a_list_; }
void AllTypes::set_a_list(const flutter::EncodableList& value_arg) {
  a_list_ = value_arg;
}

const flutter::EncodableMap& AllTypes::a_map() const { return a_map_; }
void AllTypes::set_a_map(const flutter::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;
}

flutter::EncodableList AllTypes::ToEncodableList() const {
  return flutter::EncodableList{
      flutter::EncodableValue(a_bool_),
      flutter::EncodableValue(an_int_),
      flutter::EncodableValue(a_double_),
      flutter::EncodableValue(a_byte_array_),
      flutter::EncodableValue(a4_byte_array_),
      flutter::EncodableValue(a8_byte_array_),
      flutter::EncodableValue(a_float_array_),
      flutter::EncodableValue(a_list_),
      flutter::EncodableValue(a_map_),
      flutter::EncodableValue((int)an_enum_),
      flutter::EncodableValue(a_string_),
  };
}

AllTypes::AllTypes() {}

AllTypes::AllTypes(const flutter::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 flutter::EncodableList* pointer_a_list =
          std::get_if<flutter::EncodableList>(&encodable_a_list)) {
    a_list_ = *pointer_a_list;
  }
  auto& encodable_a_map = list[8];
  if (const flutter::EncodableMap* pointer_a_map =
          std::get_if<flutter::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 flutter::EncodableList* AllNullableTypes::a_nullable_list() const {
  return a_nullable_list_ ? &(*a_nullable_list_) : nullptr;
}
void AllNullableTypes::set_a_nullable_list(
    const flutter::EncodableList* value_arg) {
  a_nullable_list_ = value_arg
                         ? std::optional<flutter::EncodableList>(*value_arg)
                         : std::nullopt;
}
void AllNullableTypes::set_a_nullable_list(
    const flutter::EncodableList& value_arg) {
  a_nullable_list_ = value_arg;
}

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

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

const flutter::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 flutter::EncodableMap* value_arg) {
  nullable_map_with_annotations_ =
      value_arg ? std::optional<flutter::EncodableMap>(*value_arg)
                : std::nullopt;
}
void AllNullableTypes::set_nullable_map_with_annotations(
    const flutter::EncodableMap& value_arg) {
  nullable_map_with_annotations_ = value_arg;
}

const flutter::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 flutter::EncodableMap* value_arg) {
  nullable_map_with_object_ =
      value_arg ? std::optional<flutter::EncodableMap>(*value_arg)
                : std::nullopt;
}
void AllNullableTypes::set_nullable_map_with_object(
    const flutter::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;
}

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

AllNullableTypes::AllNullableTypes() {}

AllNullableTypes::AllNullableTypes(const flutter::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 flutter::EncodableList* pointer_a_nullable_list =
          std::get_if<flutter::EncodableList>(&encodable_a_nullable_list)) {
    a_nullable_list_ = *pointer_a_nullable_list;
  }
  auto& encodable_a_nullable_map = list[8];
  if (const flutter::EncodableMap* pointer_a_nullable_map =
          std::get_if<flutter::EncodableMap>(&encodable_a_nullable_map)) {
    a_nullable_map_ = *pointer_a_nullable_map;
  }
  auto& encodable_nullable_nested_list = list[9];
  if (const flutter::EncodableList* pointer_nullable_nested_list =
          std::get_if<flutter::EncodableList>(
              &encodable_nullable_nested_list)) {
    nullable_nested_list_ = *pointer_nullable_nested_list;
  }
  auto& encodable_nullable_map_with_annotations = list[10];
  if (const flutter::EncodableMap* pointer_nullable_map_with_annotations =
          std::get_if<flutter::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 flutter::EncodableMap* pointer_nullable_map_with_object =
          std::get_if<flutter::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;
}

flutter::EncodableList AllNullableTypesWrapper::ToEncodableList() const {
  return flutter::EncodableList{
      flutter::EncodableValue(values_.ToEncodableList()),
  };
}

AllNullableTypesWrapper::AllNullableTypesWrapper() {}

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

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

    case 129:
      return flutter::CustomEncodableValue(AllNullableTypesWrapper(
          std::get<flutter::EncodableList>(ReadValue(stream))));

    case 130:
      return flutter::CustomEncodableValue(
          AllTypes(std::get<flutter::EncodableList>(ReadValue(stream))));

    default:
      return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
  }
}

void HostIntegrationCoreApiCodecSerializer::WriteValue(
    const flutter::EncodableValue& value,
    flutter::ByteStreamWriter* stream) const {
  if (const flutter::CustomEncodableValue* custom_value =
          std::get_if<flutter::CustomEncodableValue>(&value)) {
    if (custom_value->type() == typeid(AllNullableTypes)) {
      stream->WriteByte(128);
      WriteValue(
          flutter::EncodableValue(
              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
          stream);
      return;
    }
    if (custom_value->type() == typeid(AllNullableTypesWrapper)) {
      stream->WriteByte(129);
      WriteValue(flutter::EncodableValue(
                     std::any_cast<AllNullableTypesWrapper>(*custom_value)
                         .ToEncodableList()),
                 stream);
      return;
    }
    if (custom_value->type() == typeid(AllTypes)) {
      stream->WriteByte(130);
      WriteValue(flutter::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<flutter::BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noop",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              std::optional<FlutterError> output = api->Noop();
              if (output.has_value()) {
                reply(WrapError(output.value()));
                return;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(flutter::EncodableValue());
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllTypes", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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<flutter::CustomEncodableValue>(
                      encodable_everything_arg));
              ErrorOr<AllTypes> output = api->EchoAllTypes(everything_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(
                  flutter::CustomEncodableValue(std::move(output).TakeValue()));
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_everything_arg = args.at(0);
              const auto* everything_arg =
                  &(std::any_cast<const AllNullableTypes&>(
                      std::get<flutter::CustomEncodableValue>(
                          encodable_everything_arg)));
              ErrorOr<std::optional<AllNullableTypes>> output =
                  api->EchoAllNullableTypes(everything_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              flutter::EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(flutter::CustomEncodableValue(
                    std::move(output_optional).value()));
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.throwError", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              std::optional<FlutterError> output = api->ThrowError();
              if (output.has_value()) {
                reply(WrapError(output.value()));
                return;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(flutter::EncodableValue());
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoInt",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(
                  flutter::EncodableValue(std::move(output).TakeValue()));
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoDouble", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(
                  flutter::EncodableValue(std::move(output).TakeValue()));
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.echoBool",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(
                  flutter::EncodableValue(std::move(output).TakeValue()));
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoString", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(
                  flutter::EncodableValue(std::move(output).TakeValue()));
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoUint8List", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(
                  flutter::EncodableValue(std::move(output).TakeValue()));
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoObject", &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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<flutter::EncodableValue> output =
                  api->EchoObject(an_object_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(
                  flutter::EncodableValue(std::move(output).TakeValue()));
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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<flutter::CustomEncodableValue>(
                          encodable_wrapper_arg));
              ErrorOr<std::optional<std::string>> output =
                  api->ExtractNestedNullableString(wrapper_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              flutter::EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(flutter::EncodableValue(
                    std::move(output_optional).value()));
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(
                  flutter::CustomEncodableValue(std::move(output).TakeValue()));
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(
                  flutter::CustomEncodableValue(std::move(output).TakeValue()));
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(flutter::EncodableValue(
                    std::move(output_optional).value()));
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(flutter::EncodableValue(
                    std::move(output_optional).value()));
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(flutter::EncodableValue(
                    std::move(output_optional).value()));
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(flutter::EncodableValue(
                    std::move(output_optional).value()));
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
              }
              flutter::EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(flutter::EncodableValue(
                    std::move(output_optional).value()));
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableObject",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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<flutter::EncodableValue>> output =
                  api->EchoNullableObject(a_nullable_object_arg);
              if (output.has_error()) {
                reply(WrapError(output.error()));
                return;
              }
              flutter::EncodableList wrapped;
              auto output_optional = std::move(output).TakeValue();
              if (output_optional) {
                wrapped.push_back(flutter::EncodableValue(
                    std::move(output_optional).value()));
              } else {
                wrapped.push_back(flutter::EncodableValue());
              }
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostIntegrationCoreApi.noopAsync",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              api->NoopAsync([reply](std::optional<FlutterError>&& output) {
                if (output.has_value()) {
                  reply(WrapError(output.value()));
                  return;
                }
                flutter::EncodableList wrapped;
                wrapped.push_back(flutter::EncodableValue());
                reply(flutter::EncodableValue(std::move(wrapped)));
              });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.echoAsyncString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(
                        flutter::EncodableValue(std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterNoop",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              api->CallFlutterNoop(
                  [reply](std::optional<FlutterError>&& output) {
                    if (output.has_value()) {
                      reply(WrapError(output.value()));
                      return;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(flutter::EncodableValue());
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoAllTypes",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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<flutter::CustomEncodableValue>(
                      encodable_everything_arg));
              api->CallFlutterEchoAllTypes(
                  everything_arg, [reply](ErrorOr<AllTypes>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(flutter::CustomEncodableValue(
                        std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi."
        "callFlutterSendMultipleNullableTypes",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(flutter::CustomEncodableValue(
                        std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoBool",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(
                        flutter::EncodableValue(std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoInt",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(
                        flutter::EncodableValue(std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoDouble",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(
                        flutter::EncodableValue(std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(
                        flutter::EncodableValue(std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoUint8List",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(
                        flutter::EncodableValue(std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoList",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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<flutter::EncodableList>(encodable_a_list_arg);
              api->CallFlutterEchoList(
                  a_list_arg,
                  [reply](ErrorOr<flutter::EncodableList>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(
                        flutter::EncodableValue(std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoMap",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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<flutter::EncodableMap>(encodable_a_map_arg);
              api->CallFlutterEchoMap(
                  a_map_arg, [reply](ErrorOr<flutter::EncodableMap>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    flutter::EncodableList wrapped;
                    wrapped.push_back(
                        flutter::EncodableValue(std::move(output).TakeValue()));
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableBool",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(flutter::EncodableValue(
                          std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(flutter::EncodableValue());
                    }
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableInt",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(flutter::EncodableValue(
                          std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(flutter::EncodableValue());
                    }
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi."
        "callFlutterEchoNullableDouble",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(flutter::EncodableValue(
                          std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(flutter::EncodableValue());
                    }
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi."
        "callFlutterEchoNullableString",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(flutter::EncodableValue(
                          std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(flutter::EncodableValue());
                    }
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi."
        "callFlutterEchoNullableUint8List",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::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;
                    }
                    flutter::EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(flutter::EncodableValue(
                          std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(flutter::EncodableValue());
                    }
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableList",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_list_arg = args.at(0);
              const auto* a_list_arg =
                  std::get_if<flutter::EncodableList>(&encodable_a_list_arg);
              api->CallFlutterEchoNullableList(
                  a_list_arg,
                  [reply](
                      ErrorOr<std::optional<flutter::EncodableList>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    flutter::EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(flutter::EncodableValue(
                          std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(flutter::EncodableValue());
                    }
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
  {
    auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
        binary_messenger,
        "dev.flutter.pigeon.HostIntegrationCoreApi.callFlutterEchoNullableMap",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              const auto& args = std::get<flutter::EncodableList>(message);
              const auto& encodable_a_map_arg = args.at(0);
              const auto* a_map_arg =
                  std::get_if<flutter::EncodableMap>(&encodable_a_map_arg);
              api->CallFlutterEchoNullableMap(
                  a_map_arg,
                  [reply](
                      ErrorOr<std::optional<flutter::EncodableMap>>&& output) {
                    if (output.has_error()) {
                      reply(WrapError(output.error()));
                      return;
                    }
                    flutter::EncodableList wrapped;
                    auto output_optional = std::move(output).TakeValue();
                    if (output_optional) {
                      wrapped.push_back(flutter::EncodableValue(
                          std::move(output_optional).value()));
                    } else {
                      wrapped.push_back(flutter::EncodableValue());
                    }
                    reply(flutter::EncodableValue(std::move(wrapped)));
                  });
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
}

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

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

    case 129:
      return flutter::CustomEncodableValue(AllNullableTypesWrapper(
          std::get<flutter::EncodableList>(ReadValue(stream))));

    case 130:
      return flutter::CustomEncodableValue(
          AllTypes(std::get<flutter::EncodableList>(ReadValue(stream))));

    default:
      return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
  }
}

void FlutterIntegrationCoreApiCodecSerializer::WriteValue(
    const flutter::EncodableValue& value,
    flutter::ByteStreamWriter* stream) const {
  if (const flutter::CustomEncodableValue* custom_value =
          std::get_if<flutter::CustomEncodableValue>(&value)) {
    if (custom_value->type() == typeid(AllNullableTypes)) {
      stream->WriteByte(128);
      WriteValue(
          flutter::EncodableValue(
              std::any_cast<AllNullableTypes>(*custom_value).ToEncodableList()),
          stream);
      return;
    }
    if (custom_value->type() == typeid(AllNullableTypesWrapper)) {
      stream->WriteByte(129);
      WriteValue(flutter::EncodableValue(
                     std::any_cast<AllNullableTypesWrapper>(*custom_value)
                         .ToEncodableList()),
                 stream);
      return;
    }
    if (custom_value->type() == typeid(AllTypes)) {
      stream->WriteByte(130);
      WriteValue(flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_, "dev.flutter.pigeon.FlutterIntegrationCoreApi.noop",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments = flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllTypes", &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          flutter::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<flutter::EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value = std::any_cast<const AllTypes&>(
            std::get<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          flutter::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<flutter::EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value = std::any_cast<const AllNullableTypes&>(
            std::get<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.sendMultipleNullableTypes",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          a_nullable_bool_arg ? flutter::EncodableValue(*a_nullable_bool_arg)
                              : flutter::EncodableValue(),
          a_nullable_int_arg ? flutter::EncodableValue(*a_nullable_int_arg)
                             : flutter::EncodableValue(),
          a_nullable_string_arg
              ? flutter::EncodableValue(*a_nullable_string_arg)
              : flutter::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<flutter::EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value = std::any_cast<const AllNullableTypes&>(
            std::get<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoBool", &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          flutter::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<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoInt",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          flutter::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<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoDouble", &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          flutter::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<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString", &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          flutter::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<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoUint8List",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          flutter::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<flutter::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 flutter::EncodableList& a_list_arg,
    std::function<void(const flutter::EncodableList&)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoList", &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          flutter::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<flutter::EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value =
            std::get<flutter::EncodableList>(encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoMap(
    const flutter::EncodableMap& a_map_arg,
    std::function<void(const flutter::EncodableMap&)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
      binary_messenger_, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoMap",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          flutter::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<flutter::EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto& return_value =
            std::get<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableBool",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          a_bool_arg ? flutter::EncodableValue(*a_bool_arg)
                     : flutter::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<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableInt",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          an_int_arg ? flutter::EncodableValue(*an_int_arg)
                     : flutter::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<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableDouble",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          a_double_arg ? flutter::EncodableValue(*a_double_arg)
                       : flutter::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<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableString",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          a_string_arg ? flutter::EncodableValue(*a_string_arg)
                       : flutter::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<flutter::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<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableUint8List",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          a_list_arg ? flutter::EncodableValue(*a_list_arg)
                     : flutter::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<flutter::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 flutter::EncodableList* a_list_arg,
    std::function<void(const flutter::EncodableList*)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableList",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          a_list_arg ? flutter::EncodableValue(*a_list_arg)
                     : flutter::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<flutter::EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto* return_value =
            std::get_if<flutter::EncodableList>(&encodable_return_value);
        on_success(return_value);
      });
}
void FlutterIntegrationCoreApi::EchoNullableMap(
    const flutter::EncodableMap* a_map_arg,
    std::function<void(const flutter::EncodableMap*)>&& on_success,
    std::function<void(const FlutterError&)>&& on_error) {
  auto channel = std::make_unique<flutter::BasicMessageChannel<>>(
      binary_messenger_,
      "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoNullableMap",
      &GetCodec());
  flutter::EncodableValue encoded_api_arguments =
      flutter::EncodableValue(flutter::EncodableList{
          a_map_arg ? flutter::EncodableValue(*a_map_arg)
                    : flutter::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<flutter::EncodableValue> response =
            GetCodec().DecodeMessage(reply, reply_size);
        const auto& encodable_return_value = *response;
        const auto* return_value =
            std::get_if<flutter::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<flutter::BasicMessageChannel<>>(
        binary_messenger, "dev.flutter.pigeon.HostTrivialApi.noop",
        &GetCodec());
    if (api != nullptr) {
      channel->SetMessageHandler(
          [api](const flutter::EncodableValue& message,
                const flutter::MessageReply<flutter::EncodableValue>& reply) {
            try {
              std::optional<FlutterError> output = api->Noop();
              if (output.has_value()) {
                reply(WrapError(output.value()));
                return;
              }
              flutter::EncodableList wrapped;
              wrapped.push_back(flutter::EncodableValue());
              reply(flutter::EncodableValue(std::move(wrapped)));
            } catch (const std::exception& exception) {
              reply(WrapError(exception.what()));
            }
          });
    } else {
      channel->SetMessageHandler(nullptr);
    }
  }
}

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

}  // namespace core_tests_pigeontest
