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

#ifndef PROTOBUF_INCLUDED_dmi_2fhw_5fmanagement_5fservice_2eproto
#define PROTOBUF_INCLUDED_dmi_2fhw_5fmanagement_5fservice_2eproto

#include <limits>
#include <string>

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

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

// Internal implementation detail -- do not use these members.
struct TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto {
  static const ::google::protobuf::internal::ParseTableField entries[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::ParseTable schema[25]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::FieldMetadata field_metadata[];
  static const ::google::protobuf::internal::SerializationTable serialization_table[];
  static const ::google::protobuf::uint32 offsets[];
};
void AddDescriptors_dmi_2fhw_5fmanagement_5fservice_2eproto();
namespace dmi {
class EntitiesLogLevel;
class EntitiesLogLevelDefaultTypeInternal;
extern EntitiesLogLevelDefaultTypeInternal _EntitiesLogLevel_default_instance_;
class GetLogLevelRequest;
class GetLogLevelRequestDefaultTypeInternal;
extern GetLogLevelRequestDefaultTypeInternal _GetLogLevelRequest_default_instance_;
class GetLogLevelResponse;
class GetLogLevelResponseDefaultTypeInternal;
extern GetLogLevelResponseDefaultTypeInternal _GetLogLevelResponse_default_instance_;
class GetLoggableEntitiesRequest;
class GetLoggableEntitiesRequestDefaultTypeInternal;
extern GetLoggableEntitiesRequestDefaultTypeInternal _GetLoggableEntitiesRequest_default_instance_;
class GetLoggingEndpointResponse;
class GetLoggingEndpointResponseDefaultTypeInternal;
extern GetLoggingEndpointResponseDefaultTypeInternal _GetLoggingEndpointResponse_default_instance_;
class GetMsgBusEndpointResponse;
class GetMsgBusEndpointResponseDefaultTypeInternal;
extern GetMsgBusEndpointResponseDefaultTypeInternal _GetMsgBusEndpointResponse_default_instance_;
class HWComponentInfoGetRequest;
class HWComponentInfoGetRequestDefaultTypeInternal;
extern HWComponentInfoGetRequestDefaultTypeInternal _HWComponentInfoGetRequest_default_instance_;
class HWComponentInfoGetResponse;
class HWComponentInfoGetResponseDefaultTypeInternal;
extern HWComponentInfoGetResponseDefaultTypeInternal _HWComponentInfoGetResponse_default_instance_;
class HWComponentInfoSetRequest;
class HWComponentInfoSetRequestDefaultTypeInternal;
extern HWComponentInfoSetRequestDefaultTypeInternal _HWComponentInfoSetRequest_default_instance_;
class HWComponentInfoSetResponse;
class HWComponentInfoSetResponseDefaultTypeInternal;
extern HWComponentInfoSetResponseDefaultTypeInternal _HWComponentInfoSetResponse_default_instance_;
class Heartbeat;
class HeartbeatDefaultTypeInternal;
extern HeartbeatDefaultTypeInternal _Heartbeat_default_instance_;
class ManagedDeviceInfo;
class ManagedDeviceInfoDefaultTypeInternal;
extern ManagedDeviceInfoDefaultTypeInternal _ManagedDeviceInfo_default_instance_;
class ManagedDevicesResponse;
class ManagedDevicesResponseDefaultTypeInternal;
extern ManagedDevicesResponseDefaultTypeInternal _ManagedDevicesResponse_default_instance_;
class PhysicalInventoryRequest;
class PhysicalInventoryRequestDefaultTypeInternal;
extern PhysicalInventoryRequestDefaultTypeInternal _PhysicalInventoryRequest_default_instance_;
class PhysicalInventoryResponse;
class PhysicalInventoryResponseDefaultTypeInternal;
extern PhysicalInventoryResponseDefaultTypeInternal _PhysicalInventoryResponse_default_instance_;
class RebootDeviceRequest;
class RebootDeviceRequestDefaultTypeInternal;
extern RebootDeviceRequestDefaultTypeInternal _RebootDeviceRequest_default_instance_;
class RebootDeviceResponse;
class RebootDeviceResponseDefaultTypeInternal;
extern RebootDeviceResponseDefaultTypeInternal _RebootDeviceResponse_default_instance_;
class SetLogLevelRequest;
class SetLogLevelRequestDefaultTypeInternal;
extern SetLogLevelRequestDefaultTypeInternal _SetLogLevelRequest_default_instance_;
class SetLogLevelResponse;
class SetLogLevelResponseDefaultTypeInternal;
extern SetLogLevelResponseDefaultTypeInternal _SetLogLevelResponse_default_instance_;
class SetLoggingEndpointRequest;
class SetLoggingEndpointRequestDefaultTypeInternal;
extern SetLoggingEndpointRequestDefaultTypeInternal _SetLoggingEndpointRequest_default_instance_;
class SetMsgBusEndpointRequest;
class SetMsgBusEndpointRequestDefaultTypeInternal;
extern SetMsgBusEndpointRequestDefaultTypeInternal _SetMsgBusEndpointRequest_default_instance_;
class SetRemoteEndpointResponse;
class SetRemoteEndpointResponseDefaultTypeInternal;
extern SetRemoteEndpointResponseDefaultTypeInternal _SetRemoteEndpointResponse_default_instance_;
class StartManagingDeviceResponse;
class StartManagingDeviceResponseDefaultTypeInternal;
extern StartManagingDeviceResponseDefaultTypeInternal _StartManagingDeviceResponse_default_instance_;
class StopManagingDeviceRequest;
class StopManagingDeviceRequestDefaultTypeInternal;
extern StopManagingDeviceRequestDefaultTypeInternal _StopManagingDeviceRequest_default_instance_;
class StopManagingDeviceResponse;
class StopManagingDeviceResponseDefaultTypeInternal;
extern StopManagingDeviceResponseDefaultTypeInternal _StopManagingDeviceResponse_default_instance_;
}  // namespace dmi
namespace google {
namespace protobuf {
template<> ::dmi::EntitiesLogLevel* Arena::CreateMaybeMessage<::dmi::EntitiesLogLevel>(Arena*);
template<> ::dmi::GetLogLevelRequest* Arena::CreateMaybeMessage<::dmi::GetLogLevelRequest>(Arena*);
template<> ::dmi::GetLogLevelResponse* Arena::CreateMaybeMessage<::dmi::GetLogLevelResponse>(Arena*);
template<> ::dmi::GetLoggableEntitiesRequest* Arena::CreateMaybeMessage<::dmi::GetLoggableEntitiesRequest>(Arena*);
template<> ::dmi::GetLoggingEndpointResponse* Arena::CreateMaybeMessage<::dmi::GetLoggingEndpointResponse>(Arena*);
template<> ::dmi::GetMsgBusEndpointResponse* Arena::CreateMaybeMessage<::dmi::GetMsgBusEndpointResponse>(Arena*);
template<> ::dmi::HWComponentInfoGetRequest* Arena::CreateMaybeMessage<::dmi::HWComponentInfoGetRequest>(Arena*);
template<> ::dmi::HWComponentInfoGetResponse* Arena::CreateMaybeMessage<::dmi::HWComponentInfoGetResponse>(Arena*);
template<> ::dmi::HWComponentInfoSetRequest* Arena::CreateMaybeMessage<::dmi::HWComponentInfoSetRequest>(Arena*);
template<> ::dmi::HWComponentInfoSetResponse* Arena::CreateMaybeMessage<::dmi::HWComponentInfoSetResponse>(Arena*);
template<> ::dmi::Heartbeat* Arena::CreateMaybeMessage<::dmi::Heartbeat>(Arena*);
template<> ::dmi::ManagedDeviceInfo* Arena::CreateMaybeMessage<::dmi::ManagedDeviceInfo>(Arena*);
template<> ::dmi::ManagedDevicesResponse* Arena::CreateMaybeMessage<::dmi::ManagedDevicesResponse>(Arena*);
template<> ::dmi::PhysicalInventoryRequest* Arena::CreateMaybeMessage<::dmi::PhysicalInventoryRequest>(Arena*);
template<> ::dmi::PhysicalInventoryResponse* Arena::CreateMaybeMessage<::dmi::PhysicalInventoryResponse>(Arena*);
template<> ::dmi::RebootDeviceRequest* Arena::CreateMaybeMessage<::dmi::RebootDeviceRequest>(Arena*);
template<> ::dmi::RebootDeviceResponse* Arena::CreateMaybeMessage<::dmi::RebootDeviceResponse>(Arena*);
template<> ::dmi::SetLogLevelRequest* Arena::CreateMaybeMessage<::dmi::SetLogLevelRequest>(Arena*);
template<> ::dmi::SetLogLevelResponse* Arena::CreateMaybeMessage<::dmi::SetLogLevelResponse>(Arena*);
template<> ::dmi::SetLoggingEndpointRequest* Arena::CreateMaybeMessage<::dmi::SetLoggingEndpointRequest>(Arena*);
template<> ::dmi::SetMsgBusEndpointRequest* Arena::CreateMaybeMessage<::dmi::SetMsgBusEndpointRequest>(Arena*);
template<> ::dmi::SetRemoteEndpointResponse* Arena::CreateMaybeMessage<::dmi::SetRemoteEndpointResponse>(Arena*);
template<> ::dmi::StartManagingDeviceResponse* Arena::CreateMaybeMessage<::dmi::StartManagingDeviceResponse>(Arena*);
template<> ::dmi::StopManagingDeviceRequest* Arena::CreateMaybeMessage<::dmi::StopManagingDeviceRequest>(Arena*);
template<> ::dmi::StopManagingDeviceResponse* Arena::CreateMaybeMessage<::dmi::StopManagingDeviceResponse>(Arena*);
}  // namespace protobuf
}  // namespace google
namespace dmi {

enum PhysicalInventoryResponse_Reason {
  PhysicalInventoryResponse_Reason_UNDEFINED_REASON = 0,
  PhysicalInventoryResponse_Reason_UNKNOWN_DEVICE = 1,
  PhysicalInventoryResponse_Reason_INTERNAL_ERROR = 2,
  PhysicalInventoryResponse_Reason_DEVICE_UNREACHABLE = 3,
  PhysicalInventoryResponse_Reason_PhysicalInventoryResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  PhysicalInventoryResponse_Reason_PhysicalInventoryResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool PhysicalInventoryResponse_Reason_IsValid(int value);
const PhysicalInventoryResponse_Reason PhysicalInventoryResponse_Reason_Reason_MIN = PhysicalInventoryResponse_Reason_UNDEFINED_REASON;
const PhysicalInventoryResponse_Reason PhysicalInventoryResponse_Reason_Reason_MAX = PhysicalInventoryResponse_Reason_DEVICE_UNREACHABLE;
const int PhysicalInventoryResponse_Reason_Reason_ARRAYSIZE = PhysicalInventoryResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* PhysicalInventoryResponse_Reason_descriptor();
inline const ::std::string& PhysicalInventoryResponse_Reason_Name(PhysicalInventoryResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    PhysicalInventoryResponse_Reason_descriptor(), value);
}
inline bool PhysicalInventoryResponse_Reason_Parse(
    const ::std::string& name, PhysicalInventoryResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<PhysicalInventoryResponse_Reason>(
    PhysicalInventoryResponse_Reason_descriptor(), name, value);
}
enum HWComponentInfoGetResponse_Reason {
  HWComponentInfoGetResponse_Reason_UNDEFINED_REASON = 0,
  HWComponentInfoGetResponse_Reason_UNKNOWN_DEVICE = 1,
  HWComponentInfoGetResponse_Reason_UNKNOWN_COMPONENT = 2,
  HWComponentInfoGetResponse_Reason_INTERNAL_ERROR = 3,
  HWComponentInfoGetResponse_Reason_DEVICE_UNREACHABLE = 4,
  HWComponentInfoGetResponse_Reason_HWComponentInfoGetResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  HWComponentInfoGetResponse_Reason_HWComponentInfoGetResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool HWComponentInfoGetResponse_Reason_IsValid(int value);
const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse_Reason_Reason_MIN = HWComponentInfoGetResponse_Reason_UNDEFINED_REASON;
const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse_Reason_Reason_MAX = HWComponentInfoGetResponse_Reason_DEVICE_UNREACHABLE;
const int HWComponentInfoGetResponse_Reason_Reason_ARRAYSIZE = HWComponentInfoGetResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* HWComponentInfoGetResponse_Reason_descriptor();
inline const ::std::string& HWComponentInfoGetResponse_Reason_Name(HWComponentInfoGetResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    HWComponentInfoGetResponse_Reason_descriptor(), value);
}
inline bool HWComponentInfoGetResponse_Reason_Parse(
    const ::std::string& name, HWComponentInfoGetResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<HWComponentInfoGetResponse_Reason>(
    HWComponentInfoGetResponse_Reason_descriptor(), name, value);
}
enum HWComponentInfoSetResponse_Reason {
  HWComponentInfoSetResponse_Reason_UNDEFINED_REASON = 0,
  HWComponentInfoSetResponse_Reason_UNKNOWN_DEVICE = 1,
  HWComponentInfoSetResponse_Reason_UNKNOWN_COMPONENT = 2,
  HWComponentInfoSetResponse_Reason_INVALID_PARAMS = 3,
  HWComponentInfoSetResponse_Reason_INTERNAL_ERROR = 4,
  HWComponentInfoSetResponse_Reason_DEVICE_UNREACHABLE = 5,
  HWComponentInfoSetResponse_Reason_HWComponentInfoSetResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  HWComponentInfoSetResponse_Reason_HWComponentInfoSetResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool HWComponentInfoSetResponse_Reason_IsValid(int value);
const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse_Reason_Reason_MIN = HWComponentInfoSetResponse_Reason_UNDEFINED_REASON;
const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse_Reason_Reason_MAX = HWComponentInfoSetResponse_Reason_DEVICE_UNREACHABLE;
const int HWComponentInfoSetResponse_Reason_Reason_ARRAYSIZE = HWComponentInfoSetResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* HWComponentInfoSetResponse_Reason_descriptor();
inline const ::std::string& HWComponentInfoSetResponse_Reason_Name(HWComponentInfoSetResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    HWComponentInfoSetResponse_Reason_descriptor(), value);
}
inline bool HWComponentInfoSetResponse_Reason_Parse(
    const ::std::string& name, HWComponentInfoSetResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<HWComponentInfoSetResponse_Reason>(
    HWComponentInfoSetResponse_Reason_descriptor(), name, value);
}
enum StartManagingDeviceResponse_Reason {
  StartManagingDeviceResponse_Reason_UNDEFINED_REASON = 0,
  StartManagingDeviceResponse_Reason_DEVICE_ALREADY_MANAGED = 1,
  StartManagingDeviceResponse_Reason_OPERATION_ALREADY_IN_PROGRESS = 2,
  StartManagingDeviceResponse_Reason_INVALID_PARAMS = 3,
  StartManagingDeviceResponse_Reason_INTERNAL_ERROR = 4,
  StartManagingDeviceResponse_Reason_StartManagingDeviceResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  StartManagingDeviceResponse_Reason_StartManagingDeviceResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool StartManagingDeviceResponse_Reason_IsValid(int value);
const StartManagingDeviceResponse_Reason StartManagingDeviceResponse_Reason_Reason_MIN = StartManagingDeviceResponse_Reason_UNDEFINED_REASON;
const StartManagingDeviceResponse_Reason StartManagingDeviceResponse_Reason_Reason_MAX = StartManagingDeviceResponse_Reason_INTERNAL_ERROR;
const int StartManagingDeviceResponse_Reason_Reason_ARRAYSIZE = StartManagingDeviceResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* StartManagingDeviceResponse_Reason_descriptor();
inline const ::std::string& StartManagingDeviceResponse_Reason_Name(StartManagingDeviceResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    StartManagingDeviceResponse_Reason_descriptor(), value);
}
inline bool StartManagingDeviceResponse_Reason_Parse(
    const ::std::string& name, StartManagingDeviceResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<StartManagingDeviceResponse_Reason>(
    StartManagingDeviceResponse_Reason_descriptor(), name, value);
}
enum StopManagingDeviceResponse_Reason {
  StopManagingDeviceResponse_Reason_UNDEFINED_REASON = 0,
  StopManagingDeviceResponse_Reason_UNKNOWN_DEVICE = 1,
  StopManagingDeviceResponse_Reason_StopManagingDeviceResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  StopManagingDeviceResponse_Reason_StopManagingDeviceResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool StopManagingDeviceResponse_Reason_IsValid(int value);
const StopManagingDeviceResponse_Reason StopManagingDeviceResponse_Reason_Reason_MIN = StopManagingDeviceResponse_Reason_UNDEFINED_REASON;
const StopManagingDeviceResponse_Reason StopManagingDeviceResponse_Reason_Reason_MAX = StopManagingDeviceResponse_Reason_UNKNOWN_DEVICE;
const int StopManagingDeviceResponse_Reason_Reason_ARRAYSIZE = StopManagingDeviceResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* StopManagingDeviceResponse_Reason_descriptor();
inline const ::std::string& StopManagingDeviceResponse_Reason_Name(StopManagingDeviceResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    StopManagingDeviceResponse_Reason_descriptor(), value);
}
inline bool StopManagingDeviceResponse_Reason_Parse(
    const ::std::string& name, StopManagingDeviceResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<StopManagingDeviceResponse_Reason>(
    StopManagingDeviceResponse_Reason_descriptor(), name, value);
}
enum ManagedDevicesResponse_Reason {
  ManagedDevicesResponse_Reason_UNDEFINED_REASON = 0,
  ManagedDevicesResponse_Reason_INTERNAL_ERROR = 1,
  ManagedDevicesResponse_Reason_ManagedDevicesResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ManagedDevicesResponse_Reason_ManagedDevicesResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ManagedDevicesResponse_Reason_IsValid(int value);
const ManagedDevicesResponse_Reason ManagedDevicesResponse_Reason_Reason_MIN = ManagedDevicesResponse_Reason_UNDEFINED_REASON;
const ManagedDevicesResponse_Reason ManagedDevicesResponse_Reason_Reason_MAX = ManagedDevicesResponse_Reason_INTERNAL_ERROR;
const int ManagedDevicesResponse_Reason_Reason_ARRAYSIZE = ManagedDevicesResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* ManagedDevicesResponse_Reason_descriptor();
inline const ::std::string& ManagedDevicesResponse_Reason_Name(ManagedDevicesResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    ManagedDevicesResponse_Reason_descriptor(), value);
}
inline bool ManagedDevicesResponse_Reason_Parse(
    const ::std::string& name, ManagedDevicesResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ManagedDevicesResponse_Reason>(
    ManagedDevicesResponse_Reason_descriptor(), name, value);
}
enum SetRemoteEndpointResponse_Reason {
  SetRemoteEndpointResponse_Reason_UNDEFINED_REASON = 0,
  SetRemoteEndpointResponse_Reason_UNKNOWN_DEVICE = 1,
  SetRemoteEndpointResponse_Reason_INTERNAL_ERROR = 2,
  SetRemoteEndpointResponse_Reason_LOGGING_ENDPOINT_ERROR = 3,
  SetRemoteEndpointResponse_Reason_LOGGING_ENDPOINT_PROTOCOL_ERROR = 4,
  SetRemoteEndpointResponse_Reason_MSGBUS_ENDPOINT_ERROR = 5,
  SetRemoteEndpointResponse_Reason_DEVICE_UNREACHABLE = 6,
  SetRemoteEndpointResponse_Reason_SetRemoteEndpointResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  SetRemoteEndpointResponse_Reason_SetRemoteEndpointResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool SetRemoteEndpointResponse_Reason_IsValid(int value);
const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse_Reason_Reason_MIN = SetRemoteEndpointResponse_Reason_UNDEFINED_REASON;
const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse_Reason_Reason_MAX = SetRemoteEndpointResponse_Reason_DEVICE_UNREACHABLE;
const int SetRemoteEndpointResponse_Reason_Reason_ARRAYSIZE = SetRemoteEndpointResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* SetRemoteEndpointResponse_Reason_descriptor();
inline const ::std::string& SetRemoteEndpointResponse_Reason_Name(SetRemoteEndpointResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    SetRemoteEndpointResponse_Reason_descriptor(), value);
}
inline bool SetRemoteEndpointResponse_Reason_Parse(
    const ::std::string& name, SetRemoteEndpointResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<SetRemoteEndpointResponse_Reason>(
    SetRemoteEndpointResponse_Reason_descriptor(), name, value);
}
enum GetLoggingEndpointResponse_Reason {
  GetLoggingEndpointResponse_Reason_UNDEFINED_REASON = 0,
  GetLoggingEndpointResponse_Reason_UNKNOWN_DEVICE = 1,
  GetLoggingEndpointResponse_Reason_INTERNAL_ERROR = 2,
  GetLoggingEndpointResponse_Reason_DEVICE_UNREACHABLE = 3,
  GetLoggingEndpointResponse_Reason_GetLoggingEndpointResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  GetLoggingEndpointResponse_Reason_GetLoggingEndpointResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool GetLoggingEndpointResponse_Reason_IsValid(int value);
const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse_Reason_Reason_MIN = GetLoggingEndpointResponse_Reason_UNDEFINED_REASON;
const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse_Reason_Reason_MAX = GetLoggingEndpointResponse_Reason_DEVICE_UNREACHABLE;
const int GetLoggingEndpointResponse_Reason_Reason_ARRAYSIZE = GetLoggingEndpointResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* GetLoggingEndpointResponse_Reason_descriptor();
inline const ::std::string& GetLoggingEndpointResponse_Reason_Name(GetLoggingEndpointResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    GetLoggingEndpointResponse_Reason_descriptor(), value);
}
inline bool GetLoggingEndpointResponse_Reason_Parse(
    const ::std::string& name, GetLoggingEndpointResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<GetLoggingEndpointResponse_Reason>(
    GetLoggingEndpointResponse_Reason_descriptor(), name, value);
}
enum GetMsgBusEndpointResponse_Reason {
  GetMsgBusEndpointResponse_Reason_UNDEFINED_REASON = 0,
  GetMsgBusEndpointResponse_Reason_INTERNAL_ERROR = 1,
  GetMsgBusEndpointResponse_Reason_DEVICE_UNREACHABLE = 2,
  GetMsgBusEndpointResponse_Reason_GetMsgBusEndpointResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  GetMsgBusEndpointResponse_Reason_GetMsgBusEndpointResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool GetMsgBusEndpointResponse_Reason_IsValid(int value);
const GetMsgBusEndpointResponse_Reason GetMsgBusEndpointResponse_Reason_Reason_MIN = GetMsgBusEndpointResponse_Reason_UNDEFINED_REASON;
const GetMsgBusEndpointResponse_Reason GetMsgBusEndpointResponse_Reason_Reason_MAX = GetMsgBusEndpointResponse_Reason_DEVICE_UNREACHABLE;
const int GetMsgBusEndpointResponse_Reason_Reason_ARRAYSIZE = GetMsgBusEndpointResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* GetMsgBusEndpointResponse_Reason_descriptor();
inline const ::std::string& GetMsgBusEndpointResponse_Reason_Name(GetMsgBusEndpointResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    GetMsgBusEndpointResponse_Reason_descriptor(), value);
}
inline bool GetMsgBusEndpointResponse_Reason_Parse(
    const ::std::string& name, GetMsgBusEndpointResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<GetMsgBusEndpointResponse_Reason>(
    GetMsgBusEndpointResponse_Reason_descriptor(), name, value);
}
enum SetLogLevelResponse_Reason {
  SetLogLevelResponse_Reason_UNDEFINED_REASON = 0,
  SetLogLevelResponse_Reason_UNKNOWN_DEVICE = 1,
  SetLogLevelResponse_Reason_INTERNAL_ERROR = 2,
  SetLogLevelResponse_Reason_UNKNOWN_LOG_ENTITY = 3,
  SetLogLevelResponse_Reason_DEVICE_UNREACHABLE = 4,
  SetLogLevelResponse_Reason_SetLogLevelResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  SetLogLevelResponse_Reason_SetLogLevelResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool SetLogLevelResponse_Reason_IsValid(int value);
const SetLogLevelResponse_Reason SetLogLevelResponse_Reason_Reason_MIN = SetLogLevelResponse_Reason_UNDEFINED_REASON;
const SetLogLevelResponse_Reason SetLogLevelResponse_Reason_Reason_MAX = SetLogLevelResponse_Reason_DEVICE_UNREACHABLE;
const int SetLogLevelResponse_Reason_Reason_ARRAYSIZE = SetLogLevelResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* SetLogLevelResponse_Reason_descriptor();
inline const ::std::string& SetLogLevelResponse_Reason_Name(SetLogLevelResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    SetLogLevelResponse_Reason_descriptor(), value);
}
inline bool SetLogLevelResponse_Reason_Parse(
    const ::std::string& name, SetLogLevelResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<SetLogLevelResponse_Reason>(
    SetLogLevelResponse_Reason_descriptor(), name, value);
}
enum GetLogLevelResponse_Reason {
  GetLogLevelResponse_Reason_UNDEFINED_REASON = 0,
  GetLogLevelResponse_Reason_UNKNOWN_DEVICE = 1,
  GetLogLevelResponse_Reason_INTERNAL_ERROR = 2,
  GetLogLevelResponse_Reason_UNKNOWN_LOG_ENTITY = 3,
  GetLogLevelResponse_Reason_DEVICE_UNREACHABLE = 4,
  GetLogLevelResponse_Reason_GetLogLevelResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  GetLogLevelResponse_Reason_GetLogLevelResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool GetLogLevelResponse_Reason_IsValid(int value);
const GetLogLevelResponse_Reason GetLogLevelResponse_Reason_Reason_MIN = GetLogLevelResponse_Reason_UNDEFINED_REASON;
const GetLogLevelResponse_Reason GetLogLevelResponse_Reason_Reason_MAX = GetLogLevelResponse_Reason_DEVICE_UNREACHABLE;
const int GetLogLevelResponse_Reason_Reason_ARRAYSIZE = GetLogLevelResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* GetLogLevelResponse_Reason_descriptor();
inline const ::std::string& GetLogLevelResponse_Reason_Name(GetLogLevelResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    GetLogLevelResponse_Reason_descriptor(), value);
}
inline bool GetLogLevelResponse_Reason_Parse(
    const ::std::string& name, GetLogLevelResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<GetLogLevelResponse_Reason>(
    GetLogLevelResponse_Reason_descriptor(), name, value);
}
enum RebootDeviceResponse_Reason {
  RebootDeviceResponse_Reason_UNDEFINED_REASON = 0,
  RebootDeviceResponse_Reason_UNKNOWN_DEVICE = 1,
  RebootDeviceResponse_Reason_INTERNAL_ERROR = 2,
  RebootDeviceResponse_Reason_DEVICE_UNREACHABLE = 3,
  RebootDeviceResponse_Reason_RebootDeviceResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  RebootDeviceResponse_Reason_RebootDeviceResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool RebootDeviceResponse_Reason_IsValid(int value);
const RebootDeviceResponse_Reason RebootDeviceResponse_Reason_Reason_MIN = RebootDeviceResponse_Reason_UNDEFINED_REASON;
const RebootDeviceResponse_Reason RebootDeviceResponse_Reason_Reason_MAX = RebootDeviceResponse_Reason_DEVICE_UNREACHABLE;
const int RebootDeviceResponse_Reason_Reason_ARRAYSIZE = RebootDeviceResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* RebootDeviceResponse_Reason_descriptor();
inline const ::std::string& RebootDeviceResponse_Reason_Name(RebootDeviceResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    RebootDeviceResponse_Reason_descriptor(), value);
}
inline bool RebootDeviceResponse_Reason_Parse(
    const ::std::string& name, RebootDeviceResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<RebootDeviceResponse_Reason>(
    RebootDeviceResponse_Reason_descriptor(), name, value);
}
// ===================================================================

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

