// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: dmi/hw_events_mgmt_service.proto

#ifndef PROTOBUF_INCLUDED_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto
#define PROTOBUF_INCLUDED_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3007000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3007000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/inlined_string_field.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
#include <google/protobuf/extension_set.h>  // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
#include "dmi/commons.pb.h"
#include "dmi/hw.pb.h"
#include <google/protobuf/timestamp.pb.h>
#include <google/protobuf/empty.pb.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto

// Internal implementation detail -- do not use these members.
struct TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto {
  static const ::google::protobuf::internal::ParseTableField entries[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::ParseTable schema[11]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::FieldMetadata field_metadata[];
  static const ::google::protobuf::internal::SerializationTable serialization_table[];
  static const ::google::protobuf::uint32 offsets[];
};
void AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto();
namespace dmi {
class Event;
class EventDefaultTypeInternal;
extern EventDefaultTypeInternal _Event_default_instance_;
class EventCfg;
class EventCfgDefaultTypeInternal;
extern EventCfgDefaultTypeInternal _EventCfg_default_instance_;
class EventMetaData;
class EventMetaDataDefaultTypeInternal;
extern EventMetaDataDefaultTypeInternal _EventMetaData_default_instance_;
class EventsCfg;
class EventsCfgDefaultTypeInternal;
extern EventsCfgDefaultTypeInternal _EventsCfg_default_instance_;
class EventsConfigurationRequest;
class EventsConfigurationRequestDefaultTypeInternal;
extern EventsConfigurationRequestDefaultTypeInternal _EventsConfigurationRequest_default_instance_;
class EventsConfigurationResponse;
class EventsConfigurationResponseDefaultTypeInternal;
extern EventsConfigurationResponseDefaultTypeInternal _EventsConfigurationResponse_default_instance_;
class ListEventsResponse;
class ListEventsResponseDefaultTypeInternal;
extern ListEventsResponseDefaultTypeInternal _ListEventsResponse_default_instance_;
class ThresholdInformation;
class ThresholdInformationDefaultTypeInternal;
extern ThresholdInformationDefaultTypeInternal _ThresholdInformation_default_instance_;
class Thresholds;
class ThresholdsDefaultTypeInternal;
extern ThresholdsDefaultTypeInternal _Thresholds_default_instance_;
class ValueType;
class ValueTypeDefaultTypeInternal;
extern ValueTypeDefaultTypeInternal _ValueType_default_instance_;
class WaterMarks;
class WaterMarksDefaultTypeInternal;
extern WaterMarksDefaultTypeInternal _WaterMarks_default_instance_;
}  // namespace dmi
namespace google {
namespace protobuf {
template<> ::dmi::Event* Arena::CreateMaybeMessage<::dmi::Event>(Arena*);
template<> ::dmi::EventCfg* Arena::CreateMaybeMessage<::dmi::EventCfg>(Arena*);
template<> ::dmi::EventMetaData* Arena::CreateMaybeMessage<::dmi::EventMetaData>(Arena*);
template<> ::dmi::EventsCfg* Arena::CreateMaybeMessage<::dmi::EventsCfg>(Arena*);
template<> ::dmi::EventsConfigurationRequest* Arena::CreateMaybeMessage<::dmi::EventsConfigurationRequest>(Arena*);
template<> ::dmi::EventsConfigurationResponse* Arena::CreateMaybeMessage<::dmi::EventsConfigurationResponse>(Arena*);
template<> ::dmi::ListEventsResponse* Arena::CreateMaybeMessage<::dmi::ListEventsResponse>(Arena*);
template<> ::dmi::ThresholdInformation* Arena::CreateMaybeMessage<::dmi::ThresholdInformation>(Arena*);
template<> ::dmi::Thresholds* Arena::CreateMaybeMessage<::dmi::Thresholds>(Arena*);
template<> ::dmi::ValueType* Arena::CreateMaybeMessage<::dmi::ValueType>(Arena*);
template<> ::dmi::WaterMarks* Arena::CreateMaybeMessage<::dmi::WaterMarks>(Arena*);
}  // namespace protobuf
}  // namespace google
namespace dmi {

enum ListEventsResponse_Reason {
  ListEventsResponse_Reason_UNDEFINED_REASON = 0,
  ListEventsResponse_Reason_UNKNOWN_DEVICE = 1,
  ListEventsResponse_Reason_INTERNAL_ERROR = 2,
  ListEventsResponse_Reason_DEVICE_UNREACHABLE = 3,
  ListEventsResponse_Reason_ListEventsResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ListEventsResponse_Reason_ListEventsResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ListEventsResponse_Reason_IsValid(int value);
const ListEventsResponse_Reason ListEventsResponse_Reason_Reason_MIN = ListEventsResponse_Reason_UNDEFINED_REASON;
const ListEventsResponse_Reason ListEventsResponse_Reason_Reason_MAX = ListEventsResponse_Reason_DEVICE_UNREACHABLE;
const int ListEventsResponse_Reason_Reason_ARRAYSIZE = ListEventsResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* ListEventsResponse_Reason_descriptor();
inline const ::std::string& ListEventsResponse_Reason_Name(ListEventsResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    ListEventsResponse_Reason_descriptor(), value);
}
inline bool ListEventsResponse_Reason_Parse(
    const ::std::string& name, ListEventsResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ListEventsResponse_Reason>(
    ListEventsResponse_Reason_descriptor(), name, value);
}
enum EventsConfigurationResponse_Reason {
  EventsConfigurationResponse_Reason_UNDEFINED_REASON = 0,
  EventsConfigurationResponse_Reason_UNKNOWN_DEVICE = 1,
  EventsConfigurationResponse_Reason_INTERNAL_ERROR = 2,
  EventsConfigurationResponse_Reason_INVALID_CONFIG = 3,
  EventsConfigurationResponse_Reason_DEVICE_UNREACHABLE = 4,
  EventsConfigurationResponse_Reason_EventsConfigurationResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  EventsConfigurationResponse_Reason_EventsConfigurationResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool EventsConfigurationResponse_Reason_IsValid(int value);
const EventsConfigurationResponse_Reason EventsConfigurationResponse_Reason_Reason_MIN = EventsConfigurationResponse_Reason_UNDEFINED_REASON;
const EventsConfigurationResponse_Reason EventsConfigurationResponse_Reason_Reason_MAX = EventsConfigurationResponse_Reason_DEVICE_UNREACHABLE;
const int EventsConfigurationResponse_Reason_Reason_ARRAYSIZE = EventsConfigurationResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* EventsConfigurationResponse_Reason_descriptor();
inline const ::std::string& EventsConfigurationResponse_Reason_Name(EventsConfigurationResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    EventsConfigurationResponse_Reason_descriptor(), value);
}
inline bool EventsConfigurationResponse_Reason_Parse(
    const ::std::string& name, EventsConfigurationResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<EventsConfigurationResponse_Reason>(
    EventsConfigurationResponse_Reason_descriptor(), name, value);
}
enum EventIds {
  EVENT_NAME_UNDEFINED = 0,
  EVENT_TRANSCEIVER_PLUG_OUT = 100,
  EVENT_TRANSCEIVER_PLUG_IN = 101,
  EVENT_TRANSCEIVER_VOLTAGE_ABOVE_THRESHOLD = 102,
  EVENT_TRANSCEIVER_VOLTAGE_BELOW_THRESHOLD = 103,
  EVENT_TRANSCEIVER_TEMPERATURE_ABOVE_THRESHOLD = 104,
  EVENT_TRANSCEIVER_TEMPERATURE_BELOW_THRESHOLD = 105,
  EVENT_TRANSCEIVER_CURRENT_ABOVE_THRESHOLD = 106,
  EVENT_TRANSCEIVER_CURRENT_BELOW_THRESHOLD = 107,
  EVENT_TRANSCEIVER_RX_POWER_ABOVE_THRESHOLD = 108,
  EVENT_TRANSCEIVER_RX_POWER_BELOW_THRESHOLD = 109,
  EVENT_TRANSCEIVER_TX_POWER_ABOVE_THRESHOLD = 110,
  EVENT_TRANSCEIVER_TX_POWER_BELOW_THRESHOLD = 111,
  EVENT_TRANSCEIVER_FAILURE = 112,
  EVENT_TRANSCEIVER_VOLTAGE_ABOVE_THRESHOLD_RECOVERED = 113,
  EVENT_TRANSCEIVER_VOLTAGE_BELOW_THRESHOLD_RECOVERED = 114,
  EVENT_TRANSCEIVER_TEMPERATURE_ABOVE_THRESHOLD_RECOVERED = 115,
  EVENT_TRANSCEIVER_TEMPERATURE_BELOW_THRESHOLD_RECOVERED = 116,
  EVENT_TRANSCEIVER_CURRENT_ABOVE_THRESHOLD_RECOVERED = 117,
  EVENT_TRANSCEIVER_CURRENT_BELOW_THRESHOLD_RECOVERED = 118,
  EVENT_TRANSCEIVER_RX_POWER_ABOVE_THRESHOLD_RECOVERED = 119,
  EVENT_TRANSCEIVER_RX_POWER_BELOW_THRESHOLD_RECOVERED = 120,
  EVENT_TRANSCEIVER_TX_POWER_ABOVE_THRESHOLD_RECOVERED = 121,
  EVENT_TRANSCEIVER_TX_POWER_BELOW_THRESHOLD_RECOVERED = 122,
  EVENT_TRANSCEIVER_FAILURE_RECOVERED = 123,
  EVENT_PSU_PLUG_OUT = 200,
  EVENT_PSU_PLUG_IN = 201,
  EVENT_PSU_FAILURE = 202,
  EVENT_PSU_FAILURE_RECOVERED = 203,
  EVENT_FAN_FAILURE = 300,
  EVENT_FAN_PLUG_OUT = 301,
  EVENT_FAN_PLUG_IN = 302,
  EVENT_FAN_FAILURE_RECOVERED = 303,
  EVENT_CPU_TEMPERATURE_ABOVE_CRITICAL = 400,
  EVENT_CPU_TEMPERATURE_ABOVE_FATAL = 401,
  EVENT_CPU_TEMPERATURE_ABOVE_CRITICAL_RECOVERED = 402,
  EVENT_CPU_TEMPERATURE_ABOVE_FATAL_RECOVERED = 403,
  EVENT_HW_DEVICE_RESET = 500,
  EVENT_HW_DEVICE_TEMPERATURE_ABOVE_CRITICAL = 501,
  EVENT_HW_DEVICE_TEMPERATURE_ABOVE_FATAL = 502,
  EVENT_HW_DEVICE_TEMPERATURE_ABOVE_CRITICAL_RECOVERED = 503,
  EVENT_HW_DEVICE_TEMPERATURE_ABOVE_FATAL_RECOVERED = 504,
  EVENT_HW_DEVICE_REBOOT = 505,
  EventIds_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  EventIds_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool EventIds_IsValid(int value);
const EventIds EventIds_MIN = EVENT_NAME_UNDEFINED;
const EventIds EventIds_MAX = EVENT_HW_DEVICE_REBOOT;
const int EventIds_ARRAYSIZE = EventIds_MAX + 1;

const ::google::protobuf::EnumDescriptor* EventIds_descriptor();
inline const ::std::string& EventIds_Name(EventIds value) {
  return ::google::protobuf::internal::NameOfEnum(
    EventIds_descriptor(), value);
}
inline bool EventIds_Parse(
    const ::std::string& name, EventIds* value) {
  return ::google::protobuf::internal::ParseNamedEnum<EventIds>(
    EventIds_descriptor(), name, value);
}
// ===================================================================

class ValueType final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ValueType) */ {
 public:
  ValueType();
  virtual ~ValueType();

