blob: bffd02aff269047065b13b614d19846e04eaf9d8 [file] [log] [blame]
#ifndef PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_STATE_FIELDS_H_
#define PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_STATE_FIELDS_H_
#include <string>
#include <tuple>
#include "safepower_agent.pb.h"
#include "absl/strings/string_view.h"
namespace safepower_agent {
template <typename Proto, typename FieldT>
class FieldDef {
public:
explicit constexpr FieldDef(FieldT (Proto::*get)() const,
bool (Proto::*has)() const,
void (Proto::*set)(FieldT))
: get_(get), has_(has), set_(set) {}
FieldT get_from(const Proto& proto) const { return (proto.*get_)(); }
bool is_in(const Proto& proto) const { return (proto.*has_)(); }
void set_in(Proto& proto, FieldT value) const { (proto.*set_)(value); }
private:
FieldT (Proto::*get_)() const;
bool (Proto::*has_)() const;
void (Proto::*set_)(FieldT);
};
template <typename Proto, typename FieldT>
FieldDef(FieldT (Proto::*get)() const, bool (Proto::*has)() const,
void (Proto::*set)(FieldT)) -> FieldDef<Proto, FieldT>;
template <typename Proto>
class FieldDef<Proto, std::string> {
public:
explicit constexpr FieldDef(const std::string& (Proto::*get)() const,
bool (Proto::*has)() const,
void (Proto::*set)(const std::string&))
: get_(get), has_(has), set_(set) {}
const std::string& get_from(const Proto& proto) const {
return (proto.*get_)();
}
bool is_in(const Proto& proto) const { return (proto.*has_)(); }
void set_in(Proto& proto, absl::string_view value) const {
(proto.*set_)(value);
}
private:
const std::string& (Proto::*get_)() const;
bool (Proto::*has_)() const;
void (Proto::*set_)(const std::string&);
};
template <typename Proto, typename FieldT>
class MessageFieldDef {
public:
explicit constexpr MessageFieldDef(FieldT* (Proto::*get_mutable)(),
const FieldT& (Proto::*get)() const,
bool (Proto::*has)() const)
: get_mutable_(get_mutable), get_(get), has_(has) {}
const FieldT& get_from(const Proto& proto) const { return (proto.*get_)(); }
FieldT* get_mutable_from(Proto& proto) const {
return (proto.*get_mutable_)();
}
bool is_in(const Proto& proto) const { return (proto.*has_)(); }
private:
FieldT* (Proto::*get_mutable_)();
const FieldT& (Proto::*get_)() const;
bool (Proto::*has_)() const;
};
template <typename Proto, typename FieldT>
MessageFieldDef(FieldT* (Proto::*get_mutable)(),
const FieldT& (Proto::*get)() const, bool (Proto::*has)() const)
-> MessageFieldDef<Proto, FieldT>;
template <typename Proto, typename FieldT>
class MapFieldDef {
public:
explicit constexpr MapFieldDef(FieldT* (Proto::*get_mutable)(),
const FieldT& (Proto::*get)() const)
: get_mutable_(get_mutable), get_(get) {}
const FieldT& get_from(const Proto& proto) const { return (proto.*get_)(); }
FieldT* get_mutable_from(Proto& proto) const {
return (proto.*get_mutable_)();
}
private:
FieldT* (Proto::*get_mutable_)();
const FieldT& (Proto::*get_)() const;
};
template <typename Proto, typename FieldT>
MapFieldDef(FieldT* (Proto::*get_mutable)(),
const FieldT& (Proto::*get)() const, bool (Proto::*has)() const)
-> MapFieldDef<Proto, FieldT>;
template <typename Proto>
struct ProtoFields {
// static constexpr std::tuple kFields; is not defined here so we have a
// compiler error if we forget to define it for some type.
};
#define FIELD_DEF(Proto, field_name) \
FieldDef(&Proto::field_name, &Proto::has_##field_name, \
&Proto::set_##field_name)
#define MESSAGE_FIELD_DEF(Proto, field_name) \
MessageFieldDef(&Proto::mutable_##field_name, &Proto::field_name, \
&Proto::has_##field_name)
#define MAP_FIELD_DEF(Proto, field_name) \
MapFieldDef(&Proto::mutable_##field_name, &Proto::field_name)
// LINT.IfChange(SystemStateFields)
template <>
struct ProtoFields<safepower_agent_proto::DaemonState> {
static constexpr std::tuple kFields = {
FIELD_DEF(safepower_agent_proto::DaemonState, healthy),
FIELD_DEF(safepower_agent_proto::DaemonState, restart_counter),
};
};
template <>
struct ProtoFields<safepower_agent_proto::BootState> {
static constexpr std::tuple kFields = {
FIELD_DEF(safepower_agent_proto::BootState, boot_counter),
FIELD_DEF(safepower_agent_proto::BootState, uptime_ms),
FIELD_DEF(safepower_agent_proto::BootState, state),
};
};
template <>
struct ProtoFields<safepower_agent_proto::ConnectionState> {
static constexpr std::tuple kFields = {
FIELD_DEF(safepower_agent_proto::ConnectionState, reconnect_counter),
};
};
template <>
struct ProtoFields<safepower_agent_proto::PowerState> {
static constexpr std::tuple kFields = {
FIELD_DEF(safepower_agent_proto::PowerState, state),
FIELD_DEF(safepower_agent_proto::PowerState, power_cycle_counter),
};
};
template <>
struct ProtoFields<safepower_agent_proto::NodeState> {
static constexpr std::tuple kFields = {
MESSAGE_FIELD_DEF(safepower_agent_proto::NodeState, boot_state),
MESSAGE_FIELD_DEF(safepower_agent_proto::NodeState, power_state),
MAP_FIELD_DEF(safepower_agent_proto::NodeState, daemon_state),
};
};
template <>
struct ProtoFields<safepower_agent_proto::SystemState> {
static constexpr std::tuple kFields = {
FIELD_DEF(safepower_agent_proto::SystemState, epoch_ms),
MAP_FIELD_DEF(safepower_agent_proto::SystemState, node_state),
};
};
// LINT.ThenChange(//depot/proto/safepower_agent.proto:SystemState)
#undef FIELD_DEF
#undef MESSAGE_FIELD_DEF
} // namespace safepower_agent
#endif // PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_STATE_FIELDS_H_