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

#include "dmi/hw_events_mgmt_service.pb.h"

#include <algorithm>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>

extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<5> scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto;
namespace dmi {
class ValueTypeDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<ValueType> _instance;
  ::google::protobuf::int64 int_val_;
  ::google::protobuf::uint64 uint_val_;
  float float_val_;
} _ValueType_default_instance_;
class WaterMarksDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<WaterMarks> _instance;
} _WaterMarks_default_instance_;
class ThresholdsDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<Thresholds> _instance;
  const ::dmi::WaterMarks* upper_;
  const ::dmi::WaterMarks* lower_;
} _Thresholds_default_instance_;
class ThresholdInformationDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<ThresholdInformation> _instance;
} _ThresholdInformation_default_instance_;
class EventCfgDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EventCfg> _instance;
} _EventCfg_default_instance_;
class EventsCfgDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EventsCfg> _instance;
} _EventsCfg_default_instance_;
class ListEventsResponseDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<ListEventsResponse> _instance;
} _ListEventsResponse_default_instance_;
class EventsConfigurationRequestDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EventsConfigurationRequest> _instance;
  const ::dmi::EventsCfg* changes_;
  bool reset_to_default_;
} _EventsConfigurationRequest_default_instance_;
class EventsConfigurationResponseDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EventsConfigurationResponse> _instance;
} _EventsConfigurationResponse_default_instance_;
class EventMetaDataDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<EventMetaData> _instance;
} _EventMetaData_default_instance_;
class AdminStateChangeDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<AdminStateChange> _instance;
} _AdminStateChange_default_instance_;
class OperStateChangeDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<OperStateChange> _instance;
} _OperStateChange_default_instance_;
class AlarmStateChangeDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<AlarmStateChange> _instance;
} _AlarmStateChange_default_instance_;
class UsageStateChangeDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<UsageStateChange> _instance;
} _UsageStateChange_default_instance_;
class StandbyStateChangeDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<StandbyStateChange> _instance;
} _StandbyStateChange_default_instance_;
class StateChangeInfoDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<StateChangeInfo> _instance;
  const ::dmi::AdminStateChange* admin_state_change_;
  const ::dmi::OperStateChange* oper_state_change_;
  const ::dmi::AlarmStateChange* alarm_state_change_;
  const ::dmi::UsageStateChange* usage_state_change_;
  const ::dmi::StandbyStateChange* standby_state_change_;
} _StateChangeInfo_default_instance_;
class EventDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<Event> _instance;
} _Event_default_instance_;
}  // namespace dmi
static void InitDefaultsValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_ValueType_default_instance_;
    new (ptr) ::dmi::ValueType();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::ValueType::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};

static void InitDefaultsWaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_WaterMarks_default_instance_;
    new (ptr) ::dmi::WaterMarks();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::WaterMarks::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsWaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};

static void InitDefaultsThresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_Thresholds_default_instance_;
    new (ptr) ::dmi::Thresholds();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::Thresholds::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsThresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};

static void InitDefaultsThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_ThresholdInformation_default_instance_;
    new (ptr) ::dmi::ThresholdInformation();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::ThresholdInformation::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<2> scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
      &scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};

static void InitDefaultsEventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_EventCfg_default_instance_;
    new (ptr) ::dmi::EventCfg();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::EventCfg::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<2> scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsEventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};

static void InitDefaultsEventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_EventsCfg_default_instance_;
    new (ptr) ::dmi::EventsCfg();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::EventsCfg::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};

static void InitDefaultsListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_ListEventsResponse_default_instance_;
    new (ptr) ::dmi::ListEventsResponse();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::ListEventsResponse::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_ListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};

static void InitDefaultsEventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_EventsConfigurationRequest_default_instance_;
    new (ptr) ::dmi::EventsConfigurationRequest();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::EventsConfigurationRequest::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<2> scc_info_EventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsEventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_Uuid_dmi_2fhw_2eproto.base,
      &scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};

static void InitDefaultsEventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_EventsConfigurationResponse_default_instance_;
    new (ptr) ::dmi::EventsConfigurationResponse();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::EventsConfigurationResponse::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_EventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsEventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};

static void InitDefaultsEventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_EventMetaData_default_instance_;
    new (ptr) ::dmi::EventMetaData();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::EventMetaData::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<1> scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};

static void InitDefaultsAdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_AdminStateChange_default_instance_;
    new (ptr) ::dmi::AdminStateChange();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::AdminStateChange::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsAdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};

static void InitDefaultsOperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_OperStateChange_default_instance_;
    new (ptr) ::dmi::OperStateChange();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::OperStateChange::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsOperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};

static void InitDefaultsAlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_AlarmStateChange_default_instance_;
    new (ptr) ::dmi::AlarmStateChange();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::AlarmStateChange::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsAlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};

static void InitDefaultsUsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_UsageStateChange_default_instance_;
    new (ptr) ::dmi::UsageStateChange();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::UsageStateChange::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};

static void InitDefaultsStandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_StandbyStateChange_default_instance_;
    new (ptr) ::dmi::StandbyStateChange();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::StandbyStateChange::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsStandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};

static void InitDefaultsStateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_StateChangeInfo_default_instance_;
    new (ptr) ::dmi::StateChangeInfo();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::StateChangeInfo::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<5> scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 5, InitDefaultsStateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
      &scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
      &scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
      &scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
      &scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};

static void InitDefaultsEvent_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_Event_default_instance_;
    new (ptr) ::dmi::Event();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::Event::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<4> scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 4, InitDefaultsEvent_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
      &scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,
      &scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
      &scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};

void InitDefaults_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  ::google::protobuf::internal::InitSCC(&scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_ListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
}

::google::protobuf::Metadata file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[17];
const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[3];
constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = nullptr;

const ::google::protobuf::uint32 TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::ValueType, _internal_metadata_),
  ~0u,  // no _extensions_
  PROTOBUF_FIELD_OFFSET(::dmi::ValueType, _oneof_case_[0]),
  ~0u,  // no _weak_field_map_
  offsetof(::dmi::ValueTypeDefaultTypeInternal, int_val_),
  offsetof(::dmi::ValueTypeDefaultTypeInternal, uint_val_),
  offsetof(::dmi::ValueTypeDefaultTypeInternal, float_val_),
  PROTOBUF_FIELD_OFFSET(::dmi::ValueType, typeofval_),
  PROTOBUF_FIELD_OFFSET(::dmi::ValueType, val_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::WaterMarks, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::WaterMarks, high_),
  PROTOBUF_FIELD_OFFSET(::dmi::WaterMarks, low_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::Thresholds, _internal_metadata_),
  ~0u,  // no _extensions_
  PROTOBUF_FIELD_OFFSET(::dmi::Thresholds, _oneof_case_[0]),
  ~0u,  // no _weak_field_map_
  offsetof(::dmi::ThresholdsDefaultTypeInternal, upper_),
  offsetof(::dmi::ThresholdsDefaultTypeInternal, lower_),
  PROTOBUF_FIELD_OFFSET(::dmi::Thresholds, threshold_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::ThresholdInformation, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::ThresholdInformation, observed_value_),
  PROTOBUF_FIELD_OFFSET(::dmi::ThresholdInformation, thresholds_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::EventCfg, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::EventCfg, event_id_),
  PROTOBUF_FIELD_OFFSET(::dmi::EventCfg, is_configured_),
  PROTOBUF_FIELD_OFFSET(::dmi::EventCfg, thresholds_),
  PROTOBUF_FIELD_OFFSET(::dmi::EventCfg, component_uuid_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::EventsCfg, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::EventsCfg, items_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, status_),
  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, reason_),
  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, events_),
  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, reason_detail_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationRequest, _internal_metadata_),
  ~0u,  // no _extensions_
  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationRequest, _oneof_case_[0]),
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationRequest, device_uuid_),
  offsetof(::dmi::EventsConfigurationRequestDefaultTypeInternal, changes_),
  offsetof(::dmi::EventsConfigurationRequestDefaultTypeInternal, reset_to_default_),
  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationRequest, operation_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationResponse, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationResponse, status_),
  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationResponse, reason_),
  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationResponse, reason_detail_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, device_uuid_),
  PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, component_uuid_),
  PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, component_name_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::AdminStateChange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::AdminStateChange, old_),
  PROTOBUF_FIELD_OFFSET(::dmi::AdminStateChange, new__),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::OperStateChange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::OperStateChange, old_),
  PROTOBUF_FIELD_OFFSET(::dmi::OperStateChange, new__),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::AlarmStateChange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::AlarmStateChange, old_),
  PROTOBUF_FIELD_OFFSET(::dmi::AlarmStateChange, new__),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::UsageStateChange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::UsageStateChange, old_),
  PROTOBUF_FIELD_OFFSET(::dmi::UsageStateChange, new__),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::StandbyStateChange, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::StandbyStateChange, old_),
  PROTOBUF_FIELD_OFFSET(::dmi::StandbyStateChange, new__),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::StateChangeInfo, _internal_metadata_),
  ~0u,  // no _extensions_
  PROTOBUF_FIELD_OFFSET(::dmi::StateChangeInfo, _oneof_case_[0]),
  ~0u,  // no _weak_field_map_
  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, admin_state_change_),
  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, oper_state_change_),
  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, alarm_state_change_),
  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, usage_state_change_),
  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, standby_state_change_),
  PROTOBUF_FIELD_OFFSET(::dmi::StateChangeInfo, state_change_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::Event, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::Event, event_metadata_),
  PROTOBUF_FIELD_OFFSET(::dmi::Event, event_id_),
  PROTOBUF_FIELD_OFFSET(::dmi::Event, raised_ts_),
  PROTOBUF_FIELD_OFFSET(::dmi::Event, threshold_info_),
  PROTOBUF_FIELD_OFFSET(::dmi::Event, add_info_),
  PROTOBUF_FIELD_OFFSET(::dmi::Event, state_change_info_),
};
static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
  { 0, -1, sizeof(::dmi::ValueType)},
  { 10, -1, sizeof(::dmi::WaterMarks)},
  { 17, -1, sizeof(::dmi::Thresholds)},
  { 25, -1, sizeof(::dmi::ThresholdInformation)},
  { 32, -1, sizeof(::dmi::EventCfg)},
  { 41, -1, sizeof(::dmi::EventsCfg)},
  { 47, -1, sizeof(::dmi::ListEventsResponse)},
  { 56, -1, sizeof(::dmi::EventsConfigurationRequest)},
  { 65, -1, sizeof(::dmi::EventsConfigurationResponse)},
  { 73, -1, sizeof(::dmi::EventMetaData)},
  { 81, -1, sizeof(::dmi::AdminStateChange)},
  { 88, -1, sizeof(::dmi::OperStateChange)},
  { 95, -1, sizeof(::dmi::AlarmStateChange)},
  { 102, -1, sizeof(::dmi::UsageStateChange)},
  { 109, -1, sizeof(::dmi::StandbyStateChange)},
  { 116, -1, sizeof(::dmi::StateChangeInfo)},
  { 127, -1, sizeof(::dmi::Event)},
};

static ::google::protobuf::Message const * const file_default_instances[] = {
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ValueType_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_WaterMarks_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Thresholds_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ThresholdInformation_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventCfg_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventsCfg_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ListEventsResponse_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventsConfigurationRequest_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventsConfigurationResponse_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventMetaData_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_AdminStateChange_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_OperStateChange_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_AlarmStateChange_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_UsageStateChange_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_StandbyStateChange_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_StateChangeInfo_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Event_default_instance_),
};

::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = {
  {}, AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, "dmi/hw_events_mgmt_service.proto", schemas,
  file_default_instances, TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto::offsets,
  file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 17, file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, file_level_service_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto,
};