  PhysicalInventoryRequest(const PhysicalInventoryRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::Uuid* device_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  PhysicalInventoryResponse(const PhysicalInventoryResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef PhysicalInventoryResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    PhysicalInventoryResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    PhysicalInventoryResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    PhysicalInventoryResponse_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    PhysicalInventoryResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return PhysicalInventoryResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    PhysicalInventoryResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    PhysicalInventoryResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    PhysicalInventoryResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return PhysicalInventoryResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return PhysicalInventoryResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return PhysicalInventoryResponse_Reason_Parse(name, value);
  }

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

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

  // .dmi.Hardware inventory = 3;
  bool has_inventory() const;
  void clear_inventory();
  static const int kInventoryFieldNumber = 3;
  const ::dmi::Hardware& inventory() const;
  ::dmi::Hardware* release_inventory();
  ::dmi::Hardware* mutable_inventory();
  void set_allocated_inventory(::dmi::Hardware* inventory);

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  ::dmi::Hardware* inventory_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  HWComponentInfoGetRequest(const HWComponentInfoGetRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  HWComponentInfoGetResponse(const HWComponentInfoGetResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef HWComponentInfoGetResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    HWComponentInfoGetResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    HWComponentInfoGetResponse_Reason_UNKNOWN_DEVICE;
  static const Reason UNKNOWN_COMPONENT =
    HWComponentInfoGetResponse_Reason_UNKNOWN_COMPONENT;
  static const Reason INTERNAL_ERROR =
    HWComponentInfoGetResponse_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    HWComponentInfoGetResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return HWComponentInfoGetResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    HWComponentInfoGetResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    HWComponentInfoGetResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    HWComponentInfoGetResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return HWComponentInfoGetResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return HWComponentInfoGetResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return HWComponentInfoGetResponse_Reason_Parse(name, value);
  }

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

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

  // .dmi.Component component = 3;
  bool has_component() const;
  void clear_component();
  static const int kComponentFieldNumber = 3;
  const ::dmi::Component& component() const;
  ::dmi::Component* release_component();
  ::dmi::Component* mutable_component();
  void set_allocated_component(::dmi::Component* component);

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  ::dmi::Component* component_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  HWComponentInfoSetRequest(const HWComponentInfoSetRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  HWComponentInfoSetResponse(const HWComponentInfoSetResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef HWComponentInfoSetResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    HWComponentInfoSetResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    HWComponentInfoSetResponse_Reason_UNKNOWN_DEVICE;
  static const Reason UNKNOWN_COMPONENT =
    HWComponentInfoSetResponse_Reason_UNKNOWN_COMPONENT;
  static const Reason INVALID_PARAMS =
    HWComponentInfoSetResponse_Reason_INVALID_PARAMS;
  static const Reason INTERNAL_ERROR =
    HWComponentInfoSetResponse_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    HWComponentInfoSetResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return HWComponentInfoSetResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    HWComponentInfoSetResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    HWComponentInfoSetResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    HWComponentInfoSetResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return HWComponentInfoSetResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return HWComponentInfoSetResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return HWComponentInfoSetResponse_Reason_Parse(name, value);
  }

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

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

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

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

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

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

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

  StartManagingDeviceResponse(const StartManagingDeviceResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef StartManagingDeviceResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    StartManagingDeviceResponse_Reason_UNDEFINED_REASON;
  static const Reason DEVICE_ALREADY_MANAGED =
    StartManagingDeviceResponse_Reason_DEVICE_ALREADY_MANAGED;
  static const Reason OPERATION_ALREADY_IN_PROGRESS =
    StartManagingDeviceResponse_Reason_OPERATION_ALREADY_IN_PROGRESS;
  static const Reason INVALID_PARAMS =
    StartManagingDeviceResponse_Reason_INVALID_PARAMS;
  static const Reason INTERNAL_ERROR =
    StartManagingDeviceResponse_Reason_INTERNAL_ERROR;
  static inline bool Reason_IsValid(int value) {
    return StartManagingDeviceResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    StartManagingDeviceResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    StartManagingDeviceResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    StartManagingDeviceResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return StartManagingDeviceResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return StartManagingDeviceResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return StartManagingDeviceResponse_Reason_Parse(name, value);
  }

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

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

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

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  ::dmi::Uuid* device_uuid_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  StopManagingDeviceRequest(const StopManagingDeviceRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

  // string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  StopManagingDeviceResponse(const StopManagingDeviceResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef StopManagingDeviceResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    StopManagingDeviceResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    StopManagingDeviceResponse_Reason_UNKNOWN_DEVICE;
  static inline bool Reason_IsValid(int value) {
    return StopManagingDeviceResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    StopManagingDeviceResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    StopManagingDeviceResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    StopManagingDeviceResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return StopManagingDeviceResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return StopManagingDeviceResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return StopManagingDeviceResponse_Reason_Parse(name, value);
  }

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

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

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

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

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

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

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

  ManagedDeviceInfo(const ManagedDeviceInfo& from);

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

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

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

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

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

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

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

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

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

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

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

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

  // .dmi.ModifiableComponent info = 1;
  bool has_info() const;
  void clear_info();
  static const int kInfoFieldNumber = 1;
  const ::dmi::ModifiableComponent& info() const;
  ::dmi::ModifiableComponent* release_info();
  ::dmi::ModifiableComponent* mutable_info();
  void set_allocated_info(::dmi::ModifiableComponent* info);

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::ModifiableComponent* info_;
  ::dmi::Uuid* device_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  ManagedDevicesResponse(const ManagedDevicesResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef ManagedDevicesResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    ManagedDevicesResponse_Reason_UNDEFINED_REASON;
  static const Reason INTERNAL_ERROR =
    ManagedDevicesResponse_Reason_INTERNAL_ERROR;
  static inline bool Reason_IsValid(int value) {
    return ManagedDevicesResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    ManagedDevicesResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    ManagedDevicesResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    ManagedDevicesResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return ManagedDevicesResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return ManagedDevicesResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return ManagedDevicesResponse_Reason_Parse(name, value);
  }

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

  // repeated .dmi.ManagedDeviceInfo devices = 3;
  int devices_size() const;
  void clear_devices();
  static const int kDevicesFieldNumber = 3;
  ::dmi::ManagedDeviceInfo* mutable_devices(int index);
  ::google::protobuf::RepeatedPtrField< ::dmi::ManagedDeviceInfo >*
      mutable_devices();
  const ::dmi::ManagedDeviceInfo& devices(int index) const;
  ::dmi::ManagedDeviceInfo* add_devices();
  const ::google::protobuf::RepeatedPtrField< ::dmi::ManagedDeviceInfo >&
      devices() const;

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::RepeatedPtrField< ::dmi::ManagedDeviceInfo > devices_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  SetLoggingEndpointRequest(const SetLoggingEndpointRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

  // string logging_endpoint = 2;
  void clear_logging_endpoint();
  static const int kLoggingEndpointFieldNumber = 2;
  const ::std::string& logging_endpoint() const;
  void set_logging_endpoint(const ::std::string& value);
  #if LANG_CXX11
  void set_logging_endpoint(::std::string&& value);
  #endif
  void set_logging_endpoint(const char* value);
  void set_logging_endpoint(const char* value, size_t size);
  ::std::string* mutable_logging_endpoint();
  ::std::string* release_logging_endpoint();
  void set_allocated_logging_endpoint(::std::string* logging_endpoint);

  // string logging_protocol = 3;
  void clear_logging_protocol();
  static const int kLoggingProtocolFieldNumber = 3;
  const ::std::string& logging_protocol() const;
  void set_logging_protocol(const ::std::string& value);
  #if LANG_CXX11
  void set_logging_protocol(::std::string&& value);
  #endif
  void set_logging_protocol(const char* value);
  void set_logging_protocol(const char* value, size_t size);
  ::std::string* mutable_logging_protocol();
  ::std::string* release_logging_protocol();
  void set_allocated_logging_protocol(::std::string* logging_protocol);

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr logging_endpoint_;
  ::google::protobuf::internal::ArenaStringPtr logging_protocol_;
  ::dmi::Uuid* device_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  SetRemoteEndpointResponse(const SetRemoteEndpointResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef SetRemoteEndpointResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    SetRemoteEndpointResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    SetRemoteEndpointResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    SetRemoteEndpointResponse_Reason_INTERNAL_ERROR;
  static const Reason LOGGING_ENDPOINT_ERROR =
    SetRemoteEndpointResponse_Reason_LOGGING_ENDPOINT_ERROR;
  static const Reason LOGGING_ENDPOINT_PROTOCOL_ERROR =
    SetRemoteEndpointResponse_Reason_LOGGING_ENDPOINT_PROTOCOL_ERROR;
  static const Reason MSGBUS_ENDPOINT_ERROR =
    SetRemoteEndpointResponse_Reason_MSGBUS_ENDPOINT_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    SetRemoteEndpointResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return SetRemoteEndpointResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    SetRemoteEndpointResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    SetRemoteEndpointResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    SetRemoteEndpointResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return SetRemoteEndpointResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return SetRemoteEndpointResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return SetRemoteEndpointResponse_Reason_Parse(name, value);
  }

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

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

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

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

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

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

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

  GetLoggingEndpointResponse(const GetLoggingEndpointResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef GetLoggingEndpointResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    GetLoggingEndpointResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    GetLoggingEndpointResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    GetLoggingEndpointResponse_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    GetLoggingEndpointResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return GetLoggingEndpointResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    GetLoggingEndpointResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    GetLoggingEndpointResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    GetLoggingEndpointResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return GetLoggingEndpointResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return GetLoggingEndpointResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return GetLoggingEndpointResponse_Reason_Parse(name, value);
  }

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

  // string logging_endpoint = 3;
  void clear_logging_endpoint();
  static const int kLoggingEndpointFieldNumber = 3;
  const ::std::string& logging_endpoint() const;
  void set_logging_endpoint(const ::std::string& value);
  #if LANG_CXX11
  void set_logging_endpoint(::std::string&& value);
  #endif
  void set_logging_endpoint(const char* value);
  void set_logging_endpoint(const char* value, size_t size);
  ::std::string* mutable_logging_endpoint();
  ::std::string* release_logging_endpoint();
  void set_allocated_logging_endpoint(::std::string* logging_endpoint);

  // string logging_protocol = 4;
  void clear_logging_protocol();
  static const int kLoggingProtocolFieldNumber = 4;
  const ::std::string& logging_protocol() const;
  void set_logging_protocol(const ::std::string& value);
  #if LANG_CXX11
  void set_logging_protocol(::std::string&& value);
  #endif
  void set_logging_protocol(const char* value);
  void set_logging_protocol(const char* value, size_t size);
  ::std::string* mutable_logging_protocol();
  ::std::string* release_logging_protocol();
  void set_allocated_logging_protocol(::std::string* logging_protocol);

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

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

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

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

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

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

  SetMsgBusEndpointRequest(const SetMsgBusEndpointRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

  // string msgbus_endpoint = 1;
  void clear_msgbus_endpoint();
  static const int kMsgbusEndpointFieldNumber = 1;
  const ::std::string& msgbus_endpoint() const;
  void set_msgbus_endpoint(const ::std::string& value);
  #if LANG_CXX11
  void set_msgbus_endpoint(::std::string&& value);
  #endif
  void set_msgbus_endpoint(const char* value);
  void set_msgbus_endpoint(const char* value, size_t size);
  ::std::string* mutable_msgbus_endpoint();
  ::std::string* release_msgbus_endpoint();
  void set_allocated_msgbus_endpoint(::std::string* msgbus_endpoint);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr msgbus_endpoint_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  GetMsgBusEndpointResponse(const GetMsgBusEndpointResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef GetMsgBusEndpointResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    GetMsgBusEndpointResponse_Reason_UNDEFINED_REASON;
  static const Reason INTERNAL_ERROR =
    GetMsgBusEndpointResponse_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    GetMsgBusEndpointResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return GetMsgBusEndpointResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    GetMsgBusEndpointResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    GetMsgBusEndpointResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    GetMsgBusEndpointResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return GetMsgBusEndpointResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return GetMsgBusEndpointResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return GetMsgBusEndpointResponse_Reason_Parse(name, value);
  }

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

  // string msgbus_endpoint = 3;
  void clear_msgbus_endpoint();
  static const int kMsgbusEndpointFieldNumber = 3;
  const ::std::string& msgbus_endpoint() const;
  void set_msgbus_endpoint(const ::std::string& value);
  #if LANG_CXX11
  void set_msgbus_endpoint(::std::string&& value);
  #endif
  void set_msgbus_endpoint(const char* value);
  void set_msgbus_endpoint(const char* value, size_t size);
  ::std::string* mutable_msgbus_endpoint();
  ::std::string* release_msgbus_endpoint();
  void set_allocated_msgbus_endpoint(::std::string* msgbus_endpoint);

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

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

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

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

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

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

  EntitiesLogLevel(const EntitiesLogLevel& from);

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

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

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

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

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

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

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

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

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

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

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

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

  // repeated string entities = 2;
  int entities_size() const;
  void clear_entities();
  static const int kEntitiesFieldNumber = 2;
  const ::std::string& entities(int index) const;
  ::std::string* mutable_entities(int index);
  void set_entities(int index, const ::std::string& value);
  #if LANG_CXX11
  void set_entities(int index, ::std::string&& value);
  #endif
  void set_entities(int index, const char* value);
  void set_entities(int index, const char* value, size_t size);
  ::std::string* add_entities();
  void add_entities(const ::std::string& value);
  #if LANG_CXX11
  void add_entities(::std::string&& value);
  #endif
  void add_entities(const char* value);
  void add_entities(const char* value, size_t size);
  const ::google::protobuf::RepeatedPtrField<::std::string>& entities() const;
  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_entities();

  // .dmi.LogLevel logLevel = 1;
  void clear_loglevel();
  static const int kLogLevelFieldNumber = 1;
  ::dmi::LogLevel loglevel() const;
  void set_loglevel(::dmi::LogLevel value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::RepeatedPtrField<::std::string> entities_;
  int loglevel_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  SetLogLevelRequest(const SetLogLevelRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

  // repeated .dmi.EntitiesLogLevel loglevels = 2;
  int loglevels_size() const;
  void clear_loglevels();
  static const int kLoglevelsFieldNumber = 2;
  ::dmi::EntitiesLogLevel* mutable_loglevels(int index);
  ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >*
      mutable_loglevels();
  const ::dmi::EntitiesLogLevel& loglevels(int index) const;
  ::dmi::EntitiesLogLevel* add_loglevels();
  const ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >&
      loglevels() const;

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel > loglevels_;
  ::dmi::Uuid* device_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  SetLogLevelResponse(const SetLogLevelResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef SetLogLevelResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    SetLogLevelResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    SetLogLevelResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    SetLogLevelResponse_Reason_INTERNAL_ERROR;
  static const Reason UNKNOWN_LOG_ENTITY =
    SetLogLevelResponse_Reason_UNKNOWN_LOG_ENTITY;
  static const Reason DEVICE_UNREACHABLE =
    SetLogLevelResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return SetLogLevelResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    SetLogLevelResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    SetLogLevelResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    SetLogLevelResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return SetLogLevelResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return SetLogLevelResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return SetLogLevelResponse_Reason_Parse(name, value);
  }

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

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

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

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

  // .dmi.SetLogLevelResponse.Reason reason = 3;
  void clear_reason();
  static const int kReasonFieldNumber = 3;
  ::dmi::SetLogLevelResponse_Reason reason() const;
  void set_reason(::dmi::SetLogLevelResponse_Reason value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  ::dmi::Uuid* device_uuid_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  GetLogLevelRequest(const GetLogLevelRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

  // repeated string entities = 2;
  int entities_size() const;
  void clear_entities();
  static const int kEntitiesFieldNumber = 2;
  const ::std::string& entities(int index) const;
  ::std::string* mutable_entities(int index);
  void set_entities(int index, const ::std::string& value);
  #if LANG_CXX11
  void set_entities(int index, ::std::string&& value);
  #endif
  void set_entities(int index, const char* value);
  void set_entities(int index, const char* value, size_t size);
  ::std::string* add_entities();
  void add_entities(const ::std::string& value);
  #if LANG_CXX11
  void add_entities(::std::string&& value);
  #endif
  void add_entities(const char* value);
  void add_entities(const char* value, size_t size);
  const ::google::protobuf::RepeatedPtrField<::std::string>& entities() const;
  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_entities();

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::RepeatedPtrField<::std::string> entities_;
  ::dmi::Uuid* device_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  GetLogLevelResponse(const GetLogLevelResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef GetLogLevelResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    GetLogLevelResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    GetLogLevelResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    GetLogLevelResponse_Reason_INTERNAL_ERROR;
  static const Reason UNKNOWN_LOG_ENTITY =
    GetLogLevelResponse_Reason_UNKNOWN_LOG_ENTITY;
  static const Reason DEVICE_UNREACHABLE =
    GetLogLevelResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return GetLogLevelResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    GetLogLevelResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    GetLogLevelResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    GetLogLevelResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return GetLogLevelResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return GetLogLevelResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return GetLogLevelResponse_Reason_Parse(name, value);
  }

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

  // repeated .dmi.EntitiesLogLevel logLevels = 2;
  int loglevels_size() const;
  void clear_loglevels();
  static const int kLogLevelsFieldNumber = 2;
  ::dmi::EntitiesLogLevel* mutable_loglevels(int index);
  ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >*
      mutable_loglevels();
  const ::dmi::EntitiesLogLevel& loglevels(int index) const;
  ::dmi::EntitiesLogLevel* add_loglevels();
  const ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >&
      loglevels() const;

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

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

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

  // .dmi.GetLogLevelResponse.Reason reason = 4;
  void clear_reason();
  static const int kReasonFieldNumber = 4;
  ::dmi::GetLogLevelResponse_Reason reason() const;
  void set_reason(::dmi::GetLogLevelResponse_Reason value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel > loglevels_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  ::dmi::Uuid* device_uuid_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  GetLoggableEntitiesRequest(const GetLoggableEntitiesRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::Uuid* device_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  Heartbeat(const Heartbeat& from);

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

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

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

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

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

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

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

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

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

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

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

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

  // fixed32 heartbeat_signature = 1;
  void clear_heartbeat_signature();
  static const int kHeartbeatSignatureFieldNumber = 1;
  ::google::protobuf::uint32 heartbeat_signature() const;
  void set_heartbeat_signature(::google::protobuf::uint32 value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 heartbeat_signature_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  RebootDeviceRequest(const RebootDeviceRequest& from);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::Uuid* device_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  RebootDeviceResponse(const RebootDeviceResponse& from);

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

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

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

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

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

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

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

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

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

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

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

  typedef RebootDeviceResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    RebootDeviceResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    RebootDeviceResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    RebootDeviceResponse_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    RebootDeviceResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return RebootDeviceResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    RebootDeviceResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    RebootDeviceResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    RebootDeviceResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return RebootDeviceResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return RebootDeviceResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return RebootDeviceResponse_Reason_Parse(name, value);
  }

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

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

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

  // .dmi.RebootDeviceResponse.Reason reason = 4;
  void clear_reason();
  static const int kReasonFieldNumber = 4;
  ::dmi::RebootDeviceResponse_Reason reason() const;
  void set_reason(::dmi::RebootDeviceResponse_Reason value);

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

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


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

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

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

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

// PhysicalInventoryResponse

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

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

// .dmi.Hardware inventory = 3;
inline bool PhysicalInventoryResponse::has_inventory() const {
  return this != internal_default_instance() && inventory_ != nullptr;
}
inline const ::dmi::Hardware& PhysicalInventoryResponse::inventory() const {
  const ::dmi::Hardware* p = inventory_;
  // @@protoc_insertion_point(field_get:dmi.PhysicalInventoryResponse.inventory)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Hardware*>(
      &::dmi::_Hardware_default_instance_);
}
inline ::dmi::Hardware* PhysicalInventoryResponse::release_inventory() {
  // @@protoc_insertion_point(field_release:dmi.PhysicalInventoryResponse.inventory)
  
  ::dmi::Hardware* temp = inventory_;
  inventory_ = nullptr;
  return temp;
}
inline ::dmi::Hardware* PhysicalInventoryResponse::mutable_inventory() {
  
  if (inventory_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Hardware>(GetArenaNoVirtual());
    inventory_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.PhysicalInventoryResponse.inventory)
  return inventory_;
}
inline void PhysicalInventoryResponse::set_allocated_inventory(::dmi::Hardware* inventory) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(inventory_);
  }
  if (inventory) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      inventory = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, inventory, submessage_arena);
    }
    
  } else {
    
  }
  inventory_ = inventory;
  // @@protoc_insertion_point(field_set_allocated:dmi.PhysicalInventoryResponse.inventory)
}

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

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

// HWComponentInfoGetRequest

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

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

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

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

// HWComponentInfoGetResponse

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

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

// .dmi.Component component = 3;
inline bool HWComponentInfoGetResponse::has_component() const {
  return this != internal_default_instance() && component_ != nullptr;
}
inline const ::dmi::Component& HWComponentInfoGetResponse::component() const {
  const ::dmi::Component* p = component_;
  // @@protoc_insertion_point(field_get:dmi.HWComponentInfoGetResponse.component)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Component*>(
      &::dmi::_Component_default_instance_);
}
inline ::dmi::Component* HWComponentInfoGetResponse::release_component() {
  // @@protoc_insertion_point(field_release:dmi.HWComponentInfoGetResponse.component)
  
  ::dmi::Component* temp = component_;
  component_ = nullptr;
  return temp;
}
inline ::dmi::Component* HWComponentInfoGetResponse::mutable_component() {
  
  if (component_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Component>(GetArenaNoVirtual());
    component_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.HWComponentInfoGetResponse.component)
  return component_;
}
inline void HWComponentInfoGetResponse::set_allocated_component(::dmi::Component* component) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(component_);
  }
  if (component) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      component = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, component, submessage_arena);
    }
    
  } else {
    
  }
  component_ = component;
  // @@protoc_insertion_point(field_set_allocated:dmi.HWComponentInfoGetResponse.component)
}

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

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

// HWComponentInfoSetRequest

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

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

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

// .dmi.ModifiableComponent changes = 4;
inline bool HWComponentInfoSetRequest::has_changes() const {
  return this != internal_default_instance() && changes_ != nullptr;
}
inline const ::dmi::ModifiableComponent& HWComponentInfoSetRequest::changes() const {
  const ::dmi::ModifiableComponent* p = changes_;
  // @@protoc_insertion_point(field_get:dmi.HWComponentInfoSetRequest.changes)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ModifiableComponent*>(
      &::dmi::_ModifiableComponent_default_instance_);
}
inline ::dmi::ModifiableComponent* HWComponentInfoSetRequest::release_changes() {
  // @@protoc_insertion_point(field_release:dmi.HWComponentInfoSetRequest.changes)
  
  ::dmi::ModifiableComponent* temp = changes_;
  changes_ = nullptr;
  return temp;
}
inline ::dmi::ModifiableComponent* HWComponentInfoSetRequest::mutable_changes() {
  
  if (changes_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::ModifiableComponent>(GetArenaNoVirtual());
    changes_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.HWComponentInfoSetRequest.changes)
  return changes_;
}
inline void HWComponentInfoSetRequest::set_allocated_changes(::dmi::ModifiableComponent* changes) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(changes_);
  }
  if (changes) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      changes = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, changes, submessage_arena);
    }
    
  } else {
    
  }
  changes_ = changes;
  // @@protoc_insertion_point(field_set_allocated:dmi.HWComponentInfoSetRequest.changes)
}

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

