// mojo/public/cpp/test/module.test-mojom-blink.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 "mojo/public/cpp/test/module.test-mojom-blink.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 "mojo/public/cpp/test/module.test-mojom-params-data.h"
#include "mojo/public/cpp/test/module.test-mojom-shared-message-ids.h"

#include "mojo/public/cpp/test/module.test-mojom-blink-import-headers.h"
#include "mojo/public/cpp/test/module.test-mojom-blink-test-utils.h"
#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"


#ifndef MOJO_PUBLIC_CPP_TEST_MODULE_TEST_MOJOM_BLINK_JUMBO_H_
#define MOJO_PUBLIC_CPP_TEST_MODULE_TEST_MOJOM_BLINK_JUMBO_H_
#endif



namespace test_module {
namespace blink {
const char GlobalConst[] = "testString";
const char Struct::StructConst[] = "structConst";
Struct::Struct()
    : c() {}

Struct::Struct(
    bool c_in)
    : c(std::move(c_in)) {}

Struct::~Struct() = default;
size_t Struct::Hash(size_t seed) const {
  seed = mojo::internal::WTFHash(seed, this->c);
  return seed;
}

void Struct::WriteIntoTrace(
    perfetto::TracedValue traced_context) const {
  [[maybe_unused]] auto dict = std::move(traced_context).WriteDictionary();
  perfetto::WriteIntoTracedValueWithFallback(
    dict.AddItem(
      "c"), this->c,
#if BUILDFLAG(MOJO_TRACE_ENABLED)
      "<value of type bool>"
#else
      "<value>"
#endif  // BUILDFLAG(MOJO_TRACE_ENABLED)
    );
}

bool Struct::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context);
}
Union::Union() : tag_(Tag::kA) {
  data_.a = bool();
}

Union::~Union() {
  DestroyActive();
}


void Union::set_a(
    bool a) {
  if (tag_ != Tag::kA) {
    DestroyActive();
    tag_ = Tag::kA;
  }
  data_.a = a;
}
void Union::set_b(
    int64_t b) {
  if (tag_ != Tag::kB) {
    DestroyActive();
    tag_ = Tag::kB;
  }
  data_.b = b;
}

void Union::DestroyActive() {
  switch (tag_) {

    case Tag::kA:

      break;
    case Tag::kB:

      break;
  }
}
size_t Union::Hash(size_t seed) const {
  seed = mojo::internal::HashCombine(seed, static_cast<uint32_t>(tag_));
  switch (tag_) {

    case Tag::kA:
      return mojo::internal::WTFHash(seed, data_.a);
    case Tag::kB:
      return mojo::internal::WTFHash(seed, data_.b);
    default:
      NOTREACHED();
      return seed;
  }
}

bool Union::Validate(
    const void* data,
    mojo::internal::ValidationContext* validation_context) {
  return Data_::Validate(data, validation_context, false);
}
const char Interface::Name_[] = "test_module.Interface";
constexpr bool Interface::InterfaceConst;

std::pair<uint32_t, const void*> Interface::MessageToMethodInfo_(mojo::Message& message) {
  switch (message.name()) {
    case internal::kInterface_DoSomething_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)test_module::Interface::DoSomething");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Interface::DoSomething_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
    case internal::kInterface_DoSomethingElse_Name: {
      constexpr uint32_t value = base::MD5Hash32Constexpr(
              "(Impl)test_module::Interface::DoSomethingElse");
#if BUILDFLAG(IS_FUCHSIA)
        return std::make_pair(value, nullptr);
#else
        return std::make_pair(value, reinterpret_cast<const void*>(&Interface::DoSomethingElse_Sym::IPCSymbol));
#endif // BUILDFLAG(IS_FUCHSIA)
    }
  }
  return std::make_pair(0, nullptr);
}


const char* Interface::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::kInterface_DoSomething_Name:
            return "Receive test_module::Interface::DoSomething";
      case internal::kInterface_DoSomethingElse_Name:
            return "Receive test_module::Interface::DoSomethingElse";
    }
  } else {
    switch (message.name()) {
      case internal::kInterface_DoSomething_Name:
            return "Receive reply test_module::Interface::DoSomething";
      case internal::kInterface_DoSomethingElse_Name:
            return "Receive reply test_module::Interface::DoSomethingElse";
    }
  }
  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 Interface::DoSomething_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 Interface::DoSomethingElse_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 Interface_DoSomethingElse_ForwardToCallback
    : public mojo::MessageReceiver {
 public:
  Interface_DoSomethingElse_ForwardToCallback(
      Interface::DoSomethingElseCallback callback
      ) : callback_(std::move(callback)) {
  }

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

  bool Accept(mojo::Message* message) override;
 private:
  Interface::DoSomethingElseCallback callback_;
};

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