const char descriptor_table_protodef_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[] =
  "\n dmi/hw_events_mgmt_service.proto\022\003dmi\032"
  "\021dmi/commons.proto\032\014dmi/hw.proto\032\037google"
  "/protobuf/timestamp.proto\032\033google/protob"
  "uf/empty.proto\"u\n\tValueType\022\021\n\007int_val\030\001"
  " \001(\003H\000\022\022\n\010uint_val\030\002 \001(\004H\000\022\023\n\tfloat_val\030"
  "\003 \001(\002H\000\022%\n\ttypeOfVal\030\004 \001(\0162\022.dmi.DataVal"
  "ueTypeB\005\n\003val\"G\n\nWaterMarks\022\034\n\004high\030\001 \001("
  "\0132\016.dmi.ValueType\022\033\n\003low\030\002 \001(\0132\016.dmi.Val"
  "ueType\"]\n\nThresholds\022 \n\005upper\030\001 \001(\0132\017.dm"
  "i.WaterMarksH\000\022 \n\005lower\030\002 \001(\0132\017.dmi.Wate"
  "rMarksH\000B\013\n\tthreshold\"c\n\024ThresholdInform"
  "ation\022&\n\016observed_value\030\001 \001(\0132\016.dmi.Valu"
  "eType\022#\n\nthresholds\030\002 \001(\0132\017.dmi.Threshol"
  "ds\"\212\001\n\010EventCfg\022\037\n\010event_id\030\001 \001(\0162\r.dmi."
  "EventIds\022\025\n\ris_configured\030\002 \001(\010\022#\n\nthres"
  "holds\030\003 \001(\0132\017.dmi.Thresholds\022!\n\016componen"
  "t_uuid\030\004 \001(\0132\t.dmi.Uuid\")\n\tEventsCfg\022\034\n\005"
  "items\030\001 \003(\0132\r.dmi.EventCfg\"\370\001\n\022ListEvent"
  "sResponse\022\033\n\006status\030\001 \001(\0162\013.dmi.Status\022."
  "\n\006reason\030\002 \001(\0162\036.dmi.ListEventsResponse."
  "Reason\022\036\n\006events\030\003 \001(\0132\016.dmi.EventsCfg\022\025"
  "\n\rreason_detail\030\004 \001(\t\"^\n\006Reason\022\024\n\020UNDEF"
  "INED_REASON\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INT"
  "ERNAL_ERROR\020\002\022\026\n\022DEVICE_UNREACHABLE\020\003\"\210\001"
  "\n\032EventsConfigurationRequest\022\036\n\013device_u"
  "uid\030\001 \001(\0132\t.dmi.Uuid\022!\n\007changes\030\002 \001(\0132\016."
  "dmi.EventsCfgH\000\022\032\n\020reset_to_default\030\003 \001("
  "\010H\000B\013\n\toperation\"\376\001\n\033EventsConfiguration"
  "Response\022\033\n\006status\030\001 \001(\0162\013.dmi.Status\0227\n"
  "\006reason\030\002 \001(\0162\'.dmi.EventsConfigurationR"
  "esponse.Reason\022\025\n\rreason_detail\030\003 \001(\t\"r\n"
  "\006Reason\022\024\n\020UNDEFINED_REASON\020\000\022\022\n\016UNKNOWN"
  "_DEVICE\020\001\022\022\n\016INTERNAL_ERROR\020\002\022\022\n\016INVALID"
  "_CONFIG\020\003\022\026\n\022DEVICE_UNREACHABLE\020\004\"j\n\rEve"
  "ntMetaData\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uu"
  "id\022!\n\016component_uuid\030\002 \001(\0132\t.dmi.Uuid\022\026\n"
  "\016component_name\030\003 \001(\t\"`\n\020AdminStateChang"
  "e\022%\n\003old\030\001 \001(\0162\030.dmi.ComponentAdminState"
  "\022%\n\003new\030\002 \001(\0162\030.dmi.ComponentAdminState\""
  "]\n\017OperStateChange\022$\n\003old\030\001 \001(\0162\027.dmi.Co"
  "mponentOperState\022$\n\003new\030\002 \001(\0162\027.dmi.Comp"
  "onentOperState\"`\n\020AlarmStateChange\022%\n\003ol"
  "d\030\001 \001(\0162\030.dmi.ComponentAlarmState\022%\n\003new"
  "\030\002 \001(\0162\030.dmi.ComponentAlarmState\"`\n\020Usag"
  "eStateChange\022%\n\003old\030\001 \001(\0162\030.dmi.Componen"
  "tUsageState\022%\n\003new\030\002 \001(\0162\030.dmi.Component"
  "UsageState\"f\n\022StandbyStateChange\022\'\n\003old\030"
  "\001 \001(\0162\032.dmi.ComponentStandbyState\022\'\n\003new"
  "\030\002 \001(\0162\032.dmi.ComponentStandbyState\"\254\002\n\017S"
  "tateChangeInfo\0223\n\022admin_state_change\030\001 \001"
  "(\0132\025.dmi.AdminStateChangeH\000\0221\n\021oper_stat"
  "e_change\030\002 \001(\0132\024.dmi.OperStateChangeH\000\0223"
  "\n\022alarm_state_change\030\003 \001(\0132\025.dmi.AlarmSt"
  "ateChangeH\000\0223\n\022usage_state_change\030\004 \001(\0132"
  "\025.dmi.UsageStateChangeH\000\0227\n\024standby_stat"
  "e_change\030\005 \001(\0132\027.dmi.StandbyStateChangeH"
  "\000B\016\n\014state_change\"\371\001\n\005Event\022*\n\016event_met"
  "adata\030\001 \001(\0132\022.dmi.EventMetaData\022\037\n\010event"
  "_id\030\002 \001(\0162\r.dmi.EventIds\022-\n\traised_ts\030\003 "
  "\001(\0132\032.google.protobuf.Timestamp\0221\n\016thres"
  "hold_info\030\004 \001(\0132\031.dmi.ThresholdInformati"
  "on\022\020\n\010add_info\030\005 \001(\t\022/\n\021state_change_inf"
  "o\030\006 \001(\0132\024.dmi.StateChangeInfo*\265\024\n\010EventI"
  "ds\022\030\n\024EVENT_NAME_UNDEFINED\020\000\022\036\n\032EVENT_TR"
  "ANSCEIVER_PLUG_OUT\020d\022\035\n\031EVENT_TRANSCEIVE"
  "R_PLUG_IN\020e\022-\n)EVENT_TRANSCEIVER_VOLTAGE"
  "_ABOVE_THRESHOLD\020f\022-\n)EVENT_TRANSCEIVER_"
  "VOLTAGE_BELOW_THRESHOLD\020g\0221\n-EVENT_TRANS"
  "CEIVER_TEMPERATURE_ABOVE_THRESHOLD\020h\0221\n-"
  "EVENT_TRANSCEIVER_TEMPERATURE_BELOW_THRE"
  "SHOLD\020i\022-\n)EVENT_TRANSCEIVER_CURRENT_ABO"
  "VE_THRESHOLD\020j\022-\n)EVENT_TRANSCEIVER_CURR"
  "ENT_BELOW_THRESHOLD\020k\022.\n*EVENT_TRANSCEIV"
  "ER_RX_POWER_ABOVE_THRESHOLD\020l\022.\n*EVENT_T"
  "RANSCEIVER_RX_POWER_BELOW_THRESHOLD\020m\022.\n"
  "*EVENT_TRANSCEIVER_TX_POWER_ABOVE_THRESH"
  "OLD\020n\022.\n*EVENT_TRANSCEIVER_TX_POWER_BELO"
  "W_THRESHOLD\020o\022\035\n\031EVENT_TRANSCEIVER_FAILU"
  "RE\020p\0227\n3EVENT_TRANSCEIVER_VOLTAGE_ABOVE_"
  "THRESHOLD_RECOVERED\020q\0227\n3EVENT_TRANSCEIV"
  "ER_VOLTAGE_BELOW_THRESHOLD_RECOVERED\020r\022;"
  "\n7EVENT_TRANSCEIVER_TEMPERATURE_ABOVE_TH"
  "RESHOLD_RECOVERED\020s\022;\n7EVENT_TRANSCEIVER"
  "_TEMPERATURE_BELOW_THRESHOLD_RECOVERED\020t"
  "\0227\n3EVENT_TRANSCEIVER_CURRENT_ABOVE_THRE"
  "SHOLD_RECOVERED\020u\0227\n3EVENT_TRANSCEIVER_C"
  "URRENT_BELOW_THRESHOLD_RECOVERED\020v\0228\n4EV"
  "ENT_TRANSCEIVER_RX_POWER_ABOVE_THRESHOLD"
  "_RECOVERED\020w\0228\n4EVENT_TRANSCEIVER_RX_POW"
  "ER_BELOW_THRESHOLD_RECOVERED\020x\0228\n4EVENT_"
  "TRANSCEIVER_TX_POWER_ABOVE_THRESHOLD_REC"
  "OVERED\020y\0228\n4EVENT_TRANSCEIVER_TX_POWER_B"
  "ELOW_THRESHOLD_RECOVERED\020z\022\'\n#EVENT_TRAN"
  "SCEIVER_FAILURE_RECOVERED\020{\022\027\n\022EVENT_PSU"
  "_PLUG_OUT\020\310\001\022\026\n\021EVENT_PSU_PLUG_IN\020\311\001\022\026\n\021"
  "EVENT_PSU_FAILURE\020\312\001\022 \n\033EVENT_PSU_FAILUR"
  "E_RECOVERED\020\313\001\022\026\n\021EVENT_FAN_FAILURE\020\254\002\022\027"
  "\n\022EVENT_FAN_PLUG_OUT\020\255\002\022\026\n\021EVENT_FAN_PLU"
  "G_IN\020\256\002\022 \n\033EVENT_FAN_FAILURE_RECOVERED\020\257"
  "\002\022)\n$EVENT_CPU_TEMPERATURE_ABOVE_CRITICA"
  "L\020\220\003\022&\n!EVENT_CPU_TEMPERATURE_ABOVE_FATA"
  "L\020\221\003\0223\n.EVENT_CPU_TEMPERATURE_ABOVE_CRIT"
  "ICAL_RECOVERED\020\222\003\0220\n+EVENT_CPU_TEMPERATU"
  "RE_ABOVE_FATAL_RECOVERED\020\223\003\022$\n\037EVENT_CPU"
  "_USAGE_ABOVE_THRESHOLD\020\224\003\022.\n)EVENT_CPU_U"
  "SAGE_ABOVE_THRESHOLD_RECOVERED\020\225\003\022\032\n\025EVE"
  "NT_HW_DEVICE_RESET\020\364\003\022/\n*EVENT_HW_DEVICE"
  "_TEMPERATURE_ABOVE_CRITICAL\020\365\003\022,\n\'EVENT_"
  "HW_DEVICE_TEMPERATURE_ABOVE_FATAL\020\366\003\0229\n4"
  "EVENT_HW_DEVICE_TEMPERATURE_ABOVE_CRITIC"
  "AL_RECOVERED\020\367\003\0226\n1EVENT_HW_DEVICE_TEMPE"
  "RATURE_ABOVE_FATAL_RECOVERED\020\370\003\022\033\n\026EVENT"
  "_HW_DEVICE_REBOOT\020\371\003\022\'\n\"EVENT_HW_TEMPERA"
  "TURE_SENSOR_FAILED\020\372\003\022,\n\'EVENT_HW_ALL_TE"
  "MPERATURE_SENSORS_FAILED\020\373\003\022(\n#EVENT_HW_"
  "DISK_USAGE_ABOVE_THRESHOLD\020\374\003\0222\n-EVENT_H"
  "W_DISK_USAGE_ABOVE_THRESHOLD_RECOVERED\020\375"
  "\003\022*\n%EVENT_HW_MEMORY_USAGE_ABOVE_THRESHO"
  "LD\020\376\003\0224\n/EVENT_HW_MEMORY_USAGE_ABOVE_THR"
  "ESHOLD_RECOVERED\020\377\003\022\036\n\031EVENT_HW_NTP_SYNC"
  "_FAILURE\020\200\004\022(\n#EVENT_HW_NTP_SYNC_FAILURE"
  "_RECOVERED\020\201\004\022\035\n\030EVENT_LINE_CARD_PLUG_OU"
  "T\020\330\004\022\034\n\027EVENT_LINE_CARD_PLUG_IN\020\331\004\022(\n#EV"
  "ENT_COMPONENT_ADMIN_STATE_CHANGED\020\274\005\022\'\n\""
  "EVENT_COMPONENT_OPER_STATE_CHANGED\020\275\005\022(\n"
  "#EVENT_COMPONENT_ALARM_STATE_CHANGED\020\276\005\022"
  "(\n#EVENT_COMPONENT_USAGE_STATE_CHANGED\020\277"
  "\005\022*\n%EVENT_COMPONENT_STANDBY_STATE_CHANG"
  "ED\020\300\0052\355\001\n\035NativeEventsManagementService\022"
  "6\n\nListEvents\022\017.dmi.HardwareID\032\027.dmi.Lis"
  "tEventsResponse\022^\n\031UpdateEventsConfigura"
  "tion\022\037.dmi.EventsConfigurationRequest\032 ."
  "dmi.EventsConfigurationResponse\0224\n\014Strea"
  "mEvents\022\026.google.protobuf.Empty\032\n.dmi.Ev"
  "ent0\001B;Z9github.com/opencord/device-mana"
  "gement-interface/v3/go/dmib\006proto3"
  ;
::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = {
  false, InitDefaults_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 
  descriptor_table_protodef_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto,
  "dmi/hw_events_mgmt_service.proto", &assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 5434,
};

void AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
  static constexpr ::google::protobuf::internal::InitFunc deps[4] =
  {
    ::AddDescriptors_dmi_2fcommons_2eproto,
    ::AddDescriptors_dmi_2fhw_2eproto,
    ::AddDescriptors_google_2fprotobuf_2ftimestamp_2eproto,
    ::AddDescriptors_google_2fprotobuf_2fempty_2eproto,
  };
 ::google::protobuf::internal::AddDescriptors(&descriptor_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, deps, 4);
}

// Force running AddDescriptors() at dynamic initialization time.
static bool dynamic_init_dummy_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = []() { AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto(); return true; }();
namespace dmi {
const ::google::protobuf::EnumDescriptor* ListEventsResponse_Reason_descriptor() {
  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[0];
}
bool ListEventsResponse_Reason_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const ListEventsResponse_Reason ListEventsResponse::UNDEFINED_REASON;
const ListEventsResponse_Reason ListEventsResponse::UNKNOWN_DEVICE;
const ListEventsResponse_Reason ListEventsResponse::INTERNAL_ERROR;
const ListEventsResponse_Reason ListEventsResponse::DEVICE_UNREACHABLE;
const ListEventsResponse_Reason ListEventsResponse::Reason_MIN;
const ListEventsResponse_Reason ListEventsResponse::Reason_MAX;
const int ListEventsResponse::Reason_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* EventsConfigurationResponse_Reason_descriptor() {
  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[1];
}
bool EventsConfigurationResponse_Reason_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const EventsConfigurationResponse_Reason EventsConfigurationResponse::UNDEFINED_REASON;
const EventsConfigurationResponse_Reason EventsConfigurationResponse::UNKNOWN_DEVICE;
const EventsConfigurationResponse_Reason EventsConfigurationResponse::INTERNAL_ERROR;
const EventsConfigurationResponse_Reason EventsConfigurationResponse::INVALID_CONFIG;
const EventsConfigurationResponse_Reason EventsConfigurationResponse::DEVICE_UNREACHABLE;
const EventsConfigurationResponse_Reason EventsConfigurationResponse::Reason_MIN;
const EventsConfigurationResponse_Reason EventsConfigurationResponse::Reason_MAX;
const int EventsConfigurationResponse::Reason_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
const ::google::protobuf::EnumDescriptor* EventIds_descriptor() {
  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[2];
}
bool EventIds_IsValid(int value) {
  switch (value) {
    case 0:
    case 100:
    case 101:
    case 102:
    case 103:
    case 104:
    case 105:
    case 106:
    case 107:
    case 108:
    case 109:
    case 110:
    case 111:
    case 112:
    case 113:
    case 114:
    case 115:
    case 116:
    case 117:
    case 118:
    case 119:
    case 120:
    case 121:
    case 122:
    case 123:
    case 200:
    case 201:
    case 202:
    case 203:
    case 300:
    case 301:
    case 302:
    case 303:
    case 400:
    case 401:
    case 402:
    case 403:
    case 404:
    case 405:
    case 500:
    case 501:
    case 502:
    case 503:
    case 504:
    case 505:
    case 506:
    case 507:
    case 508:
    case 509:
    case 510:
    case 511:
    case 512:
    case 513:
    case 600:
    case 601:
    case 700:
    case 701:
    case 702:
    case 703:
    case 704:
      return true;
    default:
      return false;
  }
}


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

void ValueType::InitAsDefaultInstance() {
  ::dmi::_ValueType_default_instance_.int_val_ = PROTOBUF_LONGLONG(0);
  ::dmi::_ValueType_default_instance_.uint_val_ = PROTOBUF_ULONGLONG(0);
  ::dmi::_ValueType_default_instance_.float_val_ = 0;
}
class ValueType::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ValueType::kIntValFieldNumber;
const int ValueType::kUintValFieldNumber;
const int ValueType::kFloatValFieldNumber;
const int ValueType::kTypeOfValFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

ValueType::ValueType()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.ValueType)
}
ValueType::ValueType(const ValueType& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  typeofval_ = from.typeofval_;
  clear_has_val();
  switch (from.val_case()) {
    case kIntVal: {
      set_int_val(from.int_val());
      break;
    }
    case kUintVal: {
      set_uint_val(from.uint_val());
      break;
    }
    case kFloatVal: {
      set_float_val(from.float_val());
      break;
    }
    case VAL_NOT_SET: {
      break;
    }
  }
  // @@protoc_insertion_point(copy_constructor:dmi.ValueType)
}

void ValueType::SharedCtor() {
  typeofval_ = 0;
  clear_has_val();
}

ValueType::~ValueType() {
  // @@protoc_insertion_point(destructor:dmi.ValueType)
  SharedDtor();
}

void ValueType::SharedDtor() {
  if (has_val()) {
    clear_val();
  }
}

void ValueType::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ValueType& ValueType::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void ValueType::clear_val() {
// @@protoc_insertion_point(one_of_clear_start:dmi.ValueType)
  switch (val_case()) {
    case kIntVal: {
      // No need to clear
      break;
    }
    case kUintVal: {
      // No need to clear
      break;
    }
    case kFloatVal: {
      // No need to clear
      break;
    }
    case VAL_NOT_SET: {
      break;
    }
  }
  _oneof_case_[0] = VAL_NOT_SET;
}