// HWComponentInfoSetResponse

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

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

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

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

// StartManagingDeviceResponse

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

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

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

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

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

// StopManagingDeviceRequest

// string name = 1;
inline void StopManagingDeviceRequest::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& StopManagingDeviceRequest::name() const {
  // @@protoc_insertion_point(field_get:dmi.StopManagingDeviceRequest.name)
  return name_.GetNoArena();
}
inline void StopManagingDeviceRequest::set_name(const ::std::string& value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.StopManagingDeviceRequest.name)
}
#if LANG_CXX11
inline void StopManagingDeviceRequest::set_name(::std::string&& value) {
  
  name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.StopManagingDeviceRequest.name)
}
#endif
inline void StopManagingDeviceRequest::set_name(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.StopManagingDeviceRequest.name)
}
inline void StopManagingDeviceRequest::set_name(const char* value, size_t size) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.StopManagingDeviceRequest.name)
}
inline ::std::string* StopManagingDeviceRequest::mutable_name() {
  
  // @@protoc_insertion_point(field_mutable:dmi.StopManagingDeviceRequest.name)
  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* StopManagingDeviceRequest::release_name() {
  // @@protoc_insertion_point(field_release:dmi.StopManagingDeviceRequest.name)
  
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void StopManagingDeviceRequest::set_allocated_name(::std::string* name) {
  if (name != nullptr) {
    
  } else {
    
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:dmi.StopManagingDeviceRequest.name)
}

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

// StopManagingDeviceResponse

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

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

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

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

// ManagedDeviceInfo

// .dmi.ModifiableComponent info = 1;
inline bool ManagedDeviceInfo::has_info() const {
  return this != internal_default_instance() && info_ != nullptr;
}
inline const ::dmi::ModifiableComponent& ManagedDeviceInfo::info() const {
  const ::dmi::ModifiableComponent* p = info_;
  // @@protoc_insertion_point(field_get:dmi.ManagedDeviceInfo.info)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ModifiableComponent*>(
      &::dmi::_ModifiableComponent_default_instance_);
}
inline ::dmi::ModifiableComponent* ManagedDeviceInfo::release_info() {
  // @@protoc_insertion_point(field_release:dmi.ManagedDeviceInfo.info)
  
  ::dmi::ModifiableComponent* temp = info_;
  info_ = nullptr;
  return temp;
}
inline ::dmi::ModifiableComponent* ManagedDeviceInfo::mutable_info() {
  
  if (info_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::ModifiableComponent>(GetArenaNoVirtual());
    info_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ManagedDeviceInfo.info)
  return info_;
}
inline void ManagedDeviceInfo::set_allocated_info(::dmi::ModifiableComponent* info) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(info_);
  }
  if (info) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      info = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, info, submessage_arena);
    }
    
  } else {
    
  }
  info_ = info;
  // @@protoc_insertion_point(field_set_allocated:dmi.ManagedDeviceInfo.info)
}

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

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

// ManagedDevicesResponse

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

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

// repeated .dmi.ManagedDeviceInfo devices = 3;
inline int ManagedDevicesResponse::devices_size() const {
  return devices_.size();
}
inline void ManagedDevicesResponse::clear_devices() {
  devices_.Clear();
}
inline ::dmi::ManagedDeviceInfo* ManagedDevicesResponse::mutable_devices(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.ManagedDevicesResponse.devices)
  return devices_.Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField< ::dmi::ManagedDeviceInfo >*
ManagedDevicesResponse::mutable_devices() {
  // @@protoc_insertion_point(field_mutable_list:dmi.ManagedDevicesResponse.devices)
  return &devices_;
}
inline const ::dmi::ManagedDeviceInfo& ManagedDevicesResponse::devices(int index) const {
  // @@protoc_insertion_point(field_get:dmi.ManagedDevicesResponse.devices)
  return devices_.Get(index);
}
inline ::dmi::ManagedDeviceInfo* ManagedDevicesResponse::add_devices() {
  // @@protoc_insertion_point(field_add:dmi.ManagedDevicesResponse.devices)
  return devices_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::dmi::ManagedDeviceInfo >&
ManagedDevicesResponse::devices() const {
  // @@protoc_insertion_point(field_list:dmi.ManagedDevicesResponse.devices)
  return devices_;
}

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

// SetLoggingEndpointRequest

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

// string logging_endpoint = 2;
inline void SetLoggingEndpointRequest::clear_logging_endpoint() {
  logging_endpoint_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& SetLoggingEndpointRequest::logging_endpoint() const {
  // @@protoc_insertion_point(field_get:dmi.SetLoggingEndpointRequest.logging_endpoint)
  return logging_endpoint_.GetNoArena();
}
inline void SetLoggingEndpointRequest::set_logging_endpoint(const ::std::string& value) {
  
  logging_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.SetLoggingEndpointRequest.logging_endpoint)
}
#if LANG_CXX11
inline void SetLoggingEndpointRequest::set_logging_endpoint(::std::string&& value) {
  
  logging_endpoint_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.SetLoggingEndpointRequest.logging_endpoint)
}
#endif
inline void SetLoggingEndpointRequest::set_logging_endpoint(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  logging_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.SetLoggingEndpointRequest.logging_endpoint)
}
inline void SetLoggingEndpointRequest::set_logging_endpoint(const char* value, size_t size) {
  
  logging_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.SetLoggingEndpointRequest.logging_endpoint)
}
inline ::std::string* SetLoggingEndpointRequest::mutable_logging_endpoint() {
  
  // @@protoc_insertion_point(field_mutable:dmi.SetLoggingEndpointRequest.logging_endpoint)
  return logging_endpoint_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* SetLoggingEndpointRequest::release_logging_endpoint() {
  // @@protoc_insertion_point(field_release:dmi.SetLoggingEndpointRequest.logging_endpoint)
  
  return logging_endpoint_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void SetLoggingEndpointRequest::set_allocated_logging_endpoint(::std::string* logging_endpoint) {
  if (logging_endpoint != nullptr) {
    
  } else {
    
  }
  logging_endpoint_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), logging_endpoint);
  // @@protoc_insertion_point(field_set_allocated:dmi.SetLoggingEndpointRequest.logging_endpoint)
}

