// 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_AUTHENTICATION_FAILURE = 5,
  StartManagingDeviceResponse_Reason_INCOMPATIBLE_DEVICE = 6,
  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_INCOMPATIBLE_DEVICE;
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 const Reason AUTHENTICATION_FAILURE =
    StartManagingDeviceResponse_Reason_AUTHENTICATION_FAILURE;
  static const Reason INCOMPATIBLE_DEVICE =
    StartManagingDeviceResponse_Reason_INCOMPATIBLE_DEVICE;
  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