void ValueType::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.ValueType)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  typeofval_ = 0;
  clear_val();
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* ValueType::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<ValueType*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // int64 int_val = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        msg->set_int_val(::google::protobuf::internal::ReadVarint(&ptr));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // uint64 uint_val = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        msg->set_uint_val(::google::protobuf::internal::ReadVarint(&ptr));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // float float_val = 3;
      case 3: {
        if (static_cast<::google::protobuf::uint8>(tag) != 29) goto handle_unusual;
        msg->set_float_val(::google::protobuf::io::UnalignedLoad<float>(ptr));
        ptr += sizeof(float);
        break;
      }
      // .dmi.DataValueType typeOfVal = 4;
      case 4: {
        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_typeofval(static_cast<::dmi::DataValueType>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool ValueType::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.ValueType)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // int64 int_val = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
          clear_val();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &val_.int_val_)));
          set_has_int_val();
        } else {
          goto handle_unusual;
        }
        break;
      }

      // uint64 uint_val = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
          clear_val();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                 input, &val_.uint_val_)));
          set_has_uint_val();
        } else {
          goto handle_unusual;
        }
        break;
      }

      // float float_val = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (29 & 0xFF)) {
          clear_val();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
                 input, &val_.float_val_)));
          set_has_float_val();
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.DataValueType typeOfVal = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_typeofval(static_cast< ::dmi::DataValueType >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.ValueType)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.ValueType)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void ValueType::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.ValueType)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // int64 int_val = 1;
  if (has_int_val()) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->int_val(), output);
  }

  // uint64 uint_val = 2;
  if (has_uint_val()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->uint_val(), output);
  }

  // float float_val = 3;
  if (has_float_val()) {
    ::google::protobuf::internal::WireFormatLite::WriteFloat(3, this->float_val(), output);
  }

  // .dmi.DataValueType typeOfVal = 4;
  if (this->typeofval() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      4, this->typeofval(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.ValueType)
}

::google::protobuf::uint8* ValueType::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.ValueType)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // int64 int_val = 1;
  if (has_int_val()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->int_val(), target);
  }

  // uint64 uint_val = 2;
  if (has_uint_val()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->uint_val(), target);
  }

  // float float_val = 3;
  if (has_float_val()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(3, this->float_val(), target);
  }

  // .dmi.DataValueType typeOfVal = 4;
  if (this->typeofval() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      4, this->typeofval(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.ValueType)
  return target;
}

size_t ValueType::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.ValueType)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.DataValueType typeOfVal = 4;
  if (this->typeofval() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->typeofval());
  }

  switch (val_case()) {
    // int64 int_val = 1;
    case kIntVal: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->int_val());
      break;
    }
    // uint64 uint_val = 2;
    case kUintVal: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt64Size(
          this->uint_val());
      break;
    }
    // float float_val = 3;
    case kFloatVal: {
      total_size += 1 + 4;
      break;
    }
    case VAL_NOT_SET: {
      break;
    }
  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void ValueType::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.ValueType)
  GOOGLE_DCHECK_NE(&from, this);
  const ValueType* source =
      ::google::protobuf::DynamicCastToGenerated<ValueType>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ValueType)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ValueType)
    MergeFrom(*source);
  }
}

void ValueType::MergeFrom(const ValueType& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ValueType)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.typeofval() != 0) {
    set_typeofval(from.typeofval());
  }
  switch (from.val_case()) {
    case kIntVal: {
      set_int_val(from.int_val());
      break;
    }
    case kUintVal: {
      set_uint_val(from.uint_val());
      break;
    }
    case kFloatVal: {
      set_float_val(from.float_val());
      break;
    }
    case VAL_NOT_SET: {
      break;
    }
  }
}

void ValueType::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.ValueType)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void ValueType::CopyFrom(const ValueType& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ValueType)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool ValueType::IsInitialized() const {
  return true;
}

void ValueType::Swap(ValueType* other) {
  if (other == this) return;
  InternalSwap(other);
}
void ValueType::InternalSwap(ValueType* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(typeofval_, other->typeofval_);
  swap(val_, other->val_);
  swap(_oneof_case_[0], other->_oneof_case_[0]);
}

::google::protobuf::Metadata ValueType::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void WaterMarks::InitAsDefaultInstance() {
  ::dmi::_WaterMarks_default_instance_._instance.get_mutable()->high_ = const_cast< ::dmi::ValueType*>(
      ::dmi::ValueType::internal_default_instance());
  ::dmi::_WaterMarks_default_instance_._instance.get_mutable()->low_ = const_cast< ::dmi::ValueType*>(
      ::dmi::ValueType::internal_default_instance());
}
class WaterMarks::HasBitSetters {
 public:
  static const ::dmi::ValueType& high(const WaterMarks* msg);
  static const ::dmi::ValueType& low(const WaterMarks* msg);
};

const ::dmi::ValueType&
WaterMarks::HasBitSetters::high(const WaterMarks* msg) {
  return *msg->high_;
}
const ::dmi::ValueType&
WaterMarks::HasBitSetters::low(const WaterMarks* msg) {
  return *msg->low_;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int WaterMarks::kHighFieldNumber;
const int WaterMarks::kLowFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

WaterMarks::WaterMarks()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.WaterMarks)
}
WaterMarks::WaterMarks(const WaterMarks& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_high()) {
    high_ = new ::dmi::ValueType(*from.high_);
  } else {
    high_ = nullptr;
  }
  if (from.has_low()) {
    low_ = new ::dmi::ValueType(*from.low_);
  } else {
    low_ = nullptr;
  }
  // @@protoc_insertion_point(copy_constructor:dmi.WaterMarks)
}

void WaterMarks::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::memset(&high_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&low_) -
      reinterpret_cast<char*>(&high_)) + sizeof(low_));
}

WaterMarks::~WaterMarks() {
  // @@protoc_insertion_point(destructor:dmi.WaterMarks)
  SharedDtor();
}

void WaterMarks::SharedDtor() {
  if (this != internal_default_instance()) delete high_;
  if (this != internal_default_instance()) delete low_;
}

void WaterMarks::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const WaterMarks& WaterMarks::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void WaterMarks::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.WaterMarks)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  if (GetArenaNoVirtual() == nullptr && high_ != nullptr) {
    delete high_;
  }
  high_ = nullptr;
  if (GetArenaNoVirtual() == nullptr && low_ != nullptr) {
    delete low_;
  }
  low_ = nullptr;
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* WaterMarks::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<WaterMarks*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.ValueType high = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::ValueType::_InternalParse;
        object = msg->mutable_high();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.ValueType low = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::ValueType::_InternalParse;
        object = msg->mutable_low();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool WaterMarks::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.WaterMarks)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.ValueType high = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_high()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.ValueType low = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_low()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.WaterMarks)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.WaterMarks)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void WaterMarks::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.WaterMarks)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ValueType high = 1;
  if (this->has_high()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, HasBitSetters::high(this), output);
  }

  // .dmi.ValueType low = 2;
  if (this->has_low()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, HasBitSetters::low(this), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.WaterMarks)
}

::google::protobuf::uint8* WaterMarks::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.WaterMarks)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ValueType high = 1;
  if (this->has_high()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, HasBitSetters::high(this), target);
  }

  // .dmi.ValueType low = 2;
  if (this->has_low()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, HasBitSetters::low(this), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.WaterMarks)
  return target;
}

size_t WaterMarks::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.WaterMarks)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.ValueType high = 1;
  if (this->has_high()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *high_);
  }

  // .dmi.ValueType low = 2;
  if (this->has_low()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *low_);
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void WaterMarks::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.WaterMarks)
  GOOGLE_DCHECK_NE(&from, this);
  const WaterMarks* source =
      ::google::protobuf::DynamicCastToGenerated<WaterMarks>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.WaterMarks)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.WaterMarks)
    MergeFrom(*source);
  }
}

void WaterMarks::MergeFrom(const WaterMarks& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.WaterMarks)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.has_high()) {
    mutable_high()->::dmi::ValueType::MergeFrom(from.high());
  }
  if (from.has_low()) {
    mutable_low()->::dmi::ValueType::MergeFrom(from.low());
  }
}

void WaterMarks::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.WaterMarks)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void WaterMarks::CopyFrom(const WaterMarks& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.WaterMarks)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool WaterMarks::IsInitialized() const {
  return true;
}

void WaterMarks::Swap(WaterMarks* other) {
  if (other == this) return;
  InternalSwap(other);
}
void WaterMarks::InternalSwap(WaterMarks* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(high_, other->high_);
  swap(low_, other->low_);
}

::google::protobuf::Metadata WaterMarks::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void Thresholds::InitAsDefaultInstance() {
  ::dmi::_Thresholds_default_instance_.upper_ = const_cast< ::dmi::WaterMarks*>(
      ::dmi::WaterMarks::internal_default_instance());
  ::dmi::_Thresholds_default_instance_.lower_ = const_cast< ::dmi::WaterMarks*>(
      ::dmi::WaterMarks::internal_default_instance());
}
class Thresholds::HasBitSetters {
 public:
  static const ::dmi::WaterMarks& upper(const Thresholds* msg);
  static const ::dmi::WaterMarks& lower(const Thresholds* msg);
};

const ::dmi::WaterMarks&
Thresholds::HasBitSetters::upper(const Thresholds* msg) {
  return *msg->threshold_.upper_;
}
const ::dmi::WaterMarks&
Thresholds::HasBitSetters::lower(const Thresholds* msg) {
  return *msg->threshold_.lower_;
}
void Thresholds::set_allocated_upper(::dmi::WaterMarks* upper) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  clear_threshold();
  if (upper) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      upper = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, upper, submessage_arena);
    }
    set_has_upper();
    threshold_.upper_ = upper;
  }
  // @@protoc_insertion_point(field_set_allocated:dmi.Thresholds.upper)
}
void Thresholds::set_allocated_lower(::dmi::WaterMarks* lower) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  clear_threshold();
  if (lower) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      lower = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, lower, submessage_arena);
    }
    set_has_lower();
    threshold_.lower_ = lower;
  }
  // @@protoc_insertion_point(field_set_allocated:dmi.Thresholds.lower)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Thresholds::kUpperFieldNumber;
const int Thresholds::kLowerFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Thresholds::Thresholds()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.Thresholds)
}
Thresholds::Thresholds(const Thresholds& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  clear_has_threshold();
  switch (from.threshold_case()) {
    case kUpper: {
      mutable_upper()->::dmi::WaterMarks::MergeFrom(from.upper());
      break;
    }
    case kLower: {
      mutable_lower()->::dmi::WaterMarks::MergeFrom(from.lower());
      break;
    }
    case THRESHOLD_NOT_SET: {
      break;
    }
  }
  // @@protoc_insertion_point(copy_constructor:dmi.Thresholds)
}

void Thresholds::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  clear_has_threshold();
}

Thresholds::~Thresholds() {
  // @@protoc_insertion_point(destructor:dmi.Thresholds)
  SharedDtor();
}

void Thresholds::SharedDtor() {
  if (has_threshold()) {
    clear_threshold();
  }
}

void Thresholds::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const Thresholds& Thresholds::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void Thresholds::clear_threshold() {
// @@protoc_insertion_point(one_of_clear_start:dmi.Thresholds)
  switch (threshold_case()) {
    case kUpper: {
      delete threshold_.upper_;
      break;
    }
    case kLower: {
      delete threshold_.lower_;
      break;
    }
    case THRESHOLD_NOT_SET: {
      break;
    }
  }
  _oneof_case_[0] = THRESHOLD_NOT_SET;
}


void Thresholds::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.Thresholds)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  clear_threshold();
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* Thresholds::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<Thresholds*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.WaterMarks upper = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::WaterMarks::_InternalParse;
        object = msg->mutable_upper();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.WaterMarks lower = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::WaterMarks::_InternalParse;
        object = msg->mutable_lower();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Thresholds::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.Thresholds)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.WaterMarks upper = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_upper()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.WaterMarks lower = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_lower()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.Thresholds)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.Thresholds)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void Thresholds::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.Thresholds)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.WaterMarks upper = 1;
  if (has_upper()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, HasBitSetters::upper(this), output);
  }

  // .dmi.WaterMarks lower = 2;
  if (has_lower()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, HasBitSetters::lower(this), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.Thresholds)
}

::google::protobuf::uint8* Thresholds::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.Thresholds)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.WaterMarks upper = 1;
  if (has_upper()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, HasBitSetters::upper(this), target);
  }

  // .dmi.WaterMarks lower = 2;
  if (has_lower()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, HasBitSetters::lower(this), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.Thresholds)
  return target;
}

size_t Thresholds::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.Thresholds)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  switch (threshold_case()) {
    // .dmi.WaterMarks upper = 1;
    case kUpper: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *threshold_.upper_);
      break;
    }
    // .dmi.WaterMarks lower = 2;
    case kLower: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *threshold_.lower_);
      break;
    }
    case THRESHOLD_NOT_SET: {
      break;
    }
  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void Thresholds::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.Thresholds)
  GOOGLE_DCHECK_NE(&from, this);
  const Thresholds* source =
      ::google::protobuf::DynamicCastToGenerated<Thresholds>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Thresholds)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Thresholds)
    MergeFrom(*source);
  }
}

void Thresholds::MergeFrom(const Thresholds& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Thresholds)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  switch (from.threshold_case()) {
    case kUpper: {
      mutable_upper()->::dmi::WaterMarks::MergeFrom(from.upper());
      break;
    }
    case kLower: {
      mutable_lower()->::dmi::WaterMarks::MergeFrom(from.lower());
      break;
    }
    case THRESHOLD_NOT_SET: {
      break;
    }
  }
}

void Thresholds::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.Thresholds)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void Thresholds::CopyFrom(const Thresholds& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Thresholds)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool Thresholds::IsInitialized() const {
  return true;
}

void Thresholds::Swap(Thresholds* other) {
  if (other == this) return;
  InternalSwap(other);
}
void Thresholds::InternalSwap(Thresholds* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(threshold_, other->threshold_);
  swap(_oneof_case_[0], other->_oneof_case_[0]);
}

::google::protobuf::Metadata Thresholds::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void ThresholdInformation::InitAsDefaultInstance() {
  ::dmi::_ThresholdInformation_default_instance_._instance.get_mutable()->observed_value_ = const_cast< ::dmi::ValueType*>(
      ::dmi::ValueType::internal_default_instance());
  ::dmi::_ThresholdInformation_default_instance_._instance.get_mutable()->thresholds_ = const_cast< ::dmi::Thresholds*>(
      ::dmi::Thresholds::internal_default_instance());
}
class ThresholdInformation::HasBitSetters {
 public:
  static const ::dmi::ValueType& observed_value(const ThresholdInformation* msg);
  static const ::dmi::Thresholds& thresholds(const ThresholdInformation* msg);
};

const ::dmi::ValueType&
ThresholdInformation::HasBitSetters::observed_value(const ThresholdInformation* msg) {
  return *msg->observed_value_;
}
const ::dmi::Thresholds&
ThresholdInformation::HasBitSetters::thresholds(const ThresholdInformation* msg) {
  return *msg->thresholds_;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ThresholdInformation::kObservedValueFieldNumber;
const int ThresholdInformation::kThresholdsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

ThresholdInformation::ThresholdInformation()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.ThresholdInformation)
}
ThresholdInformation::ThresholdInformation(const ThresholdInformation& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_observed_value()) {
    observed_value_ = new ::dmi::ValueType(*from.observed_value_);
  } else {
    observed_value_ = nullptr;
  }
  if (from.has_thresholds()) {
    thresholds_ = new ::dmi::Thresholds(*from.thresholds_);
  } else {
    thresholds_ = nullptr;
  }
  // @@protoc_insertion_point(copy_constructor:dmi.ThresholdInformation)
}

void ThresholdInformation::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::memset(&observed_value_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&thresholds_) -
      reinterpret_cast<char*>(&observed_value_)) + sizeof(thresholds_));
}

ThresholdInformation::~ThresholdInformation() {
  // @@protoc_insertion_point(destructor:dmi.ThresholdInformation)
  SharedDtor();
}

void ThresholdInformation::SharedDtor() {
  if (this != internal_default_instance()) delete observed_value_;
  if (this != internal_default_instance()) delete thresholds_;
}

