// 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 (v6.0.2), 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.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);
    }
  }
}

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{
          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);
      });
}
/// 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
