// This file is generated by TypeBuilder_h.template.

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

#ifndef content_protocol_DOM_h
#define content_protocol_DOM_h

#include "content/common/content_export.h"
#include "content/browser/devtools/protocol/protocol.h"
// For each imported domain we generate a ValueConversions struct instead of a full domain definition
// and include Domain::API version from there.
#include "content/browser/devtools/protocol/runtime.h"
#include "content/browser/devtools/protocol/network.h"

namespace content {
namespace protocol {
namespace DOM {
using NodeId = int;
using BackendNodeId = int;
class RGBA;

// ------------- Forward and enum declarations.

namespace Enable {
namespace IncludeWhitespaceEnum {
inline constexpr char None[] = "none";
inline constexpr char All[] = "all";
} // IncludeWhitespaceEnum
} // Enable

namespace GetElementByRelation {
namespace RelationEnum {
inline constexpr char PopoverTarget[] = "PopoverTarget";
inline constexpr char InterestTarget[] = "InterestTarget";
inline constexpr char CommandFor[] = "CommandFor";
} // RelationEnum
} // GetElementByRelation

// ------------- Type and builder declarations.

class CONTENT_EXPORT RGBA : public ::crdtp::ProtocolObject<RGBA> {
public:
    ~RGBA() override;  // Defined below

    int GetR() { return m_r; }
    void SetR(int value);  // Defined below

    int GetG() { return m_g; }
    void SetG(int value);  // Defined below

    int GetB() { return m_b; }
    void SetB(int value);  // Defined below

    bool HasA() { return !!m_a; }
    double GetA(double defaultValue) const {
       return m_a.value_or(defaultValue);
    }
    const std::optional<double>& GetA() const {
       return m_a;
    }
    void SetA(double value);  // Defined below

    template<int STATE>
    class RGBABuilder {
    public:
        enum {
            NoFieldsSet = 0,
            RSet = 1 << 1,
            GSet = 1 << 2,
            BSet = 1 << 3,
            AllFieldsSet = (RSet | GSet | BSet | 0)};


        RGBABuilder<STATE | RSet>& SetR(int value);  // Defined below

        RGBABuilder<STATE | GSet>& SetG(int value);  // Defined below

        RGBABuilder<STATE | BSet>& SetB(int value);  // Defined below

        RGBABuilder<STATE>& SetA(double value);  // Defined below

        std::unique_ptr<RGBA> Build()
        {
            static_assert(STATE == AllFieldsSet, "state should be AllFieldsSet");
            return std::move(m_result);
        }

    private:
        friend class RGBA;
        RGBABuilder() : m_result(new RGBA()) { }

        template<int STEP> RGBABuilder<STATE | STEP>& castState()
        {
            return *reinterpret_cast<RGBABuilder<STATE | STEP>*>(this);
        }

        std::unique_ptr<protocol::DOM::RGBA> m_result;
    };

    static RGBABuilder<0> Create()
    {
        return RGBABuilder<0>();
    }

private:
    DECLARE_SERIALIZATION_SUPPORT();

    RGBA();  // Defined below

    int m_r;
    int m_g;
    int m_b;
    std::optional<double> m_a;
};


// ------------- Type and builder method definitions.
//
// These methods separate from the type declaration because of
// https://github.com/llvm/llvm-project/issues/59966. The DevTools protocol has
// mutually recursive types, so we cannot simply reorder the types.
inline RGBA::~RGBA() = default;
inline void RGBA::SetR(int value) { m_r = value; }
inline void RGBA::SetG(int value) { m_g = value; }
inline void RGBA::SetB(int value) { m_b = value; }
inline void RGBA::SetA(double value) { m_a = value; }

template<int STATE>
inline RGBA::RGBABuilder<STATE | RGBA::RGBABuilder<STATE>::RSet>&
RGBA::RGBABuilder<STATE>::SetR(int value) {
  static_assert(!(STATE & RSet), "property r should not be set yet");
  m_result->SetR(value);
  return castState<RSet>();
}
template<int STATE>
inline RGBA::RGBABuilder<STATE | RGBA::RGBABuilder<STATE>::GSet>&
RGBA::RGBABuilder<STATE>::SetG(int value) {
  static_assert(!(STATE & GSet), "property g should not be set yet");
  m_result->SetG(value);
  return castState<GSet>();
}
template<int STATE>
inline RGBA::RGBABuilder<STATE | RGBA::RGBABuilder<STATE>::BSet>&
RGBA::RGBABuilder<STATE>::SetB(int value) {
  static_assert(!(STATE & BSet), "property b should not be set yet");
  m_result->SetB(value);
  return castState<BSet>();
}
template<int STATE>
inline RGBA::RGBABuilder<STATE>& RGBA::RGBABuilder<STATE>::SetA(double value) {
  m_result->SetA(value);
  return *this;
}

inline RGBA::RGBA() {
  m_r = 0;
  m_g = 0;
  m_b = 0;
}

// ------------- Backend interface.

class CONTENT_EXPORT Backend {
public:
    virtual ~Backend() { }

    virtual DispatchResponse SetFileInputFiles(std::unique_ptr<protocol::Array<String>> in_files, std::optional<int> in_nodeId, std::optional<int> in_backendNodeId, std::optional<String> in_objectId) = 0;
    virtual DispatchResponse GetFileInfo(const String& in_objectId, String* out_path) = 0;

    virtual DispatchResponse Disable()
    {
        return DispatchResponse::Success();
    }
};

// ------------- Frontend interface.

class CONTENT_EXPORT Frontend {
public:
  explicit Frontend(FrontendChannel* frontend_channel) : frontend_channel_(frontend_channel) {}

  void flush();
  void sendRawNotification(std::unique_ptr<Serializable>);
 private:
  FrontendChannel* frontend_channel_;
};

// ------------- Dispatcher.

class CONTENT_EXPORT Dispatcher {
public:
    static void wire(UberDispatcher*, Backend*);

private:
    Dispatcher() { }
};

// ------------- Metainfo.

class CONTENT_EXPORT Metainfo {
public:
    using BackendClass = Backend;
    using FrontendClass = Frontend;
    using DispatcherClass = Dispatcher;
    static const char domainName[];
    static const char commandPrefix[];
    static const char version[];
};

} // namespace DOM
} // namespace content
} // namespace protocol

#endif // !defined(content_protocol_DOM_h)