void InterfaceProxy::DoSomething(
    ) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT0("mojom", "Send test_module::Interface::DoSomething");
#endif
  const bool kExpectsResponse = false;
  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::kInterface_DoSomething_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::test_module::internal::Interface_DoSomething_Params_Data> params(
          message);
  params.Allocate();

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Interface::Name_);
  message.set_method_name("DoSomething");
#endif
  // This return value may be ignored as false implies the Connector has
  // encountered an error, which will be visible through other means.
  ::mojo::internal::SendMessage(*receiver_, message);
}

void InterfaceProxy::DoSomethingElse(
    StructPtr in_s, DoSomethingElseCallback callback) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send test_module::Interface::DoSomethingElse", "input_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("s"), in_s,
                        "<value of type StructPtr>");
   });
#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::kInterface_DoSomethingElse_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::test_module::internal::Interface_DoSomethingElse_Params_Data> params(
          message);
  params.Allocate();
  mojo::internal::MessageFragment<
      typename decltype(params->s)::BaseType> s_fragment(
          params.message());
  mojo::internal::Serialize<::test_module::StructDataView>(
      in_s, s_fragment);
  params->s.Set(
      s_fragment.is_null() ? nullptr : s_fragment.data());
  MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
      params->s.is_null(),
      mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
      "null s in Interface.DoSomethingElse request");

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

  ~Interface_DoSomethingElse_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:
  Interface_DoSomethingElse_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)
        << "Interface::DoSomethingElseCallback 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(
      GlobalEnum in_e);
};

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

  DCHECK(message->is_serialized());
  internal::Interface_DoSomethingElse_ResponseParams_Data* params =
      reinterpret_cast<
          internal::Interface_DoSomethingElse_ResponseParams_Data*>(
              message->mutable_payload());
  
  bool success = true;
  GlobalEnum p_e{};
  Interface_DoSomethingElse_ResponseParamsDataView input_data_view(params, message);
  
  if (success && !input_data_view.ReadE(&p_e))
    success = false;
  if (!success) {
    ReportValidationErrorForMessage(
        message,
        mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
        Interface::Name_, 1, true);
    return false;
  }
  if (!callback_.is_null())
    std::move(callback_).Run(
std::move(p_e));
  return true;
}

void Interface_DoSomethingElse_ProxyToResponder::Run(
    GlobalEnum in_e) {
#if BUILDFLAG(MOJO_TRACE_ENABLED)
  TRACE_EVENT1(
    "mojom", "Send reply test_module::Interface::DoSomethingElse", "async_response_parameters",
    [&](perfetto::TracedValue context){
      auto dict = std::move(context).WriteDictionary();
      perfetto::WriteIntoTracedValueWithFallback(
           dict.AddItem("e"), in_e,
                        "<value of type GlobalEnum>");
   });
#endif
  
  const uint32_t kFlags = mojo::Message::kFlagIsResponse |
      ((is_sync_) ? mojo::Message::kFlagIsSync : 0) |
      ((true) ? 0 : mojo::Message::kFlagNoInterrupt);
  
  mojo::Message message(
      internal::kInterface_DoSomethingElse_Name, kFlags, 0, 0, nullptr);
  mojo::internal::MessageFragment<
      ::test_module::internal::Interface_DoSomethingElse_ResponseParams_Data> params(
          message);
  params.Allocate();
  mojo::internal::Serialize<::test_module::GlobalEnum>(
      in_e, &params->e);

#if defined(ENABLE_IPC_FUZZER)
  message.set_interface_name(Interface::Name_);
  message.set_method_name("DoSomethingElse");
#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 InterfaceStubDispatch::Accept(
    Interface* impl,
    mojo::Message* message) {
  switch (message->header()->name) {
    case internal::kInterface_DoSomething_Name: {

      DCHECK(message->is_serialized());
      internal::Interface_DoSomething_Params_Data* params =
          reinterpret_cast<internal::Interface_DoSomething_Params_Data*>(
              message->mutable_payload());
      
      bool success = true;
      Interface_DoSomething_ParamsDataView input_data_view(params, message);
      
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            Interface::Name_, 0, false);
        return false;
      }
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->DoSomething();
      return true;
    }
    case internal::kInterface_DoSomethingElse_Name: {
      break;
    }
  }
  return false;
}

