// 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[18]
    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 AdminStateChange;
class AdminStateChangeDefaultTypeInternal;
extern AdminStateChangeDefaultTypeInternal _AdminStateChange_default_instance_;
class AlarmStateChange;
class AlarmStateChangeDefaultTypeInternal;
extern AlarmStateChangeDefaultTypeInternal _AlarmStateChange_default_instance_;
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 GenericEventInfo;
class GenericEventInfoDefaultTypeInternal;
extern GenericEventInfoDefaultTypeInternal _GenericEventInfo_default_instance_;
class ListEventsResponse;
class ListEventsResponseDefaultTypeInternal;
extern ListEventsResponseDefaultTypeInternal _ListEventsResponse_default_instance_;
class OperStateChange;
class OperStateChangeDefaultTypeInternal;
extern OperStateChangeDefaultTypeInternal _OperStateChange_default_instance_;
class StandbyStateChange;
class StandbyStateChangeDefaultTypeInternal;
extern StandbyStateChangeDefaultTypeInternal _StandbyStateChange_default_instance_;
class StateChangeInfo;
class StateChangeInfoDefaultTypeInternal;
extern StateChangeInfoDefaultTypeInternal _StateChangeInfo_default_instance_;
class ThresholdInformation;
class ThresholdInformationDefaultTypeInternal;
extern ThresholdInformationDefaultTypeInternal _ThresholdInformation_default_instance_;
class Thresholds;
class ThresholdsDefaultTypeInternal;
extern ThresholdsDefaultTypeInternal _Thresholds_default_instance_;
class UsageStateChange;
class UsageStateChangeDefaultTypeInternal;
extern UsageStateChangeDefaultTypeInternal _UsageStateChange_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::AdminStateChange* Arena::CreateMaybeMessage<::dmi::AdminStateChange>(Arena*);
template<> ::dmi::AlarmStateChange* Arena::CreateMaybeMessage<::dmi::AlarmStateChange>(Arena*);
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::GenericEventInfo* Arena::CreateMaybeMessage<::dmi::GenericEventInfo>(Arena*);
template<> ::dmi::ListEventsResponse* Arena::CreateMaybeMessage<::dmi::ListEventsResponse>(Arena*);
template<> ::dmi::OperStateChange* Arena::CreateMaybeMessage<::dmi::OperStateChange>(Arena*);
template<> ::dmi::StandbyStateChange* Arena::CreateMaybeMessage<::dmi::StandbyStateChange>(Arena*);
template<> ::dmi::StateChangeInfo* Arena::CreateMaybeMessage<::dmi::StateChangeInfo>(Arena*);
template<> ::dmi::ThresholdInformation* Arena::CreateMaybeMessage<::dmi::ThresholdInformation>(Arena*);
template<> ::dmi::Thresholds* Arena::CreateMaybeMessage<::dmi::Thresholds>(Arena*);
template<> ::dmi::UsageStateChange* Arena::CreateMaybeMessage<::dmi::UsageStateChange>(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 GenericEventInfo_EventSeverity {
  GenericEventInfo_EventSeverity_EVENT_SEVERITY_UNSPECIFIED = 0,
  GenericEventInfo_EventSeverity_CRITICAL = 1,
  GenericEventInfo_EventSeverity_MAJOR = 2,
  GenericEventInfo_EventSeverity_MINOR = 3,
  GenericEventInfo_EventSeverity_NORMAL = 4,
  GenericEventInfo_EventSeverity_INFO = 5,
  GenericEventInfo_EventSeverity_GenericEventInfo_EventSeverity_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  GenericEventInfo_EventSeverity_GenericEventInfo_EventSeverity_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool GenericEventInfo_EventSeverity_IsValid(int value);
const GenericEventInfo_EventSeverity GenericEventInfo_EventSeverity_EventSeverity_MIN = GenericEventInfo_EventSeverity_EVENT_SEVERITY_UNSPECIFIED;
const GenericEventInfo_EventSeverity GenericEventInfo_EventSeverity_EventSeverity_MAX = GenericEventInfo_EventSeverity_INFO;
const int GenericEventInfo_EventSeverity_EventSeverity_ARRAYSIZE = GenericEventInfo_EventSeverity_EventSeverity_MAX + 1;

const ::google::protobuf::EnumDescriptor* GenericEventInfo_EventSeverity_descriptor();
inline const ::std::string& GenericEventInfo_EventSeverity_Name(GenericEventInfo_EventSeverity value) {
  return ::google::protobuf::internal::NameOfEnum(
    GenericEventInfo_EventSeverity_descriptor(), value);
}
inline bool GenericEventInfo_EventSeverity_Parse(
    const ::std::string& name, GenericEventInfo_EventSeverity* value) {
  return ::google::protobuf::internal::ParseNamedEnum<GenericEventInfo_EventSeverity>(
    GenericEventInfo_EventSeverity_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_CPU_USAGE_ABOVE_THRESHOLD = 404,
  EVENT_CPU_USAGE_ABOVE_THRESHOLD_RECOVERED = 405,
  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,
  EVENT_HW_TEMPERATURE_SENSOR_FAILED = 506,
  EVENT_HW_ALL_TEMPERATURE_SENSORS_FAILED = 507,
  EVENT_HW_DISK_USAGE_ABOVE_THRESHOLD = 508,
  EVENT_HW_DISK_USAGE_ABOVE_THRESHOLD_RECOVERED = 509,
  EVENT_HW_MEMORY_USAGE_ABOVE_THRESHOLD = 510,
  EVENT_HW_MEMORY_USAGE_ABOVE_THRESHOLD_RECOVERED = 511,
  EVENT_HW_NTP_SYNC_FAILURE = 512,
  EVENT_HW_NTP_SYNC_FAILURE_RECOVERED = 513,
  EVENT_LINE_CARD_PLUG_OUT = 600,
  EVENT_LINE_CARD_PLUG_IN = 601,
  EVENT_COMPONENT_ADMIN_STATE_CHANGED = 700,
  EVENT_COMPONENT_OPER_STATE_CHANGED = 701,
  EVENT_COMPONENT_ALARM_STATE_CHANGED = 702,
  EVENT_COMPONENT_USAGE_STATE_CHANGED = 703,
  EVENT_COMPONENT_STANDBY_STATE_CHANGED = 704,
  EVENT_COMPONENT_GENERIC_EVENT = 705,
  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_COMPONENT_GENERIC_EVENT;
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 -------------------------------------------------------

  // .dmi.DataValueType typeOfVal = 4;
  void clear_typeofval();
  static const int kTypeOfValFieldNumber = 4;
  ::dmi::DataValueType typeofval() const;
  void set_typeofval(::dmi::DataValueType value);

  // 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_;
  int typeofval_;
  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.Uuid component_uuid = 4;
  bool has_component_uuid() const;
  void clear_component_uuid();
  static const int kComponentUuidFieldNumber = 4;
  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);

  // .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_;
  ::dmi::Uuid* component_uuid_;
  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 AdminStateChange final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.AdminStateChange) */ {
 public:
  AdminStateChange();
  virtual ~AdminStateChange();

  AdminStateChange(const AdminStateChange& from);

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

  inline AdminStateChange& operator=(AdminStateChange&& 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 AdminStateChange& default_instance();

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

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

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

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

  AdminStateChange* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<AdminStateChange>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const AdminStateChange& from);
  void MergeFrom(const AdminStateChange& 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(AdminStateChange* 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.ComponentAdminState old = 1;
  void clear_old();
  static const int kOldFieldNumber = 1;
  ::dmi::ComponentAdminState old() const;
  void set_old(::dmi::ComponentAdminState value);

  // .dmi.ComponentAdminState new = 2;
  void clear_new_();
  static const int kNewFieldNumber = 2;
  ::dmi::ComponentAdminState new_() const;
  void set_new_(::dmi::ComponentAdminState value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  int old_;
  int new__;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  OperStateChange(const OperStateChange& from);

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

  inline OperStateChange& operator=(OperStateChange&& 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 OperStateChange& default_instance();

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

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

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

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

  OperStateChange* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<OperStateChange>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const OperStateChange& from);
  void MergeFrom(const OperStateChange& 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(OperStateChange* 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.ComponentOperState old = 1;
  void clear_old();
  static const int kOldFieldNumber = 1;
  ::dmi::ComponentOperState old() const;
  void set_old(::dmi::ComponentOperState value);

  // .dmi.ComponentOperState new = 2;
  void clear_new_();
  static const int kNewFieldNumber = 2;
  ::dmi::ComponentOperState new_() const;
  void set_new_(::dmi::ComponentOperState value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  int old_;
  int new__;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  AlarmStateChange(const AlarmStateChange& from);

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

  inline AlarmStateChange& operator=(AlarmStateChange&& 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 AlarmStateChange& default_instance();

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

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

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

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

  AlarmStateChange* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<AlarmStateChange>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const AlarmStateChange& from);
  void MergeFrom(const AlarmStateChange& 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(AlarmStateChange* 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.ComponentAlarmState old = 1;
  void clear_old();
  static const int kOldFieldNumber = 1;
  ::dmi::ComponentAlarmState old() const;
  void set_old(::dmi::ComponentAlarmState value);

  // .dmi.ComponentAlarmState new = 2;
  void clear_new_();
  static const int kNewFieldNumber = 2;
  ::dmi::ComponentAlarmState new_() const;
  void set_new_(::dmi::ComponentAlarmState value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  int old_;
  int new__;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  UsageStateChange(const UsageStateChange& from);

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

  inline UsageStateChange& operator=(UsageStateChange&& 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 UsageStateChange& default_instance();

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

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

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

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

  UsageStateChange* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<UsageStateChange>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const UsageStateChange& from);
  void MergeFrom(const UsageStateChange& 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(UsageStateChange* 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.ComponentUsageState old = 1;
  void clear_old();
  static const int kOldFieldNumber = 1;
  ::dmi::ComponentUsageState old() const;
  void set_old(::dmi::ComponentUsageState value);

  // .dmi.ComponentUsageState new = 2;
  void clear_new_();
  static const int kNewFieldNumber = 2;
  ::dmi::ComponentUsageState new_() const;
  void set_new_(::dmi::ComponentUsageState value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  int old_;
  int new__;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  StandbyStateChange(const StandbyStateChange& from);

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

  inline StandbyStateChange& operator=(StandbyStateChange&& 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 StandbyStateChange& default_instance();

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

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

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

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

  StandbyStateChange* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<StandbyStateChange>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const StandbyStateChange& from);
  void MergeFrom(const StandbyStateChange& 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(StandbyStateChange* 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.ComponentStandbyState old = 1;
  void clear_old();
  static const int kOldFieldNumber = 1;
  ::dmi::ComponentStandbyState old() const;
  void set_old(::dmi::ComponentStandbyState value);

  // .dmi.ComponentStandbyState new = 2;
  void clear_new_();
  static const int kNewFieldNumber = 2;
  ::dmi::ComponentStandbyState new_() const;
  void set_new_(::dmi::ComponentStandbyState value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  int old_;
  int new__;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  StateChangeInfo(const StateChangeInfo& from);

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

  inline StateChangeInfo& operator=(StateChangeInfo&& 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 StateChangeInfo& default_instance();

  enum StateChangeCase {
    kAdminStateChange = 1,
    kOperStateChange = 2,
    kAlarmStateChange = 3,
    kUsageStateChange = 4,
    kStandbyStateChange = 5,
    STATE_CHANGE_NOT_SET = 0,
  };

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

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

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

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

  StateChangeInfo* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<StateChangeInfo>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const StateChangeInfo& from);
  void MergeFrom(const StateChangeInfo& 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(StateChangeInfo* 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.AdminStateChange admin_state_change = 1;
  bool has_admin_state_change() const;
  void clear_admin_state_change();
  static const int kAdminStateChangeFieldNumber = 1;
  const ::dmi::AdminStateChange& admin_state_change() const;
  ::dmi::AdminStateChange* release_admin_state_change();
  ::dmi::AdminStateChange* mutable_admin_state_change();
  void set_allocated_admin_state_change(::dmi::AdminStateChange* admin_state_change);

  // .dmi.OperStateChange oper_state_change = 2;
  bool has_oper_state_change() const;
  void clear_oper_state_change();
  static const int kOperStateChangeFieldNumber = 2;
  const ::dmi::OperStateChange& oper_state_change() const;
  ::dmi::OperStateChange* release_oper_state_change();
  ::dmi::OperStateChange* mutable_oper_state_change();
  void set_allocated_oper_state_change(::dmi::OperStateChange* oper_state_change);

  // .dmi.AlarmStateChange alarm_state_change = 3;
  bool has_alarm_state_change() const;
  void clear_alarm_state_change();
  static const int kAlarmStateChangeFieldNumber = 3;
  const ::dmi::AlarmStateChange& alarm_state_change() const;
  ::dmi::AlarmStateChange* release_alarm_state_change();
  ::dmi::AlarmStateChange* mutable_alarm_state_change();
  void set_allocated_alarm_state_change(::dmi::AlarmStateChange* alarm_state_change);

  // .dmi.UsageStateChange usage_state_change = 4;
  bool has_usage_state_change() const;
  void clear_usage_state_change();
  static const int kUsageStateChangeFieldNumber = 4;
  const ::dmi::UsageStateChange& usage_state_change() const;
  ::dmi::UsageStateChange* release_usage_state_change();
  ::dmi::UsageStateChange* mutable_usage_state_change();
  void set_allocated_usage_state_change(::dmi::UsageStateChange* usage_state_change);

  // .dmi.StandbyStateChange standby_state_change = 5;
  bool has_standby_state_change() const;
  void clear_standby_state_change();
  static const int kStandbyStateChangeFieldNumber = 5;
  const ::dmi::StandbyStateChange& standby_state_change() const;
  ::dmi::StandbyStateChange* release_standby_state_change();
  ::dmi::StandbyStateChange* mutable_standby_state_change();
  void set_allocated_standby_state_change(::dmi::StandbyStateChange* standby_state_change);

  void clear_state_change();
  StateChangeCase state_change_case() const;
  // @@protoc_insertion_point(class_scope:dmi.StateChangeInfo)
 private:
  class HasBitSetters;
  void set_has_admin_state_change();
  void set_has_oper_state_change();
  void set_has_alarm_state_change();
  void set_has_usage_state_change();
  void set_has_standby_state_change();

  inline bool has_state_change() const;
  inline void clear_has_state_change();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  union StateChangeUnion {
    StateChangeUnion() {}
    ::dmi::AdminStateChange* admin_state_change_;
    ::dmi::OperStateChange* oper_state_change_;
    ::dmi::AlarmStateChange* alarm_state_change_;
    ::dmi::UsageStateChange* usage_state_change_;
    ::dmi::StandbyStateChange* standby_state_change_;
  } state_change_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::uint32 _oneof_case_[1];

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

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

  GenericEventInfo(const GenericEventInfo& from);

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

  inline GenericEventInfo& operator=(GenericEventInfo&& 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 GenericEventInfo& default_instance();

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

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

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

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

  GenericEventInfo* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<GenericEventInfo>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const GenericEventInfo& from);
  void MergeFrom(const GenericEventInfo& 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(GenericEventInfo* 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 GenericEventInfo_EventSeverity EventSeverity;
  static const EventSeverity EVENT_SEVERITY_UNSPECIFIED =
    GenericEventInfo_EventSeverity_EVENT_SEVERITY_UNSPECIFIED;
  static const EventSeverity CRITICAL =
    GenericEventInfo_EventSeverity_CRITICAL;
  static const EventSeverity MAJOR =
    GenericEventInfo_EventSeverity_MAJOR;
  static const EventSeverity MINOR =
    GenericEventInfo_EventSeverity_MINOR;
  static const EventSeverity NORMAL =
    GenericEventInfo_EventSeverity_NORMAL;
  static const EventSeverity INFO =
    GenericEventInfo_EventSeverity_INFO;
  static inline bool EventSeverity_IsValid(int value) {
    return GenericEventInfo_EventSeverity_IsValid(value);
  }
  static const EventSeverity EventSeverity_MIN =
    GenericEventInfo_EventSeverity_EventSeverity_MIN;
  static const EventSeverity EventSeverity_MAX =
    GenericEventInfo_EventSeverity_EventSeverity_MAX;
  static const int EventSeverity_ARRAYSIZE =
    GenericEventInfo_EventSeverity_EventSeverity_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  EventSeverity_descriptor() {
    return GenericEventInfo_EventSeverity_descriptor();
  }
  static inline const ::std::string& EventSeverity_Name(EventSeverity value) {
    return GenericEventInfo_EventSeverity_Name(value);
  }
  static inline bool EventSeverity_Parse(const ::std::string& name,
      EventSeverity* value) {
    return GenericEventInfo_EventSeverity_Parse(name, value);
  }

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

  // string message = 1;
  void clear_message();
  static const int kMessageFieldNumber = 1;
  const ::std::string& message() const;
  void set_message(const ::std::string& value);
  #if LANG_CXX11
  void set_message(::std::string&& value);
  #endif
  void set_message(const char* value);
  void set_message(const char* value, size_t size);
  ::std::string* mutable_message();
  ::std::string* release_message();
  void set_allocated_message(::std::string* message);

  // string message_code = 2;
  void clear_message_code();
  static const int kMessageCodeFieldNumber = 2;
  const ::std::string& message_code() const;
  void set_message_code(const ::std::string& value);
  #if LANG_CXX11
  void set_message_code(::std::string&& value);
  #endif
  void set_message_code(const char* value);
  void set_message_code(const char* value, size_t size);
  ::std::string* mutable_message_code();
  ::std::string* release_message_code();
  void set_allocated_message_code(::std::string* message_code);

  // .dmi.GenericEventInfo.EventSeverity severity = 3;
  void clear_severity();
  static const int kSeverityFieldNumber = 3;
  ::dmi::GenericEventInfo_EventSeverity severity() const;
  void set_severity(::dmi::GenericEventInfo_EventSeverity value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr message_;
  ::google::protobuf::internal::ArenaStringPtr message_code_;
  int severity_;
  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 =
    17;

  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.StateChangeInfo state_change_info = 6;
  bool has_state_change_info() const;
  void clear_state_change_info();
  static const int kStateChangeInfoFieldNumber = 6;
  const ::dmi::StateChangeInfo& state_change_info() const;
  ::dmi::StateChangeInfo* release_state_change_info();
  ::dmi::StateChangeInfo* mutable_state_change_info();
  void set_allocated_state_change_info(::dmi::StateChangeInfo* state_change_info);

  // .dmi.GenericEventInfo generic_event_info = 7;
  bool has_generic_event_info() const;
  void clear_generic_event_info();
  static const int kGenericEventInfoFieldNumber = 7;
  const ::dmi::GenericEventInfo& generic_event_info() const;
  ::dmi::GenericEventInfo* release_generic_event_info();
  ::dmi::GenericEventInfo* mutable_generic_event_info();
  void set_allocated_generic_event_info(::dmi::GenericEventInfo* generic_event_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_;
  ::dmi::StateChangeInfo* state_change_info_;
  ::dmi::GenericEventInfo* generic_event_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)
}

// .dmi.DataValueType typeOfVal = 4;
inline void ValueType::clear_typeofval() {
  typeofval_ = 0;
}
inline ::dmi::DataValueType ValueType::typeofval() const {
  // @@protoc_insertion_point(field_get:dmi.ValueType.typeOfVal)
  return static_cast< ::dmi::DataValueType >(typeofval_);
}
inline void ValueType::set_typeofval(::dmi::DataValueType value) {
  
  typeofval_ = value;
  // @@protoc_insertion_point(field_set:dmi.ValueType.typeOfVal)
}

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)
}

// .dmi.Uuid component_uuid = 4;
inline bool EventCfg::has_component_uuid() const {
  return this != internal_default_instance() && component_uuid_ != nullptr;
}
inline const ::dmi::Uuid& EventCfg::component_uuid() const {
  const ::dmi::Uuid* p = component_uuid_;
  // @@protoc_insertion_point(field_get:dmi.EventCfg.component_uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* EventCfg::release_component_uuid() {
  // @@protoc_insertion_point(field_release:dmi.EventCfg.component_uuid)
  
  ::dmi::Uuid* temp = component_uuid_;
  component_uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* EventCfg::mutable_component_uuid() {
  
  if (component_uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    component_uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.EventCfg.component_uuid)
  return component_uuid_;
}
inline void EventCfg::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.EventCfg.component_uuid)
}

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

// 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)
}

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

// AdminStateChange

// .dmi.ComponentAdminState old = 1;
inline void AdminStateChange::clear_old() {
  old_ = 0;
}
inline ::dmi::ComponentAdminState AdminStateChange::old() const {
  // @@protoc_insertion_point(field_get:dmi.AdminStateChange.old)
  return static_cast< ::dmi::ComponentAdminState >(old_);
}
inline void AdminStateChange::set_old(::dmi::ComponentAdminState value) {
  
  old_ = value;
  // @@protoc_insertion_point(field_set:dmi.AdminStateChange.old)
}

// .dmi.ComponentAdminState new = 2;
inline void AdminStateChange::clear_new_() {
  new__ = 0;
}
inline ::dmi::ComponentAdminState AdminStateChange::new_() const {
  // @@protoc_insertion_point(field_get:dmi.AdminStateChange.new)
  return static_cast< ::dmi::ComponentAdminState >(new__);
}
inline void AdminStateChange::set_new_(::dmi::ComponentAdminState value) {
  
  new__ = value;
  // @@protoc_insertion_point(field_set:dmi.AdminStateChange.new)
}

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

// OperStateChange

// .dmi.ComponentOperState old = 1;
inline void OperStateChange::clear_old() {
  old_ = 0;
}
inline ::dmi::ComponentOperState OperStateChange::old() const {
  // @@protoc_insertion_point(field_get:dmi.OperStateChange.old)
  return static_cast< ::dmi::ComponentOperState >(old_);
}
inline void OperStateChange::set_old(::dmi::ComponentOperState value) {
  
  old_ = value;
  // @@protoc_insertion_point(field_set:dmi.OperStateChange.old)
}

// .dmi.ComponentOperState new = 2;
inline void OperStateChange::clear_new_() {
  new__ = 0;
}
inline ::dmi::ComponentOperState OperStateChange::new_() const {
  // @@protoc_insertion_point(field_get:dmi.OperStateChange.new)
  return static_cast< ::dmi::ComponentOperState >(new__);
}
inline void OperStateChange::set_new_(::dmi::ComponentOperState value) {
  
  new__ = value;
  // @@protoc_insertion_point(field_set:dmi.OperStateChange.new)
}

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

// AlarmStateChange

// .dmi.ComponentAlarmState old = 1;
inline void AlarmStateChange::clear_old() {
  old_ = 0;
}
inline ::dmi::ComponentAlarmState AlarmStateChange::old() const {
  // @@protoc_insertion_point(field_get:dmi.AlarmStateChange.old)
  return static_cast< ::dmi::ComponentAlarmState >(old_);
}
inline void AlarmStateChange::set_old(::dmi::ComponentAlarmState value) {
  
  old_ = value;
  // @@protoc_insertion_point(field_set:dmi.AlarmStateChange.old)
}

// .dmi.ComponentAlarmState new = 2;
inline void AlarmStateChange::clear_new_() {
  new__ = 0;
}
inline ::dmi::ComponentAlarmState AlarmStateChange::new_() const {
  // @@protoc_insertion_point(field_get:dmi.AlarmStateChange.new)
  return static_cast< ::dmi::ComponentAlarmState >(new__);
}
inline void AlarmStateChange::set_new_(::dmi::ComponentAlarmState value) {
  
  new__ = value;
  // @@protoc_insertion_point(field_set:dmi.AlarmStateChange.new)
}

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

// UsageStateChange

// .dmi.ComponentUsageState old = 1;
inline void UsageStateChange::clear_old() {
  old_ = 0;
}
inline ::dmi::ComponentUsageState UsageStateChange::old() const {
  // @@protoc_insertion_point(field_get:dmi.UsageStateChange.old)
  return static_cast< ::dmi::ComponentUsageState >(old_);
}
inline void UsageStateChange::set_old(::dmi::ComponentUsageState value) {
  
  old_ = value;
  // @@protoc_insertion_point(field_set:dmi.UsageStateChange.old)
}

// .dmi.ComponentUsageState new = 2;
inline void UsageStateChange::clear_new_() {
  new__ = 0;
}
inline ::dmi::ComponentUsageState UsageStateChange::new_() const {
  // @@protoc_insertion_point(field_get:dmi.UsageStateChange.new)
  return static_cast< ::dmi::ComponentUsageState >(new__);
}
inline void UsageStateChange::set_new_(::dmi::ComponentUsageState value) {
  
  new__ = value;
  // @@protoc_insertion_point(field_set:dmi.UsageStateChange.new)
}

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

// StandbyStateChange

// .dmi.ComponentStandbyState old = 1;
inline void StandbyStateChange::clear_old() {
  old_ = 0;
}
inline ::dmi::ComponentStandbyState StandbyStateChange::old() const {
  // @@protoc_insertion_point(field_get:dmi.StandbyStateChange.old)
  return static_cast< ::dmi::ComponentStandbyState >(old_);
}
inline void StandbyStateChange::set_old(::dmi::ComponentStandbyState value) {
  
  old_ = value;
  // @@protoc_insertion_point(field_set:dmi.StandbyStateChange.old)
}

// .dmi.ComponentStandbyState new = 2;
inline void StandbyStateChange::clear_new_() {
  new__ = 0;
}
inline ::dmi::ComponentStandbyState StandbyStateChange::new_() const {
  // @@protoc_insertion_point(field_get:dmi.StandbyStateChange.new)
  return static_cast< ::dmi::ComponentStandbyState >(new__);
}
inline void StandbyStateChange::set_new_(::dmi::ComponentStandbyState value) {
  
  new__ = value;
  // @@protoc_insertion_point(field_set:dmi.StandbyStateChange.new)
}

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

// StateChangeInfo

// .dmi.AdminStateChange admin_state_change = 1;
inline bool StateChangeInfo::has_admin_state_change() const {
  return state_change_case() == kAdminStateChange;
}
inline void StateChangeInfo::set_has_admin_state_change() {
  _oneof_case_[0] = kAdminStateChange;
}
inline void StateChangeInfo::clear_admin_state_change() {
  if (has_admin_state_change()) {
    delete state_change_.admin_state_change_;
    clear_has_state_change();
  }
}
inline ::dmi::AdminStateChange* StateChangeInfo::release_admin_state_change() {
  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.admin_state_change)
  if (has_admin_state_change()) {
    clear_has_state_change();
      ::dmi::AdminStateChange* temp = state_change_.admin_state_change_;
    state_change_.admin_state_change_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::AdminStateChange& StateChangeInfo::admin_state_change() const {
  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.admin_state_change)
  return has_admin_state_change()
      ? *state_change_.admin_state_change_
      : *reinterpret_cast< ::dmi::AdminStateChange*>(&::dmi::_AdminStateChange_default_instance_);
}
inline ::dmi::AdminStateChange* StateChangeInfo::mutable_admin_state_change() {
  if (!has_admin_state_change()) {
    clear_state_change();
    set_has_admin_state_change();
    state_change_.admin_state_change_ = CreateMaybeMessage< ::dmi::AdminStateChange >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.admin_state_change)
  return state_change_.admin_state_change_;
}

// .dmi.OperStateChange oper_state_change = 2;
inline bool StateChangeInfo::has_oper_state_change() const {
  return state_change_case() == kOperStateChange;
}
inline void StateChangeInfo::set_has_oper_state_change() {
  _oneof_case_[0] = kOperStateChange;
}
inline void StateChangeInfo::clear_oper_state_change() {
  if (has_oper_state_change()) {
    delete state_change_.oper_state_change_;
    clear_has_state_change();
  }
}
inline ::dmi::OperStateChange* StateChangeInfo::release_oper_state_change() {
  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.oper_state_change)
  if (has_oper_state_change()) {
    clear_has_state_change();
      ::dmi::OperStateChange* temp = state_change_.oper_state_change_;
    state_change_.oper_state_change_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::OperStateChange& StateChangeInfo::oper_state_change() const {
  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.oper_state_change)
  return has_oper_state_change()
      ? *state_change_.oper_state_change_
      : *reinterpret_cast< ::dmi::OperStateChange*>(&::dmi::_OperStateChange_default_instance_);
}
inline ::dmi::OperStateChange* StateChangeInfo::mutable_oper_state_change() {
  if (!has_oper_state_change()) {
    clear_state_change();
    set_has_oper_state_change();
    state_change_.oper_state_change_ = CreateMaybeMessage< ::dmi::OperStateChange >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.oper_state_change)
  return state_change_.oper_state_change_;
}

// .dmi.AlarmStateChange alarm_state_change = 3;
inline bool StateChangeInfo::has_alarm_state_change() const {
  return state_change_case() == kAlarmStateChange;
}
inline void StateChangeInfo::set_has_alarm_state_change() {
  _oneof_case_[0] = kAlarmStateChange;
}
inline void StateChangeInfo::clear_alarm_state_change() {
  if (has_alarm_state_change()) {
    delete state_change_.alarm_state_change_;
    clear_has_state_change();
  }
}
inline ::dmi::AlarmStateChange* StateChangeInfo::release_alarm_state_change() {
  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.alarm_state_change)
  if (has_alarm_state_change()) {
    clear_has_state_change();
      ::dmi::AlarmStateChange* temp = state_change_.alarm_state_change_;
    state_change_.alarm_state_change_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::AlarmStateChange& StateChangeInfo::alarm_state_change() const {
  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.alarm_state_change)
  return has_alarm_state_change()
      ? *state_change_.alarm_state_change_
      : *reinterpret_cast< ::dmi::AlarmStateChange*>(&::dmi::_AlarmStateChange_default_instance_);
}
inline ::dmi::AlarmStateChange* StateChangeInfo::mutable_alarm_state_change() {
  if (!has_alarm_state_change()) {
    clear_state_change();
    set_has_alarm_state_change();
    state_change_.alarm_state_change_ = CreateMaybeMessage< ::dmi::AlarmStateChange >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.alarm_state_change)
  return state_change_.alarm_state_change_;
}

// .dmi.UsageStateChange usage_state_change = 4;
inline bool StateChangeInfo::has_usage_state_change() const {
  return state_change_case() == kUsageStateChange;
}
inline void StateChangeInfo::set_has_usage_state_change() {
  _oneof_case_[0] = kUsageStateChange;
}
inline void StateChangeInfo::clear_usage_state_change() {
  if (has_usage_state_change()) {
    delete state_change_.usage_state_change_;
    clear_has_state_change();
  }
}
inline ::dmi::UsageStateChange* StateChangeInfo::release_usage_state_change() {
  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.usage_state_change)
  if (has_usage_state_change()) {
    clear_has_state_change();
      ::dmi::UsageStateChange* temp = state_change_.usage_state_change_;
    state_change_.usage_state_change_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::UsageStateChange& StateChangeInfo::usage_state_change() const {
  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.usage_state_change)
  return has_usage_state_change()
      ? *state_change_.usage_state_change_
      : *reinterpret_cast< ::dmi::UsageStateChange*>(&::dmi::_UsageStateChange_default_instance_);
}
inline ::dmi::UsageStateChange* StateChangeInfo::mutable_usage_state_change() {
  if (!has_usage_state_change()) {
    clear_state_change();
    set_has_usage_state_change();
    state_change_.usage_state_change_ = CreateMaybeMessage< ::dmi::UsageStateChange >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.usage_state_change)
  return state_change_.usage_state_change_;
}

// .dmi.StandbyStateChange standby_state_change = 5;
inline bool StateChangeInfo::has_standby_state_change() const {
  return state_change_case() == kStandbyStateChange;
}
inline void StateChangeInfo::set_has_standby_state_change() {
  _oneof_case_[0] = kStandbyStateChange;
}
inline void StateChangeInfo::clear_standby_state_change() {
  if (has_standby_state_change()) {
    delete state_change_.standby_state_change_;
    clear_has_state_change();
  }
}
inline ::dmi::StandbyStateChange* StateChangeInfo::release_standby_state_change() {
  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.standby_state_change)
  if (has_standby_state_change()) {
    clear_has_state_change();
      ::dmi::StandbyStateChange* temp = state_change_.standby_state_change_;
    state_change_.standby_state_change_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::StandbyStateChange& StateChangeInfo::standby_state_change() const {
  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.standby_state_change)
  return has_standby_state_change()
      ? *state_change_.standby_state_change_
      : *reinterpret_cast< ::dmi::StandbyStateChange*>(&::dmi::_StandbyStateChange_default_instance_);
}
inline ::dmi::StandbyStateChange* StateChangeInfo::mutable_standby_state_change() {
  if (!has_standby_state_change()) {
    clear_state_change();
    set_has_standby_state_change();
    state_change_.standby_state_change_ = CreateMaybeMessage< ::dmi::StandbyStateChange >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.standby_state_change)
  return state_change_.standby_state_change_;
}

inline bool StateChangeInfo::has_state_change() const {
  return state_change_case() != STATE_CHANGE_NOT_SET;
}
inline void StateChangeInfo::clear_has_state_change() {
  _oneof_case_[0] = STATE_CHANGE_NOT_SET;
}
inline StateChangeInfo::StateChangeCase StateChangeInfo::state_change_case() const {
  return StateChangeInfo::StateChangeCase(_oneof_case_[0]);
}
// -------------------------------------------------------------------

// GenericEventInfo

// string message = 1;
inline void GenericEventInfo::clear_message() {
  message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& GenericEventInfo::message() const {
  // @@protoc_insertion_point(field_get:dmi.GenericEventInfo.message)
  return message_.GetNoArena();
}
inline void GenericEventInfo::set_message(const ::std::string& value) {
  
  message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.GenericEventInfo.message)
}
#if LANG_CXX11
inline void GenericEventInfo::set_message(::std::string&& value) {
  
  message_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.GenericEventInfo.message)
}
#endif
inline void GenericEventInfo::set_message(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.GenericEventInfo.message)
}
inline void GenericEventInfo::set_message(const char* value, size_t size) {
  
  message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.GenericEventInfo.message)
}
inline ::std::string* GenericEventInfo::mutable_message() {
  
  // @@protoc_insertion_point(field_mutable:dmi.GenericEventInfo.message)
  return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* GenericEventInfo::release_message() {
  // @@protoc_insertion_point(field_release:dmi.GenericEventInfo.message)
  
  return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void GenericEventInfo::set_allocated_message(::std::string* message) {
  if (message != nullptr) {
    
  } else {
    
  }
  message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message);
  // @@protoc_insertion_point(field_set_allocated:dmi.GenericEventInfo.message)
}

// string message_code = 2;
inline void GenericEventInfo::clear_message_code() {
  message_code_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& GenericEventInfo::message_code() const {
  // @@protoc_insertion_point(field_get:dmi.GenericEventInfo.message_code)
  return message_code_.GetNoArena();
}
inline void GenericEventInfo::set_message_code(const ::std::string& value) {
  
  message_code_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.GenericEventInfo.message_code)
}
#if LANG_CXX11
inline void GenericEventInfo::set_message_code(::std::string&& value) {
  
  message_code_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.GenericEventInfo.message_code)
}
#endif
inline void GenericEventInfo::set_message_code(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  message_code_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.GenericEventInfo.message_code)
}
inline void GenericEventInfo::set_message_code(const char* value, size_t size) {
  
  message_code_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.GenericEventInfo.message_code)
}
inline ::std::string* GenericEventInfo::mutable_message_code() {
  
  // @@protoc_insertion_point(field_mutable:dmi.GenericEventInfo.message_code)
  return message_code_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* GenericEventInfo::release_message_code() {
  // @@protoc_insertion_point(field_release:dmi.GenericEventInfo.message_code)
  
  return message_code_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void GenericEventInfo::set_allocated_message_code(::std::string* message_code) {
  if (message_code != nullptr) {
    
  } else {
    
  }
  message_code_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message_code);
  // @@protoc_insertion_point(field_set_allocated:dmi.GenericEventInfo.message_code)
}

// .dmi.GenericEventInfo.EventSeverity severity = 3;
inline void GenericEventInfo::clear_severity() {
  severity_ = 0;
}
inline ::dmi::GenericEventInfo_EventSeverity GenericEventInfo::severity() const {
  // @@protoc_insertion_point(field_get:dmi.GenericEventInfo.severity)
  return static_cast< ::dmi::GenericEventInfo_EventSeverity >(severity_);
}
inline void GenericEventInfo::set_severity(::dmi::GenericEventInfo_EventSeverity value) {
  
  severity_ = value;
  // @@protoc_insertion_point(field_set:dmi.GenericEventInfo.severity)
}

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

// 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)
}

// .dmi.StateChangeInfo state_change_info = 6;
inline bool Event::has_state_change_info() const {
  return this != internal_default_instance() && state_change_info_ != nullptr;
}
inline void Event::clear_state_change_info() {
  if (GetArenaNoVirtual() == nullptr && state_change_info_ != nullptr) {
    delete state_change_info_;
  }
  state_change_info_ = nullptr;
}
inline const ::dmi::StateChangeInfo& Event::state_change_info() const {
  const ::dmi::StateChangeInfo* p = state_change_info_;
  // @@protoc_insertion_point(field_get:dmi.Event.state_change_info)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::StateChangeInfo*>(
      &::dmi::_StateChangeInfo_default_instance_);
}
inline ::dmi::StateChangeInfo* Event::release_state_change_info() {
  // @@protoc_insertion_point(field_release:dmi.Event.state_change_info)
  
  ::dmi::StateChangeInfo* temp = state_change_info_;
  state_change_info_ = nullptr;
  return temp;
}
inline ::dmi::StateChangeInfo* Event::mutable_state_change_info() {
  
  if (state_change_info_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::StateChangeInfo>(GetArenaNoVirtual());
    state_change_info_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Event.state_change_info)
  return state_change_info_;
}
inline void Event::set_allocated_state_change_info(::dmi::StateChangeInfo* state_change_info) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete state_change_info_;
  }
  if (state_change_info) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      state_change_info = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, state_change_info, submessage_arena);
    }
    
  } else {
    
  }
  state_change_info_ = state_change_info;
  // @@protoc_insertion_point(field_set_allocated:dmi.Event.state_change_info)
}

// .dmi.GenericEventInfo generic_event_info = 7;
inline bool Event::has_generic_event_info() const {
  return this != internal_default_instance() && generic_event_info_ != nullptr;
}
inline void Event::clear_generic_event_info() {
  if (GetArenaNoVirtual() == nullptr && generic_event_info_ != nullptr) {
    delete generic_event_info_;
  }
  generic_event_info_ = nullptr;
}
inline const ::dmi::GenericEventInfo& Event::generic_event_info() const {
  const ::dmi::GenericEventInfo* p = generic_event_info_;
  // @@protoc_insertion_point(field_get:dmi.Event.generic_event_info)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::GenericEventInfo*>(
      &::dmi::_GenericEventInfo_default_instance_);
}
inline ::dmi::GenericEventInfo* Event::release_generic_event_info() {
  // @@protoc_insertion_point(field_release:dmi.Event.generic_event_info)
  
  ::dmi::GenericEventInfo* temp = generic_event_info_;
  generic_event_info_ = nullptr;
  return temp;
}
inline ::dmi::GenericEventInfo* Event::mutable_generic_event_info() {
  
  if (generic_event_info_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::GenericEventInfo>(GetArenaNoVirtual());
    generic_event_info_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Event.generic_event_info)
  return generic_event_info_;
}
inline void Event::set_allocated_generic_event_info(::dmi::GenericEventInfo* generic_event_info) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete generic_event_info_;
  }
  if (generic_event_info) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      generic_event_info = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, generic_event_info, submessage_arena);
    }
    
  } else {
    
  }
  generic_event_info_ = generic_event_info;
  // @@protoc_insertion_point(field_set_allocated:dmi.Event.generic_event_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::GenericEventInfo_EventSeverity> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::GenericEventInfo_EventSeverity>() {
  return ::dmi::GenericEventInfo_EventSeverity_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
