// 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_SET_UNSUPPORTED = 6,
  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_SET_UNSUPPORTED;
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_DEVICE_UNREACHABLE = 2,
  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_DEVICE_UNREACHABLE;
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_DEVICE_IN_WRONG_STATE = 4,
  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_IN_WRONG_STATE;
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 const Reason SET_UNSUPPORTED =
    HWComponentInfoSetResponse_Reason_SET_UNSUPPORTED;
  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 const Reason DEVICE_UNREACHABLE =
    StopManagingDeviceResponse_Reason_DEVICE_UNREACHABLE;
  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 const Reason DEVICE_IN_WRONG_STATE =
    RebootDeviceResponse_Reason_DEVICE_IN_WRONG_STATE;
  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