// string logging_protocol = 3;
inline void SetLoggingEndpointRequest::clear_logging_protocol() {
  logging_protocol_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& SetLoggingEndpointRequest::logging_protocol() const {
  // @@protoc_insertion_point(field_get:dmi.SetLoggingEndpointRequest.logging_protocol)
  return logging_protocol_.GetNoArena();
}
inline void SetLoggingEndpointRequest::set_logging_protocol(const ::std::string& value) {
  
  logging_protocol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.SetLoggingEndpointRequest.logging_protocol)
}
#if LANG_CXX11
inline void SetLoggingEndpointRequest::set_logging_protocol(::std::string&& value) {
  
  logging_protocol_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.SetLoggingEndpointRequest.logging_protocol)
}
#endif
inline void SetLoggingEndpointRequest::set_logging_protocol(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  logging_protocol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.SetLoggingEndpointRequest.logging_protocol)
}
inline void SetLoggingEndpointRequest::set_logging_protocol(const char* value, size_t size) {
  
  logging_protocol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.SetLoggingEndpointRequest.logging_protocol)
}
inline ::std::string* SetLoggingEndpointRequest::mutable_logging_protocol() {
  
  // @@protoc_insertion_point(field_mutable:dmi.SetLoggingEndpointRequest.logging_protocol)
  return logging_protocol_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* SetLoggingEndpointRequest::release_logging_protocol() {
  // @@protoc_insertion_point(field_release:dmi.SetLoggingEndpointRequest.logging_protocol)
  
  return logging_protocol_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void SetLoggingEndpointRequest::set_allocated_logging_protocol(::std::string* logging_protocol) {
  if (logging_protocol != nullptr) {
    
  } else {
    
  }
  logging_protocol_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), logging_protocol);
  // @@protoc_insertion_point(field_set_allocated:dmi.SetLoggingEndpointRequest.logging_protocol)
}

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