void ThresholdInformation::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ThresholdInformation& ThresholdInformation::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void ThresholdInformation::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.ThresholdInformation)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  if (GetArenaNoVirtual() == nullptr && observed_value_ != nullptr) {
    delete observed_value_;
  }
  observed_value_ = nullptr;
  if (GetArenaNoVirtual() == nullptr && thresholds_ != nullptr) {
    delete thresholds_;
  }
  thresholds_ = nullptr;
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* ThresholdInformation::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<ThresholdInformation*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.ValueType observed_value = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::ValueType::_InternalParse;
        object = msg->mutable_observed_value();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.Thresholds thresholds = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::Thresholds::_InternalParse;
        object = msg->mutable_thresholds();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool ThresholdInformation::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.ThresholdInformation)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.ValueType observed_value = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_observed_value()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.Thresholds thresholds = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_thresholds()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.ThresholdInformation)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.ThresholdInformation)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void ThresholdInformation::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.ThresholdInformation)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ValueType observed_value = 1;
  if (this->has_observed_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, HasBitSetters::observed_value(this), output);
  }

  // .dmi.Thresholds thresholds = 2;
  if (this->has_thresholds()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, HasBitSetters::thresholds(this), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.ThresholdInformation)
}

::google::protobuf::uint8* ThresholdInformation::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.ThresholdInformation)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ValueType observed_value = 1;
  if (this->has_observed_value()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, HasBitSetters::observed_value(this), target);
  }

  // .dmi.Thresholds thresholds = 2;
  if (this->has_thresholds()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, HasBitSetters::thresholds(this), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.ThresholdInformation)
  return target;
}

size_t ThresholdInformation::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.ThresholdInformation)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.ValueType observed_value = 1;
  if (this->has_observed_value()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *observed_value_);
  }

  // .dmi.Thresholds thresholds = 2;
  if (this->has_thresholds()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *thresholds_);
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void ThresholdInformation::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.ThresholdInformation)
  GOOGLE_DCHECK_NE(&from, this);
  const ThresholdInformation* source =
      ::google::protobuf::DynamicCastToGenerated<ThresholdInformation>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ThresholdInformation)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ThresholdInformation)
    MergeFrom(*source);
  }
}

void ThresholdInformation::MergeFrom(const ThresholdInformation& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ThresholdInformation)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.has_observed_value()) {
    mutable_observed_value()->::dmi::ValueType::MergeFrom(from.observed_value());
  }
  if (from.has_thresholds()) {
    mutable_thresholds()->::dmi::Thresholds::MergeFrom(from.thresholds());
  }
}

void ThresholdInformation::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.ThresholdInformation)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void ThresholdInformation::CopyFrom(const ThresholdInformation& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ThresholdInformation)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool ThresholdInformation::IsInitialized() const {
  return true;
}

void ThresholdInformation::Swap(ThresholdInformation* other) {
  if (other == this) return;
  InternalSwap(other);
}
void ThresholdInformation::InternalSwap(ThresholdInformation* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(observed_value_, other->observed_value_);
  swap(thresholds_, other->thresholds_);
}

::google::protobuf::Metadata ThresholdInformation::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void EventCfg::InitAsDefaultInstance() {
  ::dmi::_EventCfg_default_instance_._instance.get_mutable()->thresholds_ = const_cast< ::dmi::Thresholds*>(
      ::dmi::Thresholds::internal_default_instance());
  ::dmi::_EventCfg_default_instance_._instance.get_mutable()->component_uuid_ = const_cast< ::dmi::Uuid*>(
      ::dmi::Uuid::internal_default_instance());
}
class EventCfg::HasBitSetters {
 public:
  static const ::dmi::Thresholds& thresholds(const EventCfg* msg);
  static const ::dmi::Uuid& component_uuid(const EventCfg* msg);
};

const ::dmi::Thresholds&
EventCfg::HasBitSetters::thresholds(const EventCfg* msg) {
  return *msg->thresholds_;
}
const ::dmi::Uuid&
EventCfg::HasBitSetters::component_uuid(const EventCfg* msg) {
  return *msg->component_uuid_;
}
void EventCfg::clear_component_uuid() {
  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
    delete component_uuid_;
  }
  component_uuid_ = nullptr;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EventCfg::kEventIdFieldNumber;
const int EventCfg::kIsConfiguredFieldNumber;
const int EventCfg::kThresholdsFieldNumber;
const int EventCfg::kComponentUuidFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EventCfg::EventCfg()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.EventCfg)
}
EventCfg::EventCfg(const EventCfg& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_thresholds()) {
    thresholds_ = new ::dmi::Thresholds(*from.thresholds_);
  } else {
    thresholds_ = nullptr;
  }
  if (from.has_component_uuid()) {
    component_uuid_ = new ::dmi::Uuid(*from.component_uuid_);
  } else {
    component_uuid_ = nullptr;
  }
  ::memcpy(&event_id_, &from.event_id_,
    static_cast<size_t>(reinterpret_cast<char*>(&is_configured_) -
    reinterpret_cast<char*>(&event_id_)) + sizeof(is_configured_));
  // @@protoc_insertion_point(copy_constructor:dmi.EventCfg)
}

void EventCfg::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  ::memset(&thresholds_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&is_configured_) -
      reinterpret_cast<char*>(&thresholds_)) + sizeof(is_configured_));
}

EventCfg::~EventCfg() {
  // @@protoc_insertion_point(destructor:dmi.EventCfg)
  SharedDtor();
}

void EventCfg::SharedDtor() {
  if (this != internal_default_instance()) delete thresholds_;
  if (this != internal_default_instance()) delete component_uuid_;
}

void EventCfg::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const EventCfg& EventCfg::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void EventCfg::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.EventCfg)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  if (GetArenaNoVirtual() == nullptr && thresholds_ != nullptr) {
    delete thresholds_;
  }
  thresholds_ = nullptr;
  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
    delete component_uuid_;
  }
  component_uuid_ = nullptr;
  ::memset(&event_id_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&is_configured_) -
      reinterpret_cast<char*>(&event_id_)) + sizeof(is_configured_));
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* EventCfg::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<EventCfg*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.EventIds event_id = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_event_id(static_cast<::dmi::EventIds>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // bool is_configured = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        msg->set_is_configured(::google::protobuf::internal::ReadVarint(&ptr));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.Thresholds thresholds = 3;
      case 3: {
        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::Thresholds::_InternalParse;
        object = msg->mutable_thresholds();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.Uuid component_uuid = 4;
      case 4: {
        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::Uuid::_InternalParse;
        object = msg->mutable_component_uuid();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EventCfg::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.EventCfg)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.EventIds event_id = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_event_id(static_cast< ::dmi::EventIds >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // bool is_configured = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {

          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &is_configured_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.Thresholds thresholds = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_thresholds()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.Uuid component_uuid = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_component_uuid()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.EventCfg)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.EventCfg)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void EventCfg::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.EventCfg)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.EventIds event_id = 1;
  if (this->event_id() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->event_id(), output);
  }

  // bool is_configured = 2;
  if (this->is_configured() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_configured(), output);
  }

  // .dmi.Thresholds thresholds = 3;
  if (this->has_thresholds()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, HasBitSetters::thresholds(this), output);
  }

  // .dmi.Uuid component_uuid = 4;
  if (this->has_component_uuid()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, HasBitSetters::component_uuid(this), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.EventCfg)
}

::google::protobuf::uint8* EventCfg::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventCfg)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.EventIds event_id = 1;
  if (this->event_id() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->event_id(), target);
  }

  // bool is_configured = 2;
  if (this->is_configured() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_configured(), target);
  }

  // .dmi.Thresholds thresholds = 3;
  if (this->has_thresholds()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, HasBitSetters::thresholds(this), target);
  }

  // .dmi.Uuid component_uuid = 4;
  if (this->has_component_uuid()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        4, HasBitSetters::component_uuid(this), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventCfg)
  return target;
}

size_t EventCfg::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.EventCfg)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.Thresholds thresholds = 3;
  if (this->has_thresholds()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *thresholds_);
  }

  // .dmi.Uuid component_uuid = 4;
  if (this->has_component_uuid()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *component_uuid_);
  }

  // .dmi.EventIds event_id = 1;
  if (this->event_id() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->event_id());
  }

  // bool is_configured = 2;
  if (this->is_configured() != 0) {
    total_size += 1 + 1;
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void EventCfg::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventCfg)
  GOOGLE_DCHECK_NE(&from, this);
  const EventCfg* source =
      ::google::protobuf::DynamicCastToGenerated<EventCfg>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventCfg)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventCfg)
    MergeFrom(*source);
  }
}

void EventCfg::MergeFrom(const EventCfg& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventCfg)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.has_thresholds()) {
    mutable_thresholds()->::dmi::Thresholds::MergeFrom(from.thresholds());
  }
  if (from.has_component_uuid()) {
    mutable_component_uuid()->::dmi::Uuid::MergeFrom(from.component_uuid());
  }
  if (from.event_id() != 0) {
    set_event_id(from.event_id());
  }
  if (from.is_configured() != 0) {
    set_is_configured(from.is_configured());
  }
}

void EventCfg::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventCfg)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EventCfg::CopyFrom(const EventCfg& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventCfg)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EventCfg::IsInitialized() const {
  return true;
}

void EventCfg::Swap(EventCfg* other) {
  if (other == this) return;
  InternalSwap(other);
}
void EventCfg::InternalSwap(EventCfg* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(thresholds_, other->thresholds_);
  swap(component_uuid_, other->component_uuid_);
  swap(event_id_, other->event_id_);
  swap(is_configured_, other->is_configured_);
}

::google::protobuf::Metadata EventCfg::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void EventsCfg::InitAsDefaultInstance() {
}
class EventsCfg::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EventsCfg::kItemsFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EventsCfg::EventsCfg()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.EventsCfg)
}
EventsCfg::EventsCfg(const EventsCfg& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr),
      items_(from.items_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  // @@protoc_insertion_point(copy_constructor:dmi.EventsCfg)
}

void EventsCfg::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
}

EventsCfg::~EventsCfg() {
  // @@protoc_insertion_point(destructor:dmi.EventsCfg)
  SharedDtor();
}

void EventsCfg::SharedDtor() {
}

void EventsCfg::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const EventsCfg& EventsCfg::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void EventsCfg::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.EventsCfg)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  items_.Clear();
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* EventsCfg::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<EventsCfg*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // repeated .dmi.EventCfg items = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
        do {
          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
          parser_till_end = ::dmi::EventCfg::_InternalParse;
          object = msg->add_items();
          if (size > end - ptr) goto len_delim_till_end;
          ptr += size;
          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
              {parser_till_end, object}, ptr - size, ptr));
          if (ptr >= end) break;
        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EventsCfg::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.EventsCfg)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .dmi.EventCfg items = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
                input, add_items()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.EventsCfg)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.EventsCfg)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void EventsCfg::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.EventsCfg)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .dmi.EventCfg items = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->items_size()); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1,
      this->items(static_cast<int>(i)),
      output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.EventsCfg)
}

::google::protobuf::uint8* EventsCfg::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventsCfg)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // repeated .dmi.EventCfg items = 1;
  for (unsigned int i = 0,
      n = static_cast<unsigned int>(this->items_size()); i < n; i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, this->items(static_cast<int>(i)), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventsCfg)
  return target;
}

size_t EventsCfg::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.EventsCfg)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // repeated .dmi.EventCfg items = 1;
  {
    unsigned int count = static_cast<unsigned int>(this->items_size());
    total_size += 1UL * count;
    for (unsigned int i = 0; i < count; i++) {
      total_size +=
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          this->items(static_cast<int>(i)));
    }
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void EventsCfg::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventsCfg)
  GOOGLE_DCHECK_NE(&from, this);
  const EventsCfg* source =
      ::google::protobuf::DynamicCastToGenerated<EventsCfg>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventsCfg)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventsCfg)
    MergeFrom(*source);
  }
}

void EventsCfg::MergeFrom(const EventsCfg& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventsCfg)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  items_.MergeFrom(from.items_);
}

void EventsCfg::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventsCfg)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EventsCfg::CopyFrom(const EventsCfg& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventsCfg)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EventsCfg::IsInitialized() const {
  return true;
}

void EventsCfg::Swap(EventsCfg* other) {
  if (other == this) return;
  InternalSwap(other);
}
void EventsCfg::InternalSwap(EventsCfg* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  CastToBase(&items_)->InternalSwap(CastToBase(&other->items_));
}

::google::protobuf::Metadata EventsCfg::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void ListEventsResponse::InitAsDefaultInstance() {
  ::dmi::_ListEventsResponse_default_instance_._instance.get_mutable()->events_ = const_cast< ::dmi::EventsCfg*>(
      ::dmi::EventsCfg::internal_default_instance());
}
class ListEventsResponse::HasBitSetters {
 public:
  static const ::dmi::EventsCfg& events(const ListEventsResponse* msg);
};

const ::dmi::EventsCfg&
ListEventsResponse::HasBitSetters::events(const ListEventsResponse* msg) {
  return *msg->events_;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int ListEventsResponse::kStatusFieldNumber;
const int ListEventsResponse::kReasonFieldNumber;
const int ListEventsResponse::kEventsFieldNumber;
const int ListEventsResponse::kReasonDetailFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

ListEventsResponse::ListEventsResponse()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.ListEventsResponse)
}
ListEventsResponse::ListEventsResponse(const ListEventsResponse& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.reason_detail().size() > 0) {
    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
  }
  if (from.has_events()) {
    events_ = new ::dmi::EventsCfg(*from.events_);
  } else {
    events_ = nullptr;
  }
  ::memcpy(&status_, &from.status_,
    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
  // @@protoc_insertion_point(copy_constructor:dmi.ListEventsResponse)
}

void ListEventsResponse::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_ListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&events_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&reason_) -
      reinterpret_cast<char*>(&events_)) + sizeof(reason_));
}

ListEventsResponse::~ListEventsResponse() {
  // @@protoc_insertion_point(destructor:dmi.ListEventsResponse)
  SharedDtor();
}

void ListEventsResponse::SharedDtor() {
  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete events_;
}

void ListEventsResponse::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const ListEventsResponse& ListEventsResponse::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_ListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void ListEventsResponse::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.ListEventsResponse)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (GetArenaNoVirtual() == nullptr && events_ != nullptr) {
    delete events_;
  }
  events_ = nullptr;
  ::memset(&status_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&reason_) -
      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* ListEventsResponse::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<ListEventsResponse*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.Status status = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_status(static_cast<::dmi::Status>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.ListEventsResponse.Reason reason = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_reason(static_cast<::dmi::ListEventsResponse_Reason>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.EventsCfg events = 3;
      case 3: {
        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::EventsCfg::_InternalParse;
        object = msg->mutable_events();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // string reason_detail = 4;
      case 4: {
        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        ctx->extra_parse_data().SetFieldName("dmi.ListEventsResponse.reason_detail");
        object = msg->mutable_reason_detail();
        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
          goto string_till_end;
        }
        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
        ptr += size;
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
string_till_end:
  static_cast<::std::string*>(object)->clear();
  static_cast<::std::string*>(object)->reserve(size);
  goto len_delim_till_end;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool ListEventsResponse::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.ListEventsResponse)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.Status status = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_status(static_cast< ::dmi::Status >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.ListEventsResponse.Reason reason = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_reason(static_cast< ::dmi::ListEventsResponse_Reason >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.EventsCfg events = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_events()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // string reason_detail = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_reason_detail()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "dmi.ListEventsResponse.reason_detail"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.ListEventsResponse)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.ListEventsResponse)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void ListEventsResponse::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.ListEventsResponse)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.Status status = 1;
  if (this->status() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->status(), output);
  }

  // .dmi.ListEventsResponse.Reason reason = 2;
  if (this->reason() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->reason(), output);
  }

  // .dmi.EventsCfg events = 3;
  if (this->has_events()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, HasBitSetters::events(this), output);
  }

  // string reason_detail = 4;
  if (this->reason_detail().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.ListEventsResponse.reason_detail");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      4, this->reason_detail(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.ListEventsResponse)
}

::google::protobuf::uint8* ListEventsResponse::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.ListEventsResponse)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.Status status = 1;
  if (this->status() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->status(), target);
  }

  // .dmi.ListEventsResponse.Reason reason = 2;
  if (this->reason() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->reason(), target);
  }

  // .dmi.EventsCfg events = 3;
  if (this->has_events()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, HasBitSetters::events(this), target);
  }

  // string reason_detail = 4;
  if (this->reason_detail().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.ListEventsResponse.reason_detail");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        4, this->reason_detail(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.ListEventsResponse)
  return target;
}

