// chrome/browser/ui/webui/reset_password/reset_password.mojom.h 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.

#ifndef CHROME_BROWSER_UI_WEBUI_RESET_PASSWORD_RESET_PASSWORD_MOJOM_H_
#define CHROME_BROWSER_UI_WEBUI_RESET_PASSWORD_RESET_PASSWORD_MOJOM_H_

#include <stdint.h>

#include <limits>
#include <type_traits>
#include <utility>

#include "third_party/abseil-cpp/absl/types/optional.h"
#include "mojo/public/cpp/bindings/clone_traits.h"
#include "mojo/public/cpp/bindings/equals_traits.h"
#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/struct_ptr.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/cpp/bindings/union_traits.h"

#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"

#include "chrome/browser/ui/webui/reset_password/reset_password.mojom-shared.h"
#include "chrome/browser/ui/webui/reset_password/reset_password.mojom-forward.h"
#include <string>
#include <vector>

#include "mojo/public/cpp/bindings/lib/control_message_handler.h"
#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"



#ifdef KYTHE_IS_RUNNING
#pragma kythe_inline_metadata "Metadata comment"
#endif


namespace mojom {

class ResetPasswordHandlerProxy;

template <typename ImplRefTraits>
class ResetPasswordHandlerStub;

class ResetPasswordHandlerRequestValidator;


// @generated_from: mojom.ResetPasswordHandler
class  ResetPasswordHandler
    : public ResetPasswordHandlerInterfaceBase {
 public:
  static const char Name_[];
  static std::pair<uint32_t, const void*> MessageToMethodInfo_(mojo::Message& message);
  static const char* MessageToMethodName_(mojo::Message& message);
  static constexpr uint32_t Version_ = 0;
  static constexpr bool PassesAssociatedKinds_ = false;
  static constexpr bool HasSyncMethods_ = false;
  static constexpr bool HasUninterruptableMethods_ = false;

  using Base_ = ResetPasswordHandlerInterfaceBase;
  using Proxy_ = ResetPasswordHandlerProxy;

  template <typename ImplRefTraits>
  using Stub_ = ResetPasswordHandlerStub<ImplRefTraits>;

  using RequestValidator_ = ResetPasswordHandlerRequestValidator;
  using ResponseValidator_ = mojo::PassThroughFilter;
  enum MethodMinVersions : uint32_t {
    kHandlePasswordResetMinVersion = 0,
  };

// crbug.com/1340245 - this causes binary size bloat on Fuchsia, and we're OK
// with not having this data in traces there.
#if !BUILDFLAG(IS_FUCHSIA)
  struct HandlePasswordReset_Sym {
    NOINLINE static void IPCSymbol();
  };
#endif // !BUILDFLAG(IS_FUCHSIA)
  virtual ~ResetPasswordHandler() = default;

  
// @generated_from: mojom.ResetPasswordHandler.HandlePasswordReset
  virtual void HandlePasswordReset() = 0;
};



// @generated_from: mojom.ResetPasswordHandler
class  ResetPasswordHandlerProxy
    : public ResetPasswordHandler {
 public:
  using InterfaceType = ResetPasswordHandler;

  explicit ResetPasswordHandlerProxy(mojo::MessageReceiverWithResponder* receiver);
  
// @generated_from: mojom.ResetPasswordHandler.HandlePasswordReset
  void HandlePasswordReset() final;

 private:
  mojo::MessageReceiverWithResponder* receiver_;
};
class  ResetPasswordHandlerStubDispatch {
 public:
  static bool Accept(ResetPasswordHandler* impl, mojo::Message* message);
  static bool AcceptWithResponder(
      ResetPasswordHandler* impl,
      mojo::Message* message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder);
};

template <typename ImplRefTraits =
              mojo::RawPtrImplRefTraits<ResetPasswordHandler>>
class ResetPasswordHandlerStub
    : public mojo::MessageReceiverWithResponderStatus {
 public:
  using ImplPointerType = typename ImplRefTraits::PointerType;

  ResetPasswordHandlerStub() = default;
  ~ResetPasswordHandlerStub() override = default;

  void set_sink(ImplPointerType sink) { sink_ = std::move(sink); }
  ImplPointerType& sink() { return sink_; }

  bool Accept(mojo::Message* message) override {
    if (ImplRefTraits::IsNull(sink_))
      return false;
    return ResetPasswordHandlerStubDispatch::Accept(
        ImplRefTraits::GetRawPointer(&sink_), message);
  }

  bool AcceptWithResponder(
      mojo::Message* message,
      std::unique_ptr<mojo::MessageReceiverWithStatus> responder) override {
    if (ImplRefTraits::IsNull(sink_))
      return false;
    return ResetPasswordHandlerStubDispatch::AcceptWithResponder(
        ImplRefTraits::GetRawPointer(&sink_), message, std::move(responder));
  }

 private:
  ImplPointerType sink_;
};
class  ResetPasswordHandlerRequestValidator : public mojo::MessageReceiver {
 public:
  bool Accept(mojo::Message* message) override;
};





}  // namespace mojom

namespace mojo {

}  // namespace mojo

#endif  // CHROME_BROWSER_UI_WEBUI_RESET_PASSWORD_RESET_PASSWORD_MOJOM_H_

/* Metadata comment
eyJtZXRhIjogW3siZW5kIjogMTYxOSwgImJlZ2luIjogMTU5OSwgImVkZ2UiOiAiJS9reXRoZS9l
ZGdlL2dlbmVyYXRlcyIsICJ0eXBlIjogImFuY2hvcl9kZWZpbmVzIiwgInZuYW1lIjogeyJjb3Jw
dXMiOiAiY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMiLCAibGFuZ3VhZ2Ui
OiAibW9qb20iLCAic2lnbmF0dXJlIjogIm1vam9tLlJlc2V0UGFzc3dvcmRIYW5kbGVyIn19LCB7
ImVuZCI6IDI4NzYsICJiZWdpbiI6IDI4NTcsICJlZGdlIjogIiUva3l0aGUvZWRnZS9nZW5lcmF0
ZXMiLCAidHlwZSI6ICJhbmNob3JfZGVmaW5lcyIsICJ2bmFtZSI6IHsiY29ycHVzIjogImNocm9t
aXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vc3JjIiwgImxhbmd1YWdlIjogIm1vam9tIiwg
InNpZ25hdHVyZSI6ICJtb2pvbS5SZXNldFBhc3N3b3JkSGFuZGxlci5IYW5kbGVQYXNzd29yZFJl
c2V0In19LCB7ImVuZCI6IDMyNDIsICJiZWdpbiI6IDMyMjMsICJlZGdlIjogIiUva3l0aGUvZWRn
ZS9nZW5lcmF0ZXMiLCAidHlwZSI6ICJhbmNob3JfZGVmaW5lcyIsICJ2bmFtZSI6IHsiY29ycHVz
IjogImNocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vc3JjIiwgImxhbmd1YWdlIjog
Im1vam9tIiwgInNpZ25hdHVyZSI6ICJtb2pvbS5SZXNldFBhc3N3b3JkSGFuZGxlci5IYW5kbGVQ
YXNzd29yZFJlc2V0In19XSwgInR5cGUiOiAia3l0aGUwIn0=
*/