  ValueType(const ValueType& from);

  inline ValueType& operator=(const ValueType& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  ValueType(ValueType&& from) noexcept
    : ValueType() {
    *this = ::std::move(from);
  }

  inline ValueType& operator=(ValueType&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const ValueType& default_instance();

  enum ValCase {
    kIntVal = 1,
    kUintVal = 2,
    kFloatVal = 3,
    VAL_NOT_SET = 0,
  };

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const ValueType* internal_default_instance() {
    return reinterpret_cast<const ValueType*>(
               &_ValueType_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  void Swap(ValueType* other);
  friend void swap(ValueType& a, ValueType& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline ValueType* New() const final {
    return CreateMaybeMessage<ValueType>(nullptr);
  }

  ValueType* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ValueType>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ValueType& from);
  void MergeFrom(const ValueType& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ValueType* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // int64 int_val = 1;
  private:
  bool has_int_val() const;
  public:
  void clear_int_val();
  static const int kIntValFieldNumber = 1;
  ::google::protobuf::int64 int_val() const;
  void set_int_val(::google::protobuf::int64 value);

  // uint64 uint_val = 2;
  private:
  bool has_uint_val() const;
  public:
  void clear_uint_val();
  static const int kUintValFieldNumber = 2;
  ::google::protobuf::uint64 uint_val() const;
  void set_uint_val(::google::protobuf::uint64 value);

  // float float_val = 3;
  private:
  bool has_float_val() const;
  public:
  void clear_float_val();
  static const int kFloatValFieldNumber = 3;
  float float_val() const;
  void set_float_val(float value);

  void clear_val();
  ValCase val_case() const;
  // @@protoc_insertion_point(class_scope:dmi.ValueType)
 private:
  class HasBitSetters;
  void set_has_int_val();
  void set_has_uint_val();
  void set_has_float_val();

  inline bool has_val() const;
  inline void clear_has_val();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  union ValUnion {
    ValUnion() {}
    ::google::protobuf::int64 int_val_;
    ::google::protobuf::uint64 uint_val_;
    float float_val_;
  } val_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::uint32 _oneof_case_[1];

  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class WaterMarks final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.WaterMarks) */ {
 public:
  WaterMarks();
  virtual ~WaterMarks();

  WaterMarks(const WaterMarks& from);

  inline WaterMarks& operator=(const WaterMarks& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  WaterMarks(WaterMarks&& from) noexcept
    : WaterMarks() {
    *this = ::std::move(from);
  }

  inline WaterMarks& operator=(WaterMarks&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const WaterMarks& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const WaterMarks* internal_default_instance() {
    return reinterpret_cast<const WaterMarks*>(
               &_WaterMarks_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  void Swap(WaterMarks* other);
  friend void swap(WaterMarks& a, WaterMarks& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline WaterMarks* New() const final {
    return CreateMaybeMessage<WaterMarks>(nullptr);
  }

  WaterMarks* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<WaterMarks>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const WaterMarks& from);
  void MergeFrom(const WaterMarks& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(WaterMarks* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // .dmi.ValueType high = 1;
  bool has_high() const;
  void clear_high();
  static const int kHighFieldNumber = 1;
  const ::dmi::ValueType& high() const;
  ::dmi::ValueType* release_high();
  ::dmi::ValueType* mutable_high();
  void set_allocated_high(::dmi::ValueType* high);

  // .dmi.ValueType low = 2;
  bool has_low() const;
  void clear_low();
  static const int kLowFieldNumber = 2;
  const ::dmi::ValueType& low() const;
  ::dmi::ValueType* release_low();
  ::dmi::ValueType* mutable_low();
  void set_allocated_low(::dmi::ValueType* low);

  // @@protoc_insertion_point(class_scope:dmi.WaterMarks)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::ValueType* high_;
  ::dmi::ValueType* low_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class Thresholds final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Thresholds) */ {
 public:
  Thresholds();
  virtual ~Thresholds();

  Thresholds(const Thresholds& from);

  inline Thresholds& operator=(const Thresholds& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Thresholds(Thresholds&& from) noexcept
    : Thresholds() {
    *this = ::std::move(from);
  }

  inline Thresholds& operator=(Thresholds&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const Thresholds& default_instance();

  enum ThresholdCase {
    kUpper = 1,
    kLower = 2,
    THRESHOLD_NOT_SET = 0,
  };

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Thresholds* internal_default_instance() {
    return reinterpret_cast<const Thresholds*>(
               &_Thresholds_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  void Swap(Thresholds* other);
  friend void swap(Thresholds& a, Thresholds& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline Thresholds* New() const final {
    return CreateMaybeMessage<Thresholds>(nullptr);
  }

  Thresholds* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<Thresholds>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const Thresholds& from);
  void MergeFrom(const Thresholds& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Thresholds* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // .dmi.WaterMarks upper = 1;
  bool has_upper() const;
  void clear_upper();
  static const int kUpperFieldNumber = 1;
  const ::dmi::WaterMarks& upper() const;
  ::dmi::WaterMarks* release_upper();
  ::dmi::WaterMarks* mutable_upper();
  void set_allocated_upper(::dmi::WaterMarks* upper);

  // .dmi.WaterMarks lower = 2;
  bool has_lower() const;
  void clear_lower();
  static const int kLowerFieldNumber = 2;
  const ::dmi::WaterMarks& lower() const;
  ::dmi::WaterMarks* release_lower();
  ::dmi::WaterMarks* mutable_lower();
  void set_allocated_lower(::dmi::WaterMarks* lower);

  void clear_threshold();
  ThresholdCase threshold_case() const;
  // @@protoc_insertion_point(class_scope:dmi.Thresholds)
 private:
  class HasBitSetters;
  void set_has_upper();
  void set_has_lower();

  inline bool has_threshold() const;
  inline void clear_has_threshold();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  union ThresholdUnion {
    ThresholdUnion() {}
    ::dmi::WaterMarks* upper_;
    ::dmi::WaterMarks* lower_;
  } threshold_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::uint32 _oneof_case_[1];

  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class ThresholdInformation final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ThresholdInformation) */ {
 public:
  ThresholdInformation();
  virtual ~ThresholdInformation();

  ThresholdInformation(const ThresholdInformation& from);

  inline ThresholdInformation& operator=(const ThresholdInformation& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  ThresholdInformation(ThresholdInformation&& from) noexcept
    : ThresholdInformation() {
    *this = ::std::move(from);
  }

  inline ThresholdInformation& operator=(ThresholdInformation&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const ThresholdInformation& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const ThresholdInformation* internal_default_instance() {
    return reinterpret_cast<const ThresholdInformation*>(
               &_ThresholdInformation_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  void Swap(ThresholdInformation* other);
  friend void swap(ThresholdInformation& a, ThresholdInformation& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline ThresholdInformation* New() const final {
    return CreateMaybeMessage<ThresholdInformation>(nullptr);
  }

  ThresholdInformation* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ThresholdInformation>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ThresholdInformation& from);
  void MergeFrom(const ThresholdInformation& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ThresholdInformation* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // .dmi.ValueType observed_value = 1;
  bool has_observed_value() const;
  void clear_observed_value();
  static const int kObservedValueFieldNumber = 1;
  const ::dmi::ValueType& observed_value() const;
  ::dmi::ValueType* release_observed_value();
  ::dmi::ValueType* mutable_observed_value();
  void set_allocated_observed_value(::dmi::ValueType* observed_value);

  // .dmi.Thresholds thresholds = 2;
  bool has_thresholds() const;
  void clear_thresholds();
  static const int kThresholdsFieldNumber = 2;
  const ::dmi::Thresholds& thresholds() const;
  ::dmi::Thresholds* release_thresholds();
  ::dmi::Thresholds* mutable_thresholds();
  void set_allocated_thresholds(::dmi::Thresholds* thresholds);

  // @@protoc_insertion_point(class_scope:dmi.ThresholdInformation)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::ValueType* observed_value_;
  ::dmi::Thresholds* thresholds_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class EventCfg final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventCfg) */ {
 public:
  EventCfg();
  virtual ~EventCfg();

  EventCfg(const EventCfg& from);

  inline EventCfg& operator=(const EventCfg& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  EventCfg(EventCfg&& from) noexcept
    : EventCfg() {
    *this = ::std::move(from);
  }

  inline EventCfg& operator=(EventCfg&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const EventCfg& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const EventCfg* internal_default_instance() {
    return reinterpret_cast<const EventCfg*>(
               &_EventCfg_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    4;

  void Swap(EventCfg* other);
  friend void swap(EventCfg& a, EventCfg& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline EventCfg* New() const final {
    return CreateMaybeMessage<EventCfg>(nullptr);
  }

  EventCfg* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<EventCfg>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const EventCfg& from);
  void MergeFrom(const EventCfg& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EventCfg* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // .dmi.Thresholds thresholds = 3;
  bool has_thresholds() const;
  void clear_thresholds();
  static const int kThresholdsFieldNumber = 3;
  const ::dmi::Thresholds& thresholds() const;
  ::dmi::Thresholds* release_thresholds();
  ::dmi::Thresholds* mutable_thresholds();
  void set_allocated_thresholds(::dmi::Thresholds* thresholds);

  // .dmi.EventIds event_id = 1;
  void clear_event_id();
  static const int kEventIdFieldNumber = 1;
  ::dmi::EventIds event_id() const;
  void set_event_id(::dmi::EventIds value);

  // bool is_configured = 2;
  void clear_is_configured();
  static const int kIsConfiguredFieldNumber = 2;
  bool is_configured() const;
  void set_is_configured(bool value);

  // @@protoc_insertion_point(class_scope:dmi.EventCfg)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::Thresholds* thresholds_;
  int event_id_;
  bool is_configured_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class EventsCfg final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventsCfg) */ {
 public:
  EventsCfg();
  virtual ~EventsCfg();

  EventsCfg(const EventsCfg& from);

  inline EventsCfg& operator=(const EventsCfg& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  EventsCfg(EventsCfg&& from) noexcept
    : EventsCfg() {
    *this = ::std::move(from);
  }

  inline EventsCfg& operator=(EventsCfg&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const EventsCfg& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const EventsCfg* internal_default_instance() {
    return reinterpret_cast<const EventsCfg*>(
               &_EventsCfg_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    5;

  void Swap(EventsCfg* other);
  friend void swap(EventsCfg& a, EventsCfg& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline EventsCfg* New() const final {
    return CreateMaybeMessage<EventsCfg>(nullptr);
  }

  EventsCfg* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<EventsCfg>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const EventsCfg& from);
  void MergeFrom(const EventsCfg& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EventsCfg* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // repeated .dmi.EventCfg items = 1;
  int items_size() const;
  void clear_items();
  static const int kItemsFieldNumber = 1;
  ::dmi::EventCfg* mutable_items(int index);
  ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg >*
      mutable_items();
  const ::dmi::EventCfg& items(int index) const;
  ::dmi::EventCfg* add_items();
  const ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg >&
      items() const;

  // @@protoc_insertion_point(class_scope:dmi.EventsCfg)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg > items_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class ListEventsResponse final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ListEventsResponse) */ {
 public:
  ListEventsResponse();
  virtual ~ListEventsResponse();

  ListEventsResponse(const ListEventsResponse& from);

  inline ListEventsResponse& operator=(const ListEventsResponse& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  ListEventsResponse(ListEventsResponse&& from) noexcept
    : ListEventsResponse() {
    *this = ::std::move(from);
  }

  inline ListEventsResponse& operator=(ListEventsResponse&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const ListEventsResponse& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const ListEventsResponse* internal_default_instance() {
    return reinterpret_cast<const ListEventsResponse*>(
               &_ListEventsResponse_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    6;

  void Swap(ListEventsResponse* other);
  friend void swap(ListEventsResponse& a, ListEventsResponse& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline ListEventsResponse* New() const final {
    return CreateMaybeMessage<ListEventsResponse>(nullptr);
  }

  ListEventsResponse* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ListEventsResponse>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ListEventsResponse& from);
  void MergeFrom(const ListEventsResponse& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ListEventsResponse* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  typedef ListEventsResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    ListEventsResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    ListEventsResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    ListEventsResponse_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    ListEventsResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return ListEventsResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    ListEventsResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    ListEventsResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    ListEventsResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return ListEventsResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return ListEventsResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return ListEventsResponse_Reason_Parse(name, value);
  }

  // accessors -------------------------------------------------------

  // string reason_detail = 4;
  void clear_reason_detail();
  static const int kReasonDetailFieldNumber = 4;
  const ::std::string& reason_detail() const;
  void set_reason_detail(const ::std::string& value);
  #if LANG_CXX11
  void set_reason_detail(::std::string&& value);
  #endif
  void set_reason_detail(const char* value);
  void set_reason_detail(const char* value, size_t size);
  ::std::string* mutable_reason_detail();
  ::std::string* release_reason_detail();
  void set_allocated_reason_detail(::std::string* reason_detail);

  // .dmi.EventsCfg events = 3;
  bool has_events() const;
  void clear_events();
  static const int kEventsFieldNumber = 3;
  const ::dmi::EventsCfg& events() const;
  ::dmi::EventsCfg* release_events();
  ::dmi::EventsCfg* mutable_events();
  void set_allocated_events(::dmi::EventsCfg* events);

  // .dmi.Status status = 1;
  void clear_status();
  static const int kStatusFieldNumber = 1;
  ::dmi::Status status() const;
  void set_status(::dmi::Status value);

  // .dmi.ListEventsResponse.Reason reason = 2;
  void clear_reason();
  static const int kReasonFieldNumber = 2;
  ::dmi::ListEventsResponse_Reason reason() const;
  void set_reason(::dmi::ListEventsResponse_Reason value);

  // @@protoc_insertion_point(class_scope:dmi.ListEventsResponse)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  ::dmi::EventsCfg* events_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class EventsConfigurationRequest final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventsConfigurationRequest) */ {
 public:
  EventsConfigurationRequest();
  virtual ~EventsConfigurationRequest();

  EventsConfigurationRequest(const EventsConfigurationRequest& from);

  inline EventsConfigurationRequest& operator=(const EventsConfigurationRequest& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  EventsConfigurationRequest(EventsConfigurationRequest&& from) noexcept
    : EventsConfigurationRequest() {
    *this = ::std::move(from);
  }

  inline EventsConfigurationRequest& operator=(EventsConfigurationRequest&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const EventsConfigurationRequest& default_instance();

  enum OperationCase {
    kChanges = 2,
    kResetToDefault = 3,
    OPERATION_NOT_SET = 0,
  };

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const EventsConfigurationRequest* internal_default_instance() {
    return reinterpret_cast<const EventsConfigurationRequest*>(
               &_EventsConfigurationRequest_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    7;

  void Swap(EventsConfigurationRequest* other);
  friend void swap(EventsConfigurationRequest& a, EventsConfigurationRequest& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline EventsConfigurationRequest* New() const final {
    return CreateMaybeMessage<EventsConfigurationRequest>(nullptr);
  }

  EventsConfigurationRequest* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<EventsConfigurationRequest>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const EventsConfigurationRequest& from);
  void MergeFrom(const EventsConfigurationRequest& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EventsConfigurationRequest* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // .dmi.Uuid device_uuid = 1;
  bool has_device_uuid() const;
  void clear_device_uuid();
  static const int kDeviceUuidFieldNumber = 1;
  const ::dmi::Uuid& device_uuid() const;
  ::dmi::Uuid* release_device_uuid();
  ::dmi::Uuid* mutable_device_uuid();
  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);

  // .dmi.EventsCfg changes = 2;
  bool has_changes() const;
  void clear_changes();
  static const int kChangesFieldNumber = 2;
  const ::dmi::EventsCfg& changes() const;
  ::dmi::EventsCfg* release_changes();
  ::dmi::EventsCfg* mutable_changes();
  void set_allocated_changes(::dmi::EventsCfg* changes);

  // bool reset_to_default = 3;
  private:
  bool has_reset_to_default() const;
  public:
  void clear_reset_to_default();
  static const int kResetToDefaultFieldNumber = 3;
  bool reset_to_default() const;
  void set_reset_to_default(bool value);

  void clear_operation();
  OperationCase operation_case() const;
  // @@protoc_insertion_point(class_scope:dmi.EventsConfigurationRequest)
 private:
  class HasBitSetters;
  void set_has_changes();
  void set_has_reset_to_default();

  inline bool has_operation() const;
  inline void clear_has_operation();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::Uuid* device_uuid_;
  union OperationUnion {
    OperationUnion() {}
    ::dmi::EventsCfg* changes_;
    bool reset_to_default_;
  } operation_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::uint32 _oneof_case_[1];

  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class EventsConfigurationResponse final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventsConfigurationResponse) */ {
 public:
  EventsConfigurationResponse();
  virtual ~EventsConfigurationResponse();

  EventsConfigurationResponse(const EventsConfigurationResponse& from);

  inline EventsConfigurationResponse& operator=(const EventsConfigurationResponse& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  EventsConfigurationResponse(EventsConfigurationResponse&& from) noexcept
    : EventsConfigurationResponse() {
    *this = ::std::move(from);
  }

  inline EventsConfigurationResponse& operator=(EventsConfigurationResponse&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const EventsConfigurationResponse& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const EventsConfigurationResponse* internal_default_instance() {
    return reinterpret_cast<const EventsConfigurationResponse*>(
               &_EventsConfigurationResponse_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    8;

  void Swap(EventsConfigurationResponse* other);
  friend void swap(EventsConfigurationResponse& a, EventsConfigurationResponse& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline EventsConfigurationResponse* New() const final {
    return CreateMaybeMessage<EventsConfigurationResponse>(nullptr);
  }

  EventsConfigurationResponse* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<EventsConfigurationResponse>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const EventsConfigurationResponse& from);
  void MergeFrom(const EventsConfigurationResponse& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EventsConfigurationResponse* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  typedef EventsConfigurationResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    EventsConfigurationResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    EventsConfigurationResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    EventsConfigurationResponse_Reason_INTERNAL_ERROR;
  static const Reason INVALID_CONFIG =
    EventsConfigurationResponse_Reason_INVALID_CONFIG;
  static const Reason DEVICE_UNREACHABLE =
    EventsConfigurationResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return EventsConfigurationResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    EventsConfigurationResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    EventsConfigurationResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    EventsConfigurationResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return EventsConfigurationResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return EventsConfigurationResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return EventsConfigurationResponse_Reason_Parse(name, value);
  }

  // accessors -------------------------------------------------------

  // string reason_detail = 3;
  void clear_reason_detail();
  static const int kReasonDetailFieldNumber = 3;
  const ::std::string& reason_detail() const;
  void set_reason_detail(const ::std::string& value);
  #if LANG_CXX11
  void set_reason_detail(::std::string&& value);
  #endif
  void set_reason_detail(const char* value);
  void set_reason_detail(const char* value, size_t size);
  ::std::string* mutable_reason_detail();
  ::std::string* release_reason_detail();
  void set_allocated_reason_detail(::std::string* reason_detail);

  // .dmi.Status status = 1;
  void clear_status();
  static const int kStatusFieldNumber = 1;
  ::dmi::Status status() const;
  void set_status(::dmi::Status value);

  // .dmi.EventsConfigurationResponse.Reason reason = 2;
  void clear_reason();
  static const int kReasonFieldNumber = 2;
  ::dmi::EventsConfigurationResponse_Reason reason() const;
  void set_reason(::dmi::EventsConfigurationResponse_Reason value);

  // @@protoc_insertion_point(class_scope:dmi.EventsConfigurationResponse)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class EventMetaData final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventMetaData) */ {
 public:
  EventMetaData();
  virtual ~EventMetaData();

  EventMetaData(const EventMetaData& from);

  inline EventMetaData& operator=(const EventMetaData& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  EventMetaData(EventMetaData&& from) noexcept
    : EventMetaData() {
    *this = ::std::move(from);
  }

  inline EventMetaData& operator=(EventMetaData&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const EventMetaData& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const EventMetaData* internal_default_instance() {
    return reinterpret_cast<const EventMetaData*>(
               &_EventMetaData_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    9;

  void Swap(EventMetaData* other);
  friend void swap(EventMetaData& a, EventMetaData& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline EventMetaData* New() const final {
    return CreateMaybeMessage<EventMetaData>(nullptr);
  }

  EventMetaData* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<EventMetaData>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const EventMetaData& from);
  void MergeFrom(const EventMetaData& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(EventMetaData* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // string component_name = 3;
  void clear_component_name();
  static const int kComponentNameFieldNumber = 3;
  const ::std::string& component_name() const;
  void set_component_name(const ::std::string& value);
  #if LANG_CXX11
  void set_component_name(::std::string&& value);
  #endif
  void set_component_name(const char* value);
  void set_component_name(const char* value, size_t size);
  ::std::string* mutable_component_name();
  ::std::string* release_component_name();
  void set_allocated_component_name(::std::string* component_name);

  // .dmi.Uuid device_uuid = 1;
  bool has_device_uuid() const;
  void clear_device_uuid();
  static const int kDeviceUuidFieldNumber = 1;
  const ::dmi::Uuid& device_uuid() const;
  ::dmi::Uuid* release_device_uuid();
  ::dmi::Uuid* mutable_device_uuid();
  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);

  // .dmi.Uuid component_uuid = 2;
  bool has_component_uuid() const;
  void clear_component_uuid();
  static const int kComponentUuidFieldNumber = 2;
  const ::dmi::Uuid& component_uuid() const;
  ::dmi::Uuid* release_component_uuid();
  ::dmi::Uuid* mutable_component_uuid();
  void set_allocated_component_uuid(::dmi::Uuid* component_uuid);

  // @@protoc_insertion_point(class_scope:dmi.EventMetaData)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr component_name_;
  ::dmi::Uuid* device_uuid_;
  ::dmi::Uuid* component_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

class Event final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Event) */ {
 public:
  Event();
  virtual ~Event();

  Event(const Event& from);

  inline Event& operator=(const Event& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Event(Event&& from) noexcept
    : Event() {
    *this = ::std::move(from);
  }

  inline Event& operator=(Event&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const Event& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Event* internal_default_instance() {
    return reinterpret_cast<const Event*>(
               &_Event_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    10;

  void Swap(Event* other);
  friend void swap(Event& a, Event& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline Event* New() const final {
    return CreateMaybeMessage<Event>(nullptr);
  }

  Event* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<Event>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const Event& from);
  void MergeFrom(const Event& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Event* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // string add_info = 5;
  void clear_add_info();
  static const int kAddInfoFieldNumber = 5;
  const ::std::string& add_info() const;
  void set_add_info(const ::std::string& value);
  #if LANG_CXX11
  void set_add_info(::std::string&& value);
  #endif
  void set_add_info(const char* value);
  void set_add_info(const char* value, size_t size);
  ::std::string* mutable_add_info();
  ::std::string* release_add_info();
  void set_allocated_add_info(::std::string* add_info);

  // .dmi.EventMetaData event_metadata = 1;
  bool has_event_metadata() const;
  void clear_event_metadata();
  static const int kEventMetadataFieldNumber = 1;
  const ::dmi::EventMetaData& event_metadata() const;
  ::dmi::EventMetaData* release_event_metadata();
  ::dmi::EventMetaData* mutable_event_metadata();
  void set_allocated_event_metadata(::dmi::EventMetaData* event_metadata);

  // .google.protobuf.Timestamp raised_ts = 3;
  bool has_raised_ts() const;
  void clear_raised_ts();
  static const int kRaisedTsFieldNumber = 3;
  const ::google::protobuf::Timestamp& raised_ts() const;
  ::google::protobuf::Timestamp* release_raised_ts();
  ::google::protobuf::Timestamp* mutable_raised_ts();
  void set_allocated_raised_ts(::google::protobuf::Timestamp* raised_ts);

  // .dmi.ThresholdInformation threshold_info = 4;
  bool has_threshold_info() const;
  void clear_threshold_info();
  static const int kThresholdInfoFieldNumber = 4;
  const ::dmi::ThresholdInformation& threshold_info() const;
  ::dmi::ThresholdInformation* release_threshold_info();
  ::dmi::ThresholdInformation* mutable_threshold_info();
  void set_allocated_threshold_info(::dmi::ThresholdInformation* threshold_info);

  // .dmi.EventIds event_id = 2;
  void clear_event_id();
  static const int kEventIdFieldNumber = 2;
  ::dmi::EventIds event_id() const;
  void set_event_id(::dmi::EventIds value);

  // @@protoc_insertion_point(class_scope:dmi.Event)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr add_info_;
  ::dmi::EventMetaData* event_metadata_;
  ::google::protobuf::Timestamp* raised_ts_;
  ::dmi::ThresholdInformation* threshold_info_;
  int event_id_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// ===================================================================


// ===================================================================

#ifdef __GNUC__
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// ValueType

// int64 int_val = 1;
inline bool ValueType::has_int_val() const {
  return val_case() == kIntVal;
}
inline void ValueType::set_has_int_val() {
  _oneof_case_[0] = kIntVal;
}
inline void ValueType::clear_int_val() {
  if (has_int_val()) {
    val_.int_val_ = PROTOBUF_LONGLONG(0);
    clear_has_val();
  }
}
inline ::google::protobuf::int64 ValueType::int_val() const {
  // @@protoc_insertion_point(field_get:dmi.ValueType.int_val)
  if (has_int_val()) {
    return val_.int_val_;
  }
  return PROTOBUF_LONGLONG(0);
}
inline void ValueType::set_int_val(::google::protobuf::int64 value) {
  if (!has_int_val()) {
    clear_val();
    set_has_int_val();
  }
  val_.int_val_ = value;
  // @@protoc_insertion_point(field_set:dmi.ValueType.int_val)
}

// uint64 uint_val = 2;
inline bool ValueType::has_uint_val() const {
  return val_case() == kUintVal;
}
inline void ValueType::set_has_uint_val() {
  _oneof_case_[0] = kUintVal;
}
inline void ValueType::clear_uint_val() {
  if (has_uint_val()) {
    val_.uint_val_ = PROTOBUF_ULONGLONG(0);
    clear_has_val();
  }
}
inline ::google::protobuf::uint64 ValueType::uint_val() const {
  // @@protoc_insertion_point(field_get:dmi.ValueType.uint_val)
  if (has_uint_val()) {
    return val_.uint_val_;
  }
  return PROTOBUF_ULONGLONG(0);
}
inline void ValueType::set_uint_val(::google::protobuf::uint64 value) {
  if (!has_uint_val()) {
    clear_val();
    set_has_uint_val();
  }
  val_.uint_val_ = value;
  // @@protoc_insertion_point(field_set:dmi.ValueType.uint_val)
}

// float float_val = 3;
inline bool ValueType::has_float_val() const {
  return val_case() == kFloatVal;
}
inline void ValueType::set_has_float_val() {
  _oneof_case_[0] = kFloatVal;
}
inline void ValueType::clear_float_val() {
  if (has_float_val()) {
    val_.float_val_ = 0;
    clear_has_val();
  }
}
inline float ValueType::float_val() const {
  // @@protoc_insertion_point(field_get:dmi.ValueType.float_val)
  if (has_float_val()) {
    return val_.float_val_;
  }
  return 0;
}
inline void ValueType::set_float_val(float value) {
  if (!has_float_val()) {
    clear_val();
    set_has_float_val();
  }
  val_.float_val_ = value;
  // @@protoc_insertion_point(field_set:dmi.ValueType.float_val)
}

inline bool ValueType::has_val() const {
  return val_case() != VAL_NOT_SET;
}
inline void ValueType::clear_has_val() {
  _oneof_case_[0] = VAL_NOT_SET;
}
inline ValueType::ValCase ValueType::val_case() const {
  return ValueType::ValCase(_oneof_case_[0]);
}
// -------------------------------------------------------------------

// WaterMarks

// .dmi.ValueType high = 1;
inline bool WaterMarks::has_high() const {
  return this != internal_default_instance() && high_ != nullptr;
}
inline void WaterMarks::clear_high() {
  if (GetArenaNoVirtual() == nullptr && high_ != nullptr) {
    delete high_;
  }
  high_ = nullptr;
}
inline const ::dmi::ValueType& WaterMarks::high() const {
  const ::dmi::ValueType* p = high_;
  // @@protoc_insertion_point(field_get:dmi.WaterMarks.high)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ValueType*>(
      &::dmi::_ValueType_default_instance_);
}
inline ::dmi::ValueType* WaterMarks::release_high() {
  // @@protoc_insertion_point(field_release:dmi.WaterMarks.high)
  
  ::dmi::ValueType* temp = high_;
  high_ = nullptr;
  return temp;
}
inline ::dmi::ValueType* WaterMarks::mutable_high() {
  
  if (high_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::ValueType>(GetArenaNoVirtual());
    high_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.WaterMarks.high)
  return high_;
}
inline void WaterMarks::set_allocated_high(::dmi::ValueType* high) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete high_;
  }
  if (high) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      high = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, high, submessage_arena);
    }
    
  } else {
    
  }
  high_ = high;
  // @@protoc_insertion_point(field_set_allocated:dmi.WaterMarks.high)
}

// .dmi.ValueType low = 2;
inline bool WaterMarks::has_low() const {
  return this != internal_default_instance() && low_ != nullptr;
}
inline void WaterMarks::clear_low() {
  if (GetArenaNoVirtual() == nullptr && low_ != nullptr) {
    delete low_;
  }
  low_ = nullptr;
}
inline const ::dmi::ValueType& WaterMarks::low() const {
  const ::dmi::ValueType* p = low_;
  // @@protoc_insertion_point(field_get:dmi.WaterMarks.low)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ValueType*>(
      &::dmi::_ValueType_default_instance_);
}
inline ::dmi::ValueType* WaterMarks::release_low() {
  // @@protoc_insertion_point(field_release:dmi.WaterMarks.low)
  
  ::dmi::ValueType* temp = low_;
  low_ = nullptr;
  return temp;
}
inline ::dmi::ValueType* WaterMarks::mutable_low() {
  
  if (low_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::ValueType>(GetArenaNoVirtual());
    low_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.WaterMarks.low)
  return low_;
}
inline void WaterMarks::set_allocated_low(::dmi::ValueType* low) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete low_;
  }
  if (low) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      low = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, low, submessage_arena);
    }
    
  } else {
    
  }
  low_ = low;
  // @@protoc_insertion_point(field_set_allocated:dmi.WaterMarks.low)
}

// -------------------------------------------------------------------

// Thresholds

// .dmi.WaterMarks upper = 1;
inline bool Thresholds::has_upper() const {
  return threshold_case() == kUpper;
}
inline void Thresholds::set_has_upper() {
  _oneof_case_[0] = kUpper;
}
inline void Thresholds::clear_upper() {
  if (has_upper()) {
    delete threshold_.upper_;
    clear_has_threshold();
  }
}
inline ::dmi::WaterMarks* Thresholds::release_upper() {
  // @@protoc_insertion_point(field_release:dmi.Thresholds.upper)
  if (has_upper()) {
    clear_has_threshold();
      ::dmi::WaterMarks* temp = threshold_.upper_;
    threshold_.upper_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::WaterMarks& Thresholds::upper() const {
  // @@protoc_insertion_point(field_get:dmi.Thresholds.upper)
  return has_upper()
      ? *threshold_.upper_
      : *reinterpret_cast< ::dmi::WaterMarks*>(&::dmi::_WaterMarks_default_instance_);
}
inline ::dmi::WaterMarks* Thresholds::mutable_upper() {
  if (!has_upper()) {
    clear_threshold();
    set_has_upper();
    threshold_.upper_ = CreateMaybeMessage< ::dmi::WaterMarks >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.Thresholds.upper)
  return threshold_.upper_;
}

// .dmi.WaterMarks lower = 2;
inline bool Thresholds::has_lower() const {
  return threshold_case() == kLower;
}
inline void Thresholds::set_has_lower() {
  _oneof_case_[0] = kLower;
}
inline void Thresholds::clear_lower() {
  if (has_lower()) {
    delete threshold_.lower_;
    clear_has_threshold();
  }
}
inline ::dmi::WaterMarks* Thresholds::release_lower() {
  // @@protoc_insertion_point(field_release:dmi.Thresholds.lower)
  if (has_lower()) {
    clear_has_threshold();
      ::dmi::WaterMarks* temp = threshold_.lower_;
    threshold_.lower_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::WaterMarks& Thresholds::lower() const {
  // @@protoc_insertion_point(field_get:dmi.Thresholds.lower)
  return has_lower()
      ? *threshold_.lower_
      : *reinterpret_cast< ::dmi::WaterMarks*>(&::dmi::_WaterMarks_default_instance_);
}
inline ::dmi::WaterMarks* Thresholds::mutable_lower() {
  if (!has_lower()) {
    clear_threshold();
    set_has_lower();
    threshold_.lower_ = CreateMaybeMessage< ::dmi::WaterMarks >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.Thresholds.lower)
  return threshold_.lower_;
}

inline bool Thresholds::has_threshold() const {
  return threshold_case() != THRESHOLD_NOT_SET;
}
inline void Thresholds::clear_has_threshold() {
  _oneof_case_[0] = THRESHOLD_NOT_SET;
}
inline Thresholds::ThresholdCase Thresholds::threshold_case() const {
  return Thresholds::ThresholdCase(_oneof_case_[0]);
}
// -------------------------------------------------------------------

// ThresholdInformation

// .dmi.ValueType observed_value = 1;
inline bool ThresholdInformation::has_observed_value() const {
  return this != internal_default_instance() && observed_value_ != nullptr;
}
inline void ThresholdInformation::clear_observed_value() {
  if (GetArenaNoVirtual() == nullptr && observed_value_ != nullptr) {
    delete observed_value_;
  }
  observed_value_ = nullptr;
}
inline const ::dmi::ValueType& ThresholdInformation::observed_value() const {
  const ::dmi::ValueType* p = observed_value_;
  // @@protoc_insertion_point(field_get:dmi.ThresholdInformation.observed_value)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ValueType*>(
      &::dmi::_ValueType_default_instance_);
}
inline ::dmi::ValueType* ThresholdInformation::release_observed_value() {
  // @@protoc_insertion_point(field_release:dmi.ThresholdInformation.observed_value)
  
  ::dmi::ValueType* temp = observed_value_;
  observed_value_ = nullptr;
  return temp;
}
inline ::dmi::ValueType* ThresholdInformation::mutable_observed_value() {
  
  if (observed_value_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::ValueType>(GetArenaNoVirtual());
    observed_value_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ThresholdInformation.observed_value)
  return observed_value_;
}
inline void ThresholdInformation::set_allocated_observed_value(::dmi::ValueType* observed_value) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete observed_value_;
  }
  if (observed_value) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      observed_value = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, observed_value, submessage_arena);
    }
    
  } else {
    
  }
  observed_value_ = observed_value;
  // @@protoc_insertion_point(field_set_allocated:dmi.ThresholdInformation.observed_value)
}

// .dmi.Thresholds thresholds = 2;
inline bool ThresholdInformation::has_thresholds() const {
  return this != internal_default_instance() && thresholds_ != nullptr;
}
inline void ThresholdInformation::clear_thresholds() {
  if (GetArenaNoVirtual() == nullptr && thresholds_ != nullptr) {
    delete thresholds_;
  }
  thresholds_ = nullptr;
}
inline const ::dmi::Thresholds& ThresholdInformation::thresholds() const {
  const ::dmi::Thresholds* p = thresholds_;
  // @@protoc_insertion_point(field_get:dmi.ThresholdInformation.thresholds)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Thresholds*>(
      &::dmi::_Thresholds_default_instance_);
}
inline ::dmi::Thresholds* ThresholdInformation::release_thresholds() {
  // @@protoc_insertion_point(field_release:dmi.ThresholdInformation.thresholds)
  
  ::dmi::Thresholds* temp = thresholds_;
  thresholds_ = nullptr;
  return temp;
}
inline ::dmi::Thresholds* ThresholdInformation::mutable_thresholds() {
  
  if (thresholds_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Thresholds>(GetArenaNoVirtual());
    thresholds_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ThresholdInformation.thresholds)
  return thresholds_;
}
inline void ThresholdInformation::set_allocated_thresholds(::dmi::Thresholds* thresholds) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete thresholds_;
  }
  if (thresholds) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      thresholds = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, thresholds, submessage_arena);
    }
    
  } else {
    
  }
  thresholds_ = thresholds;
  // @@protoc_insertion_point(field_set_allocated:dmi.ThresholdInformation.thresholds)
}

// -------------------------------------------------------------------

// EventCfg

// .dmi.EventIds event_id = 1;
inline void EventCfg::clear_event_id() {
  event_id_ = 0;
}
inline ::dmi::EventIds EventCfg::event_id() const {
  // @@protoc_insertion_point(field_get:dmi.EventCfg.event_id)
  return static_cast< ::dmi::EventIds >(event_id_);
}
inline void EventCfg::set_event_id(::dmi::EventIds value) {
  
  event_id_ = value;
  // @@protoc_insertion_point(field_set:dmi.EventCfg.event_id)
}

// bool is_configured = 2;
inline void EventCfg::clear_is_configured() {
  is_configured_ = false;
}
inline bool EventCfg::is_configured() const {
  // @@protoc_insertion_point(field_get:dmi.EventCfg.is_configured)
  return is_configured_;
}
inline void EventCfg::set_is_configured(bool value) {
  
  is_configured_ = value;
  // @@protoc_insertion_point(field_set:dmi.EventCfg.is_configured)
}

// .dmi.Thresholds thresholds = 3;
inline bool EventCfg::has_thresholds() const {
  return this != internal_default_instance() && thresholds_ != nullptr;
}
inline void EventCfg::clear_thresholds() {
  if (GetArenaNoVirtual() == nullptr && thresholds_ != nullptr) {
    delete thresholds_;
  }
  thresholds_ = nullptr;
}
inline const ::dmi::Thresholds& EventCfg::thresholds() const {
  const ::dmi::Thresholds* p = thresholds_;
  // @@protoc_insertion_point(field_get:dmi.EventCfg.thresholds)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Thresholds*>(
      &::dmi::_Thresholds_default_instance_);
}
inline ::dmi::Thresholds* EventCfg::release_thresholds() {
  // @@protoc_insertion_point(field_release:dmi.EventCfg.thresholds)
  
  ::dmi::Thresholds* temp = thresholds_;
  thresholds_ = nullptr;
  return temp;
}
inline ::dmi::Thresholds* EventCfg::mutable_thresholds() {
  
  if (thresholds_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Thresholds>(GetArenaNoVirtual());
    thresholds_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.EventCfg.thresholds)
  return thresholds_;
}
inline void EventCfg::set_allocated_thresholds(::dmi::Thresholds* thresholds) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete thresholds_;
  }
  if (thresholds) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      thresholds = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, thresholds, submessage_arena);
    }
    
  } else {
    
  }
  thresholds_ = thresholds;
  // @@protoc_insertion_point(field_set_allocated:dmi.EventCfg.thresholds)
}

// -------------------------------------------------------------------

// EventsCfg

// repeated .dmi.EventCfg items = 1;
inline int EventsCfg::items_size() const {
  return items_.size();
}
inline void EventsCfg::clear_items() {
  items_.Clear();
}
inline ::dmi::EventCfg* EventsCfg::mutable_items(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.EventsCfg.items)
  return items_.Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg >*
EventsCfg::mutable_items() {
  // @@protoc_insertion_point(field_mutable_list:dmi.EventsCfg.items)
  return &items_;
}
inline const ::dmi::EventCfg& EventsCfg::items(int index) const {
  // @@protoc_insertion_point(field_get:dmi.EventsCfg.items)
  return items_.Get(index);
}
inline ::dmi::EventCfg* EventsCfg::add_items() {
  // @@protoc_insertion_point(field_add:dmi.EventsCfg.items)
  return items_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg >&
EventsCfg::items() const {
  // @@protoc_insertion_point(field_list:dmi.EventsCfg.items)
  return items_;
}

// -------------------------------------------------------------------

// ListEventsResponse

// .dmi.Status status = 1;
inline void ListEventsResponse::clear_status() {
  status_ = 0;
}
inline ::dmi::Status ListEventsResponse::status() const {
  // @@protoc_insertion_point(field_get:dmi.ListEventsResponse.status)
  return static_cast< ::dmi::Status >(status_);
}
inline void ListEventsResponse::set_status(::dmi::Status value) {
  
  status_ = value;
  // @@protoc_insertion_point(field_set:dmi.ListEventsResponse.status)
}

// .dmi.ListEventsResponse.Reason reason = 2;
inline void ListEventsResponse::clear_reason() {
  reason_ = 0;
}
inline ::dmi::ListEventsResponse_Reason ListEventsResponse::reason() const {
  // @@protoc_insertion_point(field_get:dmi.ListEventsResponse.reason)
  return static_cast< ::dmi::ListEventsResponse_Reason >(reason_);
}
inline void ListEventsResponse::set_reason(::dmi::ListEventsResponse_Reason value) {
  
  reason_ = value;
  // @@protoc_insertion_point(field_set:dmi.ListEventsResponse.reason)
}

// .dmi.EventsCfg events = 3;
inline bool ListEventsResponse::has_events() const {
  return this != internal_default_instance() && events_ != nullptr;
}
inline void ListEventsResponse::clear_events() {
  if (GetArenaNoVirtual() == nullptr && events_ != nullptr) {
    delete events_;
  }
  events_ = nullptr;
}
inline const ::dmi::EventsCfg& ListEventsResponse::events() const {
  const ::dmi::EventsCfg* p = events_;
  // @@protoc_insertion_point(field_get:dmi.ListEventsResponse.events)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::EventsCfg*>(
      &::dmi::_EventsCfg_default_instance_);
}
inline ::dmi::EventsCfg* ListEventsResponse::release_events() {
  // @@protoc_insertion_point(field_release:dmi.ListEventsResponse.events)
  
  ::dmi::EventsCfg* temp = events_;
  events_ = nullptr;
  return temp;
}
inline ::dmi::EventsCfg* ListEventsResponse::mutable_events() {
  
  if (events_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::EventsCfg>(GetArenaNoVirtual());
    events_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ListEventsResponse.events)
  return events_;
}
inline void ListEventsResponse::set_allocated_events(::dmi::EventsCfg* events) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete events_;
  }
  if (events) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      events = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, events, submessage_arena);
    }
    
  } else {
    
  }
  events_ = events;
  // @@protoc_insertion_point(field_set_allocated:dmi.ListEventsResponse.events)
}

// string reason_detail = 4;
inline void ListEventsResponse::clear_reason_detail() {
  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ListEventsResponse::reason_detail() const {
  // @@protoc_insertion_point(field_get:dmi.ListEventsResponse.reason_detail)
  return reason_detail_.GetNoArena();
}
inline void ListEventsResponse::set_reason_detail(const ::std::string& value) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ListEventsResponse.reason_detail)
}
#if LANG_CXX11
inline void ListEventsResponse::set_reason_detail(::std::string&& value) {
  
  reason_detail_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ListEventsResponse.reason_detail)
}
#endif
inline void ListEventsResponse::set_reason_detail(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ListEventsResponse.reason_detail)
}
inline void ListEventsResponse::set_reason_detail(const char* value, size_t size) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ListEventsResponse.reason_detail)
}
inline ::std::string* ListEventsResponse::mutable_reason_detail() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ListEventsResponse.reason_detail)
  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ListEventsResponse::release_reason_detail() {
  // @@protoc_insertion_point(field_release:dmi.ListEventsResponse.reason_detail)
  
  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ListEventsResponse::set_allocated_reason_detail(::std::string* reason_detail) {
  if (reason_detail != nullptr) {
    
  } else {
    
  }
  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
  // @@protoc_insertion_point(field_set_allocated:dmi.ListEventsResponse.reason_detail)
}

// -------------------------------------------------------------------

// EventsConfigurationRequest

// .dmi.Uuid device_uuid = 1;
inline bool EventsConfigurationRequest::has_device_uuid() const {
  return this != internal_default_instance() && device_uuid_ != nullptr;
}
inline const ::dmi::Uuid& EventsConfigurationRequest::device_uuid() const {
  const ::dmi::Uuid* p = device_uuid_;
  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationRequest.device_uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* EventsConfigurationRequest::release_device_uuid() {
  // @@protoc_insertion_point(field_release:dmi.EventsConfigurationRequest.device_uuid)
  
  ::dmi::Uuid* temp = device_uuid_;
  device_uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* EventsConfigurationRequest::mutable_device_uuid() {
  
  if (device_uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    device_uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.EventsConfigurationRequest.device_uuid)
  return device_uuid_;
}
inline void EventsConfigurationRequest::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
  }
  if (device_uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, device_uuid, submessage_arena);
    }
    
  } else {
    
  }
  device_uuid_ = device_uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.EventsConfigurationRequest.device_uuid)
}

// .dmi.EventsCfg changes = 2;
inline bool EventsConfigurationRequest::has_changes() const {
  return operation_case() == kChanges;
}
inline void EventsConfigurationRequest::set_has_changes() {
  _oneof_case_[0] = kChanges;
}
inline void EventsConfigurationRequest::clear_changes() {
  if (has_changes()) {
    delete operation_.changes_;
    clear_has_operation();
  }
}
inline ::dmi::EventsCfg* EventsConfigurationRequest::release_changes() {
  // @@protoc_insertion_point(field_release:dmi.EventsConfigurationRequest.changes)
  if (has_changes()) {
    clear_has_operation();
      ::dmi::EventsCfg* temp = operation_.changes_;
    operation_.changes_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::EventsCfg& EventsConfigurationRequest::changes() const {
  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationRequest.changes)
  return has_changes()
      ? *operation_.changes_
      : *reinterpret_cast< ::dmi::EventsCfg*>(&::dmi::_EventsCfg_default_instance_);
}
inline ::dmi::EventsCfg* EventsConfigurationRequest::mutable_changes() {
  if (!has_changes()) {
    clear_operation();
    set_has_changes();
    operation_.changes_ = CreateMaybeMessage< ::dmi::EventsCfg >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.EventsConfigurationRequest.changes)
  return operation_.changes_;
}

// bool reset_to_default = 3;
inline bool EventsConfigurationRequest::has_reset_to_default() const {
  return operation_case() == kResetToDefault;
}
inline void EventsConfigurationRequest::set_has_reset_to_default() {
  _oneof_case_[0] = kResetToDefault;
}
inline void EventsConfigurationRequest::clear_reset_to_default() {
  if (has_reset_to_default()) {
    operation_.reset_to_default_ = false;
    clear_has_operation();
  }
}
inline bool EventsConfigurationRequest::reset_to_default() const {
  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationRequest.reset_to_default)
  if (has_reset_to_default()) {
    return operation_.reset_to_default_;
  }
  return false;
}
inline void EventsConfigurationRequest::set_reset_to_default(bool value) {
  if (!has_reset_to_default()) {
    clear_operation();
    set_has_reset_to_default();
  }
  operation_.reset_to_default_ = value;
  // @@protoc_insertion_point(field_set:dmi.EventsConfigurationRequest.reset_to_default)
}

inline bool EventsConfigurationRequest::has_operation() const {
  return operation_case() != OPERATION_NOT_SET;
}
inline void EventsConfigurationRequest::clear_has_operation() {
  _oneof_case_[0] = OPERATION_NOT_SET;
}
inline EventsConfigurationRequest::OperationCase EventsConfigurationRequest::operation_case() const {
  return EventsConfigurationRequest::OperationCase(_oneof_case_[0]);
}
// -------------------------------------------------------------------

// EventsConfigurationResponse

// .dmi.Status status = 1;
inline void EventsConfigurationResponse::clear_status() {
  status_ = 0;
}
inline ::dmi::Status EventsConfigurationResponse::status() const {
  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationResponse.status)
  return static_cast< ::dmi::Status >(status_);
}
inline void EventsConfigurationResponse::set_status(::dmi::Status value) {
  
  status_ = value;
  // @@protoc_insertion_point(field_set:dmi.EventsConfigurationResponse.status)
}

// .dmi.EventsConfigurationResponse.Reason reason = 2;
inline void EventsConfigurationResponse::clear_reason() {
  reason_ = 0;
}
inline ::dmi::EventsConfigurationResponse_Reason EventsConfigurationResponse::reason() const {
  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationResponse.reason)
  return static_cast< ::dmi::EventsConfigurationResponse_Reason >(reason_);
}
inline void EventsConfigurationResponse::set_reason(::dmi::EventsConfigurationResponse_Reason value) {
  
  reason_ = value;
  // @@protoc_insertion_point(field_set:dmi.EventsConfigurationResponse.reason)
}

// string reason_detail = 3;
inline void EventsConfigurationResponse::clear_reason_detail() {
  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& EventsConfigurationResponse::reason_detail() const {
  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationResponse.reason_detail)
  return reason_detail_.GetNoArena();
}
inline void EventsConfigurationResponse::set_reason_detail(const ::std::string& value) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.EventsConfigurationResponse.reason_detail)
}
#if LANG_CXX11
inline void EventsConfigurationResponse::set_reason_detail(::std::string&& value) {
  
  reason_detail_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.EventsConfigurationResponse.reason_detail)
}
#endif
inline void EventsConfigurationResponse::set_reason_detail(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.EventsConfigurationResponse.reason_detail)
}
inline void EventsConfigurationResponse::set_reason_detail(const char* value, size_t size) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.EventsConfigurationResponse.reason_detail)
}
inline ::std::string* EventsConfigurationResponse::mutable_reason_detail() {
  
  // @@protoc_insertion_point(field_mutable:dmi.EventsConfigurationResponse.reason_detail)
  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* EventsConfigurationResponse::release_reason_detail() {
  // @@protoc_insertion_point(field_release:dmi.EventsConfigurationResponse.reason_detail)
  
  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void EventsConfigurationResponse::set_allocated_reason_detail(::std::string* reason_detail) {
  if (reason_detail != nullptr) {
    
  } else {
    
  }
  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
  // @@protoc_insertion_point(field_set_allocated:dmi.EventsConfigurationResponse.reason_detail)
}

// -------------------------------------------------------------------

// EventMetaData

// .dmi.Uuid device_uuid = 1;
inline bool EventMetaData::has_device_uuid() const {
  return this != internal_default_instance() && device_uuid_ != nullptr;
}
inline const ::dmi::Uuid& EventMetaData::device_uuid() const {
  const ::dmi::Uuid* p = device_uuid_;
  // @@protoc_insertion_point(field_get:dmi.EventMetaData.device_uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* EventMetaData::release_device_uuid() {
  // @@protoc_insertion_point(field_release:dmi.EventMetaData.device_uuid)
  
  ::dmi::Uuid* temp = device_uuid_;
  device_uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* EventMetaData::mutable_device_uuid() {
  
  if (device_uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    device_uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.EventMetaData.device_uuid)
  return device_uuid_;
}
inline void EventMetaData::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
  }
  if (device_uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, device_uuid, submessage_arena);
    }
    
  } else {
    
  }
  device_uuid_ = device_uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.EventMetaData.device_uuid)
}

// .dmi.Uuid component_uuid = 2;
inline bool EventMetaData::has_component_uuid() const {
  return this != internal_default_instance() && component_uuid_ != nullptr;
}
inline const ::dmi::Uuid& EventMetaData::component_uuid() const {
  const ::dmi::Uuid* p = component_uuid_;
  // @@protoc_insertion_point(field_get:dmi.EventMetaData.component_uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* EventMetaData::release_component_uuid() {
  // @@protoc_insertion_point(field_release:dmi.EventMetaData.component_uuid)
  
  ::dmi::Uuid* temp = component_uuid_;
  component_uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* EventMetaData::mutable_component_uuid() {
  
  if (component_uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    component_uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.EventMetaData.component_uuid)
  return component_uuid_;
}
inline void EventMetaData::set_allocated_component_uuid(::dmi::Uuid* component_uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(component_uuid_);
  }
  if (component_uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      component_uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, component_uuid, submessage_arena);
    }
    
  } else {
    
  }
  component_uuid_ = component_uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.EventMetaData.component_uuid)
}

// string component_name = 3;
inline void EventMetaData::clear_component_name() {
  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& EventMetaData::component_name() const {
  // @@protoc_insertion_point(field_get:dmi.EventMetaData.component_name)
  return component_name_.GetNoArena();
}
inline void EventMetaData::set_component_name(const ::std::string& value) {
  
  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.EventMetaData.component_name)
}
#if LANG_CXX11
inline void EventMetaData::set_component_name(::std::string&& value) {
  
  component_name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.EventMetaData.component_name)
}
#endif
inline void EventMetaData::set_component_name(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.EventMetaData.component_name)
}
inline void EventMetaData::set_component_name(const char* value, size_t size) {
  
  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.EventMetaData.component_name)
}
inline ::std::string* EventMetaData::mutable_component_name() {
  
  // @@protoc_insertion_point(field_mutable:dmi.EventMetaData.component_name)
  return component_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* EventMetaData::release_component_name() {
  // @@protoc_insertion_point(field_release:dmi.EventMetaData.component_name)
  
  return component_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void EventMetaData::set_allocated_component_name(::std::string* component_name) {
  if (component_name != nullptr) {
    
  } else {
    
  }
  component_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), component_name);
  // @@protoc_insertion_point(field_set_allocated:dmi.EventMetaData.component_name)
}

// -------------------------------------------------------------------

// Event

// .dmi.EventMetaData event_metadata = 1;
inline bool Event::has_event_metadata() const {
  return this != internal_default_instance() && event_metadata_ != nullptr;
}
inline void Event::clear_event_metadata() {
  if (GetArenaNoVirtual() == nullptr && event_metadata_ != nullptr) {
    delete event_metadata_;
  }
  event_metadata_ = nullptr;
}
inline const ::dmi::EventMetaData& Event::event_metadata() const {
  const ::dmi::EventMetaData* p = event_metadata_;
  // @@protoc_insertion_point(field_get:dmi.Event.event_metadata)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::EventMetaData*>(
      &::dmi::_EventMetaData_default_instance_);
}
inline ::dmi::EventMetaData* Event::release_event_metadata() {
  // @@protoc_insertion_point(field_release:dmi.Event.event_metadata)
  
  ::dmi::EventMetaData* temp = event_metadata_;
  event_metadata_ = nullptr;
  return temp;
}
inline ::dmi::EventMetaData* Event::mutable_event_metadata() {
  
  if (event_metadata_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::EventMetaData>(GetArenaNoVirtual());
    event_metadata_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Event.event_metadata)
  return event_metadata_;
}
inline void Event::set_allocated_event_metadata(::dmi::EventMetaData* event_metadata) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete event_metadata_;
  }
  if (event_metadata) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      event_metadata = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, event_metadata, submessage_arena);
    }
    
  } else {
    
  }
  event_metadata_ = event_metadata;
  // @@protoc_insertion_point(field_set_allocated:dmi.Event.event_metadata)
}