size_t ListEventsResponse::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.ListEventsResponse)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // string reason_detail = 4;
  if (this->reason_detail().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->reason_detail());
  }

  // .dmi.EventsCfg events = 3;
  if (this->has_events()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *events_);
  }

  // .dmi.Status status = 1;
  if (this->status() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
  }

  // .dmi.ListEventsResponse.Reason reason = 2;
  if (this->reason() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void ListEventsResponse::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.ListEventsResponse)
  GOOGLE_DCHECK_NE(&from, this);
  const ListEventsResponse* source =
      ::google::protobuf::DynamicCastToGenerated<ListEventsResponse>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ListEventsResponse)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ListEventsResponse)
    MergeFrom(*source);
  }
}

void ListEventsResponse::MergeFrom(const ListEventsResponse& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ListEventsResponse)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.reason_detail().size() > 0) {

    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
  }
  if (from.has_events()) {
    mutable_events()->::dmi::EventsCfg::MergeFrom(from.events());
  }
  if (from.status() != 0) {
    set_status(from.status());
  }
  if (from.reason() != 0) {
    set_reason(from.reason());
  }
}

void ListEventsResponse::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.ListEventsResponse)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void ListEventsResponse::CopyFrom(const ListEventsResponse& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ListEventsResponse)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool ListEventsResponse::IsInitialized() const {
  return true;
}

void ListEventsResponse::Swap(ListEventsResponse* other) {
  if (other == this) return;
  InternalSwap(other);
}
void ListEventsResponse::InternalSwap(ListEventsResponse* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(events_, other->events_);
  swap(status_, other->status_);
  swap(reason_, other->reason_);
}

::google::protobuf::Metadata ListEventsResponse::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void EventsConfigurationRequest::InitAsDefaultInstance() {
  ::dmi::_EventsConfigurationRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
      ::dmi::Uuid::internal_default_instance());
  ::dmi::_EventsConfigurationRequest_default_instance_.changes_ = const_cast< ::dmi::EventsCfg*>(
      ::dmi::EventsCfg::internal_default_instance());
  ::dmi::_EventsConfigurationRequest_default_instance_.reset_to_default_ = false;
}
class EventsConfigurationRequest::HasBitSetters {
 public:
  static const ::dmi::Uuid& device_uuid(const EventsConfigurationRequest* msg);
  static const ::dmi::EventsCfg& changes(const EventsConfigurationRequest* msg);
};

const ::dmi::Uuid&
EventsConfigurationRequest::HasBitSetters::device_uuid(const EventsConfigurationRequest* msg) {
  return *msg->device_uuid_;
}
const ::dmi::EventsCfg&
EventsConfigurationRequest::HasBitSetters::changes(const EventsConfigurationRequest* msg) {
  return *msg->operation_.changes_;
}
void EventsConfigurationRequest::clear_device_uuid() {
  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
    delete device_uuid_;
  }
  device_uuid_ = nullptr;
}
void EventsConfigurationRequest::set_allocated_changes(::dmi::EventsCfg* changes) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  clear_operation();
  if (changes) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      changes = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, changes, submessage_arena);
    }
    set_has_changes();
    operation_.changes_ = changes;
  }
  // @@protoc_insertion_point(field_set_allocated:dmi.EventsConfigurationRequest.changes)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EventsConfigurationRequest::kDeviceUuidFieldNumber;
const int EventsConfigurationRequest::kChangesFieldNumber;
const int EventsConfigurationRequest::kResetToDefaultFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EventsConfigurationRequest::EventsConfigurationRequest()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.EventsConfigurationRequest)
}
EventsConfigurationRequest::EventsConfigurationRequest(const EventsConfigurationRequest& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_device_uuid()) {
    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
  } else {
    device_uuid_ = nullptr;
  }
  clear_has_operation();
  switch (from.operation_case()) {
    case kChanges: {
      mutable_changes()->::dmi::EventsCfg::MergeFrom(from.changes());
      break;
    }
    case kResetToDefault: {
      set_reset_to_default(from.reset_to_default());
      break;
    }
    case OPERATION_NOT_SET: {
      break;
    }
  }
  // @@protoc_insertion_point(copy_constructor:dmi.EventsConfigurationRequest)
}

void EventsConfigurationRequest::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_EventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  device_uuid_ = nullptr;
  clear_has_operation();
}

EventsConfigurationRequest::~EventsConfigurationRequest() {
  // @@protoc_insertion_point(destructor:dmi.EventsConfigurationRequest)
  SharedDtor();
}

void EventsConfigurationRequest::SharedDtor() {
  if (this != internal_default_instance()) delete device_uuid_;
  if (has_operation()) {
    clear_operation();
  }
}

void EventsConfigurationRequest::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const EventsConfigurationRequest& EventsConfigurationRequest::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_EventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void EventsConfigurationRequest::clear_operation() {
// @@protoc_insertion_point(one_of_clear_start:dmi.EventsConfigurationRequest)
  switch (operation_case()) {
    case kChanges: {
      delete operation_.changes_;
      break;
    }
    case kResetToDefault: {
      // No need to clear
      break;
    }
    case OPERATION_NOT_SET: {
      break;
    }
  }
  _oneof_case_[0] = OPERATION_NOT_SET;
}


void EventsConfigurationRequest::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.EventsConfigurationRequest)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
    delete device_uuid_;
  }
  device_uuid_ = nullptr;
  clear_operation();
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* EventsConfigurationRequest::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<EventsConfigurationRequest*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.Uuid device_uuid = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::Uuid::_InternalParse;
        object = msg->mutable_device_uuid();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.EventsCfg changes = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::EventsCfg::_InternalParse;
        object = msg->mutable_changes();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // bool reset_to_default = 3;
      case 3: {
        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
        msg->set_reset_to_default(::google::protobuf::internal::ReadVarint(&ptr));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EventsConfigurationRequest::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.EventsConfigurationRequest)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.Uuid device_uuid = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_device_uuid()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.EventsCfg changes = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_changes()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // bool reset_to_default = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
          clear_operation();
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &operation_.reset_to_default_)));
          set_has_reset_to_default();
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.EventsConfigurationRequest)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.EventsConfigurationRequest)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void EventsConfigurationRequest::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.EventsConfigurationRequest)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.Uuid device_uuid = 1;
  if (this->has_device_uuid()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, HasBitSetters::device_uuid(this), output);
  }

  // .dmi.EventsCfg changes = 2;
  if (has_changes()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, HasBitSetters::changes(this), output);
  }

  // bool reset_to_default = 3;
  if (has_reset_to_default()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->reset_to_default(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.EventsConfigurationRequest)
}

::google::protobuf::uint8* EventsConfigurationRequest::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventsConfigurationRequest)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.Uuid device_uuid = 1;
  if (this->has_device_uuid()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, HasBitSetters::device_uuid(this), target);
  }

  // .dmi.EventsCfg changes = 2;
  if (has_changes()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, HasBitSetters::changes(this), target);
  }

  // bool reset_to_default = 3;
  if (has_reset_to_default()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->reset_to_default(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventsConfigurationRequest)
  return target;
}

size_t EventsConfigurationRequest::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.EventsConfigurationRequest)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.Uuid device_uuid = 1;
  if (this->has_device_uuid()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *device_uuid_);
  }

  switch (operation_case()) {
    // .dmi.EventsCfg changes = 2;
    case kChanges: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *operation_.changes_);
      break;
    }
    // bool reset_to_default = 3;
    case kResetToDefault: {
      total_size += 1 + 1;
      break;
    }
    case OPERATION_NOT_SET: {
      break;
    }
  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void EventsConfigurationRequest::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventsConfigurationRequest)
  GOOGLE_DCHECK_NE(&from, this);
  const EventsConfigurationRequest* source =
      ::google::protobuf::DynamicCastToGenerated<EventsConfigurationRequest>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventsConfigurationRequest)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventsConfigurationRequest)
    MergeFrom(*source);
  }
}

void EventsConfigurationRequest::MergeFrom(const EventsConfigurationRequest& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventsConfigurationRequest)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.has_device_uuid()) {
    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
  }
  switch (from.operation_case()) {
    case kChanges: {
      mutable_changes()->::dmi::EventsCfg::MergeFrom(from.changes());
      break;
    }
    case kResetToDefault: {
      set_reset_to_default(from.reset_to_default());
      break;
    }
    case OPERATION_NOT_SET: {
      break;
    }
  }
}

void EventsConfigurationRequest::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventsConfigurationRequest)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EventsConfigurationRequest::CopyFrom(const EventsConfigurationRequest& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventsConfigurationRequest)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EventsConfigurationRequest::IsInitialized() const {
  return true;
}

void EventsConfigurationRequest::Swap(EventsConfigurationRequest* other) {
  if (other == this) return;
  InternalSwap(other);
}
void EventsConfigurationRequest::InternalSwap(EventsConfigurationRequest* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(device_uuid_, other->device_uuid_);
  swap(operation_, other->operation_);
  swap(_oneof_case_[0], other->_oneof_case_[0]);
}

::google::protobuf::Metadata EventsConfigurationRequest::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void EventsConfigurationResponse::InitAsDefaultInstance() {
}
class EventsConfigurationResponse::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EventsConfigurationResponse::kStatusFieldNumber;
const int EventsConfigurationResponse::kReasonFieldNumber;
const int EventsConfigurationResponse::kReasonDetailFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EventsConfigurationResponse::EventsConfigurationResponse()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.EventsConfigurationResponse)
}
EventsConfigurationResponse::EventsConfigurationResponse(const EventsConfigurationResponse& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.reason_detail().size() > 0) {
    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
  }
  ::memcpy(&status_, &from.status_,
    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
  // @@protoc_insertion_point(copy_constructor:dmi.EventsConfigurationResponse)
}

void EventsConfigurationResponse::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_EventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&status_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&reason_) -
      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
}

EventsConfigurationResponse::~EventsConfigurationResponse() {
  // @@protoc_insertion_point(destructor:dmi.EventsConfigurationResponse)
  SharedDtor();
}

void EventsConfigurationResponse::SharedDtor() {
  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

void EventsConfigurationResponse::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const EventsConfigurationResponse& EventsConfigurationResponse::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_EventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void EventsConfigurationResponse::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.EventsConfigurationResponse)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&status_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&reason_) -
      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* EventsConfigurationResponse::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<EventsConfigurationResponse*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.Status status = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_status(static_cast<::dmi::Status>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.EventsConfigurationResponse.Reason reason = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_reason(static_cast<::dmi::EventsConfigurationResponse_Reason>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // string reason_detail = 3;
      case 3: {
        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        ctx->extra_parse_data().SetFieldName("dmi.EventsConfigurationResponse.reason_detail");
        object = msg->mutable_reason_detail();
        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
          goto string_till_end;
        }
        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
        ptr += size;
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
string_till_end:
  static_cast<::std::string*>(object)->clear();
  static_cast<::std::string*>(object)->reserve(size);
  goto len_delim_till_end;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EventsConfigurationResponse::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.EventsConfigurationResponse)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.Status status = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_status(static_cast< ::dmi::Status >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.EventsConfigurationResponse.Reason reason = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_reason(static_cast< ::dmi::EventsConfigurationResponse_Reason >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // string reason_detail = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_reason_detail()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "dmi.EventsConfigurationResponse.reason_detail"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.EventsConfigurationResponse)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.EventsConfigurationResponse)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void EventsConfigurationResponse::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.EventsConfigurationResponse)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.Status status = 1;
  if (this->status() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->status(), output);
  }

  // .dmi.EventsConfigurationResponse.Reason reason = 2;
  if (this->reason() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->reason(), output);
  }

  // string reason_detail = 3;
  if (this->reason_detail().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.EventsConfigurationResponse.reason_detail");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      3, this->reason_detail(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.EventsConfigurationResponse)
}

::google::protobuf::uint8* EventsConfigurationResponse::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventsConfigurationResponse)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.Status status = 1;
  if (this->status() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->status(), target);
  }

  // .dmi.EventsConfigurationResponse.Reason reason = 2;
  if (this->reason() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->reason(), target);
  }

  // string reason_detail = 3;
  if (this->reason_detail().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.EventsConfigurationResponse.reason_detail");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        3, this->reason_detail(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventsConfigurationResponse)
  return target;
}

size_t EventsConfigurationResponse::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.EventsConfigurationResponse)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // string reason_detail = 3;
  if (this->reason_detail().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->reason_detail());
  }

  // .dmi.Status status = 1;
  if (this->status() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
  }

  // .dmi.EventsConfigurationResponse.Reason reason = 2;
  if (this->reason() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void EventsConfigurationResponse::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventsConfigurationResponse)
  GOOGLE_DCHECK_NE(&from, this);
  const EventsConfigurationResponse* source =
      ::google::protobuf::DynamicCastToGenerated<EventsConfigurationResponse>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventsConfigurationResponse)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventsConfigurationResponse)
    MergeFrom(*source);
  }
}

void EventsConfigurationResponse::MergeFrom(const EventsConfigurationResponse& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventsConfigurationResponse)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.reason_detail().size() > 0) {

    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
  }
  if (from.status() != 0) {
    set_status(from.status());
  }
  if (from.reason() != 0) {
    set_reason(from.reason());
  }
}

void EventsConfigurationResponse::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventsConfigurationResponse)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EventsConfigurationResponse::CopyFrom(const EventsConfigurationResponse& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventsConfigurationResponse)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EventsConfigurationResponse::IsInitialized() const {
  return true;
}

void EventsConfigurationResponse::Swap(EventsConfigurationResponse* other) {
  if (other == this) return;
  InternalSwap(other);
}
void EventsConfigurationResponse::InternalSwap(EventsConfigurationResponse* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(status_, other->status_);
  swap(reason_, other->reason_);
}

::google::protobuf::Metadata EventsConfigurationResponse::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void EventMetaData::InitAsDefaultInstance() {
  ::dmi::_EventMetaData_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
      ::dmi::Uuid::internal_default_instance());
  ::dmi::_EventMetaData_default_instance_._instance.get_mutable()->component_uuid_ = const_cast< ::dmi::Uuid*>(
      ::dmi::Uuid::internal_default_instance());
}
class EventMetaData::HasBitSetters {
 public:
  static const ::dmi::Uuid& device_uuid(const EventMetaData* msg);
  static const ::dmi::Uuid& component_uuid(const EventMetaData* msg);
};