// SetRemoteEndpointResponse

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

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

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

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

// GetLoggingEndpointResponse

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

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

// string logging_endpoint = 3;
inline void GetLoggingEndpointResponse::clear_logging_endpoint() {
  logging_endpoint_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& GetLoggingEndpointResponse::logging_endpoint() const {
  // @@protoc_insertion_point(field_get:dmi.GetLoggingEndpointResponse.logging_endpoint)
  return logging_endpoint_.GetNoArena();
}
inline void GetLoggingEndpointResponse::set_logging_endpoint(const ::std::string& value) {
  
  logging_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.GetLoggingEndpointResponse.logging_endpoint)
}
#if LANG_CXX11
inline void GetLoggingEndpointResponse::set_logging_endpoint(::std::string&& value) {
  
  logging_endpoint_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.GetLoggingEndpointResponse.logging_endpoint)
}
#endif
inline void GetLoggingEndpointResponse::set_logging_endpoint(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  logging_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.GetLoggingEndpointResponse.logging_endpoint)
}
inline void GetLoggingEndpointResponse::set_logging_endpoint(const char* value, size_t size) {
  
  logging_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.GetLoggingEndpointResponse.logging_endpoint)
}
inline ::std::string* GetLoggingEndpointResponse::mutable_logging_endpoint() {
  
  // @@protoc_insertion_point(field_mutable:dmi.GetLoggingEndpointResponse.logging_endpoint)
  return logging_endpoint_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* GetLoggingEndpointResponse::release_logging_endpoint() {
  // @@protoc_insertion_point(field_release:dmi.GetLoggingEndpointResponse.logging_endpoint)
  
  return logging_endpoint_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void GetLoggingEndpointResponse::set_allocated_logging_endpoint(::std::string* logging_endpoint) {
  if (logging_endpoint != nullptr) {
    
  } else {
    
  }
  logging_endpoint_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), logging_endpoint);
  // @@protoc_insertion_point(field_set_allocated:dmi.GetLoggingEndpointResponse.logging_endpoint)
}

// string logging_protocol = 4;
inline void GetLoggingEndpointResponse::clear_logging_protocol() {
  logging_protocol_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& GetLoggingEndpointResponse::logging_protocol() const {
  // @@protoc_insertion_point(field_get:dmi.GetLoggingEndpointResponse.logging_protocol)
  return logging_protocol_.GetNoArena();
}
inline void GetLoggingEndpointResponse::set_logging_protocol(const ::std::string& value) {
  
  logging_protocol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.GetLoggingEndpointResponse.logging_protocol)
}
#if LANG_CXX11
inline void GetLoggingEndpointResponse::set_logging_protocol(::std::string&& value) {
  
  logging_protocol_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.GetLoggingEndpointResponse.logging_protocol)
}
#endif
inline void GetLoggingEndpointResponse::set_logging_protocol(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  logging_protocol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.GetLoggingEndpointResponse.logging_protocol)
}
inline void GetLoggingEndpointResponse::set_logging_protocol(const char* value, size_t size) {
  
  logging_protocol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.GetLoggingEndpointResponse.logging_protocol)
}
inline ::std::string* GetLoggingEndpointResponse::mutable_logging_protocol() {
  
  // @@protoc_insertion_point(field_mutable:dmi.GetLoggingEndpointResponse.logging_protocol)
  return logging_protocol_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* GetLoggingEndpointResponse::release_logging_protocol() {
  // @@protoc_insertion_point(field_release:dmi.GetLoggingEndpointResponse.logging_protocol)
  
  return logging_protocol_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void GetLoggingEndpointResponse::set_allocated_logging_protocol(::std::string* logging_protocol) {
  if (logging_protocol != nullptr) {
    
  } else {
    
  }
  logging_protocol_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), logging_protocol);
  // @@protoc_insertion_point(field_set_allocated:dmi.GetLoggingEndpointResponse.logging_protocol)
}

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

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

// SetMsgBusEndpointRequest

// string msgbus_endpoint = 1;
inline void SetMsgBusEndpointRequest::clear_msgbus_endpoint() {
  msgbus_endpoint_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& SetMsgBusEndpointRequest::msgbus_endpoint() const {
  // @@protoc_insertion_point(field_get:dmi.SetMsgBusEndpointRequest.msgbus_endpoint)
  return msgbus_endpoint_.GetNoArena();
}
inline void SetMsgBusEndpointRequest::set_msgbus_endpoint(const ::std::string& value) {
  
  msgbus_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.SetMsgBusEndpointRequest.msgbus_endpoint)
}
#if LANG_CXX11
inline void SetMsgBusEndpointRequest::set_msgbus_endpoint(::std::string&& value) {
  
  msgbus_endpoint_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.SetMsgBusEndpointRequest.msgbus_endpoint)
}
#endif
inline void SetMsgBusEndpointRequest::set_msgbus_endpoint(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  msgbus_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.SetMsgBusEndpointRequest.msgbus_endpoint)
}
inline void SetMsgBusEndpointRequest::set_msgbus_endpoint(const char* value, size_t size) {
  
  msgbus_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.SetMsgBusEndpointRequest.msgbus_endpoint)
}
inline ::std::string* SetMsgBusEndpointRequest::mutable_msgbus_endpoint() {
  
  // @@protoc_insertion_point(field_mutable:dmi.SetMsgBusEndpointRequest.msgbus_endpoint)
  return msgbus_endpoint_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* SetMsgBusEndpointRequest::release_msgbus_endpoint() {
  // @@protoc_insertion_point(field_release:dmi.SetMsgBusEndpointRequest.msgbus_endpoint)
  
  return msgbus_endpoint_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void SetMsgBusEndpointRequest::set_allocated_msgbus_endpoint(::std::string* msgbus_endpoint) {
  if (msgbus_endpoint != nullptr) {
    
  } else {
    
  }
  msgbus_endpoint_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), msgbus_endpoint);
  // @@protoc_insertion_point(field_set_allocated:dmi.SetMsgBusEndpointRequest.msgbus_endpoint)
}

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

// GetMsgBusEndpointResponse

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

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

// string msgbus_endpoint = 3;
inline void GetMsgBusEndpointResponse::clear_msgbus_endpoint() {
  msgbus_endpoint_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& GetMsgBusEndpointResponse::msgbus_endpoint() const {
  // @@protoc_insertion_point(field_get:dmi.GetMsgBusEndpointResponse.msgbus_endpoint)
  return msgbus_endpoint_.GetNoArena();
}
inline void GetMsgBusEndpointResponse::set_msgbus_endpoint(const ::std::string& value) {
  
  msgbus_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.GetMsgBusEndpointResponse.msgbus_endpoint)
}
#if LANG_CXX11
inline void GetMsgBusEndpointResponse::set_msgbus_endpoint(::std::string&& value) {
  
  msgbus_endpoint_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.GetMsgBusEndpointResponse.msgbus_endpoint)
}
#endif
inline void GetMsgBusEndpointResponse::set_msgbus_endpoint(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  msgbus_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.GetMsgBusEndpointResponse.msgbus_endpoint)
}
inline void GetMsgBusEndpointResponse::set_msgbus_endpoint(const char* value, size_t size) {
  
  msgbus_endpoint_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.GetMsgBusEndpointResponse.msgbus_endpoint)
}
inline ::std::string* GetMsgBusEndpointResponse::mutable_msgbus_endpoint() {
  
  // @@protoc_insertion_point(field_mutable:dmi.GetMsgBusEndpointResponse.msgbus_endpoint)
  return msgbus_endpoint_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* GetMsgBusEndpointResponse::release_msgbus_endpoint() {
  // @@protoc_insertion_point(field_release:dmi.GetMsgBusEndpointResponse.msgbus_endpoint)
  
  return msgbus_endpoint_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void GetMsgBusEndpointResponse::set_allocated_msgbus_endpoint(::std::string* msgbus_endpoint) {
  if (msgbus_endpoint != nullptr) {
    
  } else {
    
  }
  msgbus_endpoint_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), msgbus_endpoint);
  // @@protoc_insertion_point(field_set_allocated:dmi.GetMsgBusEndpointResponse.msgbus_endpoint)
}

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

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

// EntitiesLogLevel

// .dmi.LogLevel logLevel = 1;
inline void EntitiesLogLevel::clear_loglevel() {
  loglevel_ = 0;
}
inline ::dmi::LogLevel EntitiesLogLevel::loglevel() const {
  // @@protoc_insertion_point(field_get:dmi.EntitiesLogLevel.logLevel)
  return static_cast< ::dmi::LogLevel >(loglevel_);
}
inline void EntitiesLogLevel::set_loglevel(::dmi::LogLevel value) {
  
  loglevel_ = value;
  // @@protoc_insertion_point(field_set:dmi.EntitiesLogLevel.logLevel)
}