// static
bool InterfaceStubDispatch::AcceptWithResponder(
    Interface* 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::kInterface_DoSomething_Name: {
      break;
    }
    case internal::kInterface_DoSomethingElse_Name: {

      internal::Interface_DoSomethingElse_Params_Data* params =
          reinterpret_cast<
              internal::Interface_DoSomethingElse_Params_Data*>(
                  message->mutable_payload());
      
      bool success = true;
      StructPtr p_s{};
      Interface_DoSomethingElse_ParamsDataView input_data_view(params, message);
      
      if (success && !input_data_view.ReadS(&p_s))
        success = false;
      if (!success) {
        ReportValidationErrorForMessage(
            message,
            mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED,
            Interface::Name_, 1, false);
        return false;
      }
      Interface::DoSomethingElseCallback callback =
          Interface_DoSomethingElse_ProxyToResponder::CreateCallback(
              *message, std::move(responder));
      // A null |impl| means no implementation was bound.
      DCHECK(impl);
      impl->DoSomethingElse(
std::move(p_s), std::move(callback));
      return true;
    }
  }
  return false;
}


static const std::pair<uint32_t, mojo::internal::GenericValidationInfo> kInterfaceValidationInfo[] = {
    {internal::kInterface_DoSomething_Name,
     {&internal::Interface_DoSomething_Params_Data::Validate,
      nullptr /* no response */}},
    {internal::kInterface_DoSomethingElse_Name,
     {&internal::Interface_DoSomethingElse_Params_Data::Validate,
      &internal::Interface_DoSomethingElse_ResponseParams_Data::Validate}},
};

bool InterfaceRequestValidator::Accept(mojo::Message* message) {
  const char* name = ::test_module::blink::Interface::Name_;
  return mojo::internal::ValidateRequestGeneric(message, name, kInterfaceValidationInfo);
}

bool InterfaceResponseValidator::Accept(mojo::Message* message) {
  const char* name = ::test_module::blink::Interface::Name_;
  return mojo::internal::ValidateResponseGeneric(message, name, kInterfaceValidationInfo);

}


}  // namespace blink
}  // namespace test_module


namespace mojo {


// static
bool StructTraits<::test_module::blink::Struct::DataView, ::test_module::blink::StructPtr>::Read(
    ::test_module::blink::Struct::DataView input,
    ::test_module::blink::StructPtr* output) {
  bool success = true;
  ::test_module::blink::StructPtr result(::test_module::blink::Struct::New());
  
      if (success)
        result->c = input.c();
  *output = std::move(result);
  return success;
}

// static
bool UnionTraits<::test_module::blink::Union::DataView, ::test_module::blink::UnionPtr>::Read(
    ::test_module::blink::Union::DataView input,
    ::test_module::blink::UnionPtr* output) {
  using UnionType = ::test_module::blink::Union;
  using Tag = UnionType::Tag;

  switch (input.tag()) {
    case Tag::kA: {
      *output = UnionType::NewA(input.a());
      break;
    }
    case Tag::kB: {
      *output = UnionType::NewB(input.b());
      break;
    }
    default:

      return false;
  }
  return true;
}

}  // namespace mojo


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


namespace test_module {
namespace blink {


void InterfaceInterceptorForTesting::DoSomething() {
  GetForwardingInterface()->DoSomething();
}
void InterfaceInterceptorForTesting::DoSomethingElse(StructPtr s, DoSomethingElseCallback callback) {
  GetForwardingInterface()->DoSomethingElse(std::move(s), std::move(callback));
}
InterfaceAsyncWaiter::InterfaceAsyncWaiter(
    Interface* proxy) : proxy_(proxy) {}

InterfaceAsyncWaiter::~InterfaceAsyncWaiter() = default;

void InterfaceAsyncWaiter::DoSomethingElse(
    StructPtr s, GlobalEnum* out_e) {
  base::RunLoop loop;
  proxy_->DoSomethingElse(std::move(s),
      base::BindOnce(
          [](base::RunLoop* loop,
             GlobalEnum* out_e
,
             GlobalEnum e) {*out_e = std::move(e);
            loop->Quit();
          },
          &loop,
          out_e));
  loop.Run();
}





}  // namespace blink
}  // namespace test_module


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