const ::dmi::Uuid&
EventMetaData::HasBitSetters::device_uuid(const EventMetaData* msg) {
  return *msg->device_uuid_;
}
const ::dmi::Uuid&
EventMetaData::HasBitSetters::component_uuid(const EventMetaData* msg) {
  return *msg->component_uuid_;
}
void EventMetaData::clear_device_uuid() {
  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
    delete device_uuid_;
  }
  device_uuid_ = nullptr;
}
void EventMetaData::clear_component_uuid() {
  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
    delete component_uuid_;
  }
  component_uuid_ = nullptr;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EventMetaData::kDeviceUuidFieldNumber;
const int EventMetaData::kComponentUuidFieldNumber;
const int EventMetaData::kComponentNameFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

EventMetaData::EventMetaData()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.EventMetaData)
}
EventMetaData::EventMetaData(const EventMetaData& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.component_name().size() > 0) {
    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
  }
  if (from.has_device_uuid()) {
    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
  } else {
    device_uuid_ = nullptr;
  }
  if (from.has_component_uuid()) {
    component_uuid_ = new ::dmi::Uuid(*from.component_uuid_);
  } else {
    component_uuid_ = nullptr;
  }
  // @@protoc_insertion_point(copy_constructor:dmi.EventMetaData)
}

void EventMetaData::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&device_uuid_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&component_uuid_) -
      reinterpret_cast<char*>(&device_uuid_)) + sizeof(component_uuid_));
}

EventMetaData::~EventMetaData() {
  // @@protoc_insertion_point(destructor:dmi.EventMetaData)
  SharedDtor();
}

void EventMetaData::SharedDtor() {
  component_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete device_uuid_;
  if (this != internal_default_instance()) delete component_uuid_;
}

void EventMetaData::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const EventMetaData& EventMetaData::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void EventMetaData::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.EventMetaData)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
    delete device_uuid_;
  }
  device_uuid_ = nullptr;
  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
    delete component_uuid_;
  }
  component_uuid_ = nullptr;
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* EventMetaData::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<EventMetaData*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.Uuid device_uuid = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::Uuid::_InternalParse;
        object = msg->mutable_device_uuid();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.Uuid component_uuid = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::Uuid::_InternalParse;
        object = msg->mutable_component_uuid();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // string component_name = 3;
      case 3: {
        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        ctx->extra_parse_data().SetFieldName("dmi.EventMetaData.component_name");
        object = msg->mutable_component_name();
        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
          goto string_till_end;
        }
        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
        ptr += size;
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
string_till_end:
  static_cast<::std::string*>(object)->clear();
  static_cast<::std::string*>(object)->reserve(size);
  goto len_delim_till_end;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool EventMetaData::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.EventMetaData)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.Uuid device_uuid = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_device_uuid()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.Uuid component_uuid = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_component_uuid()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // string component_name = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_component_name()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->component_name().data(), static_cast<int>(this->component_name().length()),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "dmi.EventMetaData.component_name"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.EventMetaData)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.EventMetaData)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void EventMetaData::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.EventMetaData)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.Uuid device_uuid = 1;
  if (this->has_device_uuid()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, HasBitSetters::device_uuid(this), output);
  }

  // .dmi.Uuid component_uuid = 2;
  if (this->has_component_uuid()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, HasBitSetters::component_uuid(this), output);
  }

  // string component_name = 3;
  if (this->component_name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->component_name().data(), static_cast<int>(this->component_name().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.EventMetaData.component_name");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      3, this->component_name(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.EventMetaData)
}

::google::protobuf::uint8* EventMetaData::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventMetaData)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.Uuid device_uuid = 1;
  if (this->has_device_uuid()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, HasBitSetters::device_uuid(this), target);
  }

  // .dmi.Uuid component_uuid = 2;
  if (this->has_component_uuid()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, HasBitSetters::component_uuid(this), target);
  }

  // string component_name = 3;
  if (this->component_name().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->component_name().data(), static_cast<int>(this->component_name().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.EventMetaData.component_name");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        3, this->component_name(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventMetaData)
  return target;
}

size_t EventMetaData::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.EventMetaData)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // string component_name = 3;
  if (this->component_name().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->component_name());
  }

  // .dmi.Uuid device_uuid = 1;
  if (this->has_device_uuid()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *device_uuid_);
  }

  // .dmi.Uuid component_uuid = 2;
  if (this->has_component_uuid()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *component_uuid_);
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void EventMetaData::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventMetaData)
  GOOGLE_DCHECK_NE(&from, this);
  const EventMetaData* source =
      ::google::protobuf::DynamicCastToGenerated<EventMetaData>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventMetaData)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventMetaData)
    MergeFrom(*source);
  }
}

void EventMetaData::MergeFrom(const EventMetaData& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventMetaData)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.component_name().size() > 0) {

    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
  }
  if (from.has_device_uuid()) {
    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
  }
  if (from.has_component_uuid()) {
    mutable_component_uuid()->::dmi::Uuid::MergeFrom(from.component_uuid());
  }
}

void EventMetaData::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventMetaData)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EventMetaData::CopyFrom(const EventMetaData& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventMetaData)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EventMetaData::IsInitialized() const {
  return true;
}

void EventMetaData::Swap(EventMetaData* other) {
  if (other == this) return;
  InternalSwap(other);
}
void EventMetaData::InternalSwap(EventMetaData* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  component_name_.Swap(&other->component_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(device_uuid_, other->device_uuid_);
  swap(component_uuid_, other->component_uuid_);
}

::google::protobuf::Metadata EventMetaData::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void AdminStateChange::InitAsDefaultInstance() {
}
class AdminStateChange::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int AdminStateChange::kOldFieldNumber;
const int AdminStateChange::kNewFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

AdminStateChange::AdminStateChange()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.AdminStateChange)
}
AdminStateChange::AdminStateChange(const AdminStateChange& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&old_, &from.old_,
    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
    reinterpret_cast<char*>(&old_)) + sizeof(new__));
  // @@protoc_insertion_point(copy_constructor:dmi.AdminStateChange)
}

void AdminStateChange::SharedCtor() {
  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
}

AdminStateChange::~AdminStateChange() {
  // @@protoc_insertion_point(destructor:dmi.AdminStateChange)
  SharedDtor();
}

void AdminStateChange::SharedDtor() {
}

void AdminStateChange::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const AdminStateChange& AdminStateChange::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void AdminStateChange::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.AdminStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* AdminStateChange::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<AdminStateChange*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.ComponentAdminState old = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_old(static_cast<::dmi::ComponentAdminState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.ComponentAdminState new = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_new_(static_cast<::dmi::ComponentAdminState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool AdminStateChange::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.AdminStateChange)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.ComponentAdminState old = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_old(static_cast< ::dmi::ComponentAdminState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.ComponentAdminState new = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_new_(static_cast< ::dmi::ComponentAdminState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.AdminStateChange)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.AdminStateChange)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void AdminStateChange::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.AdminStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentAdminState old = 1;
  if (this->old() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->old(), output);
  }

  // .dmi.ComponentAdminState new = 2;
  if (this->new_() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->new_(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.AdminStateChange)
}

::google::protobuf::uint8* AdminStateChange::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.AdminStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentAdminState old = 1;
  if (this->old() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->old(), target);
  }

  // .dmi.ComponentAdminState new = 2;
  if (this->new_() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->new_(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.AdminStateChange)
  return target;
}

size_t AdminStateChange::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.AdminStateChange)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.ComponentAdminState old = 1;
  if (this->old() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
  }

  // .dmi.ComponentAdminState new = 2;
  if (this->new_() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void AdminStateChange::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.AdminStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  const AdminStateChange* source =
      ::google::protobuf::DynamicCastToGenerated<AdminStateChange>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.AdminStateChange)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.AdminStateChange)
    MergeFrom(*source);
  }
}

void AdminStateChange::MergeFrom(const AdminStateChange& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.AdminStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.old() != 0) {
    set_old(from.old());
  }
  if (from.new_() != 0) {
    set_new_(from.new_());
  }
}

void AdminStateChange::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.AdminStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void AdminStateChange::CopyFrom(const AdminStateChange& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.AdminStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool AdminStateChange::IsInitialized() const {
  return true;
}

void AdminStateChange::Swap(AdminStateChange* other) {
  if (other == this) return;
  InternalSwap(other);
}
void AdminStateChange::InternalSwap(AdminStateChange* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(old_, other->old_);
  swap(new__, other->new__);
}

::google::protobuf::Metadata AdminStateChange::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void OperStateChange::InitAsDefaultInstance() {
}
class OperStateChange::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int OperStateChange::kOldFieldNumber;
const int OperStateChange::kNewFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

OperStateChange::OperStateChange()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.OperStateChange)
}
OperStateChange::OperStateChange(const OperStateChange& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&old_, &from.old_,
    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
    reinterpret_cast<char*>(&old_)) + sizeof(new__));
  // @@protoc_insertion_point(copy_constructor:dmi.OperStateChange)
}

void OperStateChange::SharedCtor() {
  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
}

OperStateChange::~OperStateChange() {
  // @@protoc_insertion_point(destructor:dmi.OperStateChange)
  SharedDtor();
}

void OperStateChange::SharedDtor() {
}

void OperStateChange::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const OperStateChange& OperStateChange::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void OperStateChange::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.OperStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* OperStateChange::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<OperStateChange*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.ComponentOperState old = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_old(static_cast<::dmi::ComponentOperState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.ComponentOperState new = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_new_(static_cast<::dmi::ComponentOperState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool OperStateChange::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.OperStateChange)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.ComponentOperState old = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_old(static_cast< ::dmi::ComponentOperState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.ComponentOperState new = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_new_(static_cast< ::dmi::ComponentOperState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.OperStateChange)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.OperStateChange)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void OperStateChange::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.OperStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentOperState old = 1;
  if (this->old() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->old(), output);
  }

  // .dmi.ComponentOperState new = 2;
  if (this->new_() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->new_(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.OperStateChange)
}

::google::protobuf::uint8* OperStateChange::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.OperStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentOperState old = 1;
  if (this->old() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->old(), target);
  }

  // .dmi.ComponentOperState new = 2;
  if (this->new_() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->new_(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.OperStateChange)
  return target;
}

size_t OperStateChange::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.OperStateChange)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.ComponentOperState old = 1;
  if (this->old() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
  }

  // .dmi.ComponentOperState new = 2;
  if (this->new_() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void OperStateChange::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.OperStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  const OperStateChange* source =
      ::google::protobuf::DynamicCastToGenerated<OperStateChange>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.OperStateChange)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.OperStateChange)
    MergeFrom(*source);
  }
}

void OperStateChange::MergeFrom(const OperStateChange& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.OperStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.old() != 0) {
    set_old(from.old());
  }
  if (from.new_() != 0) {
    set_new_(from.new_());
  }
}

void OperStateChange::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.OperStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void OperStateChange::CopyFrom(const OperStateChange& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.OperStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool OperStateChange::IsInitialized() const {
  return true;
}

void OperStateChange::Swap(OperStateChange* other) {
  if (other == this) return;
  InternalSwap(other);
}
void OperStateChange::InternalSwap(OperStateChange* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(old_, other->old_);
  swap(new__, other->new__);
}

::google::protobuf::Metadata OperStateChange::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void AlarmStateChange::InitAsDefaultInstance() {
}
class AlarmStateChange::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int AlarmStateChange::kOldFieldNumber;
const int AlarmStateChange::kNewFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

AlarmStateChange::AlarmStateChange()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.AlarmStateChange)
}
AlarmStateChange::AlarmStateChange(const AlarmStateChange& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&old_, &from.old_,
    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
    reinterpret_cast<char*>(&old_)) + sizeof(new__));
  // @@protoc_insertion_point(copy_constructor:dmi.AlarmStateChange)
}

void AlarmStateChange::SharedCtor() {
  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
}

AlarmStateChange::~AlarmStateChange() {
  // @@protoc_insertion_point(destructor:dmi.AlarmStateChange)
  SharedDtor();
}

void AlarmStateChange::SharedDtor() {
}

void AlarmStateChange::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const AlarmStateChange& AlarmStateChange::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void AlarmStateChange::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.AlarmStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* AlarmStateChange::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<AlarmStateChange*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.ComponentAlarmState old = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_old(static_cast<::dmi::ComponentAlarmState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.ComponentAlarmState new = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_new_(static_cast<::dmi::ComponentAlarmState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool AlarmStateChange::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.AlarmStateChange)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.ComponentAlarmState old = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_old(static_cast< ::dmi::ComponentAlarmState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.ComponentAlarmState new = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_new_(static_cast< ::dmi::ComponentAlarmState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.AlarmStateChange)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.AlarmStateChange)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void AlarmStateChange::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.AlarmStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentAlarmState old = 1;
  if (this->old() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->old(), output);
  }

  // .dmi.ComponentAlarmState new = 2;
  if (this->new_() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->new_(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.AlarmStateChange)
}

::google::protobuf::uint8* AlarmStateChange::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.AlarmStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentAlarmState old = 1;
  if (this->old() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->old(), target);
  }

  // .dmi.ComponentAlarmState new = 2;
  if (this->new_() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->new_(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.AlarmStateChange)
  return target;
}

size_t AlarmStateChange::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.AlarmStateChange)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.ComponentAlarmState old = 1;
  if (this->old() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
  }

  // .dmi.ComponentAlarmState new = 2;
  if (this->new_() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void AlarmStateChange::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.AlarmStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  const AlarmStateChange* source =
      ::google::protobuf::DynamicCastToGenerated<AlarmStateChange>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.AlarmStateChange)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.AlarmStateChange)
    MergeFrom(*source);
  }
}

void AlarmStateChange::MergeFrom(const AlarmStateChange& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.AlarmStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.old() != 0) {
    set_old(from.old());
  }
  if (from.new_() != 0) {
    set_new_(from.new_());
  }
}

void AlarmStateChange::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.AlarmStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void AlarmStateChange::CopyFrom(const AlarmStateChange& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.AlarmStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool AlarmStateChange::IsInitialized() const {
  return true;
}

void AlarmStateChange::Swap(AlarmStateChange* other) {
  if (other == this) return;
  InternalSwap(other);
}
void AlarmStateChange::InternalSwap(AlarmStateChange* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(old_, other->old_);
  swap(new__, other->new__);
}

::google::protobuf::Metadata AlarmStateChange::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void UsageStateChange::InitAsDefaultInstance() {
}
class UsageStateChange::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int UsageStateChange::kOldFieldNumber;
const int UsageStateChange::kNewFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

UsageStateChange::UsageStateChange()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.UsageStateChange)
}
UsageStateChange::UsageStateChange(const UsageStateChange& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&old_, &from.old_,
    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
    reinterpret_cast<char*>(&old_)) + sizeof(new__));
  // @@protoc_insertion_point(copy_constructor:dmi.UsageStateChange)
}

void UsageStateChange::SharedCtor() {
  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
}

UsageStateChange::~UsageStateChange() {
  // @@protoc_insertion_point(destructor:dmi.UsageStateChange)
  SharedDtor();
}

void UsageStateChange::SharedDtor() {
}

void UsageStateChange::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const UsageStateChange& UsageStateChange::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void UsageStateChange::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.UsageStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* UsageStateChange::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<UsageStateChange*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.ComponentUsageState old = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_old(static_cast<::dmi::ComponentUsageState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.ComponentUsageState new = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_new_(static_cast<::dmi::ComponentUsageState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool UsageStateChange::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.UsageStateChange)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.ComponentUsageState old = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_old(static_cast< ::dmi::ComponentUsageState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.ComponentUsageState new = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_new_(static_cast< ::dmi::ComponentUsageState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.UsageStateChange)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.UsageStateChange)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void UsageStateChange::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.UsageStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentUsageState old = 1;
  if (this->old() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->old(), output);
  }

  // .dmi.ComponentUsageState new = 2;
  if (this->new_() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->new_(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.UsageStateChange)
}