// repeated string entities = 2;
inline int EntitiesLogLevel::entities_size() const {
  return entities_.size();
}
inline void EntitiesLogLevel::clear_entities() {
  entities_.Clear();
}
inline const ::std::string& EntitiesLogLevel::entities(int index) const {
  // @@protoc_insertion_point(field_get:dmi.EntitiesLogLevel.entities)
  return entities_.Get(index);
}
inline ::std::string* EntitiesLogLevel::mutable_entities(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.EntitiesLogLevel.entities)
  return entities_.Mutable(index);
}
inline void EntitiesLogLevel::set_entities(int index, const ::std::string& value) {
  // @@protoc_insertion_point(field_set:dmi.EntitiesLogLevel.entities)
  entities_.Mutable(index)->assign(value);
}
#if LANG_CXX11
inline void EntitiesLogLevel::set_entities(int index, ::std::string&& value) {
  // @@protoc_insertion_point(field_set:dmi.EntitiesLogLevel.entities)
  entities_.Mutable(index)->assign(std::move(value));
}
#endif
inline void EntitiesLogLevel::set_entities(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  entities_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:dmi.EntitiesLogLevel.entities)
}
inline void EntitiesLogLevel::set_entities(int index, const char* value, size_t size) {
  entities_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:dmi.EntitiesLogLevel.entities)
}
inline ::std::string* EntitiesLogLevel::add_entities() {
  // @@protoc_insertion_point(field_add_mutable:dmi.EntitiesLogLevel.entities)
  return entities_.Add();
}
inline void EntitiesLogLevel::add_entities(const ::std::string& value) {
  entities_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:dmi.EntitiesLogLevel.entities)
}
#if LANG_CXX11
inline void EntitiesLogLevel::add_entities(::std::string&& value) {
  entities_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:dmi.EntitiesLogLevel.entities)
}
#endif
inline void EntitiesLogLevel::add_entities(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  entities_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:dmi.EntitiesLogLevel.entities)
}
inline void EntitiesLogLevel::add_entities(const char* value, size_t size) {
  entities_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:dmi.EntitiesLogLevel.entities)
}
inline const ::google::protobuf::RepeatedPtrField<::std::string>&
EntitiesLogLevel::entities() const {
  // @@protoc_insertion_point(field_list:dmi.EntitiesLogLevel.entities)
  return entities_;
}
inline ::google::protobuf::RepeatedPtrField<::std::string>*
EntitiesLogLevel::mutable_entities() {
  // @@protoc_insertion_point(field_mutable_list:dmi.EntitiesLogLevel.entities)
  return &entities_;
}

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

// SetLogLevelRequest

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

// repeated .dmi.EntitiesLogLevel loglevels = 2;
inline int SetLogLevelRequest::loglevels_size() const {
  return loglevels_.size();
}
inline void SetLogLevelRequest::clear_loglevels() {
  loglevels_.Clear();
}
inline ::dmi::EntitiesLogLevel* SetLogLevelRequest::mutable_loglevels(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.SetLogLevelRequest.loglevels)
  return loglevels_.Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >*
SetLogLevelRequest::mutable_loglevels() {
  // @@protoc_insertion_point(field_mutable_list:dmi.SetLogLevelRequest.loglevels)
  return &loglevels_;
}
inline const ::dmi::EntitiesLogLevel& SetLogLevelRequest::loglevels(int index) const {
  // @@protoc_insertion_point(field_get:dmi.SetLogLevelRequest.loglevels)
  return loglevels_.Get(index);
}
inline ::dmi::EntitiesLogLevel* SetLogLevelRequest::add_loglevels() {
  // @@protoc_insertion_point(field_add:dmi.SetLogLevelRequest.loglevels)
  return loglevels_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >&
SetLogLevelRequest::loglevels() const {
  // @@protoc_insertion_point(field_list:dmi.SetLogLevelRequest.loglevels)
  return loglevels_;
}

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

// SetLogLevelResponse

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

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

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

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

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

// GetLogLevelRequest

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

// repeated string entities = 2;
inline int GetLogLevelRequest::entities_size() const {
  return entities_.size();
}
inline void GetLogLevelRequest::clear_entities() {
  entities_.Clear();
}
inline const ::std::string& GetLogLevelRequest::entities(int index) const {
  // @@protoc_insertion_point(field_get:dmi.GetLogLevelRequest.entities)
  return entities_.Get(index);
}
inline ::std::string* GetLogLevelRequest::mutable_entities(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.GetLogLevelRequest.entities)
  return entities_.Mutable(index);
}
inline void GetLogLevelRequest::set_entities(int index, const ::std::string& value) {
  // @@protoc_insertion_point(field_set:dmi.GetLogLevelRequest.entities)
  entities_.Mutable(index)->assign(value);
}
#if LANG_CXX11
inline void GetLogLevelRequest::set_entities(int index, ::std::string&& value) {
  // @@protoc_insertion_point(field_set:dmi.GetLogLevelRequest.entities)
  entities_.Mutable(index)->assign(std::move(value));
}
#endif
inline void GetLogLevelRequest::set_entities(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  entities_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:dmi.GetLogLevelRequest.entities)
}
inline void GetLogLevelRequest::set_entities(int index, const char* value, size_t size) {
  entities_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:dmi.GetLogLevelRequest.entities)
}
inline ::std::string* GetLogLevelRequest::add_entities() {
  // @@protoc_insertion_point(field_add_mutable:dmi.GetLogLevelRequest.entities)
  return entities_.Add();
}
inline void GetLogLevelRequest::add_entities(const ::std::string& value) {
  entities_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:dmi.GetLogLevelRequest.entities)
}
#if LANG_CXX11
inline void GetLogLevelRequest::add_entities(::std::string&& value) {
  entities_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:dmi.GetLogLevelRequest.entities)
}
#endif
inline void GetLogLevelRequest::add_entities(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  entities_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:dmi.GetLogLevelRequest.entities)
}
inline void GetLogLevelRequest::add_entities(const char* value, size_t size) {
  entities_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:dmi.GetLogLevelRequest.entities)
}
inline const ::google::protobuf::RepeatedPtrField<::std::string>&
GetLogLevelRequest::entities() const {
  // @@protoc_insertion_point(field_list:dmi.GetLogLevelRequest.entities)
  return entities_;
}
inline ::google::protobuf::RepeatedPtrField<::std::string>*
GetLogLevelRequest::mutable_entities() {
  // @@protoc_insertion_point(field_mutable_list:dmi.GetLogLevelRequest.entities)
  return &entities_;
}

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

// GetLogLevelResponse

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

// repeated .dmi.EntitiesLogLevel logLevels = 2;
inline int GetLogLevelResponse::loglevels_size() const {
  return loglevels_.size();
}
inline void GetLogLevelResponse::clear_loglevels() {
  loglevels_.Clear();
}
inline ::dmi::EntitiesLogLevel* GetLogLevelResponse::mutable_loglevels(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.GetLogLevelResponse.logLevels)
  return loglevels_.Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >*
GetLogLevelResponse::mutable_loglevels() {
  // @@protoc_insertion_point(field_mutable_list:dmi.GetLogLevelResponse.logLevels)
  return &loglevels_;
}
inline const ::dmi::EntitiesLogLevel& GetLogLevelResponse::loglevels(int index) const {
  // @@protoc_insertion_point(field_get:dmi.GetLogLevelResponse.logLevels)
  return loglevels_.Get(index);
}
inline ::dmi::EntitiesLogLevel* GetLogLevelResponse::add_loglevels() {
  // @@protoc_insertion_point(field_add:dmi.GetLogLevelResponse.logLevels)
  return loglevels_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >&
GetLogLevelResponse::loglevels() const {
  // @@protoc_insertion_point(field_list:dmi.GetLogLevelResponse.logLevels)
  return loglevels_;
}

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

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

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

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

// GetLoggableEntitiesRequest

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

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

// Heartbeat

// fixed32 heartbeat_signature = 1;
inline void Heartbeat::clear_heartbeat_signature() {
  heartbeat_signature_ = 0u;
}
inline ::google::protobuf::uint32 Heartbeat::heartbeat_signature() const {
  // @@protoc_insertion_point(field_get:dmi.Heartbeat.heartbeat_signature)
  return heartbeat_signature_;
}
inline void Heartbeat::set_heartbeat_signature(::google::protobuf::uint32 value) {
  
  heartbeat_signature_ = value;
  // @@protoc_insertion_point(field_set:dmi.Heartbeat.heartbeat_signature)
}

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

// RebootDeviceRequest

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

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

// RebootDeviceResponse

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace dmi

namespace google {
namespace protobuf {

template <> struct is_proto_enum< ::dmi::PhysicalInventoryResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PhysicalInventoryResponse_Reason>() {
  return ::dmi::PhysicalInventoryResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::HWComponentInfoGetResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::HWComponentInfoGetResponse_Reason>() {
  return ::dmi::HWComponentInfoGetResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::HWComponentInfoSetResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::HWComponentInfoSetResponse_Reason>() {
  return ::dmi::HWComponentInfoSetResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::StartManagingDeviceResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::StartManagingDeviceResponse_Reason>() {
  return ::dmi::StartManagingDeviceResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::StopManagingDeviceResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::StopManagingDeviceResponse_Reason>() {
  return ::dmi::StopManagingDeviceResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::ManagedDevicesResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ManagedDevicesResponse_Reason>() {
  return ::dmi::ManagedDevicesResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::SetRemoteEndpointResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::SetRemoteEndpointResponse_Reason>() {
  return ::dmi::SetRemoteEndpointResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::GetLoggingEndpointResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::GetLoggingEndpointResponse_Reason>() {
  return ::dmi::GetLoggingEndpointResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::GetMsgBusEndpointResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::GetMsgBusEndpointResponse_Reason>() {
  return ::dmi::GetMsgBusEndpointResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::SetLogLevelResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::SetLogLevelResponse_Reason>() {
  return ::dmi::SetLogLevelResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::GetLogLevelResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::GetLogLevelResponse_Reason>() {
  return ::dmi::GetLogLevelResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::RebootDeviceResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::RebootDeviceResponse_Reason>() {
  return ::dmi::RebootDeviceResponse_Reason_descriptor();
}

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

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