// chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals.mojom.cc is auto generated by mojom_bindings_generator.py, do not edit

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
#endif

#include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals.mojom.h"

#include <math.h>
#include <stdint.h>
#include <utility>

#include "base/debug/alias.h"
#include "base/hash/md5_constexpr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/typed_macros.h"
#include "mojo/public/cpp/bindings/lib/generated_code_util.h"
#include "mojo/public/cpp/bindings/lib/message_internal.h"
#include "mojo/public/cpp/bindings/lib/send_message_helper.h"
#include "mojo/public/cpp/bindings/lib/proxy_to_responder.h"
#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/lib/unserialized_message_context.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/mojo_buildflags.h"
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"

#include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals.mojom-params-data.h"
#include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals.mojom-shared-message-ids.h"

#include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals.mojom-import-headers.h"
#include "chrome/browser/ui/webui/explore_sites_internals/explore_sites_internals.mojom-test-utils.h"


#ifndef CHROME_BROWSER_UI_WEBUI_EXPLORE_SITES_INTERNALS_EXPLORE_SITES_INTERNALS_MOJOM_JUMBO_H_
#define CHROME_BROWSER_UI_WEBUI_EXPLORE_SITES_INTERNALS_EXPLORE_SITES_INTERNALS_MOJOM_JUMBO_H_
#endif



namespace explore_sites_internals {
namespace mojom {
const char PageHandler::Name_[] = "explore_sites_internals.mojom.PageHandler";

std::pair<uint32_t, const void*> PageHandler::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kPageHandler_GetProperties_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)explore_sites_internals::mojom::PageHandler::GetProperties");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&PageHandler::GetProperties_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kPageHandler_ClearCachedExploreSitesCatalog_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)explore_sites_internals::mojom::PageHandler::ClearCachedExploreSitesCatalog");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&PageHandler::ClearCachedExploreSitesCatalog_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kPageHandler_ForceNetworkRequest_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)explore_sites_internals::mojom::PageHandler::ForceNetworkRequest");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&PageHandler::ForceNetworkRequest_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kPageHandler_OverrideCountryCode_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)explore_sites_internals::mojom::PageHandler::OverrideCountryCode");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&PageHandler::OverrideCountryCode_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* PageHandler::MessageToMethodName_(mojo::Message& message) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (!is_response) {
    switch (message.name()) {
      case internal::kPageHandler_GetProperties_Name:
            return "Receive explore_sites_internals::mojom::PageHandler::GetProperties";
      case internal::kPageHandler_ClearCachedExploreSitesCatalog_Name:
            return "Receive explore_sites_internals::mojom::PageHandler::ClearCachedExploreSitesCatalog";
      case internal::kPageHandler_ForceNetworkRequest_Name:
            return "Receive explore_sites_internals::mojom::PageHandler::ForceNetworkRequest";
      case internal::kPageHandler_OverrideCountryCode_Name:
            return "Receive explore_sites_internals::mojom::PageHandler::OverrideCountryCode";
    }
  } else {
    switch (message.name()) {
      case internal::kPageHandler_GetProperties_Name:
            return "Receive reply explore_sites_internals::mojom::PageHandler::GetProperties";
      case internal::kPageHandler_ClearCachedExploreSitesCatalog_Name:
            return "Receive reply explore_sites_internals::mojom::PageHandler::ClearCachedExploreSitesCatalog";
      case internal::kPageHandler_ForceNetworkRequest_Name:
            return "Receive reply explore_sites_internals::mojom::PageHandler::ForceNetworkRequest";
      case internal::kPageHandler_OverrideCountryCode_Name:
            return "Receive reply explore_sites_internals::mojom::PageHandler::OverrideCountryCode";
    }
  }
  return "Receive unknown mojo message";
#else
  bool is_response = message.has_flag(mojo::Message::kFlagIsResponse);
  if (is_response) {
    return "Receive mojo reply";
  } else {
    return "Receive mojo message";
  }
#endif // BUILDFLAG(MOJO_TRACE_ENABLED)
}