// .dmi.EventIds event_id = 2;
inline void Event::clear_event_id() {
  event_id_ = 0;
}
inline ::dmi::EventIds Event::event_id() const {
  // @@protoc_insertion_point(field_get:dmi.Event.event_id)
  return static_cast< ::dmi::EventIds >(event_id_);
}
inline void Event::set_event_id(::dmi::EventIds value) {
  
  event_id_ = value;
  // @@protoc_insertion_point(field_set:dmi.Event.event_id)
}

// .google.protobuf.Timestamp raised_ts = 3;
inline bool Event::has_raised_ts() const {
  return this != internal_default_instance() && raised_ts_ != nullptr;
}
inline const ::google::protobuf::Timestamp& Event::raised_ts() const {
  const ::google::protobuf::Timestamp* p = raised_ts_;
  // @@protoc_insertion_point(field_get:dmi.Event.raised_ts)
  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
      &::google::protobuf::_Timestamp_default_instance_);
}
inline ::google::protobuf::Timestamp* Event::release_raised_ts() {
  // @@protoc_insertion_point(field_release:dmi.Event.raised_ts)
  
  ::google::protobuf::Timestamp* temp = raised_ts_;
  raised_ts_ = nullptr;
  return temp;
}
inline ::google::protobuf::Timestamp* Event::mutable_raised_ts() {
  
  if (raised_ts_ == nullptr) {
    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
    raised_ts_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Event.raised_ts)
  return raised_ts_;
}
inline void Event::set_allocated_raised_ts(::google::protobuf::Timestamp* raised_ts) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(raised_ts_);
  }
  if (raised_ts) {
    ::google::protobuf::Arena* submessage_arena =
      reinterpret_cast<::google::protobuf::MessageLite*>(raised_ts)->GetArena();
    if (message_arena != submessage_arena) {
      raised_ts = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, raised_ts, submessage_arena);
    }
    
  } else {
    
  }
  raised_ts_ = raised_ts;
  // @@protoc_insertion_point(field_set_allocated:dmi.Event.raised_ts)
}