::google::protobuf::uint8* UsageStateChange::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.UsageStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentUsageState old = 1;
  if (this->old() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->old(), target);
  }

  // .dmi.ComponentUsageState new = 2;
  if (this->new_() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->new_(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.UsageStateChange)
  return target;
}

size_t UsageStateChange::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.UsageStateChange)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.ComponentUsageState old = 1;
  if (this->old() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
  }

  // .dmi.ComponentUsageState new = 2;
  if (this->new_() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void UsageStateChange::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.UsageStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  const UsageStateChange* source =
      ::google::protobuf::DynamicCastToGenerated<UsageStateChange>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.UsageStateChange)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.UsageStateChange)
    MergeFrom(*source);
  }
}

void UsageStateChange::MergeFrom(const UsageStateChange& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.UsageStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.old() != 0) {
    set_old(from.old());
  }
  if (from.new_() != 0) {
    set_new_(from.new_());
  }
}

void UsageStateChange::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.UsageStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void UsageStateChange::CopyFrom(const UsageStateChange& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.UsageStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool UsageStateChange::IsInitialized() const {
  return true;
}

void UsageStateChange::Swap(UsageStateChange* other) {
  if (other == this) return;
  InternalSwap(other);
}
void UsageStateChange::InternalSwap(UsageStateChange* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(old_, other->old_);
  swap(new__, other->new__);
}

::google::protobuf::Metadata UsageStateChange::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void StandbyStateChange::InitAsDefaultInstance() {
}
class StandbyStateChange::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int StandbyStateChange::kOldFieldNumber;
const int StandbyStateChange::kNewFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

StandbyStateChange::StandbyStateChange()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.StandbyStateChange)
}
StandbyStateChange::StandbyStateChange(const StandbyStateChange& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&old_, &from.old_,
    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
    reinterpret_cast<char*>(&old_)) + sizeof(new__));
  // @@protoc_insertion_point(copy_constructor:dmi.StandbyStateChange)
}

void StandbyStateChange::SharedCtor() {
  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
}

StandbyStateChange::~StandbyStateChange() {
  // @@protoc_insertion_point(destructor:dmi.StandbyStateChange)
  SharedDtor();
}

void StandbyStateChange::SharedDtor() {
}

void StandbyStateChange::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const StandbyStateChange& StandbyStateChange::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void StandbyStateChange::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.StandbyStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  ::memset(&old_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&new__) -
      reinterpret_cast<char*>(&old_)) + sizeof(new__));
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* StandbyStateChange::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<StandbyStateChange*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.ComponentStandbyState old = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_old(static_cast<::dmi::ComponentStandbyState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.ComponentStandbyState new = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_new_(static_cast<::dmi::ComponentStandbyState>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool StandbyStateChange::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.StandbyStateChange)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.ComponentStandbyState old = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_old(static_cast< ::dmi::ComponentStandbyState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.ComponentStandbyState new = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_new_(static_cast< ::dmi::ComponentStandbyState >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.StandbyStateChange)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.StandbyStateChange)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void StandbyStateChange::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.StandbyStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentStandbyState old = 1;
  if (this->old() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->old(), output);
  }

  // .dmi.ComponentStandbyState new = 2;
  if (this->new_() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->new_(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.StandbyStateChange)
}

::google::protobuf::uint8* StandbyStateChange::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.StandbyStateChange)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.ComponentStandbyState old = 1;
  if (this->old() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->old(), target);
  }

  // .dmi.ComponentStandbyState new = 2;
  if (this->new_() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->new_(), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.StandbyStateChange)
  return target;
}

size_t StandbyStateChange::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.StandbyStateChange)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // .dmi.ComponentStandbyState old = 1;
  if (this->old() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
  }

  // .dmi.ComponentStandbyState new = 2;
  if (this->new_() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void StandbyStateChange::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.StandbyStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  const StandbyStateChange* source =
      ::google::protobuf::DynamicCastToGenerated<StandbyStateChange>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.StandbyStateChange)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.StandbyStateChange)
    MergeFrom(*source);
  }
}

void StandbyStateChange::MergeFrom(const StandbyStateChange& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.StandbyStateChange)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.old() != 0) {
    set_old(from.old());
  }
  if (from.new_() != 0) {
    set_new_(from.new_());
  }
}

void StandbyStateChange::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.StandbyStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void StandbyStateChange::CopyFrom(const StandbyStateChange& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.StandbyStateChange)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool StandbyStateChange::IsInitialized() const {
  return true;
}

void StandbyStateChange::Swap(StandbyStateChange* other) {
  if (other == this) return;
  InternalSwap(other);
}
void StandbyStateChange::InternalSwap(StandbyStateChange* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(old_, other->old_);
  swap(new__, other->new__);
}

::google::protobuf::Metadata StandbyStateChange::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void StateChangeInfo::InitAsDefaultInstance() {
  ::dmi::_StateChangeInfo_default_instance_.admin_state_change_ = const_cast< ::dmi::AdminStateChange*>(
      ::dmi::AdminStateChange::internal_default_instance());
  ::dmi::_StateChangeInfo_default_instance_.oper_state_change_ = const_cast< ::dmi::OperStateChange*>(
      ::dmi::OperStateChange::internal_default_instance());
  ::dmi::_StateChangeInfo_default_instance_.alarm_state_change_ = const_cast< ::dmi::AlarmStateChange*>(
      ::dmi::AlarmStateChange::internal_default_instance());
  ::dmi::_StateChangeInfo_default_instance_.usage_state_change_ = const_cast< ::dmi::UsageStateChange*>(
      ::dmi::UsageStateChange::internal_default_instance());
  ::dmi::_StateChangeInfo_default_instance_.standby_state_change_ = const_cast< ::dmi::StandbyStateChange*>(
      ::dmi::StandbyStateChange::internal_default_instance());
}
class StateChangeInfo::HasBitSetters {
 public:
  static const ::dmi::AdminStateChange& admin_state_change(const StateChangeInfo* msg);
  static const ::dmi::OperStateChange& oper_state_change(const StateChangeInfo* msg);
  static const ::dmi::AlarmStateChange& alarm_state_change(const StateChangeInfo* msg);
  static const ::dmi::UsageStateChange& usage_state_change(const StateChangeInfo* msg);
  static const ::dmi::StandbyStateChange& standby_state_change(const StateChangeInfo* msg);
};

const ::dmi::AdminStateChange&
StateChangeInfo::HasBitSetters::admin_state_change(const StateChangeInfo* msg) {
  return *msg->state_change_.admin_state_change_;
}
const ::dmi::OperStateChange&
StateChangeInfo::HasBitSetters::oper_state_change(const StateChangeInfo* msg) {
  return *msg->state_change_.oper_state_change_;
}
const ::dmi::AlarmStateChange&
StateChangeInfo::HasBitSetters::alarm_state_change(const StateChangeInfo* msg) {
  return *msg->state_change_.alarm_state_change_;
}
const ::dmi::UsageStateChange&
StateChangeInfo::HasBitSetters::usage_state_change(const StateChangeInfo* msg) {
  return *msg->state_change_.usage_state_change_;
}
const ::dmi::StandbyStateChange&
StateChangeInfo::HasBitSetters::standby_state_change(const StateChangeInfo* msg) {
  return *msg->state_change_.standby_state_change_;
}
void StateChangeInfo::set_allocated_admin_state_change(::dmi::AdminStateChange* admin_state_change) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  clear_state_change();
  if (admin_state_change) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      admin_state_change = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, admin_state_change, submessage_arena);
    }
    set_has_admin_state_change();
    state_change_.admin_state_change_ = admin_state_change;
  }
  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.admin_state_change)
}
void StateChangeInfo::set_allocated_oper_state_change(::dmi::OperStateChange* oper_state_change) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  clear_state_change();
  if (oper_state_change) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      oper_state_change = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, oper_state_change, submessage_arena);
    }
    set_has_oper_state_change();
    state_change_.oper_state_change_ = oper_state_change;
  }
  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.oper_state_change)
}
void StateChangeInfo::set_allocated_alarm_state_change(::dmi::AlarmStateChange* alarm_state_change) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  clear_state_change();
  if (alarm_state_change) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      alarm_state_change = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, alarm_state_change, submessage_arena);
    }
    set_has_alarm_state_change();
    state_change_.alarm_state_change_ = alarm_state_change;
  }
  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.alarm_state_change)
}
void StateChangeInfo::set_allocated_usage_state_change(::dmi::UsageStateChange* usage_state_change) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  clear_state_change();
  if (usage_state_change) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      usage_state_change = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, usage_state_change, submessage_arena);
    }
    set_has_usage_state_change();
    state_change_.usage_state_change_ = usage_state_change;
  }
  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.usage_state_change)
}
void StateChangeInfo::set_allocated_standby_state_change(::dmi::StandbyStateChange* standby_state_change) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  clear_state_change();
  if (standby_state_change) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      standby_state_change = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, standby_state_change, submessage_arena);
    }
    set_has_standby_state_change();
    state_change_.standby_state_change_ = standby_state_change;
  }
  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.standby_state_change)
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int StateChangeInfo::kAdminStateChangeFieldNumber;
const int StateChangeInfo::kOperStateChangeFieldNumber;
const int StateChangeInfo::kAlarmStateChangeFieldNumber;
const int StateChangeInfo::kUsageStateChangeFieldNumber;
const int StateChangeInfo::kStandbyStateChangeFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

StateChangeInfo::StateChangeInfo()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.StateChangeInfo)
}
StateChangeInfo::StateChangeInfo(const StateChangeInfo& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  clear_has_state_change();
  switch (from.state_change_case()) {
    case kAdminStateChange: {
      mutable_admin_state_change()->::dmi::AdminStateChange::MergeFrom(from.admin_state_change());
      break;
    }
    case kOperStateChange: {
      mutable_oper_state_change()->::dmi::OperStateChange::MergeFrom(from.oper_state_change());
      break;
    }
    case kAlarmStateChange: {
      mutable_alarm_state_change()->::dmi::AlarmStateChange::MergeFrom(from.alarm_state_change());
      break;
    }
    case kUsageStateChange: {
      mutable_usage_state_change()->::dmi::UsageStateChange::MergeFrom(from.usage_state_change());
      break;
    }
    case kStandbyStateChange: {
      mutable_standby_state_change()->::dmi::StandbyStateChange::MergeFrom(from.standby_state_change());
      break;
    }
    case STATE_CHANGE_NOT_SET: {
      break;
    }
  }
  // @@protoc_insertion_point(copy_constructor:dmi.StateChangeInfo)
}

void StateChangeInfo::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  clear_has_state_change();
}

StateChangeInfo::~StateChangeInfo() {
  // @@protoc_insertion_point(destructor:dmi.StateChangeInfo)
  SharedDtor();
}

void StateChangeInfo::SharedDtor() {
  if (has_state_change()) {
    clear_state_change();
  }
}

void StateChangeInfo::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const StateChangeInfo& StateChangeInfo::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void StateChangeInfo::clear_state_change() {
// @@protoc_insertion_point(one_of_clear_start:dmi.StateChangeInfo)
  switch (state_change_case()) {
    case kAdminStateChange: {
      delete state_change_.admin_state_change_;
      break;
    }
    case kOperStateChange: {
      delete state_change_.oper_state_change_;
      break;
    }
    case kAlarmStateChange: {
      delete state_change_.alarm_state_change_;
      break;
    }
    case kUsageStateChange: {
      delete state_change_.usage_state_change_;
      break;
    }
    case kStandbyStateChange: {
      delete state_change_.standby_state_change_;
      break;
    }
    case STATE_CHANGE_NOT_SET: {
      break;
    }
  }
  _oneof_case_[0] = STATE_CHANGE_NOT_SET;
}


void StateChangeInfo::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.StateChangeInfo)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  clear_state_change();
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* StateChangeInfo::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<StateChangeInfo*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.AdminStateChange admin_state_change = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::AdminStateChange::_InternalParse;
        object = msg->mutable_admin_state_change();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.OperStateChange oper_state_change = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::OperStateChange::_InternalParse;
        object = msg->mutable_oper_state_change();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.AlarmStateChange alarm_state_change = 3;
      case 3: {
        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::AlarmStateChange::_InternalParse;
        object = msg->mutable_alarm_state_change();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.UsageStateChange usage_state_change = 4;
      case 4: {
        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::UsageStateChange::_InternalParse;
        object = msg->mutable_usage_state_change();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.StandbyStateChange standby_state_change = 5;
      case 5: {
        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::StandbyStateChange::_InternalParse;
        object = msg->mutable_standby_state_change();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool StateChangeInfo::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.StateChangeInfo)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.AdminStateChange admin_state_change = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_admin_state_change()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.OperStateChange oper_state_change = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_oper_state_change()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.AlarmStateChange alarm_state_change = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_alarm_state_change()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.UsageStateChange usage_state_change = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_usage_state_change()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.StandbyStateChange standby_state_change = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_standby_state_change()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.StateChangeInfo)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.StateChangeInfo)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void StateChangeInfo::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.StateChangeInfo)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.AdminStateChange admin_state_change = 1;
  if (has_admin_state_change()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, HasBitSetters::admin_state_change(this), output);
  }

  // .dmi.OperStateChange oper_state_change = 2;
  if (has_oper_state_change()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, HasBitSetters::oper_state_change(this), output);
  }

  // .dmi.AlarmStateChange alarm_state_change = 3;
  if (has_alarm_state_change()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, HasBitSetters::alarm_state_change(this), output);
  }

  // .dmi.UsageStateChange usage_state_change = 4;
  if (has_usage_state_change()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, HasBitSetters::usage_state_change(this), output);
  }

  // .dmi.StandbyStateChange standby_state_change = 5;
  if (has_standby_state_change()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      5, HasBitSetters::standby_state_change(this), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.StateChangeInfo)
}

::google::protobuf::uint8* StateChangeInfo::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.StateChangeInfo)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.AdminStateChange admin_state_change = 1;
  if (has_admin_state_change()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, HasBitSetters::admin_state_change(this), target);
  }

  // .dmi.OperStateChange oper_state_change = 2;
  if (has_oper_state_change()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, HasBitSetters::oper_state_change(this), target);
  }

  // .dmi.AlarmStateChange alarm_state_change = 3;
  if (has_alarm_state_change()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, HasBitSetters::alarm_state_change(this), target);
  }

  // .dmi.UsageStateChange usage_state_change = 4;
  if (has_usage_state_change()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        4, HasBitSetters::usage_state_change(this), target);
  }

  // .dmi.StandbyStateChange standby_state_change = 5;
  if (has_standby_state_change()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        5, HasBitSetters::standby_state_change(this), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.StateChangeInfo)
  return target;
}