#if !BUILDFLAG(IS_FUCHSIA)
void PageHandler::GetProperties_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void PageHandler::ClearCachedExploreSitesCatalog_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void PageHandler::ForceNetworkRequest_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
void PageHandler::OverrideCountryCode_Sym::IPCSymbol() {
  // This method's address is used for indetifiying the mojo method name after
  // symblozation. So each IPCSymbol should have a unique address.
  NO_CODE_FOLDING();
}
# endif // !BUILDFLAG(IS_FUCHSIA)

class PageHandler_GetProperties_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  PageHandler_GetProperties_ForwardToCallback(
      PageHandler::GetPropertiesCallback callback
      ) : callback_(std::move(callback)) {
  }

  PageHandler_GetProperties_ForwardToCallback(const PageHandler_GetProperties_ForwardToCallback&) = delete;
  PageHandler_GetProperties_ForwardToCallback& operator=(const PageHandler_GetProperties_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  PageHandler::GetPropertiesCallback callback_;
};

class PageHandler_ClearCachedExploreSitesCatalog_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  PageHandler_ClearCachedExploreSitesCatalog_ForwardToCallback(
      PageHandler::ClearCachedExploreSitesCatalogCallback callback
      ) : callback_(std::move(callback)) {
  }

  PageHandler_ClearCachedExploreSitesCatalog_ForwardToCallback(const PageHandler_ClearCachedExploreSitesCatalog_ForwardToCallback&) = delete;
  PageHandler_ClearCachedExploreSitesCatalog_ForwardToCallback& operator=(const PageHandler_ClearCachedExploreSitesCatalog_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  PageHandler::ClearCachedExploreSitesCatalogCallback callback_;
};

class PageHandler_ForceNetworkRequest_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  PageHandler_ForceNetworkRequest_ForwardToCallback(
      PageHandler::ForceNetworkRequestCallback callback
      ) : callback_(std::move(callback)) {
  }

  PageHandler_ForceNetworkRequest_ForwardToCallback(const PageHandler_ForceNetworkRequest_ForwardToCallback&) = delete;
  PageHandler_ForceNetworkRequest_ForwardToCallback& operator=(const PageHandler_ForceNetworkRequest_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  PageHandler::ForceNetworkRequestCallback callback_;
};

class PageHandler_OverrideCountryCode_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  PageHandler_OverrideCountryCode_ForwardToCallback(
      PageHandler::OverrideCountryCodeCallback callback
      ) : callback_(std::move(callback)) {
  }

  PageHandler_OverrideCountryCode_ForwardToCallback(const PageHandler_OverrideCountryCode_ForwardToCallback&) = delete;
  PageHandler_OverrideCountryCode_ForwardToCallback& operator=(const PageHandler_OverrideCountryCode_ForwardToCallback&) = delete;

  bool Accept(mojo::Message* message) override;
 private:
  PageHandler::OverrideCountryCodeCallback callback_;
};

PageHandlerProxy::PageHandlerProxy(mojo::MessageReceiverWithResponder* receiver)
    : receiver_(receiver) {
}

void PageHandlerProxy::GetProperties(
    GetPropertiesCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send explore_sites_internals::mojom::PageHandler::GetProperties");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kPageHandler_GetProperties_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::explore_sites_internals::mojom::internal::PageHandler_GetProperties_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PageHandler::Name_);
  message.set_method_name("GetProperties");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new PageHandler_GetProperties_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void PageHandlerProxy::ClearCachedExploreSitesCatalog(
    ClearCachedExploreSitesCatalogCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send explore_sites_internals::mojom::PageHandler::ClearCachedExploreSitesCatalog");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kPageHandler_ClearCachedExploreSitesCatalog_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::explore_sites_internals::mojom::internal::PageHandler_ClearCachedExploreSitesCatalog_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PageHandler::Name_);
  message.set_method_name("ClearCachedExploreSitesCatalog");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new PageHandler_ClearCachedExploreSitesCatalog_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void PageHandlerProxy::ForceNetworkRequest(
    ForceNetworkRequestCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send explore_sites_internals::mojom::PageHandler::ForceNetworkRequest");
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kPageHandler_ForceNetworkRequest_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::explore_sites_internals::mojom::internal::PageHandler_ForceNetworkRequest_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PageHandler::Name_);
  message.set_method_name("ForceNetworkRequest");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new PageHandler_ForceNetworkRequest_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}

void PageHandlerProxy::OverrideCountryCode(
    const std::string& in_country_code, OverrideCountryCodeCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send explore_sites_internals::mojom::PageHandler::OverrideCountryCode", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("country_code"), in_country_code,
                        "<value of type const std::string&>");
   });