// .dmi.ThresholdInformation threshold_info = 4;
inline bool Event::has_threshold_info() const {
  return this != internal_default_instance() && threshold_info_ != nullptr;
}
inline void Event::clear_threshold_info() {
  if (GetArenaNoVirtual() == nullptr && threshold_info_ != nullptr) {
    delete threshold_info_;
  }
  threshold_info_ = nullptr;
}
inline const ::dmi::ThresholdInformation& Event::threshold_info() const {
  const ::dmi::ThresholdInformation* p = threshold_info_;
  // @@protoc_insertion_point(field_get:dmi.Event.threshold_info)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ThresholdInformation*>(
      &::dmi::_ThresholdInformation_default_instance_);
}
inline ::dmi::ThresholdInformation* Event::release_threshold_info() {
  // @@protoc_insertion_point(field_release:dmi.Event.threshold_info)
  
  ::dmi::ThresholdInformation* temp = threshold_info_;
  threshold_info_ = nullptr;
  return temp;
}
inline ::dmi::ThresholdInformation* Event::mutable_threshold_info() {
  
  if (threshold_info_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::ThresholdInformation>(GetArenaNoVirtual());
    threshold_info_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Event.threshold_info)
  return threshold_info_;
}
inline void Event::set_allocated_threshold_info(::dmi::ThresholdInformation* threshold_info) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete threshold_info_;
  }
  if (threshold_info) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      threshold_info = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, threshold_info, submessage_arena);
    }
    
  } else {
    
  }
  threshold_info_ = threshold_info;
  // @@protoc_insertion_point(field_set_allocated:dmi.Event.threshold_info)
}