size_t StateChangeInfo::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.StateChangeInfo)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  switch (state_change_case()) {
    // .dmi.AdminStateChange admin_state_change = 1;
    case kAdminStateChange: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *state_change_.admin_state_change_);
      break;
    }
    // .dmi.OperStateChange oper_state_change = 2;
    case kOperStateChange: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *state_change_.oper_state_change_);
      break;
    }
    // .dmi.AlarmStateChange alarm_state_change = 3;
    case kAlarmStateChange: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *state_change_.alarm_state_change_);
      break;
    }
    // .dmi.UsageStateChange usage_state_change = 4;
    case kUsageStateChange: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *state_change_.usage_state_change_);
      break;
    }
    // .dmi.StandbyStateChange standby_state_change = 5;
    case kStandbyStateChange: {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *state_change_.standby_state_change_);
      break;
    }
    case STATE_CHANGE_NOT_SET: {
      break;
    }
  }
  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void StateChangeInfo::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.StateChangeInfo)
  GOOGLE_DCHECK_NE(&from, this);
  const StateChangeInfo* source =
      ::google::protobuf::DynamicCastToGenerated<StateChangeInfo>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.StateChangeInfo)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.StateChangeInfo)
    MergeFrom(*source);
  }
}

void StateChangeInfo::MergeFrom(const StateChangeInfo& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.StateChangeInfo)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  switch (from.state_change_case()) {
    case kAdminStateChange: {
      mutable_admin_state_change()->::dmi::AdminStateChange::MergeFrom(from.admin_state_change());
      break;
    }
    case kOperStateChange: {
      mutable_oper_state_change()->::dmi::OperStateChange::MergeFrom(from.oper_state_change());
      break;
    }
    case kAlarmStateChange: {
      mutable_alarm_state_change()->::dmi::AlarmStateChange::MergeFrom(from.alarm_state_change());
      break;
    }
    case kUsageStateChange: {
      mutable_usage_state_change()->::dmi::UsageStateChange::MergeFrom(from.usage_state_change());
      break;
    }
    case kStandbyStateChange: {
      mutable_standby_state_change()->::dmi::StandbyStateChange::MergeFrom(from.standby_state_change());
      break;
    }
    case STATE_CHANGE_NOT_SET: {
      break;
    }
  }
}

void StateChangeInfo::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.StateChangeInfo)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void StateChangeInfo::CopyFrom(const StateChangeInfo& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.StateChangeInfo)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool StateChangeInfo::IsInitialized() const {
  return true;
}

void StateChangeInfo::Swap(StateChangeInfo* other) {
  if (other == this) return;
  InternalSwap(other);
}
void StateChangeInfo::InternalSwap(StateChangeInfo* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(state_change_, other->state_change_);
  swap(_oneof_case_[0], other->_oneof_case_[0]);
}

::google::protobuf::Metadata StateChangeInfo::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


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

void Event::InitAsDefaultInstance() {
  ::dmi::_Event_default_instance_._instance.get_mutable()->event_metadata_ = const_cast< ::dmi::EventMetaData*>(
      ::dmi::EventMetaData::internal_default_instance());
  ::dmi::_Event_default_instance_._instance.get_mutable()->raised_ts_ = const_cast< ::google::protobuf::Timestamp*>(
      ::google::protobuf::Timestamp::internal_default_instance());
  ::dmi::_Event_default_instance_._instance.get_mutable()->threshold_info_ = const_cast< ::dmi::ThresholdInformation*>(
      ::dmi::ThresholdInformation::internal_default_instance());
  ::dmi::_Event_default_instance_._instance.get_mutable()->state_change_info_ = const_cast< ::dmi::StateChangeInfo*>(
      ::dmi::StateChangeInfo::internal_default_instance());
}
class Event::HasBitSetters {
 public:
  static const ::dmi::EventMetaData& event_metadata(const Event* msg);
  static const ::google::protobuf::Timestamp& raised_ts(const Event* msg);
  static const ::dmi::ThresholdInformation& threshold_info(const Event* msg);
  static const ::dmi::StateChangeInfo& state_change_info(const Event* msg);
};

const ::dmi::EventMetaData&
Event::HasBitSetters::event_metadata(const Event* msg) {
  return *msg->event_metadata_;
}
const ::google::protobuf::Timestamp&
Event::HasBitSetters::raised_ts(const Event* msg) {
  return *msg->raised_ts_;
}
const ::dmi::ThresholdInformation&
Event::HasBitSetters::threshold_info(const Event* msg) {
  return *msg->threshold_info_;
}
const ::dmi::StateChangeInfo&
Event::HasBitSetters::state_change_info(const Event* msg) {
  return *msg->state_change_info_;
}
void Event::clear_raised_ts() {
  if (GetArenaNoVirtual() == nullptr && raised_ts_ != nullptr) {
    delete raised_ts_;
  }
  raised_ts_ = nullptr;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int Event::kEventMetadataFieldNumber;
const int Event::kEventIdFieldNumber;
const int Event::kRaisedTsFieldNumber;
const int Event::kThresholdInfoFieldNumber;
const int Event::kAddInfoFieldNumber;
const int Event::kStateChangeInfoFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

Event::Event()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.Event)
}
Event::Event(const Event& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  add_info_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.add_info().size() > 0) {
    add_info_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.add_info_);
  }
  if (from.has_event_metadata()) {
    event_metadata_ = new ::dmi::EventMetaData(*from.event_metadata_);
  } else {
    event_metadata_ = nullptr;
  }
  if (from.has_raised_ts()) {
    raised_ts_ = new ::google::protobuf::Timestamp(*from.raised_ts_);
  } else {
    raised_ts_ = nullptr;
  }
  if (from.has_threshold_info()) {
    threshold_info_ = new ::dmi::ThresholdInformation(*from.threshold_info_);
  } else {
    threshold_info_ = nullptr;
  }
  if (from.has_state_change_info()) {
    state_change_info_ = new ::dmi::StateChangeInfo(*from.state_change_info_);
  } else {
    state_change_info_ = nullptr;
  }
  event_id_ = from.event_id_;
  // @@protoc_insertion_point(copy_constructor:dmi.Event)
}

void Event::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  add_info_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&event_metadata_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&event_id_) -
      reinterpret_cast<char*>(&event_metadata_)) + sizeof(event_id_));
}

Event::~Event() {
  // @@protoc_insertion_point(destructor:dmi.Event)
  SharedDtor();
}

void Event::SharedDtor() {
  add_info_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete event_metadata_;
  if (this != internal_default_instance()) delete raised_ts_;
  if (this != internal_default_instance()) delete threshold_info_;
  if (this != internal_default_instance()) delete state_change_info_;
}

void Event::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const Event& Event::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
  return *internal_default_instance();
}


void Event::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.Event)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  add_info_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (GetArenaNoVirtual() == nullptr && event_metadata_ != nullptr) {
    delete event_metadata_;
  }
  event_metadata_ = nullptr;
  if (GetArenaNoVirtual() == nullptr && raised_ts_ != nullptr) {
    delete raised_ts_;
  }
  raised_ts_ = nullptr;
  if (GetArenaNoVirtual() == nullptr && threshold_info_ != nullptr) {
    delete threshold_info_;
  }
  threshold_info_ = nullptr;
  if (GetArenaNoVirtual() == nullptr && state_change_info_ != nullptr) {
    delete state_change_info_;
  }
  state_change_info_ = nullptr;
  event_id_ = 0;
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* Event::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<Event*>(object);
  ::google::protobuf::int32 size; (void)size;
  int depth; (void)depth;
  ::google::protobuf::uint32 tag;
  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
  auto ptr = begin;
  while (ptr < end) {
    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    switch (tag >> 3) {
      // .dmi.EventMetaData event_metadata = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::EventMetaData::_InternalParse;
        object = msg->mutable_event_metadata();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.EventIds event_id = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_event_id(static_cast<::dmi::EventIds>(val));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .google.protobuf.Timestamp raised_ts = 3;
      case 3: {
        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
        object = msg->mutable_raised_ts();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // .dmi.ThresholdInformation threshold_info = 4;
      case 4: {
        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::ThresholdInformation::_InternalParse;
        object = msg->mutable_threshold_info();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // string add_info = 5;
      case 5: {
        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        ctx->extra_parse_data().SetFieldName("dmi.Event.add_info");
        object = msg->mutable_add_info();
        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
          goto string_till_end;
        }
        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
        ptr += size;
        break;
      }
      // .dmi.StateChangeInfo state_change_info = 6;
      case 6: {
        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        parser_till_end = ::dmi::StateChangeInfo::_InternalParse;
        object = msg->mutable_state_change_info();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
string_till_end:
  static_cast<::std::string*>(object)->clear();
  static_cast<::std::string*>(object)->reserve(size);
  goto len_delim_till_end;
len_delim_till_end:
  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                               {parser_till_end, object}, size);
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool Event::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  // @@protoc_insertion_point(parse_start:dmi.Event)
  for (;;) {
    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // .dmi.EventMetaData event_metadata = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_event_metadata()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.EventIds event_id = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_event_id(static_cast< ::dmi::EventIds >(value));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .google.protobuf.Timestamp raised_ts = 3;
      case 3: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_raised_ts()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.ThresholdInformation threshold_info = 4;
      case 4: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_threshold_info()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // string add_info = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_add_info()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->add_info().data(), static_cast<int>(this->add_info().length()),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "dmi.Event.add_info"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.StateChangeInfo state_change_info = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_state_change_info()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, _internal_metadata_.mutable_unknown_fields()));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:dmi.Event)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.Event)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void Event::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.Event)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.EventMetaData event_metadata = 1;
  if (this->has_event_metadata()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, HasBitSetters::event_metadata(this), output);
  }

  // .dmi.EventIds event_id = 2;
  if (this->event_id() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      2, this->event_id(), output);
  }

  // .google.protobuf.Timestamp raised_ts = 3;
  if (this->has_raised_ts()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, HasBitSetters::raised_ts(this), output);
  }

  // .dmi.ThresholdInformation threshold_info = 4;
  if (this->has_threshold_info()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, HasBitSetters::threshold_info(this), output);
  }

  // string add_info = 5;
  if (this->add_info().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->add_info().data(), static_cast<int>(this->add_info().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.Event.add_info");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      5, this->add_info(), output);
  }

  // .dmi.StateChangeInfo state_change_info = 6;
  if (this->has_state_change_info()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      6, HasBitSetters::state_change_info(this), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.Event)
}

::google::protobuf::uint8* Event::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.Event)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.EventMetaData event_metadata = 1;
  if (this->has_event_metadata()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, HasBitSetters::event_metadata(this), target);
  }

  // .dmi.EventIds event_id = 2;
  if (this->event_id() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      2, this->event_id(), target);
  }

  // .google.protobuf.Timestamp raised_ts = 3;
  if (this->has_raised_ts()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        3, HasBitSetters::raised_ts(this), target);
  }

  // .dmi.ThresholdInformation threshold_info = 4;
  if (this->has_threshold_info()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        4, HasBitSetters::threshold_info(this), target);
  }

  // string add_info = 5;
  if (this->add_info().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->add_info().data(), static_cast<int>(this->add_info().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.Event.add_info");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        5, this->add_info(), target);
  }

  // .dmi.StateChangeInfo state_change_info = 6;
  if (this->has_state_change_info()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        6, HasBitSetters::state_change_info(this), target);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        _internal_metadata_.unknown_fields(), target);
  }
  // @@protoc_insertion_point(serialize_to_array_end:dmi.Event)
  return target;
}

size_t Event::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.Event)
  size_t total_size = 0;

  if (_internal_metadata_.have_unknown_fields()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        _internal_metadata_.unknown_fields());
  }
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  // string add_info = 5;
  if (this->add_info().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->add_info());
  }

  // .dmi.EventMetaData event_metadata = 1;
  if (this->has_event_metadata()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *event_metadata_);
  }

  // .google.protobuf.Timestamp raised_ts = 3;
  if (this->has_raised_ts()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *raised_ts_);
  }

  // .dmi.ThresholdInformation threshold_info = 4;
  if (this->has_threshold_info()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *threshold_info_);
  }

  // .dmi.StateChangeInfo state_change_info = 6;
  if (this->has_state_change_info()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *state_change_info_);
  }

  // .dmi.EventIds event_id = 2;
  if (this->event_id() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->event_id());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void Event::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.Event)
  GOOGLE_DCHECK_NE(&from, this);
  const Event* source =
      ::google::protobuf::DynamicCastToGenerated<Event>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Event)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Event)
    MergeFrom(*source);
  }
}

void Event::MergeFrom(const Event& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Event)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.add_info().size() > 0) {

    add_info_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.add_info_);
  }
  if (from.has_event_metadata()) {
    mutable_event_metadata()->::dmi::EventMetaData::MergeFrom(from.event_metadata());
  }
  if (from.has_raised_ts()) {
    mutable_raised_ts()->::google::protobuf::Timestamp::MergeFrom(from.raised_ts());
  }
  if (from.has_threshold_info()) {
    mutable_threshold_info()->::dmi::ThresholdInformation::MergeFrom(from.threshold_info());
  }
  if (from.has_state_change_info()) {
    mutable_state_change_info()->::dmi::StateChangeInfo::MergeFrom(from.state_change_info());
  }
  if (from.event_id() != 0) {
    set_event_id(from.event_id());
  }
}

void Event::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.Event)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void Event::CopyFrom(const Event& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Event)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool Event::IsInitialized() const {
  return true;
}

void Event::Swap(Event* other) {
  if (other == this) return;
  InternalSwap(other);
}
void Event::InternalSwap(Event* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  add_info_.Swap(&other->add_info_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(event_metadata_, other->event_metadata_);
  swap(raised_ts_, other->raised_ts_);
  swap(threshold_info_, other->threshold_info_);
  swap(state_change_info_, other->state_change_info_);
  swap(event_id_, other->event_id_);
}

::google::protobuf::Metadata Event::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
}


// @@protoc_insertion_point(namespace_scope)
}  // namespace dmi
namespace google {
namespace protobuf {
template<> PROTOBUF_NOINLINE ::dmi::ValueType* Arena::CreateMaybeMessage< ::dmi::ValueType >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::ValueType >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::WaterMarks* Arena::CreateMaybeMessage< ::dmi::WaterMarks >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::WaterMarks >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::Thresholds* Arena::CreateMaybeMessage< ::dmi::Thresholds >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::Thresholds >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::ThresholdInformation* Arena::CreateMaybeMessage< ::dmi::ThresholdInformation >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::ThresholdInformation >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::EventCfg* Arena::CreateMaybeMessage< ::dmi::EventCfg >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::EventCfg >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::EventsCfg* Arena::CreateMaybeMessage< ::dmi::EventsCfg >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::EventsCfg >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::ListEventsResponse* Arena::CreateMaybeMessage< ::dmi::ListEventsResponse >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::ListEventsResponse >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::EventsConfigurationRequest* Arena::CreateMaybeMessage< ::dmi::EventsConfigurationRequest >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::EventsConfigurationRequest >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::EventsConfigurationResponse* Arena::CreateMaybeMessage< ::dmi::EventsConfigurationResponse >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::EventsConfigurationResponse >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::EventMetaData* Arena::CreateMaybeMessage< ::dmi::EventMetaData >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::EventMetaData >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::AdminStateChange* Arena::CreateMaybeMessage< ::dmi::AdminStateChange >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::AdminStateChange >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::OperStateChange* Arena::CreateMaybeMessage< ::dmi::OperStateChange >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::OperStateChange >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::AlarmStateChange* Arena::CreateMaybeMessage< ::dmi::AlarmStateChange >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::AlarmStateChange >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::UsageStateChange* Arena::CreateMaybeMessage< ::dmi::UsageStateChange >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::UsageStateChange >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::StandbyStateChange* Arena::CreateMaybeMessage< ::dmi::StandbyStateChange >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::StandbyStateChange >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::StateChangeInfo* Arena::CreateMaybeMessage< ::dmi::StateChangeInfo >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::StateChangeInfo >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::Event* Arena::CreateMaybeMessage< ::dmi::Event >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::Event >(arena);
}
}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)
#include <google/protobuf/port_undef.inc>