#endif
  const bool kExpectsResponse = true;
  const bool kIsSync = false;
  const bool kAllowInterrupt = true;
  
  const uint32_t kFlags =
      ((kExpectsResponse) ? mojo::Message::kFlagExpectsResponse : 0) |
      ((kIsSync) ? mojo::Message::kFlagIsSync : 0) |
      ((kAllowInterrupt) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kPageHandler_OverrideCountryCode_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::explore_sites_internals::mojom::internal::PageHandler_OverrideCountryCode_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->country_code)::BaseType> country_code_fragment(
          params.message());
  mojo::internal::Serialize<mojo::StringDataView>(
      in_country_code, country_code_fragment);
  params->country_code.Set(
      country_code_fragment.is_null() ? nullptr : country_code_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->country_code.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null country_code in PageHandler.OverrideCountryCode request");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PageHandler::Name_);
  message.set_method_name("OverrideCountryCode");
#endif
  std::unique_ptr<mojo::MessageReceiver> responder(
      new PageHandler_OverrideCountryCode_ForwardToCallback(
          std::move(callback)));
  ::mojo::internal::SendMessage(*receiver_, message, std::move(responder));
}
class PageHandler_GetProperties_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static PageHandler::GetPropertiesCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<PageHandler_GetProperties_ProxyToResponder> proxy(
        new PageHandler_GetProperties_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&PageHandler_GetProperties_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~PageHandler_GetProperties_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  PageHandler_GetProperties_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "PageHandler::GetPropertiesCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      const base::flat_map<std::string, std::string>& in_properties);
};

bool PageHandler_GetProperties_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::PageHandler_GetProperties_ResponseParams_Data* params =
      reinterpret_cast<
          internal::PageHandler_GetProperties_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  base::flat_map<std::string, std::string> p_properties{};
  PageHandler_GetProperties_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadProperties(&p_properties))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        PageHandler::Name_, 0, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_properties));
  return true;
}

void PageHandler_GetProperties_ProxyToResponder::Run(
    const base::flat_map<std::string, std::string>& in_properties) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply explore_sites_internals::mojom::PageHandler::GetProperties", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("properties"), in_properties,
                        "<value of type const base::flat_map<std::string, std::string>&>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kPageHandler_GetProperties_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::explore_sites_internals::mojom::internal::PageHandler_GetProperties_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->properties)::BaseType>
      properties_fragment(params.message());
  const mojo::internal::ContainerValidateParams properties_validate_params(
      new mojo::internal::ContainerValidateParams(0, false, new mojo::internal::ContainerValidateParams(0, false, nullptr)), new mojo::internal::ContainerValidateParams(0, false, new mojo::internal::ContainerValidateParams(0, false, nullptr)));
  mojo::internal::Serialize<mojo::MapDataView<mojo::StringDataView, mojo::StringDataView>>(
      in_properties, properties_fragment, &properties_validate_params);
  params->properties.Set(
      properties_fragment.is_null() ? nullptr : properties_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->properties.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null properties in ");

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PageHandler::Name_);
  message.set_method_name("GetProperties");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class PageHandler_ClearCachedExploreSitesCatalog_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static PageHandler::ClearCachedExploreSitesCatalogCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<PageHandler_ClearCachedExploreSitesCatalog_ProxyToResponder> proxy(
        new PageHandler_ClearCachedExploreSitesCatalog_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&PageHandler_ClearCachedExploreSitesCatalog_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~PageHandler_ClearCachedExploreSitesCatalog_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  PageHandler_ClearCachedExploreSitesCatalog_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "PageHandler::ClearCachedExploreSitesCatalogCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool PageHandler_ClearCachedExploreSitesCatalog_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::PageHandler_ClearCachedExploreSitesCatalog_ResponseParams_Data* params =
      reinterpret_cast<
          internal::PageHandler_ClearCachedExploreSitesCatalog_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_success{};
  PageHandler_ClearCachedExploreSitesCatalog_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        PageHandler::Name_, 1, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void PageHandler_ClearCachedExploreSitesCatalog_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply explore_sites_internals::mojom::PageHandler::ClearCachedExploreSitesCatalog", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kPageHandler_ClearCachedExploreSitesCatalog_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::explore_sites_internals::mojom::internal::PageHandler_ClearCachedExploreSitesCatalog_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PageHandler::Name_);
  message.set_method_name("ClearCachedExploreSitesCatalog");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class PageHandler_ForceNetworkRequest_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static PageHandler::ForceNetworkRequestCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<PageHandler_ForceNetworkRequest_ProxyToResponder> proxy(
        new PageHandler_ForceNetworkRequest_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&PageHandler_ForceNetworkRequest_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~PageHandler_ForceNetworkRequest_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  PageHandler_ForceNetworkRequest_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "PageHandler::ForceNetworkRequestCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool PageHandler_ForceNetworkRequest_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::PageHandler_ForceNetworkRequest_ResponseParams_Data* params =
      reinterpret_cast<
          internal::PageHandler_ForceNetworkRequest_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_success{};
  PageHandler_ForceNetworkRequest_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        PageHandler::Name_, 2, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void PageHandler_ForceNetworkRequest_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply explore_sites_internals::mojom::PageHandler::ForceNetworkRequest", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kPageHandler_ForceNetworkRequest_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::explore_sites_internals::mojom::internal::PageHandler_ForceNetworkRequest_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PageHandler::Name_);
  message.set_method_name("ForceNetworkRequest");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}
class PageHandler_OverrideCountryCode_ProxyToResponder : public ::mojo::internal::ProxyToResponder {
 public:
  static PageHandler::OverrideCountryCodeCallback CreateCallback(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
    std::unique_ptr<PageHandler_OverrideCountryCode_ProxyToResponder> proxy(
        new PageHandler_OverrideCountryCode_ProxyToResponder(
            message, std::move(responder)));
    return base::BindOnce(&PageHandler_OverrideCountryCode_ProxyToResponder::Run,
                          std::move(proxy));
  }

  ~PageHandler_OverrideCountryCode_ProxyToResponder() {
#if DCHECK_IS_ON()
    if (responder_) {
      // If we're being destroyed without being run, we want to ensure the
      // binding endpoint has been closed. This checks for that asynchronously.
      // We pass a bound generated callback to handle the response so that any
      // resulting DCHECK stack will have useful interface type information.
      responder_->IsConnectedAsync(base::BindOnce(&OnIsConnectedComplete));
    }
#endif
  }

 private:
  PageHandler_OverrideCountryCode_ProxyToResponder(
      ::mojo::Message& message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder)
      : ::mojo::internal::ProxyToResponder(message, std::move(responder)) {
  }

#if DCHECK_IS_ON()
  static void OnIsConnectedComplete(bool connected) {
    DCHECK(!connected)
        << "PageHandler::OverrideCountryCodeCallback was destroyed without "
        << "first either being run or its corresponding binding being closed. "
        << "It is an error to drop response callbacks which still correspond "
        << "to an open interface pipe.";
  }
#endif

  void Run(
      bool in_success);
};

bool PageHandler_OverrideCountryCode_ForwardToCallback::Accept(
    mojo::Message* message) {

  DCHECK(message->is_serialized());
  internal::PageHandler_OverrideCountryCode_ResponseParams_Data* params =
      reinterpret_cast<
          internal::PageHandler_OverrideCountryCode_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  bool p_success{};
  PageHandler_OverrideCountryCode_ResponseParamsDataView input_data_view(params, message);
  
  if (success)
    p_success = input_data_view.success();
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        PageHandler::Name_, 3, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_success));
  return true;
}

void PageHandler_OverrideCountryCode_ProxyToResponder::Run(
    bool in_success) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply explore_sites_internals::mojom::PageHandler::OverrideCountryCode", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("success"), in_success,
                        "<value of type bool>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kPageHandler_OverrideCountryCode_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::explore_sites_internals::mojom::internal::PageHandler_OverrideCountryCode_ResponseParams_Data> params(
          message);
  params.Allocate();
  params->success = in_success;

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(PageHandler::Name_);
  message.set_method_name("OverrideCountryCode");
#endif

  message.set_request_id(request_id_);
  message.set_trace_nonce(trace_nonce_);
  ::mojo::internal::SendMessage(*responder_, message);
  // SendMessage fails silently if the responder connection is closed,
  // or if the message is malformed.
  //
  // TODO(darin): If Accept() returns false due to a malformed message, that
  // may be good reason to close the connection. However, we don't have a
  // way to do that from here. We should add a way.
  responder_ = nullptr;
}

// static
bool PageHandlerStubDispatch::Accept(
    PageHandler* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kPageHandler_GetProperties_Name: {
      break;
    }
    case internal::kPageHandler_ClearCachedExploreSitesCatalog_Name: {
      break;
    }
    case internal::kPageHandler_ForceNetworkRequest_Name: {
      break;
    }
    case internal::kPageHandler_OverrideCountryCode_Name: {
      break;
    }
  }
  return false;
}

// static
bool PageHandlerStubDispatch::AcceptWithResponder(
    PageHandler* impl,
    mojo::Message* message,
    std::unique_ptr<mojo::MessageReceiverWithStatus> responder) {
  [[maybe_unused]] const bool message_is_sync =
      message->has_flag(mojo::Message::kFlagIsSync);
  [[maybe_unused]] const uint64_t request_id = message->request_id();
  switch (message->header()->name) {
    case internal::kPageHandler_GetProperties_Name: {

      internal::PageHandler_GetProperties_Params_Data* params =
          reinterpret_cast<
              internal::PageHandler_GetProperties_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      PageHandler_GetProperties_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            PageHandler::Name_, 0, false);
        return false;
      }
      PageHandler::GetPropertiesCallback callback =
          PageHandler_GetProperties_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->GetProperties(std::move(callback));
      return true;
    }
    case internal::kPageHandler_ClearCachedExploreSitesCatalog_Name: {

      internal::PageHandler_ClearCachedExploreSitesCatalog_Params_Data* params =
          reinterpret_cast<
              internal::PageHandler_ClearCachedExploreSitesCatalog_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      PageHandler_ClearCachedExploreSitesCatalog_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            PageHandler::Name_, 1, false);
        return false;
      }
      PageHandler::ClearCachedExploreSitesCatalogCallback callback =
          PageHandler_ClearCachedExploreSitesCatalog_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->ClearCachedExploreSitesCatalog(std::move(callback));
      return true;
    }
    case internal::kPageHandler_ForceNetworkRequest_Name: {

      internal::PageHandler_ForceNetworkRequest_Params_Data* params =
          reinterpret_cast<
              internal::PageHandler_ForceNetworkRequest_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      PageHandler_ForceNetworkRequest_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            PageHandler::Name_, 2, false);
        return false;
      }
      PageHandler::ForceNetworkRequestCallback callback =
          PageHandler_ForceNetworkRequest_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->ForceNetworkRequest(std::move(callback));
      return true;
    }
    case internal::kPageHandler_OverrideCountryCode_Name: {

      internal::PageHandler_OverrideCountryCode_Params_Data* params =
          reinterpret_cast<
              internal::PageHandler_OverrideCountryCode_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      std::string p_country_code{};
      PageHandler_OverrideCountryCode_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadCountryCode(&p_country_code))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            PageHandler::Name_, 3, false);
        return false;
      }
      PageHandler::OverrideCountryCodeCallback callback =
          PageHandler_OverrideCountryCode_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->OverrideCountryCode(
std::move(p_country_code), std::move(callback));
      return true;
    }
  }
  return false;
}


static const mojo::internal::GenericValidationInfo kPageHandlerValidationInfo[] = {
    {&internal::PageHandler_GetProperties_Params_Data::Validate,
     &internal::PageHandler_GetProperties_ResponseParams_Data::Validate},
    {&internal::PageHandler_ClearCachedExploreSitesCatalog_Params_Data::Validate,
     &internal::PageHandler_ClearCachedExploreSitesCatalog_ResponseParams_Data::Validate},
    {&internal::PageHandler_ForceNetworkRequest_Params_Data::Validate,
     &internal::PageHandler_ForceNetworkRequest_ResponseParams_Data::Validate},
    {&internal::PageHandler_OverrideCountryCode_Params_Data::Validate,
     &internal::PageHandler_OverrideCountryCode_ResponseParams_Data::Validate},
};

bool PageHandlerRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::explore_sites_internals::mojom::PageHandler::Name_;
  return mojo::internal::ValidateRequestGenericPacked(message, name, kPageHandlerValidationInfo);
}

bool PageHandlerResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::explore_sites_internals::mojom::PageHandler::Name_;
  return mojo::internal::ValidateResponseGenericPacked(message, name, kPageHandlerValidationInfo);
}


}  // namespace mojom
}  // namespace explore_sites_internals


namespace mojo {

}  // namespace mojo


// Symbols declared in the -test-utils.h header are defined here instead of a
// separate .cc file to save compile time.


namespace explore_sites_internals {
namespace mojom {


void PageHandlerInterceptorForTesting::GetProperties(GetPropertiesCallback callback) {
  GetForwardingInterface()->GetProperties(std::move(callback));
}
void PageHandlerInterceptorForTesting::ClearCachedExploreSitesCatalog(ClearCachedExploreSitesCatalogCallback callback) {
  GetForwardingInterface()->ClearCachedExploreSitesCatalog(std::move(callback));
}
void PageHandlerInterceptorForTesting::ForceNetworkRequest(ForceNetworkRequestCallback callback) {
  GetForwardingInterface()->ForceNetworkRequest(std::move(callback));
}
void PageHandlerInterceptorForTesting::OverrideCountryCode(const std::string& country_code, OverrideCountryCodeCallback callback) {
  GetForwardingInterface()->OverrideCountryCode(std::move(country_code), std::move(callback));
}
PageHandlerAsyncWaiter::PageHandlerAsyncWaiter(
    PageHandler* proxy) : proxy_(proxy) {}

PageHandlerAsyncWaiter::~PageHandlerAsyncWaiter() = default;

void PageHandlerAsyncWaiter::GetProperties(
    base::flat_map<std::string, std::string>* out_properties) {
  base::RunLoop loop;
  proxy_->GetProperties(
      base::BindOnce(
          [](base::RunLoop* loop,
             base::flat_map<std::string, std::string>* out_properties
,
             const base::flat_map<std::string, std::string>& properties) {*out_properties = std::move(properties);
            loop->Quit();
          },
          &loop,
          out_properties));
  loop.Run();
}
void PageHandlerAsyncWaiter::ClearCachedExploreSitesCatalog(
    bool* out_success) {
  base::RunLoop loop;
  proxy_->ClearCachedExploreSitesCatalog(
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}
void PageHandlerAsyncWaiter::ForceNetworkRequest(
    bool* out_success) {
  base::RunLoop loop;
  proxy_->ForceNetworkRequest(
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}
void PageHandlerAsyncWaiter::OverrideCountryCode(
    const std::string& country_code, bool* out_success) {
  base::RunLoop loop;
  proxy_->OverrideCountryCode(std::move(country_code),
      base::BindOnce(
          [](base::RunLoop* loop,
             bool* out_success
,
             bool success) {*out_success = std::move(success);
            loop->Quit();
          },
          &loop,
          out_success));
  loop.Run();
}





}  // namespace mojom
}  // namespace explore_sites_internals


#if defined(__clang__)
#pragma clang diagnostic pop
#endif