// string add_info = 5;
inline void Event::clear_add_info() {
  add_info_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Event::add_info() const {
  // @@protoc_insertion_point(field_get:dmi.Event.add_info)
  return add_info_.GetNoArena();
}
inline void Event::set_add_info(const ::std::string& value) {
  
  add_info_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Event.add_info)
}
#if LANG_CXX11
inline void Event::set_add_info(::std::string&& value) {
  
  add_info_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Event.add_info)
}
#endif
inline void Event::set_add_info(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  add_info_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Event.add_info)
}
inline void Event::set_add_info(const char* value, size_t size) {
  
  add_info_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Event.add_info)
}
inline ::std::string* Event::mutable_add_info() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Event.add_info)
  return add_info_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Event::release_add_info() {
  // @@protoc_insertion_point(field_release:dmi.Event.add_info)
  
  return add_info_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Event::set_allocated_add_info(::std::string* add_info) {
  if (add_info != nullptr) {
    
  } else {
    
  }
  add_info_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), add_info);
  // @@protoc_insertion_point(field_set_allocated:dmi.Event.add_info)
}

#ifdef __GNUC__
  #pragma GCC diagnostic pop
#endif  // __GNUC__
// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------


// @@protoc_insertion_point(namespace_scope)

}  // namespace dmi

namespace google {
namespace protobuf {

template <> struct is_proto_enum< ::dmi::ListEventsResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ListEventsResponse_Reason>() {
  return ::dmi::ListEventsResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::EventsConfigurationResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::EventsConfigurationResponse_Reason>() {
  return ::dmi::EventsConfigurationResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::EventIds> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::EventIds>() {
  return ::dmi::EventIds_descriptor();
}

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

#include <google/protobuf/port_undef.inc>
#endif  // PROTOBUF_INCLUDED_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto
