diff --git a/Makefile b/Makefile
index 393c6fa..d3c0a80 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,9 @@
 # Makefile for device-management-interface
 default: test
 
+# initialize path of grpc_cpp_plugin binary
+GRPC_CPP_PLUGIN_PATH ?= $(shell which grpc_cpp_plugin)
+
 # set default shell options
 SHELL = bash -e -o pipefail
 
@@ -39,6 +42,8 @@
 PROTO_PYTHON_DEST_DIR := python/dmi
 PROTO_PYTHON_PB2 := $(foreach f, $(PROTO_FILES), $(patsubst protos/dmi/%.proto,$(PROTO_PYTHON_DEST_DIR)/%_pb2.py,$(f)))
 
+PROTO_CPP_DEST_DIR := cpp
+PROTO_CPP_PB := $(foreach f, $(PROTO_FILES), $(patsubst protos/dmi/%.proto,$(PROTO_CPP_DEST_DIR)/$(call if_package_path,$(f))/%.pb.cc,$(f)))
 # Force pb file to be regenrated every time.  Otherwise the make process assumes generated version is still valid
 .PHONY: dmi.pb
 
@@ -48,11 +53,11 @@
 	@echo "python PB files: $(PROTO_PYTHON_PB)"
 
 # Generic targets
-protos: go-protos python-protos
+protos: go-protos python-protos cpp-protos
 
 build: protos
 
-test: go-test python-test
+test: go-test python-test cpp-test
 
 
 venv_protos:
@@ -91,6 +96,16 @@
 	  --descriptor_set_out=$@ \
 	  ${PROTO_FILES}
 
+# Cpp targets
+cpp-protos:
+	echo "Creating *.pb.cpp files"
+	@${PROTOC_SH} " \
+      set -e -o pipefail; \
+      for x in ${PROTO_FILES}; do \
+		echo \$$x; \
+		protoc --cpp_out=\$(PROTO_CPP_DEST_DIR) --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` -I protos \$$x; \
+	  done"
+
 go-test:
 	test/test-go-proto-consistency.sh
 	${GO} mod verify
@@ -102,3 +117,6 @@
 python-build: setup.py python-protos
 	rm -rf dist/
 	python ./setup.py sdist
+
+cpp-test:
+	test/test-cpp-proto-consistency.sh
diff --git a/VERSION b/VERSION
index 54d1a4f..a803cc2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.13.0
+0.14.0
diff --git a/cpp/dmi/commons.pb.cc b/cpp/dmi/commons.pb.cc
new file mode 100644
index 0000000..157ab04
--- /dev/null
+++ b/cpp/dmi/commons.pb.cc
@@ -0,0 +1,102 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/commons.proto
+
+#include "dmi/commons.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+
+namespace dmi {
+}  // namespace dmi
+void InitDefaults_dmi_2fcommons_2eproto() {
+}
+
+constexpr ::google::protobuf::Metadata* file_level_metadata_dmi_2fcommons_2eproto = nullptr;
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fcommons_2eproto[2];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fcommons_2eproto = nullptr;
+const ::google::protobuf::uint32 TableStruct_dmi_2fcommons_2eproto::offsets[1] = {};
+static constexpr ::google::protobuf::internal::MigrationSchema* schemas = nullptr;
+static constexpr ::google::protobuf::Message* const* file_default_instances = nullptr;
+
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fcommons_2eproto = {
+  {}, AddDescriptors_dmi_2fcommons_2eproto, "dmi/commons.proto", schemas,
+  file_default_instances, TableStruct_dmi_2fcommons_2eproto::offsets,
+  file_level_metadata_dmi_2fcommons_2eproto, 0, file_level_enum_descriptors_dmi_2fcommons_2eproto, file_level_service_descriptors_dmi_2fcommons_2eproto,
+};
+
+const char descriptor_table_protodef_dmi_2fcommons_2eproto[] =
+  "\n\021dmi/commons.proto\022\003dmi*\?\n\006Status\022\024\n\020UN"
+  "DEFINED_STATUS\020\000\022\r\n\tOK_STATUS\020\001\022\020\n\014ERROR"
+  "_STATUS\020\002*\?\n\010LogLevel\022\t\n\005TRACE\020\000\022\t\n\005DEBU"
+  "G\020\001\022\010\n\004INFO\020\002\022\010\n\004WARN\020\003\022\t\n\005ERROR\020\004B;Z9gi"
+  "thub.com/opencord/device-management-inte"
+  "rface/v3/go/dmib\006proto3"
+  ;
+::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fcommons_2eproto = {
+  false, InitDefaults_dmi_2fcommons_2eproto, 
+  descriptor_table_protodef_dmi_2fcommons_2eproto,
+  "dmi/commons.proto", &assign_descriptors_table_dmi_2fcommons_2eproto, 223,
+};
+
+void AddDescriptors_dmi_2fcommons_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
+  };
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_dmi_2fcommons_2eproto, deps, 0);
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_dmi_2fcommons_2eproto = []() { AddDescriptors_dmi_2fcommons_2eproto(); return true; }();
+namespace dmi {
+const ::google::protobuf::EnumDescriptor* Status_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fcommons_2eproto);
+  return file_level_enum_descriptors_dmi_2fcommons_2eproto[0];
+}
+bool Status_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* LogLevel_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fcommons_2eproto);
+  return file_level_enum_descriptors_dmi_2fcommons_2eproto[1];
+}
+bool LogLevel_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+#include <google/protobuf/port_undef.inc>
diff --git a/cpp/dmi/commons.pb.h b/cpp/dmi/commons.pb.h
new file mode 100644
index 0000000..6b10482
--- /dev/null
+++ b/cpp/dmi/commons.pb.h
@@ -0,0 +1,142 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/commons.proto
+
+#ifndef PROTOBUF_INCLUDED_dmi_2fcommons_2eproto
+#define PROTOBUF_INCLUDED_dmi_2fcommons_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/repeated_field.h>  // IWYU pragma: export
+#include <google/protobuf/extension_set.h>  // IWYU pragma: export
+#include <google/protobuf/generated_enum_reflection.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_dmi_2fcommons_2eproto
+
+// Internal implementation detail -- do not use these members.
+struct TableStruct_dmi_2fcommons_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[1]
+    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_2fcommons_2eproto();
+namespace google {
+namespace protobuf {
+}  // namespace protobuf
+}  // namespace google
+namespace dmi {
+
+enum Status {
+  UNDEFINED_STATUS = 0,
+  OK_STATUS = 1,
+  ERROR_STATUS = 2,
+  Status_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  Status_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool Status_IsValid(int value);
+const Status Status_MIN = UNDEFINED_STATUS;
+const Status Status_MAX = ERROR_STATUS;
+const int Status_ARRAYSIZE = Status_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* Status_descriptor();
+inline const ::std::string& Status_Name(Status value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    Status_descriptor(), value);
+}
+inline bool Status_Parse(
+    const ::std::string& name, Status* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<Status>(
+    Status_descriptor(), name, value);
+}
+enum LogLevel {
+  TRACE = 0,
+  DEBUG = 1,
+  INFO = 2,
+  WARN = 3,
+  ERROR = 4,
+  LogLevel_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  LogLevel_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool LogLevel_IsValid(int value);
+const LogLevel LogLevel_MIN = TRACE;
+const LogLevel LogLevel_MAX = ERROR;
+const int LogLevel_ARRAYSIZE = LogLevel_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* LogLevel_descriptor();
+inline const ::std::string& LogLevel_Name(LogLevel value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    LogLevel_descriptor(), value);
+}
+inline bool LogLevel_Parse(
+    const ::std::string& name, LogLevel* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<LogLevel>(
+    LogLevel_descriptor(), name, value);
+}
+// ===================================================================
+
+
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif  // __GNUC__
+#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::Status> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::Status>() {
+  return ::dmi::Status_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::LogLevel> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::LogLevel>() {
+  return ::dmi::LogLevel_descriptor();
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#include <google/protobuf/port_undef.inc>
+#endif  // PROTOBUF_INCLUDED_dmi_2fcommons_2eproto
diff --git a/cpp/dmi/hw.pb.cc b/cpp/dmi/hw.pb.cc
new file mode 100644
index 0000000..1b32844
--- /dev/null
+++ b/cpp/dmi/hw.pb.cc
@@ -0,0 +1,7832 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/hw.proto
+
+#include "dmi/hw.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_PortComponentAttributes_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_PsuComponentAttributes_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uri_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ComponentSensorData_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ComponentState_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<9> scc_info_Component_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto;
+namespace dmi {
+class UuidDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Uuid> _instance;
+} _Uuid_default_instance_;
+class HardwareIDDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<HardwareID> _instance;
+} _HardwareID_default_instance_;
+class UriDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Uri> _instance;
+} _Uri_default_instance_;
+class ComponentStateDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ComponentState> _instance;
+} _ComponentState_default_instance_;
+class ComponentSensorDataDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ComponentSensorData> _instance;
+} _ComponentSensorData_default_instance_;
+class PortComponentAttributesDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<PortComponentAttributes> _instance;
+} _PortComponentAttributes_default_instance_;
+class ContainerComponentAttributesDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ContainerComponentAttributes> _instance;
+} _ContainerComponentAttributes_default_instance_;
+class PsuComponentAttributesDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<PsuComponentAttributes> _instance;
+} _PsuComponentAttributes_default_instance_;
+class TransceiverComponentsAttributesDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<TransceiverComponentsAttributes> _instance;
+} _TransceiverComponentsAttributes_default_instance_;
+class ComponentDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Component> _instance;
+  const ::dmi::PortComponentAttributes* port_attr_;
+  const ::dmi::ContainerComponentAttributes* container_attr_;
+  const ::dmi::PsuComponentAttributes* psu_attr_;
+  const ::dmi::TransceiverComponentsAttributes* transceiver_attr_;
+} _Component_default_instance_;
+class HardwareDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Hardware> _instance;
+} _Hardware_default_instance_;
+class ModifiableComponentDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ModifiableComponent> _instance;
+} _ModifiableComponent_default_instance_;
+}  // namespace dmi
+static void InitDefaultsUuid_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Uuid_default_instance_;
+    new (ptr) ::dmi::Uuid();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Uuid::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUuid_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsHardwareID_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_HardwareID_default_instance_;
+    new (ptr) ::dmi::HardwareID();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::HardwareID::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_HardwareID_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsHardwareID_dmi_2fhw_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsUri_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Uri_default_instance_;
+    new (ptr) ::dmi::Uri();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Uri::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_Uri_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUri_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsComponentState_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ComponentState_default_instance_;
+    new (ptr) ::dmi::ComponentState();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ComponentState::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ComponentState_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsComponentState_dmi_2fhw_2eproto}, {
+      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,}};
+
+static void InitDefaultsComponentSensorData_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ComponentSensorData_default_instance_;
+    new (ptr) ::dmi::ComponentSensorData();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ComponentSensorData::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ComponentSensorData_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsComponentSensorData_dmi_2fhw_2eproto}, {
+      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,}};
+
+static void InitDefaultsPortComponentAttributes_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_PortComponentAttributes_default_instance_;
+    new (ptr) ::dmi::PortComponentAttributes();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::PortComponentAttributes::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_PortComponentAttributes_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsPortComponentAttributes_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsContainerComponentAttributes_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ContainerComponentAttributes_default_instance_;
+    new (ptr) ::dmi::ContainerComponentAttributes();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ContainerComponentAttributes::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsContainerComponentAttributes_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsPsuComponentAttributes_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_PsuComponentAttributes_default_instance_;
+    new (ptr) ::dmi::PsuComponentAttributes();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::PsuComponentAttributes::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_PsuComponentAttributes_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsPsuComponentAttributes_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsTransceiverComponentsAttributes_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_TransceiverComponentsAttributes_default_instance_;
+    new (ptr) ::dmi::TransceiverComponentsAttributes();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::TransceiverComponentsAttributes::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsTransceiverComponentsAttributes_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsComponent_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Component_default_instance_;
+    new (ptr) ::dmi::Component();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Component::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<9> scc_info_Component_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 9, InitDefaultsComponent_dmi_2fhw_2eproto}, {
+      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,
+      &scc_info_Uri_dmi_2fhw_2eproto.base,
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,
+      &scc_info_ComponentState_dmi_2fhw_2eproto.base,
+      &scc_info_ComponentSensorData_dmi_2fhw_2eproto.base,
+      &scc_info_PortComponentAttributes_dmi_2fhw_2eproto.base,
+      &scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto.base,
+      &scc_info_PsuComponentAttributes_dmi_2fhw_2eproto.base,
+      &scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsHardware_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Hardware_default_instance_;
+    new (ptr) ::dmi::Hardware();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Hardware::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_Hardware_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsHardware_dmi_2fhw_2eproto}, {
+      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,
+      &scc_info_Component_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsModifiableComponent_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ModifiableComponent_default_instance_;
+    new (ptr) ::dmi::ModifiableComponent();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ModifiableComponent::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_ModifiableComponent_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsModifiableComponent_dmi_2fhw_2eproto}, {
+      &scc_info_Component_dmi_2fhw_2eproto.base,
+      &scc_info_Uri_dmi_2fhw_2eproto.base,}};
+
+void InitDefaults_dmi_2fhw_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_Uuid_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_HardwareID_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Uri_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ComponentState_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ComponentSensorData_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_PortComponentAttributes_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_PsuComponentAttributes_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Component_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Hardware_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ModifiableComponent_dmi_2fhw_2eproto.base);
+}
+
+::google::protobuf::Metadata file_level_metadata_dmi_2fhw_2eproto[12];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fhw_2eproto[15];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fhw_2eproto = nullptr;
+
+const ::google::protobuf::uint32 TableStruct_dmi_2fhw_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Uuid, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Uuid, uuid_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::HardwareID, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::HardwareID, uuid_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Uri, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Uri, uri_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, state_last_changed_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, admin_state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, oper_state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, usage_state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, alarm_state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, standby_state_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, value_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, type_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, scale_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, precision_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, units_display_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, timestamp_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, value_update_rate_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, data_type_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, connector_type_),
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, speed_),
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, protocol_),
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, physical_label_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ContainerComponentAttributes, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ContainerComponentAttributes, physical_label_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::PsuComponentAttributes, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::PsuComponentAttributes, supported_voltage_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, form_factor_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, trans_type_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, max_distance_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, max_distance_scale_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, rx_wavelength_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, tx_wavelength_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, wavelength_scale_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, _internal_metadata_),
+  ~0u,  // no _extensions_
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, _oneof_case_[0]),
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, class__),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, description_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, parent_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, parent_rel_pos_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, children_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, hardware_rev_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, firmware_rev_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, software_rev_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, serial_num_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, mfg_name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, model_name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, alias_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, asset_id_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, is_fru_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, mfg_date_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, uri_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, sensor_data_),
+  offsetof(::dmi::ComponentDefaultTypeInternal, port_attr_),
+  offsetof(::dmi::ComponentDefaultTypeInternal, container_attr_),
+  offsetof(::dmi::ComponentDefaultTypeInternal, psu_attr_),
+  offsetof(::dmi::ComponentDefaultTypeInternal, transceiver_attr_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, specific_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Hardware, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Hardware, last_change_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Hardware, root_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Hardware, last_booted_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, class__),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, parent_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, parent_rel_pos_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, alias_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, asset_id_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, uri_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, admin_state_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  { 0, -1, sizeof(::dmi::Uuid)},
+  { 6, -1, sizeof(::dmi::HardwareID)},
+  { 12, -1, sizeof(::dmi::Uri)},
+  { 18, -1, sizeof(::dmi::ComponentState)},
+  { 29, -1, sizeof(::dmi::ComponentSensorData)},
+  { 43, -1, sizeof(::dmi::PortComponentAttributes)},
+  { 52, -1, sizeof(::dmi::ContainerComponentAttributes)},
+  { 58, -1, sizeof(::dmi::PsuComponentAttributes)},
+  { 64, -1, sizeof(::dmi::TransceiverComponentsAttributes)},
+  { 76, -1, sizeof(::dmi::Component)},
+  { 106, -1, sizeof(::dmi::Hardware)},
+  { 114, -1, sizeof(::dmi::ModifiableComponent)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Uuid_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_HardwareID_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Uri_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ComponentState_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ComponentSensorData_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_PortComponentAttributes_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ContainerComponentAttributes_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_PsuComponentAttributes_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_TransceiverComponentsAttributes_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Component_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Hardware_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ModifiableComponent_default_instance_),
+};
+
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fhw_2eproto = {
+  {}, AddDescriptors_dmi_2fhw_2eproto, "dmi/hw.proto", schemas,
+  file_default_instances, TableStruct_dmi_2fhw_2eproto::offsets,
+  file_level_metadata_dmi_2fhw_2eproto, 12, file_level_enum_descriptors_dmi_2fhw_2eproto, file_level_service_descriptors_dmi_2fhw_2eproto,
+};
+
+const char descriptor_table_protodef_dmi_2fhw_2eproto[] =
+  "\n\014dmi/hw.proto\022\003dmi\032\037google/protobuf/tim"
+  "estamp.proto\"\024\n\004Uuid\022\014\n\004uuid\030\001 \001(\t\"%\n\nHa"
+  "rdwareID\022\027\n\004uuid\030\001 \001(\0132\t.dmi.Uuid\"\022\n\003Uri"
+  "\022\013\n\003uri\030\001 \001(\t\"\265\002\n\016ComponentState\0226\n\022stat"
+  "e_last_changed\030\001 \001(\0132\032.google.protobuf.T"
+  "imestamp\022-\n\013admin_state\030\002 \001(\0162\030.dmi.Comp"
+  "onentAdminState\022+\n\noper_state\030\003 \001(\0162\027.dm"
+  "i.ComponentOperState\022-\n\013usage_state\030\004 \001("
+  "\0162\030.dmi.ComponentUsageState\022-\n\013alarm_sta"
+  "te\030\005 \001(\0162\030.dmi.ComponentAlarmState\0221\n\rst"
+  "andby_state\030\006 \001(\0162\032.dmi.ComponentStandby"
+  "State\"\220\002\n\023ComponentSensorData\022\r\n\005value\030\001"
+  " \001(\005\022 \n\004type\030\002 \001(\0162\022.dmi.DataValueType\022\036"
+  "\n\005scale\030\003 \001(\0162\017.dmi.ValueScale\022\021\n\tprecis"
+  "ion\030\004 \001(\005\022!\n\006status\030\005 \001(\0162\021.dmi.SensorSt"
+  "atus\022\025\n\runits_display\030\006 \001(\t\022-\n\ttimestamp"
+  "\030\007 \001(\0132\032.google.protobuf.Timestamp\022\031\n\021va"
+  "lue_update_rate\030\010 \001(\r\022\021\n\tdata_type\030\t \001(\t"
+  "\"\202\005\n\027PortComponentAttributes\022B\n\016connecto"
+  "r_type\030\001 \001(\0162*.dmi.PortComponentAttribut"
+  "es.ConnectorType\0221\n\005speed\030\002 \001(\0162\".dmi.Po"
+  "rtComponentAttributes.Speed\0227\n\010protocol\030"
+  "\003 \001(\0162%.dmi.PortComponentAttributes.Prot"
+  "ocol\022\026\n\016physical_label\030\004 \001(\t\"p\n\rConnecto"
+  "rType\022\034\n\030CONNECTOR_TYPE_UNDEFINED\020\000\022\010\n\004R"
+  "J45\020\001\022\014\n\010FIBER_LC\020\002\022\017\n\013FIBER_SC_PC\020\003\022\r\n\t"
+  "FIBER_MPO\020\004\022\t\n\005RS232\020\005\"\256\001\n\005Speed\022\023\n\017SPEE"
+  "D_UNDEFINED\020\000\022\013\n\007DYNAMIC\020\001\022\r\n\tGIGABIT_1\020"
+  "\002\022\016\n\nGIGABIT_10\020\003\022\016\n\nGIGABIT_25\020\004\022\016\n\nGIG"
+  "ABIT_40\020\005\022\017\n\013GIGABIT_100\020\006\022\017\n\013GIGABIT_40"
+  "0\020\007\022\020\n\014MEGABIT_2500\020\010\022\020\n\014MEGABIT_1250\020\t\""
+  "|\n\010Protocol\022\026\n\022PROTOCOL_UNDEFINED\020\000\022\014\n\010E"
+  "THERNET\020\001\022\010\n\004GPON\020\002\022\t\n\005XGPON\020\003\022\n\n\006XGSPON"
+  "\020\004\022\t\n\005GFAST\020\005\022\n\n\006SERIAL\020\006\022\010\n\004EPON\020\007\022\010\n\004B"
+  "ITS\020\010\"6\n\034ContainerComponentAttributes\022\026\n"
+  "\016physical_label\030\001 \001(\t\"\263\001\n\026PsuComponentAt"
+  "tributes\022G\n\021supported_voltage\030\001 \001(\0162,.dm"
+  "i.PsuComponentAttributes.SupportedVoltag"
+  "e\"P\n\020SupportedVoltage\022\037\n\033SUPPORTED_VOLTA"
+  "GE_UNDEFINED\020\000\022\007\n\003V48\020\001\022\010\n\004V230\020\002\022\010\n\004V11"
+  "5\020\003\"\357\004\n\037TransceiverComponentsAttributes\022"
+  "D\n\013form_factor\030\001 \001(\0162/.dmi.TransceiverCo"
+  "mponentsAttributes.FormFactor\022=\n\ntrans_t"
+  "ype\030\002 \001(\0162).dmi.TransceiverComponentsAtt"
+  "ributes.Type\022\024\n\014max_distance\030\003 \001(\r\022+\n\022ma"
+  "x_distance_scale\030\004 \001(\0162\017.dmi.ValueScale\022"
+  "\025\n\rrx_wavelength\030\005 \003(\r\022\025\n\rtx_wavelength\030"
+  "\006 \003(\r\022)\n\020wavelength_scale\030\007 \001(\0162\017.dmi.Va"
+  "lueScale\"\300\001\n\nFormFactor\022\027\n\023FORM_FACTOR_U"
+  "NKNOWN\020\000\022\010\n\004QSFP\020\001\022\r\n\tQSFP_PLUS\020\002\022\n\n\006QSF"
+  "P28\020\003\022\007\n\003SFP\020\004\022\014\n\010SFP_PLUS\020\005\022\007\n\003XFP\020\006\022\010\n"
+  "\004CFP4\020\007\022\010\n\004CFP2\020\010\022\010\n\004CPAK\020\t\022\006\n\002X2\020\n\022\t\n\005O"
+  "THER\020\013\022\007\n\003CFP\020\014\022\014\n\010CFP2_ACO\020\r\022\014\n\010CFP2_DC"
+  "O\020\016\"h\n\004Type\022\020\n\014TYPE_UNKNOWN\020\000\022\014\n\010ETHERNE"
+  "T\020\001\022\010\n\004GPON\020\002\022\t\n\005XGPON\020\003\022\n\n\006XGSPON\020\004\022\010\n\004"
+  "CPON\020\005\022\013\n\007NG_PON2\020\006\022\010\n\004EPON\020\007\"\350\005\n\tCompon"
+  "ent\022\014\n\004name\030\001 \001(\t\022!\n\005class\030\002 \001(\0162\022.dmi.C"
+  "omponentType\022\023\n\013description\030\003 \001(\t\022\016\n\006par"
+  "ent\030\004 \001(\t\022\026\n\016parent_rel_pos\030\005 \001(\005\022 \n\010chi"
+  "ldren\030\006 \003(\0132\016.dmi.Component\022\024\n\014hardware_"
+  "rev\030\007 \001(\t\022\024\n\014firmware_rev\030\010 \001(\t\022\024\n\014softw"
+  "are_rev\030\t \001(\t\022\022\n\nserial_num\030\n \001(\t\022\020\n\010mfg"
+  "_name\030\013 \001(\t\022\022\n\nmodel_name\030\014 \001(\t\022\r\n\005alias"
+  "\030\r \001(\t\022\020\n\010asset_id\030\016 \001(\t\022\016\n\006is_fru\030\017 \001(\010"
+  "\022,\n\010mfg_date\030\020 \001(\0132\032.google.protobuf.Tim"
+  "estamp\022\025\n\003uri\030\021 \001(\0132\010.dmi.Uri\022\027\n\004uuid\030\022 "
+  "\001(\0132\t.dmi.Uuid\022\"\n\005state\030\023 \001(\0132\023.dmi.Comp"
+  "onentState\022-\n\013sensor_data\030\024 \003(\0132\030.dmi.Co"
+  "mponentSensorData\0221\n\tport_attr\0302 \001(\0132\034.d"
+  "mi.PortComponentAttributesH\000\022;\n\016containe"
+  "r_attr\0303 \001(\0132!.dmi.ContainerComponentAtt"
+  "ributesH\000\022/\n\010psu_attr\0304 \001(\0132\033.dmi.PsuCom"
+  "ponentAttributesH\000\022@\n\020transceiver_attr\0305"
+  " \001(\0132$.dmi.TransceiverComponentsAttribut"
+  "esH\000B\n\n\010specific\"\212\001\n\010Hardware\022/\n\013last_ch"
+  "ange\030\001 \001(\0132\032.google.protobuf.Timestamp\022\034"
+  "\n\004root\030\002 \001(\0132\016.dmi.Component\022/\n\013last_boo"
+  "ted\030\003 \001(\0132\032.google.protobuf.Timestamp\"\345\001"
+  "\n\023ModifiableComponent\022\014\n\004name\030\001 \001(\t\022!\n\005c"
+  "lass\030\002 \001(\0162\022.dmi.ComponentType\022\036\n\006parent"
+  "\030\003 \001(\0132\016.dmi.Component\022\026\n\016parent_rel_pos"
+  "\030\004 \001(\005\022\r\n\005alias\030\005 \001(\t\022\020\n\010asset_id\030\006 \001(\t\022"
+  "\025\n\003uri\030\007 \001(\0132\010.dmi.Uri\022-\n\013admin_state\030\010 "
+  "\001(\0162\030.dmi.ComponentAdminState*\264\003\n\rCompon"
+  "entType\022\034\n\030COMPONENT_TYPE_UNDEFINED\020\000\022\032\n"
+  "\026COMPONENT_TYPE_UNKNOWN\020\001\022\032\n\026COMPONENT_T"
+  "YPE_CHASSIS\020\002\022\034\n\030COMPONENT_TYPE_BACKPLAN"
+  "E\020\003\022\034\n\030COMPONENT_TYPE_CONTAINER\020\004\022\037\n\033COM"
+  "PONENT_TYPE_POWER_SUPPLY\020\005\022\026\n\022COMPONENT_"
+  "TYPE_FAN\020\006\022\031\n\025COMPONENT_TYPE_SENSOR\020\007\022\031\n"
+  "\025COMPONENT_TYPE_MODULE\020\010\022\027\n\023COMPONENT_TY"
+  "PE_PORT\020\t\022\026\n\022COMPONENT_TYPE_CPU\020\n\022\032\n\026COM"
+  "PONENT_TYPE_BATTERY\020\013\022\032\n\026COMPONENT_TYPE_"
+  "STORAGE\020\014\022\031\n\025COMPONENT_TYPE_MEMORY\020\r\022\036\n\032"
+  "COMPONENT_TYPE_TRANSCEIVER\020\016*\263\001\n\023Compone"
+  "ntAdminState\022\036\n\032COMP_ADMIN_STATE_UNDEFIN"
+  "ED\020\000\022\034\n\030COMP_ADMIN_STATE_UNKNOWN\020\001\022\033\n\027CO"
+  "MP_ADMIN_STATE_LOCKED\020\002\022\"\n\036COMP_ADMIN_ST"
+  "ATE_SHUTTING_DOWN\020\003\022\035\n\031COMP_ADMIN_STATE_"
+  "UNLOCKED\020\004*\250\001\n\022ComponentOperState\022\035\n\031COM"
+  "P_OPER_STATE_UNDEFINED\020\000\022\033\n\027COMP_OPER_ST"
+  "ATE_UNKNOWN\020\001\022\034\n\030COMP_OPER_STATE_DISABLE"
+  "D\020\002\022\033\n\027COMP_OPER_STATE_ENABLED\020\003\022\033\n\027COMP"
+  "_OPER_STATE_TESTING\020\004*\246\001\n\023ComponentUsage"
+  "State\022\036\n\032COMP_USAGE_STATE_UNDEFINED\020\000\022\034\n"
+  "\030COMP_USAGE_STATE_UNKNOWN\020\001\022\031\n\025COMP_USAG"
+  "E_STATE_IDLE\020\002\022\033\n\027COMP_USAGE_STATE_ACTIV"
+  "E\020\003\022\031\n\025COMP_USAGE_STATE_BUSY\020\004*\217\002\n\023Compo"
+  "nentAlarmState\022\036\n\032COMP_ALARM_STATE_UNDEF"
+  "INED\020\000\022\034\n\030COMP_ALARM_STATE_UNKNOWN\020\001\022!\n\035"
+  "COMP_ALARM_STATE_UNDER_REPAIR\020\002\022\035\n\031COMP_"
+  "ALARM_STATE_CRITICAL\020\003\022\032\n\026COMP_ALARM_STA"
+  "TE_MAJOR\020\004\022\032\n\026COMP_ALARM_STATE_MINOR\020\005\022\034"
+  "\n\030COMP_ALARM_STATE_WARNING\020\006\022\"\n\036COMP_ALA"
+  "RM_STATE_INDETERMINATE\020\007*\274\001\n\025ComponentSt"
+  "andbyState\022 \n\034COMP_STANDBY_STATE_UNDEFIN"
+  "ED\020\000\022\036\n\032COMP_STANDBY_STATE_UNKNOWN\020\001\022\032\n\026"
+  "COMP_STANDBY_STATE_HOT\020\002\022\033\n\027COMP_STANDBY"
+  "_STATE_COLD\020\003\022(\n$COMP_STANDBY_STATE_PROV"
+  "IDING_SERVICE\020\004*\211\003\n\rDataValueType\022\030\n\024VAL"
+  "UE_TYPE_UNDEFINED\020\000\022\024\n\020VALUE_TYPE_OTHER\020"
+  "\001\022\026\n\022VALUE_TYPE_UNKNOWN\020\002\022\027\n\023VALUE_TYPE_"
+  "VOLTS_AC\020\003\022\027\n\023VALUE_TYPE_VOLTS_DC\020\004\022\026\n\022V"
+  "ALUE_TYPE_AMPERES\020\005\022\024\n\020VALUE_TYPE_WATTS\020"
+  "\006\022\024\n\020VALUE_TYPE_HERTZ\020\007\022\026\n\022VALUE_TYPE_CE"
+  "LSIUS\020\010\022\031\n\025VALUE_TYPE_PERCENT_RH\020\t\022\022\n\016VA"
+  "LUE_TYPE_RPM\020\n\022\022\n\016VALUE_TYPE_CMM\020\013\022\032\n\026VA"
+  "LUE_TYPE_TRUTH_VALUE\020\014\022\026\n\022VALUE_TYPE_PER"
+  "CENT\020\r\022\025\n\021VALUE_TYPE_METERS\020\016\022\024\n\020VALUE_T"
+  "YPE_BYTES\020\017*\244\003\n\nValueScale\022\031\n\025VALUE_SCAL"
+  "E_UNDEFINED\020\000\022\025\n\021VALUE_SCALE_YOCTO\020\001\022\025\n\021"
+  "VALUE_SCALE_ZEPTO\020\002\022\024\n\020VALUE_SCALE_ATTO\020"
+  "\003\022\025\n\021VALUE_SCALE_FEMTO\020\004\022\024\n\020VALUE_SCALE_"
+  "PICO\020\005\022\024\n\020VALUE_SCALE_NANO\020\006\022\025\n\021VALUE_SC"
+  "ALE_MICRO\020\007\022\025\n\021VALUE_SCALE_MILLI\020\010\022\025\n\021VA"
+  "LUE_SCALE_UNITS\020\t\022\024\n\020VALUE_SCALE_KILO\020\n\022"
+  "\024\n\020VALUE_SCALE_MEGA\020\013\022\024\n\020VALUE_SCALE_GIG"
+  "A\020\014\022\024\n\020VALUE_SCALE_TERA\020\r\022\024\n\020VALUE_SCALE"
+  "_PETA\020\016\022\023\n\017VALUE_SCALE_EXA\020\017\022\025\n\021VALUE_SC"
+  "ALE_ZETTA\020\020\022\025\n\021VALUE_SCALE_YOTTA\020\021*\202\001\n\014S"
+  "ensorStatus\022\033\n\027SENSOR_STATUS_UNDEFINED\020\000"
+  "\022\024\n\020SENSOR_STATUS_OK\020\001\022\035\n\031SENSOR_STATUS_"
+  "UNAVAILABLE\020\002\022 \n\034SENSOR_STATUS_NONOPERAT"
+  "IONAL\020\003B;Z9github.com/opencord/device-ma"
+  "nagement-interface/v3/go/dmib\006proto3"
+  ;
+::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fhw_2eproto = {
+  false, InitDefaults_dmi_2fhw_2eproto, 
+  descriptor_table_protodef_dmi_2fhw_2eproto,
+  "dmi/hw.proto", &assign_descriptors_table_dmi_2fhw_2eproto, 5796,
+};
+
+void AddDescriptors_dmi_2fhw_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
+    ::AddDescriptors_google_2fprotobuf_2ftimestamp_2eproto,
+  };
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_dmi_2fhw_2eproto, deps, 1);
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_dmi_2fhw_2eproto = []() { AddDescriptors_dmi_2fhw_2eproto(); return true; }();
+namespace dmi {
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_ConnectorType_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[0];
+}
+bool PortComponentAttributes_ConnectorType_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const PortComponentAttributes_ConnectorType PortComponentAttributes::CONNECTOR_TYPE_UNDEFINED;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::RJ45;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::FIBER_LC;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::FIBER_SC_PC;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::FIBER_MPO;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::RS232;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::ConnectorType_MIN;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::ConnectorType_MAX;
+const int PortComponentAttributes::ConnectorType_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Speed_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[1];
+}
+bool PortComponentAttributes_Speed_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const PortComponentAttributes_Speed PortComponentAttributes::SPEED_UNDEFINED;
+const PortComponentAttributes_Speed PortComponentAttributes::DYNAMIC;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_1;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_10;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_25;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_40;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_100;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_400;
+const PortComponentAttributes_Speed PortComponentAttributes::MEGABIT_2500;
+const PortComponentAttributes_Speed PortComponentAttributes::MEGABIT_1250;
+const PortComponentAttributes_Speed PortComponentAttributes::Speed_MIN;
+const PortComponentAttributes_Speed PortComponentAttributes::Speed_MAX;
+const int PortComponentAttributes::Speed_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Protocol_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[2];
+}
+bool PortComponentAttributes_Protocol_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const PortComponentAttributes_Protocol PortComponentAttributes::PROTOCOL_UNDEFINED;
+const PortComponentAttributes_Protocol PortComponentAttributes::ETHERNET;
+const PortComponentAttributes_Protocol PortComponentAttributes::GPON;
+const PortComponentAttributes_Protocol PortComponentAttributes::XGPON;
+const PortComponentAttributes_Protocol PortComponentAttributes::XGSPON;
+const PortComponentAttributes_Protocol PortComponentAttributes::GFAST;
+const PortComponentAttributes_Protocol PortComponentAttributes::SERIAL;
+const PortComponentAttributes_Protocol PortComponentAttributes::EPON;
+const PortComponentAttributes_Protocol PortComponentAttributes::BITS;
+const PortComponentAttributes_Protocol PortComponentAttributes::Protocol_MIN;
+const PortComponentAttributes_Protocol PortComponentAttributes::Protocol_MAX;
+const int PortComponentAttributes::Protocol_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* PsuComponentAttributes_SupportedVoltage_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[3];
+}
+bool PsuComponentAttributes_SupportedVoltage_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::SUPPORTED_VOLTAGE_UNDEFINED;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::V48;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::V230;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::V115;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::SupportedVoltage_MIN;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::SupportedVoltage_MAX;
+const int PsuComponentAttributes::SupportedVoltage_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_FormFactor_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[4];
+}
+bool TransceiverComponentsAttributes_FormFactor_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::FORM_FACTOR_UNKNOWN;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::QSFP;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::QSFP_PLUS;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::QSFP28;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::SFP;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::SFP_PLUS;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::XFP;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP4;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP2;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CPAK;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::X2;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::OTHER;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP2_ACO;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP2_DCO;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::FormFactor_MIN;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::FormFactor_MAX;
+const int TransceiverComponentsAttributes::FormFactor_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_Type_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[5];
+}
+bool TransceiverComponentsAttributes_Type_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::TYPE_UNKNOWN;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::ETHERNET;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::GPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::XGPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::XGSPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::CPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::NG_PON2;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::EPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::Type_MIN;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::Type_MAX;
+const int TransceiverComponentsAttributes::Type_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* ComponentType_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[6];
+}
+bool ComponentType_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentAdminState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[7];
+}
+bool ComponentAdminState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentOperState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[8];
+}
+bool ComponentOperState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentUsageState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[9];
+}
+bool ComponentUsageState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentAlarmState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[10];
+}
+bool ComponentAlarmState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentStandbyState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[11];
+}
+bool ComponentStandbyState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* DataValueType_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[12];
+}
+bool DataValueType_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ValueScale_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[13];
+}
+bool ValueScale_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+    case 16:
+    case 17:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* SensorStatus_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[14];
+}
+bool SensorStatus_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+
+// ===================================================================
+
+void Uuid::InitAsDefaultInstance() {
+}
+class Uuid::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Uuid::kUuidFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Uuid::Uuid()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Uuid)
+}
+Uuid::Uuid(const Uuid& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  uuid_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.uuid().size() > 0) {
+    uuid_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.uuid_);
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.Uuid)
+}
+
+void Uuid::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Uuid_dmi_2fhw_2eproto.base);
+  uuid_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+Uuid::~Uuid() {
+  // @@protoc_insertion_point(destructor:dmi.Uuid)
+  SharedDtor();
+}
+
+void Uuid::SharedDtor() {
+  uuid_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void Uuid::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Uuid& Uuid::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Uuid_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Uuid::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Uuid)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  uuid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Uuid::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Uuid*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Uuid.uuid");
+        object = msg->mutable_uuid();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Uuid::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Uuid)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_uuid()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->uuid().data(), static_cast<int>(this->uuid().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Uuid.uuid"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Uuid)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Uuid)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Uuid::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Uuid)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string uuid = 1;
+  if (this->uuid().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->uuid().data(), static_cast<int>(this->uuid().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Uuid.uuid");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->uuid(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Uuid)
+}
+
+::google::protobuf::uint8* Uuid::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Uuid)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string uuid = 1;
+  if (this->uuid().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->uuid().data(), static_cast<int>(this->uuid().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Uuid.uuid");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->uuid(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Uuid)
+  return target;
+}
+
+size_t Uuid::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Uuid)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string uuid = 1;
+  if (this->uuid().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->uuid());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Uuid::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Uuid)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Uuid* source =
+      ::google::protobuf::DynamicCastToGenerated<Uuid>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Uuid)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Uuid)
+    MergeFrom(*source);
+  }
+}
+
+void Uuid::MergeFrom(const Uuid& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Uuid)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.uuid().size() > 0) {
+
+    uuid_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.uuid_);
+  }
+}
+
+void Uuid::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Uuid)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Uuid::CopyFrom(const Uuid& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Uuid)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Uuid::IsInitialized() const {
+  return true;
+}
+
+void Uuid::Swap(Uuid* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Uuid::InternalSwap(Uuid* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  uuid_.Swap(&other->uuid_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+}
+
+::google::protobuf::Metadata Uuid::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void HardwareID::InitAsDefaultInstance() {
+  ::dmi::_HardwareID_default_instance_._instance.get_mutable()->uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class HardwareID::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& uuid(const HardwareID* msg);
+};
+
+const ::dmi::Uuid&
+HardwareID::HasBitSetters::uuid(const HardwareID* msg) {
+  return *msg->uuid_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int HardwareID::kUuidFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+HardwareID::HardwareID()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.HardwareID)
+}
+HardwareID::HardwareID(const HardwareID& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_uuid()) {
+    uuid_ = new ::dmi::Uuid(*from.uuid_);
+  } else {
+    uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.HardwareID)
+}
+
+void HardwareID::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_HardwareID_dmi_2fhw_2eproto.base);
+  uuid_ = nullptr;
+}
+
+HardwareID::~HardwareID() {
+  // @@protoc_insertion_point(destructor:dmi.HardwareID)
+  SharedDtor();
+}
+
+void HardwareID::SharedDtor() {
+  if (this != internal_default_instance()) delete uuid_;
+}
+
+void HardwareID::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const HardwareID& HardwareID::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_HardwareID_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void HardwareID::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.HardwareID)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
+    delete uuid_;
+  }
+  uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* HardwareID::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<HardwareID*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool HardwareID::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.HardwareID)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.HardwareID)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.HardwareID)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void HardwareID::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.HardwareID)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid uuid = 1;
+  if (this->has_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::uuid(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.HardwareID)
+}
+
+::google::protobuf::uint8* HardwareID::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.HardwareID)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid uuid = 1;
+  if (this->has_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::uuid(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.HardwareID)
+  return target;
+}
+
+size_t HardwareID::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.HardwareID)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.Uuid uuid = 1;
+  if (this->has_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void HardwareID::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.HardwareID)
+  GOOGLE_DCHECK_NE(&from, this);
+  const HardwareID* source =
+      ::google::protobuf::DynamicCastToGenerated<HardwareID>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.HardwareID)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.HardwareID)
+    MergeFrom(*source);
+  }
+}
+
+void HardwareID::MergeFrom(const HardwareID& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.HardwareID)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_uuid()) {
+    mutable_uuid()->::dmi::Uuid::MergeFrom(from.uuid());
+  }
+}
+
+void HardwareID::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.HardwareID)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void HardwareID::CopyFrom(const HardwareID& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.HardwareID)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool HardwareID::IsInitialized() const {
+  return true;
+}
+
+void HardwareID::Swap(HardwareID* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void HardwareID::InternalSwap(HardwareID* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(uuid_, other->uuid_);
+}
+
+::google::protobuf::Metadata HardwareID::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void Uri::InitAsDefaultInstance() {
+}
+class Uri::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Uri::kUriFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Uri::Uri()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Uri)
+}
+Uri::Uri(const Uri& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  uri_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.uri().size() > 0) {
+    uri_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.uri_);
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.Uri)
+}
+
+void Uri::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Uri_dmi_2fhw_2eproto.base);
+  uri_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+Uri::~Uri() {
+  // @@protoc_insertion_point(destructor:dmi.Uri)
+  SharedDtor();
+}
+
+void Uri::SharedDtor() {
+  uri_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void Uri::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Uri& Uri::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Uri_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Uri::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Uri)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  uri_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Uri::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Uri*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string uri = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Uri.uri");
+        object = msg->mutable_uri();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Uri::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Uri)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string uri = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_uri()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->uri().data(), static_cast<int>(this->uri().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Uri.uri"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Uri)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Uri)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Uri::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Uri)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string uri = 1;
+  if (this->uri().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->uri().data(), static_cast<int>(this->uri().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Uri.uri");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->uri(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Uri)
+}
+
+::google::protobuf::uint8* Uri::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Uri)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string uri = 1;
+  if (this->uri().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->uri().data(), static_cast<int>(this->uri().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Uri.uri");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->uri(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Uri)
+  return target;
+}
+
+size_t Uri::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Uri)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string uri = 1;
+  if (this->uri().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->uri());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Uri::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Uri)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Uri* source =
+      ::google::protobuf::DynamicCastToGenerated<Uri>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Uri)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Uri)
+    MergeFrom(*source);
+  }
+}
+
+void Uri::MergeFrom(const Uri& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Uri)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.uri().size() > 0) {
+
+    uri_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.uri_);
+  }
+}
+
+void Uri::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Uri)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Uri::CopyFrom(const Uri& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Uri)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Uri::IsInitialized() const {
+  return true;
+}
+
+void Uri::Swap(Uri* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Uri::InternalSwap(Uri* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  uri_.Swap(&other->uri_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+}
+
+::google::protobuf::Metadata Uri::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ComponentState::InitAsDefaultInstance() {
+  ::dmi::_ComponentState_default_instance_._instance.get_mutable()->state_last_changed_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+}
+class ComponentState::HasBitSetters {
+ public:
+  static const ::google::protobuf::Timestamp& state_last_changed(const ComponentState* msg);
+};
+
+const ::google::protobuf::Timestamp&
+ComponentState::HasBitSetters::state_last_changed(const ComponentState* msg) {
+  return *msg->state_last_changed_;
+}
+void ComponentState::clear_state_last_changed() {
+  if (GetArenaNoVirtual() == nullptr && state_last_changed_ != nullptr) {
+    delete state_last_changed_;
+  }
+  state_last_changed_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ComponentState::kStateLastChangedFieldNumber;
+const int ComponentState::kAdminStateFieldNumber;
+const int ComponentState::kOperStateFieldNumber;
+const int ComponentState::kUsageStateFieldNumber;
+const int ComponentState::kAlarmStateFieldNumber;
+const int ComponentState::kStandbyStateFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ComponentState::ComponentState()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ComponentState)
+}
+ComponentState::ComponentState(const ComponentState& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_state_last_changed()) {
+    state_last_changed_ = new ::google::protobuf::Timestamp(*from.state_last_changed_);
+  } else {
+    state_last_changed_ = nullptr;
+  }
+  ::memcpy(&admin_state_, &from.admin_state_,
+    static_cast<size_t>(reinterpret_cast<char*>(&standby_state_) -
+    reinterpret_cast<char*>(&admin_state_)) + sizeof(standby_state_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ComponentState)
+}
+
+void ComponentState::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ComponentState_dmi_2fhw_2eproto.base);
+  ::memset(&state_last_changed_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&standby_state_) -
+      reinterpret_cast<char*>(&state_last_changed_)) + sizeof(standby_state_));
+}
+
+ComponentState::~ComponentState() {
+  // @@protoc_insertion_point(destructor:dmi.ComponentState)
+  SharedDtor();
+}
+
+void ComponentState::SharedDtor() {
+  if (this != internal_default_instance()) delete state_last_changed_;
+}
+
+void ComponentState::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ComponentState& ComponentState::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ComponentState_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ComponentState::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ComponentState)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && state_last_changed_ != nullptr) {
+    delete state_last_changed_;
+  }
+  state_last_changed_ = nullptr;
+  ::memset(&admin_state_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&standby_state_) -
+      reinterpret_cast<char*>(&admin_state_)) + sizeof(standby_state_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ComponentState::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ComponentState*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .google.protobuf.Timestamp state_last_changed = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_state_last_changed();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ComponentAdminState admin_state = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_admin_state(static_cast<::dmi::ComponentAdminState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentOperState oper_state = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_oper_state(static_cast<::dmi::ComponentOperState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentUsageState usage_state = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_usage_state(static_cast<::dmi::ComponentUsageState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentAlarmState alarm_state = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_alarm_state(static_cast<::dmi::ComponentAlarmState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentStandbyState standby_state = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_standby_state(static_cast<::dmi::ComponentStandbyState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ComponentState::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ComponentState)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .google.protobuf.Timestamp state_last_changed = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_state_last_changed()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentAdminState admin_state = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_admin_state(static_cast< ::dmi::ComponentAdminState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentOperState oper_state = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_oper_state(static_cast< ::dmi::ComponentOperState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentUsageState usage_state = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_usage_state(static_cast< ::dmi::ComponentUsageState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentAlarmState alarm_state = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_alarm_state(static_cast< ::dmi::ComponentAlarmState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentStandbyState standby_state = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (48 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_standby_state(static_cast< ::dmi::ComponentStandbyState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ComponentState)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ComponentState)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ComponentState::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ComponentState)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp state_last_changed = 1;
+  if (this->has_state_last_changed()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::state_last_changed(this), output);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 2;
+  if (this->admin_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->admin_state(), output);
+  }
+
+  // .dmi.ComponentOperState oper_state = 3;
+  if (this->oper_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      3, this->oper_state(), output);
+  }
+
+  // .dmi.ComponentUsageState usage_state = 4;
+  if (this->usage_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      4, this->usage_state(), output);
+  }
+
+  // .dmi.ComponentAlarmState alarm_state = 5;
+  if (this->alarm_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      5, this->alarm_state(), output);
+  }
+
+  // .dmi.ComponentStandbyState standby_state = 6;
+  if (this->standby_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      6, this->standby_state(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ComponentState)
+}
+
+::google::protobuf::uint8* ComponentState::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ComponentState)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp state_last_changed = 1;
+  if (this->has_state_last_changed()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::state_last_changed(this), target);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 2;
+  if (this->admin_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->admin_state(), target);
+  }
+
+  // .dmi.ComponentOperState oper_state = 3;
+  if (this->oper_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      3, this->oper_state(), target);
+  }
+
+  // .dmi.ComponentUsageState usage_state = 4;
+  if (this->usage_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      4, this->usage_state(), target);
+  }
+
+  // .dmi.ComponentAlarmState alarm_state = 5;
+  if (this->alarm_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      5, this->alarm_state(), target);
+  }
+
+  // .dmi.ComponentStandbyState standby_state = 6;
+  if (this->standby_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      6, this->standby_state(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ComponentState)
+  return target;
+}
+
+size_t ComponentState::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ComponentState)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp state_last_changed = 1;
+  if (this->has_state_last_changed()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *state_last_changed_);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 2;
+  if (this->admin_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->admin_state());
+  }
+
+  // .dmi.ComponentOperState oper_state = 3;
+  if (this->oper_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->oper_state());
+  }
+
+  // .dmi.ComponentUsageState usage_state = 4;
+  if (this->usage_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->usage_state());
+  }
+
+  // .dmi.ComponentAlarmState alarm_state = 5;
+  if (this->alarm_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->alarm_state());
+  }
+
+  // .dmi.ComponentStandbyState standby_state = 6;
+  if (this->standby_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->standby_state());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ComponentState::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ComponentState)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ComponentState* source =
+      ::google::protobuf::DynamicCastToGenerated<ComponentState>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ComponentState)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ComponentState)
+    MergeFrom(*source);
+  }
+}
+
+void ComponentState::MergeFrom(const ComponentState& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ComponentState)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_state_last_changed()) {
+    mutable_state_last_changed()->::google::protobuf::Timestamp::MergeFrom(from.state_last_changed());
+  }
+  if (from.admin_state() != 0) {
+    set_admin_state(from.admin_state());
+  }
+  if (from.oper_state() != 0) {
+    set_oper_state(from.oper_state());
+  }
+  if (from.usage_state() != 0) {
+    set_usage_state(from.usage_state());
+  }
+  if (from.alarm_state() != 0) {
+    set_alarm_state(from.alarm_state());
+  }
+  if (from.standby_state() != 0) {
+    set_standby_state(from.standby_state());
+  }
+}
+
+void ComponentState::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ComponentState)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ComponentState::CopyFrom(const ComponentState& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ComponentState)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ComponentState::IsInitialized() const {
+  return true;
+}
+
+void ComponentState::Swap(ComponentState* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ComponentState::InternalSwap(ComponentState* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(state_last_changed_, other->state_last_changed_);
+  swap(admin_state_, other->admin_state_);
+  swap(oper_state_, other->oper_state_);
+  swap(usage_state_, other->usage_state_);
+  swap(alarm_state_, other->alarm_state_);
+  swap(standby_state_, other->standby_state_);
+}
+
+::google::protobuf::Metadata ComponentState::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ComponentSensorData::InitAsDefaultInstance() {
+  ::dmi::_ComponentSensorData_default_instance_._instance.get_mutable()->timestamp_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+}
+class ComponentSensorData::HasBitSetters {
+ public:
+  static const ::google::protobuf::Timestamp& timestamp(const ComponentSensorData* msg);
+};
+
+const ::google::protobuf::Timestamp&
+ComponentSensorData::HasBitSetters::timestamp(const ComponentSensorData* msg) {
+  return *msg->timestamp_;
+}
+void ComponentSensorData::clear_timestamp() {
+  if (GetArenaNoVirtual() == nullptr && timestamp_ != nullptr) {
+    delete timestamp_;
+  }
+  timestamp_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ComponentSensorData::kValueFieldNumber;
+const int ComponentSensorData::kTypeFieldNumber;
+const int ComponentSensorData::kScaleFieldNumber;
+const int ComponentSensorData::kPrecisionFieldNumber;
+const int ComponentSensorData::kStatusFieldNumber;
+const int ComponentSensorData::kUnitsDisplayFieldNumber;
+const int ComponentSensorData::kTimestampFieldNumber;
+const int ComponentSensorData::kValueUpdateRateFieldNumber;
+const int ComponentSensorData::kDataTypeFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ComponentSensorData::ComponentSensorData()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ComponentSensorData)
+}
+ComponentSensorData::ComponentSensorData(const ComponentSensorData& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  units_display_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.units_display().size() > 0) {
+    units_display_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.units_display_);
+  }
+  data_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.data_type().size() > 0) {
+    data_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.data_type_);
+  }
+  if (from.has_timestamp()) {
+    timestamp_ = new ::google::protobuf::Timestamp(*from.timestamp_);
+  } else {
+    timestamp_ = nullptr;
+  }
+  ::memcpy(&value_, &from.value_,
+    static_cast<size_t>(reinterpret_cast<char*>(&value_update_rate_) -
+    reinterpret_cast<char*>(&value_)) + sizeof(value_update_rate_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ComponentSensorData)
+}
+
+void ComponentSensorData::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ComponentSensorData_dmi_2fhw_2eproto.base);
+  units_display_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  data_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&timestamp_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&value_update_rate_) -
+      reinterpret_cast<char*>(&timestamp_)) + sizeof(value_update_rate_));
+}
+
+ComponentSensorData::~ComponentSensorData() {
+  // @@protoc_insertion_point(destructor:dmi.ComponentSensorData)
+  SharedDtor();
+}
+
+void ComponentSensorData::SharedDtor() {
+  units_display_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  data_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete timestamp_;
+}
+
+void ComponentSensorData::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ComponentSensorData& ComponentSensorData::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ComponentSensorData_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ComponentSensorData::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ComponentSensorData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  units_display_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  data_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && timestamp_ != nullptr) {
+    delete timestamp_;
+  }
+  timestamp_ = nullptr;
+  ::memset(&value_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&value_update_rate_) -
+      reinterpret_cast<char*>(&value_)) + sizeof(value_update_rate_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ComponentSensorData::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ComponentSensorData*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // int32 value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.DataValueType type = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_type(static_cast<::dmi::DataValueType>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ValueScale scale = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_scale(static_cast<::dmi::ValueScale>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // int32 precision = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        msg->set_precision(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.SensorStatus status = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::SensorStatus>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string units_display = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ComponentSensorData.units_display");
+        object = msg->mutable_units_display();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // .google.protobuf.Timestamp timestamp = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_timestamp();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // uint32 value_update_rate = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 64) goto handle_unusual;
+        msg->set_value_update_rate(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string data_type = 9;
+      case 9: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ComponentSensorData.data_type");
+        object = msg->mutable_data_type();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ComponentSensorData::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ComponentSensorData)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // int32 value = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &value_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.DataValueType type = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_type(static_cast< ::dmi::DataValueType >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ValueScale scale = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_scale(static_cast< ::dmi::ValueScale >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // int32 precision = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &precision_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.SensorStatus status = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::SensorStatus >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string units_display = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_units_display()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->units_display().data(), static_cast<int>(this->units_display().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ComponentSensorData.units_display"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .google.protobuf.Timestamp timestamp = 7;
+      case 7: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_timestamp()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // uint32 value_update_rate = 8;
+      case 8: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (64 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, &value_update_rate_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string data_type = 9;
+      case 9: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (74 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_data_type()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->data_type().data(), static_cast<int>(this->data_type().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ComponentSensorData.data_type"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ComponentSensorData)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ComponentSensorData)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ComponentSensorData::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ComponentSensorData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // int32 value = 1;
+  if (this->value() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->value(), output);
+  }
+
+  // .dmi.DataValueType type = 2;
+  if (this->type() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->type(), output);
+  }
+
+  // .dmi.ValueScale scale = 3;
+  if (this->scale() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      3, this->scale(), output);
+  }
+
+  // int32 precision = 4;
+  if (this->precision() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->precision(), output);
+  }
+
+  // .dmi.SensorStatus status = 5;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      5, this->status(), output);
+  }
+
+  // string units_display = 6;
+  if (this->units_display().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->units_display().data(), static_cast<int>(this->units_display().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ComponentSensorData.units_display");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      6, this->units_display(), output);
+  }
+
+  // .google.protobuf.Timestamp timestamp = 7;
+  if (this->has_timestamp()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      7, HasBitSetters::timestamp(this), output);
+  }
+
+  // uint32 value_update_rate = 8;
+  if (this->value_update_rate() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32(8, this->value_update_rate(), output);
+  }
+
+  // string data_type = 9;
+  if (this->data_type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->data_type().data(), static_cast<int>(this->data_type().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ComponentSensorData.data_type");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      9, this->data_type(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ComponentSensorData)
+}
+
+::google::protobuf::uint8* ComponentSensorData::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ComponentSensorData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // int32 value = 1;
+  if (this->value() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->value(), target);
+  }
+
+  // .dmi.DataValueType type = 2;
+  if (this->type() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->type(), target);
+  }
+
+  // .dmi.ValueScale scale = 3;
+  if (this->scale() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      3, this->scale(), target);
+  }
+
+  // int32 precision = 4;
+  if (this->precision() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->precision(), target);
+  }
+
+  // .dmi.SensorStatus status = 5;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      5, this->status(), target);
+  }
+
+  // string units_display = 6;
+  if (this->units_display().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->units_display().data(), static_cast<int>(this->units_display().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ComponentSensorData.units_display");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        6, this->units_display(), target);
+  }
+
+  // .google.protobuf.Timestamp timestamp = 7;
+  if (this->has_timestamp()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        7, HasBitSetters::timestamp(this), target);
+  }
+
+  // uint32 value_update_rate = 8;
+  if (this->value_update_rate() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(8, this->value_update_rate(), target);
+  }
+
+  // string data_type = 9;
+  if (this->data_type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->data_type().data(), static_cast<int>(this->data_type().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ComponentSensorData.data_type");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        9, this->data_type(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ComponentSensorData)
+  return target;
+}
+
+size_t ComponentSensorData::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ComponentSensorData)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string units_display = 6;
+  if (this->units_display().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->units_display());
+  }
+
+  // string data_type = 9;
+  if (this->data_type().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->data_type());
+  }
+
+  // .google.protobuf.Timestamp timestamp = 7;
+  if (this->has_timestamp()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *timestamp_);
+  }
+
+  // int32 value = 1;
+  if (this->value() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->value());
+  }
+
+  // .dmi.DataValueType type = 2;
+  if (this->type() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
+  }
+
+  // .dmi.ValueScale scale = 3;
+  if (this->scale() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->scale());
+  }
+
+  // int32 precision = 4;
+  if (this->precision() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->precision());
+  }
+
+  // .dmi.SensorStatus status = 5;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // uint32 value_update_rate = 8;
+  if (this->value_update_rate() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::UInt32Size(
+        this->value_update_rate());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ComponentSensorData::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ComponentSensorData)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ComponentSensorData* source =
+      ::google::protobuf::DynamicCastToGenerated<ComponentSensorData>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ComponentSensorData)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ComponentSensorData)
+    MergeFrom(*source);
+  }
+}
+
+void ComponentSensorData::MergeFrom(const ComponentSensorData& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ComponentSensorData)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.units_display().size() > 0) {
+
+    units_display_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.units_display_);
+  }
+  if (from.data_type().size() > 0) {
+
+    data_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.data_type_);
+  }
+  if (from.has_timestamp()) {
+    mutable_timestamp()->::google::protobuf::Timestamp::MergeFrom(from.timestamp());
+  }
+  if (from.value() != 0) {
+    set_value(from.value());
+  }
+  if (from.type() != 0) {
+    set_type(from.type());
+  }
+  if (from.scale() != 0) {
+    set_scale(from.scale());
+  }
+  if (from.precision() != 0) {
+    set_precision(from.precision());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.value_update_rate() != 0) {
+    set_value_update_rate(from.value_update_rate());
+  }
+}
+
+void ComponentSensorData::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ComponentSensorData)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ComponentSensorData::CopyFrom(const ComponentSensorData& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ComponentSensorData)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ComponentSensorData::IsInitialized() const {
+  return true;
+}
+
+void ComponentSensorData::Swap(ComponentSensorData* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ComponentSensorData::InternalSwap(ComponentSensorData* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  units_display_.Swap(&other->units_display_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  data_type_.Swap(&other->data_type_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(timestamp_, other->timestamp_);
+  swap(value_, other->value_);
+  swap(type_, other->type_);
+  swap(scale_, other->scale_);
+  swap(precision_, other->precision_);
+  swap(status_, other->status_);
+  swap(value_update_rate_, other->value_update_rate_);
+}
+
+::google::protobuf::Metadata ComponentSensorData::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void PortComponentAttributes::InitAsDefaultInstance() {
+}
+class PortComponentAttributes::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int PortComponentAttributes::kConnectorTypeFieldNumber;
+const int PortComponentAttributes::kSpeedFieldNumber;
+const int PortComponentAttributes::kProtocolFieldNumber;
+const int PortComponentAttributes::kPhysicalLabelFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+PortComponentAttributes::PortComponentAttributes()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.PortComponentAttributes)
+}
+PortComponentAttributes::PortComponentAttributes(const PortComponentAttributes& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  physical_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.physical_label().size() > 0) {
+    physical_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.physical_label_);
+  }
+  ::memcpy(&connector_type_, &from.connector_type_,
+    static_cast<size_t>(reinterpret_cast<char*>(&protocol_) -
+    reinterpret_cast<char*>(&connector_type_)) + sizeof(protocol_));
+  // @@protoc_insertion_point(copy_constructor:dmi.PortComponentAttributes)
+}
+
+void PortComponentAttributes::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_PortComponentAttributes_dmi_2fhw_2eproto.base);
+  physical_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&connector_type_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&protocol_) -
+      reinterpret_cast<char*>(&connector_type_)) + sizeof(protocol_));
+}
+
+PortComponentAttributes::~PortComponentAttributes() {
+  // @@protoc_insertion_point(destructor:dmi.PortComponentAttributes)
+  SharedDtor();
+}
+
+void PortComponentAttributes::SharedDtor() {
+  physical_label_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void PortComponentAttributes::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const PortComponentAttributes& PortComponentAttributes::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_PortComponentAttributes_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void PortComponentAttributes::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.PortComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&connector_type_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&protocol_) -
+      reinterpret_cast<char*>(&connector_type_)) + sizeof(protocol_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* PortComponentAttributes::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<PortComponentAttributes*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_connector_type(static_cast<::dmi::PortComponentAttributes_ConnectorType>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.PortComponentAttributes.Speed speed = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_speed(static_cast<::dmi::PortComponentAttributes_Speed>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.PortComponentAttributes.Protocol protocol = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_protocol(static_cast<::dmi::PortComponentAttributes_Protocol>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string physical_label = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.PortComponentAttributes.physical_label");
+        object = msg->mutable_physical_label();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool PortComponentAttributes::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.PortComponentAttributes)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_connector_type(static_cast< ::dmi::PortComponentAttributes_ConnectorType >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.PortComponentAttributes.Speed speed = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_speed(static_cast< ::dmi::PortComponentAttributes_Speed >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.PortComponentAttributes.Protocol protocol = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_protocol(static_cast< ::dmi::PortComponentAttributes_Protocol >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string physical_label = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_physical_label()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.PortComponentAttributes.physical_label"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.PortComponentAttributes)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.PortComponentAttributes)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void PortComponentAttributes::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.PortComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+  if (this->connector_type() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->connector_type(), output);
+  }
+
+  // .dmi.PortComponentAttributes.Speed speed = 2;
+  if (this->speed() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->speed(), output);
+  }
+
+  // .dmi.PortComponentAttributes.Protocol protocol = 3;
+  if (this->protocol() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      3, this->protocol(), output);
+  }
+
+  // string physical_label = 4;
+  if (this->physical_label().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.PortComponentAttributes.physical_label");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->physical_label(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.PortComponentAttributes)
+}
+
+::google::protobuf::uint8* PortComponentAttributes::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.PortComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+  if (this->connector_type() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->connector_type(), target);
+  }
+
+  // .dmi.PortComponentAttributes.Speed speed = 2;
+  if (this->speed() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->speed(), target);
+  }
+
+  // .dmi.PortComponentAttributes.Protocol protocol = 3;
+  if (this->protocol() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      3, this->protocol(), target);
+  }
+
+  // string physical_label = 4;
+  if (this->physical_label().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.PortComponentAttributes.physical_label");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->physical_label(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.PortComponentAttributes)
+  return target;
+}
+
+size_t PortComponentAttributes::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.PortComponentAttributes)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string physical_label = 4;
+  if (this->physical_label().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->physical_label());
+  }
+
+  // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+  if (this->connector_type() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->connector_type());
+  }
+
+  // .dmi.PortComponentAttributes.Speed speed = 2;
+  if (this->speed() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->speed());
+  }
+
+  // .dmi.PortComponentAttributes.Protocol protocol = 3;
+  if (this->protocol() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->protocol());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void PortComponentAttributes::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.PortComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  const PortComponentAttributes* source =
+      ::google::protobuf::DynamicCastToGenerated<PortComponentAttributes>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.PortComponentAttributes)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.PortComponentAttributes)
+    MergeFrom(*source);
+  }
+}
+
+void PortComponentAttributes::MergeFrom(const PortComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.PortComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.physical_label().size() > 0) {
+
+    physical_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.physical_label_);
+  }
+  if (from.connector_type() != 0) {
+    set_connector_type(from.connector_type());
+  }
+  if (from.speed() != 0) {
+    set_speed(from.speed());
+  }
+  if (from.protocol() != 0) {
+    set_protocol(from.protocol());
+  }
+}
+
+void PortComponentAttributes::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.PortComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void PortComponentAttributes::CopyFrom(const PortComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.PortComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool PortComponentAttributes::IsInitialized() const {
+  return true;
+}
+
+void PortComponentAttributes::Swap(PortComponentAttributes* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void PortComponentAttributes::InternalSwap(PortComponentAttributes* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  physical_label_.Swap(&other->physical_label_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(connector_type_, other->connector_type_);
+  swap(speed_, other->speed_);
+  swap(protocol_, other->protocol_);
+}
+
+::google::protobuf::Metadata PortComponentAttributes::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ContainerComponentAttributes::InitAsDefaultInstance() {
+}
+class ContainerComponentAttributes::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ContainerComponentAttributes::kPhysicalLabelFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ContainerComponentAttributes::ContainerComponentAttributes()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ContainerComponentAttributes)
+}
+ContainerComponentAttributes::ContainerComponentAttributes(const ContainerComponentAttributes& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  physical_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.physical_label().size() > 0) {
+    physical_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.physical_label_);
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.ContainerComponentAttributes)
+}
+
+void ContainerComponentAttributes::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto.base);
+  physical_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+ContainerComponentAttributes::~ContainerComponentAttributes() {
+  // @@protoc_insertion_point(destructor:dmi.ContainerComponentAttributes)
+  SharedDtor();
+}
+
+void ContainerComponentAttributes::SharedDtor() {
+  physical_label_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void ContainerComponentAttributes::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ContainerComponentAttributes& ContainerComponentAttributes::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ContainerComponentAttributes::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ContainerComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ContainerComponentAttributes::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ContainerComponentAttributes*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string physical_label = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ContainerComponentAttributes.physical_label");
+        object = msg->mutable_physical_label();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ContainerComponentAttributes::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ContainerComponentAttributes)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string physical_label = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_physical_label()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ContainerComponentAttributes.physical_label"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ContainerComponentAttributes)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ContainerComponentAttributes)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ContainerComponentAttributes::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ContainerComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string physical_label = 1;
+  if (this->physical_label().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ContainerComponentAttributes.physical_label");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->physical_label(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ContainerComponentAttributes)
+}
+
+::google::protobuf::uint8* ContainerComponentAttributes::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ContainerComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string physical_label = 1;
+  if (this->physical_label().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ContainerComponentAttributes.physical_label");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->physical_label(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ContainerComponentAttributes)
+  return target;
+}
+
+size_t ContainerComponentAttributes::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ContainerComponentAttributes)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string physical_label = 1;
+  if (this->physical_label().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->physical_label());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ContainerComponentAttributes::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ContainerComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ContainerComponentAttributes* source =
+      ::google::protobuf::DynamicCastToGenerated<ContainerComponentAttributes>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ContainerComponentAttributes)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ContainerComponentAttributes)
+    MergeFrom(*source);
+  }
+}
+
+void ContainerComponentAttributes::MergeFrom(const ContainerComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ContainerComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.physical_label().size() > 0) {
+
+    physical_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.physical_label_);
+  }
+}
+
+void ContainerComponentAttributes::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ContainerComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ContainerComponentAttributes::CopyFrom(const ContainerComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ContainerComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ContainerComponentAttributes::IsInitialized() const {
+  return true;
+}
+
+void ContainerComponentAttributes::Swap(ContainerComponentAttributes* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ContainerComponentAttributes::InternalSwap(ContainerComponentAttributes* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  physical_label_.Swap(&other->physical_label_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+}
+
+::google::protobuf::Metadata ContainerComponentAttributes::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void PsuComponentAttributes::InitAsDefaultInstance() {
+}
+class PsuComponentAttributes::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int PsuComponentAttributes::kSupportedVoltageFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+PsuComponentAttributes::PsuComponentAttributes()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.PsuComponentAttributes)
+}
+PsuComponentAttributes::PsuComponentAttributes(const PsuComponentAttributes& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  supported_voltage_ = from.supported_voltage_;
+  // @@protoc_insertion_point(copy_constructor:dmi.PsuComponentAttributes)
+}
+
+void PsuComponentAttributes::SharedCtor() {
+  supported_voltage_ = 0;
+}
+
+PsuComponentAttributes::~PsuComponentAttributes() {
+  // @@protoc_insertion_point(destructor:dmi.PsuComponentAttributes)
+  SharedDtor();
+}
+
+void PsuComponentAttributes::SharedDtor() {
+}
+
+void PsuComponentAttributes::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const PsuComponentAttributes& PsuComponentAttributes::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_PsuComponentAttributes_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void PsuComponentAttributes::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.PsuComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  supported_voltage_ = 0;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* PsuComponentAttributes::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<PsuComponentAttributes*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_supported_voltage(static_cast<::dmi::PsuComponentAttributes_SupportedVoltage>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool PsuComponentAttributes::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.PsuComponentAttributes)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_supported_voltage(static_cast< ::dmi::PsuComponentAttributes_SupportedVoltage >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.PsuComponentAttributes)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.PsuComponentAttributes)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void PsuComponentAttributes::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.PsuComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+  if (this->supported_voltage() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->supported_voltage(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.PsuComponentAttributes)
+}
+
+::google::protobuf::uint8* PsuComponentAttributes::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.PsuComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+  if (this->supported_voltage() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->supported_voltage(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.PsuComponentAttributes)
+  return target;
+}
+
+size_t PsuComponentAttributes::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.PsuComponentAttributes)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+  if (this->supported_voltage() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->supported_voltage());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void PsuComponentAttributes::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.PsuComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  const PsuComponentAttributes* source =
+      ::google::protobuf::DynamicCastToGenerated<PsuComponentAttributes>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.PsuComponentAttributes)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.PsuComponentAttributes)
+    MergeFrom(*source);
+  }
+}
+
+void PsuComponentAttributes::MergeFrom(const PsuComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.PsuComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.supported_voltage() != 0) {
+    set_supported_voltage(from.supported_voltage());
+  }
+}
+
+void PsuComponentAttributes::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.PsuComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void PsuComponentAttributes::CopyFrom(const PsuComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.PsuComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool PsuComponentAttributes::IsInitialized() const {
+  return true;
+}
+
+void PsuComponentAttributes::Swap(PsuComponentAttributes* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void PsuComponentAttributes::InternalSwap(PsuComponentAttributes* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(supported_voltage_, other->supported_voltage_);
+}
+
+::google::protobuf::Metadata PsuComponentAttributes::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void TransceiverComponentsAttributes::InitAsDefaultInstance() {
+}
+class TransceiverComponentsAttributes::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int TransceiverComponentsAttributes::kFormFactorFieldNumber;
+const int TransceiverComponentsAttributes::kTransTypeFieldNumber;
+const int TransceiverComponentsAttributes::kMaxDistanceFieldNumber;
+const int TransceiverComponentsAttributes::kMaxDistanceScaleFieldNumber;
+const int TransceiverComponentsAttributes::kRxWavelengthFieldNumber;
+const int TransceiverComponentsAttributes::kTxWavelengthFieldNumber;
+const int TransceiverComponentsAttributes::kWavelengthScaleFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+TransceiverComponentsAttributes::TransceiverComponentsAttributes()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.TransceiverComponentsAttributes)
+}
+TransceiverComponentsAttributes::TransceiverComponentsAttributes(const TransceiverComponentsAttributes& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      rx_wavelength_(from.rx_wavelength_),
+      tx_wavelength_(from.tx_wavelength_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::memcpy(&form_factor_, &from.form_factor_,
+    static_cast<size_t>(reinterpret_cast<char*>(&wavelength_scale_) -
+    reinterpret_cast<char*>(&form_factor_)) + sizeof(wavelength_scale_));
+  // @@protoc_insertion_point(copy_constructor:dmi.TransceiverComponentsAttributes)
+}
+
+void TransceiverComponentsAttributes::SharedCtor() {
+  ::memset(&form_factor_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&wavelength_scale_) -
+      reinterpret_cast<char*>(&form_factor_)) + sizeof(wavelength_scale_));
+}
+
+TransceiverComponentsAttributes::~TransceiverComponentsAttributes() {
+  // @@protoc_insertion_point(destructor:dmi.TransceiverComponentsAttributes)
+  SharedDtor();
+}
+
+void TransceiverComponentsAttributes::SharedDtor() {
+}
+
+void TransceiverComponentsAttributes::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const TransceiverComponentsAttributes& TransceiverComponentsAttributes::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void TransceiverComponentsAttributes::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.TransceiverComponentsAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  rx_wavelength_.Clear();
+  tx_wavelength_.Clear();
+  ::memset(&form_factor_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&wavelength_scale_) -
+      reinterpret_cast<char*>(&form_factor_)) + sizeof(wavelength_scale_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* TransceiverComponentsAttributes::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<TransceiverComponentsAttributes*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_form_factor(static_cast<::dmi::TransceiverComponentsAttributes_FormFactor>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_trans_type(static_cast<::dmi::TransceiverComponentsAttributes_Type>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // uint32 max_distance = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        msg->set_max_distance(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ValueScale max_distance_scale = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_max_distance_scale(static_cast<::dmi::ValueScale>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // repeated uint32 rx_wavelength = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) == 42) {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::google::protobuf::internal::PackedUInt32Parser;
+          object = msg->mutable_rx_wavelength();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (size) ptr = parser_till_end(ptr, newend, object, ctx);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr == newend);
+          break;
+        } else if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        do {
+          msg->add_rx_wavelength(::google::protobuf::internal::ReadVarint(&ptr));
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 40 && (ptr += 1));
+        break;
+      }
+      // repeated uint32 tx_wavelength = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) == 50) {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::google::protobuf::internal::PackedUInt32Parser;
+          object = msg->mutable_tx_wavelength();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (size) ptr = parser_till_end(ptr, newend, object, ctx);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr == newend);
+          break;
+        } else if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
+        do {
+          msg->add_tx_wavelength(::google::protobuf::internal::ReadVarint(&ptr));
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 48 && (ptr += 1));
+        break;
+      }
+      // .dmi.ValueScale wavelength_scale = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_wavelength_scale(static_cast<::dmi::ValueScale>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool TransceiverComponentsAttributes::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.TransceiverComponentsAttributes)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_form_factor(static_cast< ::dmi::TransceiverComponentsAttributes_FormFactor >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_trans_type(static_cast< ::dmi::TransceiverComponentsAttributes_Type >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // uint32 max_distance = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, &max_distance_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ValueScale max_distance_scale = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_max_distance_scale(static_cast< ::dmi::ValueScale >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated uint32 rx_wavelength = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, this->mutable_rx_wavelength())));
+        } else if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 1, 42u, input, this->mutable_rx_wavelength())));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated uint32 tx_wavelength = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, this->mutable_tx_wavelength())));
+        } else if (static_cast< ::google::protobuf::uint8>(tag) == (48 & 0xFF)) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 1, 50u, input, this->mutable_tx_wavelength())));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ValueScale wavelength_scale = 7;
+      case 7: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (56 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_wavelength_scale(static_cast< ::dmi::ValueScale >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.TransceiverComponentsAttributes)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.TransceiverComponentsAttributes)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void TransceiverComponentsAttributes::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.TransceiverComponentsAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+  if (this->form_factor() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->form_factor(), output);
+  }
+
+  // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+  if (this->trans_type() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->trans_type(), output);
+  }
+
+  // uint32 max_distance = 3;
+  if (this->max_distance() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->max_distance(), output);
+  }
+
+  // .dmi.ValueScale max_distance_scale = 4;
+  if (this->max_distance_scale() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      4, this->max_distance_scale(), output);
+  }
+
+  // repeated uint32 rx_wavelength = 5;
+  if (this->rx_wavelength_size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteTag(5, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+    output->WriteVarint32(_rx_wavelength_cached_byte_size_.load(
+        std::memory_order_relaxed));
+  }
+  for (int i = 0, n = this->rx_wavelength_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
+      this->rx_wavelength(i), output);
+  }
+
+  // repeated uint32 tx_wavelength = 6;
+  if (this->tx_wavelength_size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+    output->WriteVarint32(_tx_wavelength_cached_byte_size_.load(
+        std::memory_order_relaxed));
+  }
+  for (int i = 0, n = this->tx_wavelength_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
+      this->tx_wavelength(i), output);
+  }
+
+  // .dmi.ValueScale wavelength_scale = 7;
+  if (this->wavelength_scale() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      7, this->wavelength_scale(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.TransceiverComponentsAttributes)
+}
+
+::google::protobuf::uint8* TransceiverComponentsAttributes::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.TransceiverComponentsAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+  if (this->form_factor() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->form_factor(), target);
+  }
+
+  // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+  if (this->trans_type() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->trans_type(), target);
+  }
+
+  // uint32 max_distance = 3;
+  if (this->max_distance() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->max_distance(), target);
+  }
+
+  // .dmi.ValueScale max_distance_scale = 4;
+  if (this->max_distance_scale() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      4, this->max_distance_scale(), target);
+  }
+
+  // repeated uint32 rx_wavelength = 5;
+  if (this->rx_wavelength_size() > 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+      5,
+      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+      target);
+    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+        _rx_wavelength_cached_byte_size_.load(std::memory_order_relaxed),
+         target);
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteUInt32NoTagToArray(this->rx_wavelength_, target);
+  }
+
+  // repeated uint32 tx_wavelength = 6;
+  if (this->tx_wavelength_size() > 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+      6,
+      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+      target);
+    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+        _tx_wavelength_cached_byte_size_.load(std::memory_order_relaxed),
+         target);
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteUInt32NoTagToArray(this->tx_wavelength_, target);
+  }
+
+  // .dmi.ValueScale wavelength_scale = 7;
+  if (this->wavelength_scale() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      7, this->wavelength_scale(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.TransceiverComponentsAttributes)
+  return target;
+}
+
+size_t TransceiverComponentsAttributes::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.TransceiverComponentsAttributes)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated uint32 rx_wavelength = 5;
+  {
+    size_t data_size = ::google::protobuf::internal::WireFormatLite::
+      UInt32Size(this->rx_wavelength_);
+    if (data_size > 0) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+            static_cast<::google::protobuf::int32>(data_size));
+    }
+    int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
+    _rx_wavelength_cached_byte_size_.store(cached_size,
+                                    std::memory_order_relaxed);
+    total_size += data_size;
+  }
+
+  // repeated uint32 tx_wavelength = 6;
+  {
+    size_t data_size = ::google::protobuf::internal::WireFormatLite::
+      UInt32Size(this->tx_wavelength_);
+    if (data_size > 0) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+            static_cast<::google::protobuf::int32>(data_size));
+    }
+    int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
+    _tx_wavelength_cached_byte_size_.store(cached_size,
+                                    std::memory_order_relaxed);
+    total_size += data_size;
+  }
+
+  // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+  if (this->form_factor() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->form_factor());
+  }
+
+  // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+  if (this->trans_type() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->trans_type());
+  }
+
+  // uint32 max_distance = 3;
+  if (this->max_distance() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::UInt32Size(
+        this->max_distance());
+  }
+
+  // .dmi.ValueScale max_distance_scale = 4;
+  if (this->max_distance_scale() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->max_distance_scale());
+  }
+
+  // .dmi.ValueScale wavelength_scale = 7;
+  if (this->wavelength_scale() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->wavelength_scale());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void TransceiverComponentsAttributes::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.TransceiverComponentsAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  const TransceiverComponentsAttributes* source =
+      ::google::protobuf::DynamicCastToGenerated<TransceiverComponentsAttributes>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.TransceiverComponentsAttributes)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.TransceiverComponentsAttributes)
+    MergeFrom(*source);
+  }
+}
+
+void TransceiverComponentsAttributes::MergeFrom(const TransceiverComponentsAttributes& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.TransceiverComponentsAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  rx_wavelength_.MergeFrom(from.rx_wavelength_);
+  tx_wavelength_.MergeFrom(from.tx_wavelength_);
+  if (from.form_factor() != 0) {
+    set_form_factor(from.form_factor());
+  }
+  if (from.trans_type() != 0) {
+    set_trans_type(from.trans_type());
+  }
+  if (from.max_distance() != 0) {
+    set_max_distance(from.max_distance());
+  }
+  if (from.max_distance_scale() != 0) {
+    set_max_distance_scale(from.max_distance_scale());
+  }
+  if (from.wavelength_scale() != 0) {
+    set_wavelength_scale(from.wavelength_scale());
+  }
+}
+
+void TransceiverComponentsAttributes::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.TransceiverComponentsAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void TransceiverComponentsAttributes::CopyFrom(const TransceiverComponentsAttributes& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.TransceiverComponentsAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool TransceiverComponentsAttributes::IsInitialized() const {
+  return true;
+}
+
+void TransceiverComponentsAttributes::Swap(TransceiverComponentsAttributes* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void TransceiverComponentsAttributes::InternalSwap(TransceiverComponentsAttributes* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  rx_wavelength_.InternalSwap(&other->rx_wavelength_);
+  tx_wavelength_.InternalSwap(&other->tx_wavelength_);
+  swap(form_factor_, other->form_factor_);
+  swap(trans_type_, other->trans_type_);
+  swap(max_distance_, other->max_distance_);
+  swap(max_distance_scale_, other->max_distance_scale_);
+  swap(wavelength_scale_, other->wavelength_scale_);
+}
+
+::google::protobuf::Metadata TransceiverComponentsAttributes::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void Component::InitAsDefaultInstance() {
+  ::dmi::_Component_default_instance_._instance.get_mutable()->mfg_date_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+  ::dmi::_Component_default_instance_._instance.get_mutable()->uri_ = const_cast< ::dmi::Uri*>(
+      ::dmi::Uri::internal_default_instance());
+  ::dmi::_Component_default_instance_._instance.get_mutable()->uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_Component_default_instance_._instance.get_mutable()->state_ = const_cast< ::dmi::ComponentState*>(
+      ::dmi::ComponentState::internal_default_instance());
+  ::dmi::_Component_default_instance_.port_attr_ = const_cast< ::dmi::PortComponentAttributes*>(
+      ::dmi::PortComponentAttributes::internal_default_instance());
+  ::dmi::_Component_default_instance_.container_attr_ = const_cast< ::dmi::ContainerComponentAttributes*>(
+      ::dmi::ContainerComponentAttributes::internal_default_instance());
+  ::dmi::_Component_default_instance_.psu_attr_ = const_cast< ::dmi::PsuComponentAttributes*>(
+      ::dmi::PsuComponentAttributes::internal_default_instance());
+  ::dmi::_Component_default_instance_.transceiver_attr_ = const_cast< ::dmi::TransceiverComponentsAttributes*>(
+      ::dmi::TransceiverComponentsAttributes::internal_default_instance());
+}
+class Component::HasBitSetters {
+ public:
+  static const ::google::protobuf::Timestamp& mfg_date(const Component* msg);
+  static const ::dmi::Uri& uri(const Component* msg);
+  static const ::dmi::Uuid& uuid(const Component* msg);
+  static const ::dmi::ComponentState& state(const Component* msg);
+  static const ::dmi::PortComponentAttributes& port_attr(const Component* msg);
+  static const ::dmi::ContainerComponentAttributes& container_attr(const Component* msg);
+  static const ::dmi::PsuComponentAttributes& psu_attr(const Component* msg);
+  static const ::dmi::TransceiverComponentsAttributes& transceiver_attr(const Component* msg);
+};
+
+const ::google::protobuf::Timestamp&
+Component::HasBitSetters::mfg_date(const Component* msg) {
+  return *msg->mfg_date_;
+}
+const ::dmi::Uri&
+Component::HasBitSetters::uri(const Component* msg) {
+  return *msg->uri_;
+}
+const ::dmi::Uuid&
+Component::HasBitSetters::uuid(const Component* msg) {
+  return *msg->uuid_;
+}
+const ::dmi::ComponentState&
+Component::HasBitSetters::state(const Component* msg) {
+  return *msg->state_;
+}
+const ::dmi::PortComponentAttributes&
+Component::HasBitSetters::port_attr(const Component* msg) {
+  return *msg->specific_.port_attr_;
+}
+const ::dmi::ContainerComponentAttributes&
+Component::HasBitSetters::container_attr(const Component* msg) {
+  return *msg->specific_.container_attr_;
+}
+const ::dmi::PsuComponentAttributes&
+Component::HasBitSetters::psu_attr(const Component* msg) {
+  return *msg->specific_.psu_attr_;
+}
+const ::dmi::TransceiverComponentsAttributes&
+Component::HasBitSetters::transceiver_attr(const Component* msg) {
+  return *msg->specific_.transceiver_attr_;
+}
+void Component::clear_mfg_date() {
+  if (GetArenaNoVirtual() == nullptr && mfg_date_ != nullptr) {
+    delete mfg_date_;
+  }
+  mfg_date_ = nullptr;
+}
+void Component::set_allocated_port_attr(::dmi::PortComponentAttributes* port_attr) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_specific();
+  if (port_attr) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      port_attr = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, port_attr, submessage_arena);
+    }
+    set_has_port_attr();
+    specific_.port_attr_ = port_attr;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.port_attr)
+}
+void Component::set_allocated_container_attr(::dmi::ContainerComponentAttributes* container_attr) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_specific();
+  if (container_attr) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      container_attr = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, container_attr, submessage_arena);
+    }
+    set_has_container_attr();
+    specific_.container_attr_ = container_attr;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.container_attr)
+}
+void Component::set_allocated_psu_attr(::dmi::PsuComponentAttributes* psu_attr) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_specific();
+  if (psu_attr) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      psu_attr = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, psu_attr, submessage_arena);
+    }
+    set_has_psu_attr();
+    specific_.psu_attr_ = psu_attr;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.psu_attr)
+}
+void Component::set_allocated_transceiver_attr(::dmi::TransceiverComponentsAttributes* transceiver_attr) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_specific();
+  if (transceiver_attr) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      transceiver_attr = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, transceiver_attr, submessage_arena);
+    }
+    set_has_transceiver_attr();
+    specific_.transceiver_attr_ = transceiver_attr;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.transceiver_attr)
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Component::kNameFieldNumber;
+const int Component::kClassFieldNumber;
+const int Component::kDescriptionFieldNumber;
+const int Component::kParentFieldNumber;
+const int Component::kParentRelPosFieldNumber;
+const int Component::kChildrenFieldNumber;
+const int Component::kHardwareRevFieldNumber;
+const int Component::kFirmwareRevFieldNumber;
+const int Component::kSoftwareRevFieldNumber;
+const int Component::kSerialNumFieldNumber;
+const int Component::kMfgNameFieldNumber;
+const int Component::kModelNameFieldNumber;
+const int Component::kAliasFieldNumber;
+const int Component::kAssetIdFieldNumber;
+const int Component::kIsFruFieldNumber;
+const int Component::kMfgDateFieldNumber;
+const int Component::kUriFieldNumber;
+const int Component::kUuidFieldNumber;
+const int Component::kStateFieldNumber;
+const int Component::kSensorDataFieldNumber;
+const int Component::kPortAttrFieldNumber;
+const int Component::kContainerAttrFieldNumber;
+const int Component::kPsuAttrFieldNumber;
+const int Component::kTransceiverAttrFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Component::Component()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Component)
+}
+Component::Component(const Component& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      children_(from.children_),
+      sensor_data_(from.sensor_data_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.name().size() > 0) {
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  description_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.description().size() > 0) {
+    description_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.description_);
+  }
+  parent_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.parent().size() > 0) {
+    parent_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parent_);
+  }
+  hardware_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.hardware_rev().size() > 0) {
+    hardware_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.hardware_rev_);
+  }
+  firmware_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.firmware_rev().size() > 0) {
+    firmware_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.firmware_rev_);
+  }
+  software_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.software_rev().size() > 0) {
+    software_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.software_rev_);
+  }
+  serial_num_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.serial_num().size() > 0) {
+    serial_num_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.serial_num_);
+  }
+  mfg_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.mfg_name().size() > 0) {
+    mfg_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.mfg_name_);
+  }
+  model_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.model_name().size() > 0) {
+    model_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.model_name_);
+  }
+  alias_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.alias().size() > 0) {
+    alias_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.alias_);
+  }
+  asset_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.asset_id().size() > 0) {
+    asset_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.asset_id_);
+  }
+  if (from.has_mfg_date()) {
+    mfg_date_ = new ::google::protobuf::Timestamp(*from.mfg_date_);
+  } else {
+    mfg_date_ = nullptr;
+  }
+  if (from.has_uri()) {
+    uri_ = new ::dmi::Uri(*from.uri_);
+  } else {
+    uri_ = nullptr;
+  }
+  if (from.has_uuid()) {
+    uuid_ = new ::dmi::Uuid(*from.uuid_);
+  } else {
+    uuid_ = nullptr;
+  }
+  if (from.has_state()) {
+    state_ = new ::dmi::ComponentState(*from.state_);
+  } else {
+    state_ = nullptr;
+  }
+  ::memcpy(&class__, &from.class__,
+    static_cast<size_t>(reinterpret_cast<char*>(&is_fru_) -
+    reinterpret_cast<char*>(&class__)) + sizeof(is_fru_));
+  clear_has_specific();
+  switch (from.specific_case()) {
+    case kPortAttr: {
+      mutable_port_attr()->::dmi::PortComponentAttributes::MergeFrom(from.port_attr());
+      break;
+    }
+    case kContainerAttr: {
+      mutable_container_attr()->::dmi::ContainerComponentAttributes::MergeFrom(from.container_attr());
+      break;
+    }
+    case kPsuAttr: {
+      mutable_psu_attr()->::dmi::PsuComponentAttributes::MergeFrom(from.psu_attr());
+      break;
+    }
+    case kTransceiverAttr: {
+      mutable_transceiver_attr()->::dmi::TransceiverComponentsAttributes::MergeFrom(from.transceiver_attr());
+      break;
+    }
+    case SPECIFIC_NOT_SET: {
+      break;
+    }
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.Component)
+}
+
+void Component::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Component_dmi_2fhw_2eproto.base);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  description_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  parent_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  hardware_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  firmware_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  software_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  serial_num_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  mfg_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  model_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&mfg_date_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&is_fru_) -
+      reinterpret_cast<char*>(&mfg_date_)) + sizeof(is_fru_));
+  clear_has_specific();
+}
+
+Component::~Component() {
+  // @@protoc_insertion_point(destructor:dmi.Component)
+  SharedDtor();
+}
+
+void Component::SharedDtor() {
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  description_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  parent_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  hardware_rev_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  firmware_rev_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  software_rev_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  serial_num_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  mfg_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  model_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete mfg_date_;
+  if (this != internal_default_instance()) delete uri_;
+  if (this != internal_default_instance()) delete uuid_;
+  if (this != internal_default_instance()) delete state_;
+  if (has_specific()) {
+    clear_specific();
+  }
+}
+
+void Component::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Component& Component::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Component_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Component::clear_specific() {
+// @@protoc_insertion_point(one_of_clear_start:dmi.Component)
+  switch (specific_case()) {
+    case kPortAttr: {
+      delete specific_.port_attr_;
+      break;
+    }
+    case kContainerAttr: {
+      delete specific_.container_attr_;
+      break;
+    }
+    case kPsuAttr: {
+      delete specific_.psu_attr_;
+      break;
+    }
+    case kTransceiverAttr: {
+      delete specific_.transceiver_attr_;
+      break;
+    }
+    case SPECIFIC_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = SPECIFIC_NOT_SET;
+}
+
+
+void Component::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Component)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  children_.Clear();
+  sensor_data_.Clear();
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  description_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  parent_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  hardware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  firmware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  software_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  serial_num_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  mfg_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  model_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && mfg_date_ != nullptr) {
+    delete mfg_date_;
+  }
+  mfg_date_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
+    delete uri_;
+  }
+  uri_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
+    delete uuid_;
+  }
+  uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && state_ != nullptr) {
+    delete state_;
+  }
+  state_ = nullptr;
+  ::memset(&class__, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&is_fru_) -
+      reinterpret_cast<char*>(&class__)) + sizeof(is_fru_));
+  clear_specific();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Component::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Component*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.name");
+        object = msg->mutable_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // .dmi.ComponentType class = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_class_(static_cast<::dmi::ComponentType>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string description = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.description");
+        object = msg->mutable_description();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string parent = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.parent");
+        object = msg->mutable_parent();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // int32 parent_rel_pos = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        msg->set_parent_rel_pos(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // repeated .dmi.Component children = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::Component::_InternalParse;
+          object = msg->add_children();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
+        break;
+      }
+      // string hardware_rev = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.hardware_rev");
+        object = msg->mutable_hardware_rev();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string firmware_rev = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.firmware_rev");
+        object = msg->mutable_firmware_rev();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string software_rev = 9;
+      case 9: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.software_rev");
+        object = msg->mutable_software_rev();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string serial_num = 10;
+      case 10: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.serial_num");
+        object = msg->mutable_serial_num();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string mfg_name = 11;
+      case 11: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 90) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.mfg_name");
+        object = msg->mutable_mfg_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string model_name = 12;
+      case 12: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 98) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.model_name");
+        object = msg->mutable_model_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string alias = 13;
+      case 13: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 106) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.alias");
+        object = msg->mutable_alias();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string asset_id = 14;
+      case 14: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 114) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.asset_id");
+        object = msg->mutable_asset_id();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // bool is_fru = 15;
+      case 15: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 120) goto handle_unusual;
+        msg->set_is_fru(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .google.protobuf.Timestamp mfg_date = 16;
+      case 16: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 130) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_mfg_date();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uri uri = 17;
+      case 17: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 138) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uri::_InternalParse;
+        object = msg->mutable_uri();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid uuid = 18;
+      case 18: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 146) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ComponentState state = 19;
+      case 19: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 154) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ComponentState::_InternalParse;
+        object = msg->mutable_state();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // repeated .dmi.ComponentSensorData sensor_data = 20;
+      case 20: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 162) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::ComponentSensorData::_InternalParse;
+          object = msg->add_sensor_data();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 418 && (ptr += 2));
+        break;
+      }
+      // .dmi.PortComponentAttributes port_attr = 50;
+      case 50: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 146) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::PortComponentAttributes::_InternalParse;
+        object = msg->mutable_port_attr();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ContainerComponentAttributes container_attr = 51;
+      case 51: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 154) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ContainerComponentAttributes::_InternalParse;
+        object = msg->mutable_container_attr();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.PsuComponentAttributes psu_attr = 52;
+      case 52: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 162) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::PsuComponentAttributes::_InternalParse;
+        object = msg->mutable_psu_attr();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+      case 53: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 170) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::TransceiverComponentsAttributes::_InternalParse;
+        object = msg->mutable_transceiver_attr();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Component::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Component)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string name = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->name().data(), static_cast<int>(this->name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentType class = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_class_(static_cast< ::dmi::ComponentType >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string description = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_description()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->description().data(), static_cast<int>(this->description().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.description"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string parent = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_parent()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->parent().data(), static_cast<int>(this->parent().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.parent"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // int32 parent_rel_pos = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &parent_rel_pos_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated .dmi.Component children = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_children()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string hardware_rev = 7;
+      case 7: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_hardware_rev()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->hardware_rev().data(), static_cast<int>(this->hardware_rev().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.hardware_rev"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string firmware_rev = 8;
+      case 8: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (66 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_firmware_rev()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->firmware_rev().data(), static_cast<int>(this->firmware_rev().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.firmware_rev"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string software_rev = 9;
+      case 9: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (74 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_software_rev()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->software_rev().data(), static_cast<int>(this->software_rev().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.software_rev"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string serial_num = 10;
+      case 10: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (82 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_serial_num()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->serial_num().data(), static_cast<int>(this->serial_num().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.serial_num"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string mfg_name = 11;
+      case 11: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (90 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_mfg_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->mfg_name().data(), static_cast<int>(this->mfg_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.mfg_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string model_name = 12;
+      case 12: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (98 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_model_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->model_name().data(), static_cast<int>(this->model_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.model_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string alias = 13;
+      case 13: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (106 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_alias()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->alias().data(), static_cast<int>(this->alias().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.alias"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string asset_id = 14;
+      case 14: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (114 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_asset_id()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.asset_id"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // bool is_fru = 15;
+      case 15: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (120 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &is_fru_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .google.protobuf.Timestamp mfg_date = 16;
+      case 16: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (130 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_mfg_date()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uri uri = 17;
+      case 17: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (138 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_uri()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid uuid = 18;
+      case 18: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (146 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentState state = 19;
+      case 19: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (154 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_state()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated .dmi.ComponentSensorData sensor_data = 20;
+      case 20: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (162 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_sensor_data()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.PortComponentAttributes port_attr = 50;
+      case 50: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (402 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_port_attr()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ContainerComponentAttributes container_attr = 51;
+      case 51: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (410 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_container_attr()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.PsuComponentAttributes psu_attr = 52;
+      case 52: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (418 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_psu_attr()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+      case 53: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (426 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_transceiver_attr()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Component)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Component)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Component::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Component)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->class_(), output);
+  }
+
+  // string description = 3;
+  if (this->description().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->description().data(), static_cast<int>(this->description().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.description");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->description(), output);
+  }
+
+  // string parent = 4;
+  if (this->parent().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->parent().data(), static_cast<int>(this->parent().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.parent");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->parent(), output);
+  }
+
+  // int32 parent_rel_pos = 5;
+  if (this->parent_rel_pos() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->parent_rel_pos(), output);
+  }
+
+  // repeated .dmi.Component children = 6;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->children_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      6,
+      this->children(static_cast<int>(i)),
+      output);
+  }
+
+  // string hardware_rev = 7;
+  if (this->hardware_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->hardware_rev().data(), static_cast<int>(this->hardware_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.hardware_rev");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      7, this->hardware_rev(), output);
+  }
+
+  // string firmware_rev = 8;
+  if (this->firmware_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->firmware_rev().data(), static_cast<int>(this->firmware_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.firmware_rev");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      8, this->firmware_rev(), output);
+  }
+
+  // string software_rev = 9;
+  if (this->software_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->software_rev().data(), static_cast<int>(this->software_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.software_rev");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      9, this->software_rev(), output);
+  }
+
+  // string serial_num = 10;
+  if (this->serial_num().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->serial_num().data(), static_cast<int>(this->serial_num().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.serial_num");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      10, this->serial_num(), output);
+  }
+
+  // string mfg_name = 11;
+  if (this->mfg_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->mfg_name().data(), static_cast<int>(this->mfg_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.mfg_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      11, this->mfg_name(), output);
+  }
+
+  // string model_name = 12;
+  if (this->model_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->model_name().data(), static_cast<int>(this->model_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.model_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      12, this->model_name(), output);
+  }
+
+  // string alias = 13;
+  if (this->alias().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->alias().data(), static_cast<int>(this->alias().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.alias");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      13, this->alias(), output);
+  }
+
+  // string asset_id = 14;
+  if (this->asset_id().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.asset_id");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      14, this->asset_id(), output);
+  }
+
+  // bool is_fru = 15;
+  if (this->is_fru() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(15, this->is_fru(), output);
+  }
+
+  // .google.protobuf.Timestamp mfg_date = 16;
+  if (this->has_mfg_date()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      16, HasBitSetters::mfg_date(this), output);
+  }
+
+  // .dmi.Uri uri = 17;
+  if (this->has_uri()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      17, HasBitSetters::uri(this), output);
+  }
+
+  // .dmi.Uuid uuid = 18;
+  if (this->has_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      18, HasBitSetters::uuid(this), output);
+  }
+
+  // .dmi.ComponentState state = 19;
+  if (this->has_state()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      19, HasBitSetters::state(this), output);
+  }
+
+  // repeated .dmi.ComponentSensorData sensor_data = 20;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->sensor_data_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      20,
+      this->sensor_data(static_cast<int>(i)),
+      output);
+  }
+
+  // .dmi.PortComponentAttributes port_attr = 50;
+  if (has_port_attr()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      50, HasBitSetters::port_attr(this), output);
+  }
+
+  // .dmi.ContainerComponentAttributes container_attr = 51;
+  if (has_container_attr()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      51, HasBitSetters::container_attr(this), output);
+  }
+
+  // .dmi.PsuComponentAttributes psu_attr = 52;
+  if (has_psu_attr()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      52, HasBitSetters::psu_attr(this), output);
+  }
+
+  // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+  if (has_transceiver_attr()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      53, HasBitSetters::transceiver_attr(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Component)
+}
+
+::google::protobuf::uint8* Component::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Component)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->class_(), target);
+  }
+
+  // string description = 3;
+  if (this->description().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->description().data(), static_cast<int>(this->description().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.description");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->description(), target);
+  }
+
+  // string parent = 4;
+  if (this->parent().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->parent().data(), static_cast<int>(this->parent().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.parent");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->parent(), target);
+  }
+
+  // int32 parent_rel_pos = 5;
+  if (this->parent_rel_pos() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(5, this->parent_rel_pos(), target);
+  }
+
+  // repeated .dmi.Component children = 6;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->children_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        6, this->children(static_cast<int>(i)), target);
+  }
+
+  // string hardware_rev = 7;
+  if (this->hardware_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->hardware_rev().data(), static_cast<int>(this->hardware_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.hardware_rev");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        7, this->hardware_rev(), target);
+  }
+
+  // string firmware_rev = 8;
+  if (this->firmware_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->firmware_rev().data(), static_cast<int>(this->firmware_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.firmware_rev");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        8, this->firmware_rev(), target);
+  }
+
+  // string software_rev = 9;
+  if (this->software_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->software_rev().data(), static_cast<int>(this->software_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.software_rev");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        9, this->software_rev(), target);
+  }
+
+  // string serial_num = 10;
+  if (this->serial_num().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->serial_num().data(), static_cast<int>(this->serial_num().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.serial_num");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        10, this->serial_num(), target);
+  }
+
+  // string mfg_name = 11;
+  if (this->mfg_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->mfg_name().data(), static_cast<int>(this->mfg_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.mfg_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        11, this->mfg_name(), target);
+  }
+
+  // string model_name = 12;
+  if (this->model_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->model_name().data(), static_cast<int>(this->model_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.model_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        12, this->model_name(), target);
+  }
+
+  // string alias = 13;
+  if (this->alias().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->alias().data(), static_cast<int>(this->alias().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.alias");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        13, this->alias(), target);
+  }
+
+  // string asset_id = 14;
+  if (this->asset_id().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.asset_id");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        14, this->asset_id(), target);
+  }
+
+  // bool is_fru = 15;
+  if (this->is_fru() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(15, this->is_fru(), target);
+  }
+
+  // .google.protobuf.Timestamp mfg_date = 16;
+  if (this->has_mfg_date()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        16, HasBitSetters::mfg_date(this), target);
+  }
+
+  // .dmi.Uri uri = 17;
+  if (this->has_uri()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        17, HasBitSetters::uri(this), target);
+  }
+
+  // .dmi.Uuid uuid = 18;
+  if (this->has_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        18, HasBitSetters::uuid(this), target);
+  }
+
+  // .dmi.ComponentState state = 19;
+  if (this->has_state()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        19, HasBitSetters::state(this), target);
+  }
+
+  // repeated .dmi.ComponentSensorData sensor_data = 20;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->sensor_data_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        20, this->sensor_data(static_cast<int>(i)), target);
+  }
+
+  // .dmi.PortComponentAttributes port_attr = 50;
+  if (has_port_attr()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        50, HasBitSetters::port_attr(this), target);
+  }
+
+  // .dmi.ContainerComponentAttributes container_attr = 51;
+  if (has_container_attr()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        51, HasBitSetters::container_attr(this), target);
+  }
+
+  // .dmi.PsuComponentAttributes psu_attr = 52;
+  if (has_psu_attr()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        52, HasBitSetters::psu_attr(this), target);
+  }
+
+  // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+  if (has_transceiver_attr()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        53, HasBitSetters::transceiver_attr(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Component)
+  return target;
+}
+
+size_t Component::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Component)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated .dmi.Component children = 6;
+  {
+    unsigned int count = static_cast<unsigned int>(this->children_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->children(static_cast<int>(i)));
+    }
+  }
+
+  // repeated .dmi.ComponentSensorData sensor_data = 20;
+  {
+    unsigned int count = static_cast<unsigned int>(this->sensor_data_size());
+    total_size += 2UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->sensor_data(static_cast<int>(i)));
+    }
+  }
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->name());
+  }
+
+  // string description = 3;
+  if (this->description().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->description());
+  }
+
+  // string parent = 4;
+  if (this->parent().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->parent());
+  }
+
+  // string hardware_rev = 7;
+  if (this->hardware_rev().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->hardware_rev());
+  }
+
+  // string firmware_rev = 8;
+  if (this->firmware_rev().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->firmware_rev());
+  }
+
+  // string software_rev = 9;
+  if (this->software_rev().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->software_rev());
+  }
+
+  // string serial_num = 10;
+  if (this->serial_num().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->serial_num());
+  }
+
+  // string mfg_name = 11;
+  if (this->mfg_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->mfg_name());
+  }
+
+  // string model_name = 12;
+  if (this->model_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->model_name());
+  }
+
+  // string alias = 13;
+  if (this->alias().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->alias());
+  }
+
+  // string asset_id = 14;
+  if (this->asset_id().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->asset_id());
+  }
+
+  // .google.protobuf.Timestamp mfg_date = 16;
+  if (this->has_mfg_date()) {
+    total_size += 2 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *mfg_date_);
+  }
+
+  // .dmi.Uri uri = 17;
+  if (this->has_uri()) {
+    total_size += 2 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *uri_);
+  }
+
+  // .dmi.Uuid uuid = 18;
+  if (this->has_uuid()) {
+    total_size += 2 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *uuid_);
+  }
+
+  // .dmi.ComponentState state = 19;
+  if (this->has_state()) {
+    total_size += 2 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *state_);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->class_());
+  }
+
+  // int32 parent_rel_pos = 5;
+  if (this->parent_rel_pos() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->parent_rel_pos());
+  }
+
+  // bool is_fru = 15;
+  if (this->is_fru() != 0) {
+    total_size += 1 + 1;
+  }
+
+  switch (specific_case()) {
+    // .dmi.PortComponentAttributes port_attr = 50;
+    case kPortAttr: {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *specific_.port_attr_);
+      break;
+    }
+    // .dmi.ContainerComponentAttributes container_attr = 51;
+    case kContainerAttr: {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *specific_.container_attr_);
+      break;
+    }
+    // .dmi.PsuComponentAttributes psu_attr = 52;
+    case kPsuAttr: {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *specific_.psu_attr_);
+      break;
+    }
+    // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+    case kTransceiverAttr: {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *specific_.transceiver_attr_);
+      break;
+    }
+    case SPECIFIC_NOT_SET: {
+      break;
+    }
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Component::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Component)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Component* source =
+      ::google::protobuf::DynamicCastToGenerated<Component>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Component)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Component)
+    MergeFrom(*source);
+  }
+}
+
+void Component::MergeFrom(const Component& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Component)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  children_.MergeFrom(from.children_);
+  sensor_data_.MergeFrom(from.sensor_data_);
+  if (from.name().size() > 0) {
+
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  if (from.description().size() > 0) {
+
+    description_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.description_);
+  }
+  if (from.parent().size() > 0) {
+
+    parent_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parent_);
+  }
+  if (from.hardware_rev().size() > 0) {
+
+    hardware_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.hardware_rev_);
+  }
+  if (from.firmware_rev().size() > 0) {
+
+    firmware_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.firmware_rev_);
+  }
+  if (from.software_rev().size() > 0) {
+
+    software_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.software_rev_);
+  }
+  if (from.serial_num().size() > 0) {
+
+    serial_num_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.serial_num_);
+  }
+  if (from.mfg_name().size() > 0) {
+
+    mfg_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.mfg_name_);
+  }
+  if (from.model_name().size() > 0) {
+
+    model_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.model_name_);
+  }
+  if (from.alias().size() > 0) {
+
+    alias_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.alias_);
+  }
+  if (from.asset_id().size() > 0) {
+
+    asset_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.asset_id_);
+  }
+  if (from.has_mfg_date()) {
+    mutable_mfg_date()->::google::protobuf::Timestamp::MergeFrom(from.mfg_date());
+  }
+  if (from.has_uri()) {
+    mutable_uri()->::dmi::Uri::MergeFrom(from.uri());
+  }
+  if (from.has_uuid()) {
+    mutable_uuid()->::dmi::Uuid::MergeFrom(from.uuid());
+  }
+  if (from.has_state()) {
+    mutable_state()->::dmi::ComponentState::MergeFrom(from.state());
+  }
+  if (from.class_() != 0) {
+    set_class_(from.class_());
+  }
+  if (from.parent_rel_pos() != 0) {
+    set_parent_rel_pos(from.parent_rel_pos());
+  }
+  if (from.is_fru() != 0) {
+    set_is_fru(from.is_fru());
+  }
+  switch (from.specific_case()) {
+    case kPortAttr: {
+      mutable_port_attr()->::dmi::PortComponentAttributes::MergeFrom(from.port_attr());
+      break;
+    }
+    case kContainerAttr: {
+      mutable_container_attr()->::dmi::ContainerComponentAttributes::MergeFrom(from.container_attr());
+      break;
+    }
+    case kPsuAttr: {
+      mutable_psu_attr()->::dmi::PsuComponentAttributes::MergeFrom(from.psu_attr());
+      break;
+    }
+    case kTransceiverAttr: {
+      mutable_transceiver_attr()->::dmi::TransceiverComponentsAttributes::MergeFrom(from.transceiver_attr());
+      break;
+    }
+    case SPECIFIC_NOT_SET: {
+      break;
+    }
+  }
+}
+
+void Component::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Component)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Component::CopyFrom(const Component& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Component)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Component::IsInitialized() const {
+  return true;
+}
+
+void Component::Swap(Component* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Component::InternalSwap(Component* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  CastToBase(&children_)->InternalSwap(CastToBase(&other->children_));
+  CastToBase(&sensor_data_)->InternalSwap(CastToBase(&other->sensor_data_));
+  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  description_.Swap(&other->description_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  parent_.Swap(&other->parent_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  hardware_rev_.Swap(&other->hardware_rev_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  firmware_rev_.Swap(&other->firmware_rev_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  software_rev_.Swap(&other->software_rev_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  serial_num_.Swap(&other->serial_num_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  mfg_name_.Swap(&other->mfg_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  model_name_.Swap(&other->model_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  alias_.Swap(&other->alias_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  asset_id_.Swap(&other->asset_id_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(mfg_date_, other->mfg_date_);
+  swap(uri_, other->uri_);
+  swap(uuid_, other->uuid_);
+  swap(state_, other->state_);
+  swap(class__, other->class__);
+  swap(parent_rel_pos_, other->parent_rel_pos_);
+  swap(is_fru_, other->is_fru_);
+  swap(specific_, other->specific_);
+  swap(_oneof_case_[0], other->_oneof_case_[0]);
+}
+
+::google::protobuf::Metadata Component::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void Hardware::InitAsDefaultInstance() {
+  ::dmi::_Hardware_default_instance_._instance.get_mutable()->last_change_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+  ::dmi::_Hardware_default_instance_._instance.get_mutable()->root_ = const_cast< ::dmi::Component*>(
+      ::dmi::Component::internal_default_instance());
+  ::dmi::_Hardware_default_instance_._instance.get_mutable()->last_booted_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+}
+class Hardware::HasBitSetters {
+ public:
+  static const ::google::protobuf::Timestamp& last_change(const Hardware* msg);
+  static const ::dmi::Component& root(const Hardware* msg);
+  static const ::google::protobuf::Timestamp& last_booted(const Hardware* msg);
+};
+
+const ::google::protobuf::Timestamp&
+Hardware::HasBitSetters::last_change(const Hardware* msg) {
+  return *msg->last_change_;
+}
+const ::dmi::Component&
+Hardware::HasBitSetters::root(const Hardware* msg) {
+  return *msg->root_;
+}
+const ::google::protobuf::Timestamp&
+Hardware::HasBitSetters::last_booted(const Hardware* msg) {
+  return *msg->last_booted_;
+}
+void Hardware::clear_last_change() {
+  if (GetArenaNoVirtual() == nullptr && last_change_ != nullptr) {
+    delete last_change_;
+  }
+  last_change_ = nullptr;
+}
+void Hardware::clear_last_booted() {
+  if (GetArenaNoVirtual() == nullptr && last_booted_ != nullptr) {
+    delete last_booted_;
+  }
+  last_booted_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Hardware::kLastChangeFieldNumber;
+const int Hardware::kRootFieldNumber;
+const int Hardware::kLastBootedFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Hardware::Hardware()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Hardware)
+}
+Hardware::Hardware(const Hardware& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_last_change()) {
+    last_change_ = new ::google::protobuf::Timestamp(*from.last_change_);
+  } else {
+    last_change_ = nullptr;
+  }
+  if (from.has_root()) {
+    root_ = new ::dmi::Component(*from.root_);
+  } else {
+    root_ = nullptr;
+  }
+  if (from.has_last_booted()) {
+    last_booted_ = new ::google::protobuf::Timestamp(*from.last_booted_);
+  } else {
+    last_booted_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.Hardware)
+}
+
+void Hardware::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Hardware_dmi_2fhw_2eproto.base);
+  ::memset(&last_change_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&last_booted_) -
+      reinterpret_cast<char*>(&last_change_)) + sizeof(last_booted_));
+}
+
+Hardware::~Hardware() {
+  // @@protoc_insertion_point(destructor:dmi.Hardware)
+  SharedDtor();
+}
+
+void Hardware::SharedDtor() {
+  if (this != internal_default_instance()) delete last_change_;
+  if (this != internal_default_instance()) delete root_;
+  if (this != internal_default_instance()) delete last_booted_;
+}
+
+void Hardware::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Hardware& Hardware::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Hardware_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Hardware::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Hardware)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && last_change_ != nullptr) {
+    delete last_change_;
+  }
+  last_change_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && root_ != nullptr) {
+    delete root_;
+  }
+  root_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && last_booted_ != nullptr) {
+    delete last_booted_;
+  }
+  last_booted_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Hardware::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Hardware*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .google.protobuf.Timestamp last_change = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_last_change();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Component root = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Component::_InternalParse;
+        object = msg->mutable_root();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .google.protobuf.Timestamp last_booted = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_last_booted();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Hardware::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Hardware)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .google.protobuf.Timestamp last_change = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_last_change()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Component root = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_root()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .google.protobuf.Timestamp last_booted = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_last_booted()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Hardware)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Hardware)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Hardware::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Hardware)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp last_change = 1;
+  if (this->has_last_change()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::last_change(this), output);
+  }
+
+  // .dmi.Component root = 2;
+  if (this->has_root()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::root(this), output);
+  }
+
+  // .google.protobuf.Timestamp last_booted = 3;
+  if (this->has_last_booted()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::last_booted(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Hardware)
+}
+
+::google::protobuf::uint8* Hardware::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Hardware)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp last_change = 1;
+  if (this->has_last_change()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::last_change(this), target);
+  }
+
+  // .dmi.Component root = 2;
+  if (this->has_root()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::root(this), target);
+  }
+
+  // .google.protobuf.Timestamp last_booted = 3;
+  if (this->has_last_booted()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::last_booted(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Hardware)
+  return target;
+}
+
+size_t Hardware::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Hardware)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp last_change = 1;
+  if (this->has_last_change()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *last_change_);
+  }
+
+  // .dmi.Component root = 2;
+  if (this->has_root()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *root_);
+  }
+
+  // .google.protobuf.Timestamp last_booted = 3;
+  if (this->has_last_booted()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *last_booted_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Hardware::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Hardware)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Hardware* source =
+      ::google::protobuf::DynamicCastToGenerated<Hardware>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Hardware)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Hardware)
+    MergeFrom(*source);
+  }
+}
+
+void Hardware::MergeFrom(const Hardware& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Hardware)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_last_change()) {
+    mutable_last_change()->::google::protobuf::Timestamp::MergeFrom(from.last_change());
+  }
+  if (from.has_root()) {
+    mutable_root()->::dmi::Component::MergeFrom(from.root());
+  }
+  if (from.has_last_booted()) {
+    mutable_last_booted()->::google::protobuf::Timestamp::MergeFrom(from.last_booted());
+  }
+}
+
+void Hardware::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Hardware)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Hardware::CopyFrom(const Hardware& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Hardware)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Hardware::IsInitialized() const {
+  return true;
+}
+
+void Hardware::Swap(Hardware* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Hardware::InternalSwap(Hardware* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(last_change_, other->last_change_);
+  swap(root_, other->root_);
+  swap(last_booted_, other->last_booted_);
+}
+
+::google::protobuf::Metadata Hardware::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ModifiableComponent::InitAsDefaultInstance() {
+  ::dmi::_ModifiableComponent_default_instance_._instance.get_mutable()->parent_ = const_cast< ::dmi::Component*>(
+      ::dmi::Component::internal_default_instance());
+  ::dmi::_ModifiableComponent_default_instance_._instance.get_mutable()->uri_ = const_cast< ::dmi::Uri*>(
+      ::dmi::Uri::internal_default_instance());
+}
+class ModifiableComponent::HasBitSetters {
+ public:
+  static const ::dmi::Component& parent(const ModifiableComponent* msg);
+  static const ::dmi::Uri& uri(const ModifiableComponent* msg);
+};
+
+const ::dmi::Component&
+ModifiableComponent::HasBitSetters::parent(const ModifiableComponent* msg) {
+  return *msg->parent_;
+}
+const ::dmi::Uri&
+ModifiableComponent::HasBitSetters::uri(const ModifiableComponent* msg) {
+  return *msg->uri_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ModifiableComponent::kNameFieldNumber;
+const int ModifiableComponent::kClassFieldNumber;
+const int ModifiableComponent::kParentFieldNumber;
+const int ModifiableComponent::kParentRelPosFieldNumber;
+const int ModifiableComponent::kAliasFieldNumber;
+const int ModifiableComponent::kAssetIdFieldNumber;
+const int ModifiableComponent::kUriFieldNumber;
+const int ModifiableComponent::kAdminStateFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ModifiableComponent::ModifiableComponent()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ModifiableComponent)
+}
+ModifiableComponent::ModifiableComponent(const ModifiableComponent& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.name().size() > 0) {
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  alias_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.alias().size() > 0) {
+    alias_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.alias_);
+  }
+  asset_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.asset_id().size() > 0) {
+    asset_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.asset_id_);
+  }
+  if (from.has_parent()) {
+    parent_ = new ::dmi::Component(*from.parent_);
+  } else {
+    parent_ = nullptr;
+  }
+  if (from.has_uri()) {
+    uri_ = new ::dmi::Uri(*from.uri_);
+  } else {
+    uri_ = nullptr;
+  }
+  ::memcpy(&class__, &from.class__,
+    static_cast<size_t>(reinterpret_cast<char*>(&admin_state_) -
+    reinterpret_cast<char*>(&class__)) + sizeof(admin_state_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ModifiableComponent)
+}
+
+void ModifiableComponent::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ModifiableComponent_dmi_2fhw_2eproto.base);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&parent_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&admin_state_) -
+      reinterpret_cast<char*>(&parent_)) + sizeof(admin_state_));
+}
+
+ModifiableComponent::~ModifiableComponent() {
+  // @@protoc_insertion_point(destructor:dmi.ModifiableComponent)
+  SharedDtor();
+}
+
+void ModifiableComponent::SharedDtor() {
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete parent_;
+  if (this != internal_default_instance()) delete uri_;
+}
+
+void ModifiableComponent::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ModifiableComponent& ModifiableComponent::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ModifiableComponent_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ModifiableComponent::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ModifiableComponent)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && parent_ != nullptr) {
+    delete parent_;
+  }
+  parent_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
+    delete uri_;
+  }
+  uri_ = nullptr;
+  ::memset(&class__, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&admin_state_) -
+      reinterpret_cast<char*>(&class__)) + sizeof(admin_state_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ModifiableComponent::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ModifiableComponent*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ModifiableComponent.name");
+        object = msg->mutable_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // .dmi.ComponentType class = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_class_(static_cast<::dmi::ComponentType>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.Component parent = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Component::_InternalParse;
+        object = msg->mutable_parent();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // int32 parent_rel_pos = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        msg->set_parent_rel_pos(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string alias = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ModifiableComponent.alias");
+        object = msg->mutable_alias();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string asset_id = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ModifiableComponent.asset_id");
+        object = msg->mutable_asset_id();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // .dmi.Uri uri = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uri::_InternalParse;
+        object = msg->mutable_uri();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ComponentAdminState admin_state = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 64) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_admin_state(static_cast<::dmi::ComponentAdminState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ModifiableComponent::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ModifiableComponent)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string name = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->name().data(), static_cast<int>(this->name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ModifiableComponent.name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentType class = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_class_(static_cast< ::dmi::ComponentType >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Component parent = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_parent()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // int32 parent_rel_pos = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &parent_rel_pos_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string alias = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_alias()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->alias().data(), static_cast<int>(this->alias().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ModifiableComponent.alias"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string asset_id = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_asset_id()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ModifiableComponent.asset_id"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uri uri = 7;
+      case 7: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_uri()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentAdminState admin_state = 8;
+      case 8: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (64 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_admin_state(static_cast< ::dmi::ComponentAdminState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ModifiableComponent)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ModifiableComponent)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ModifiableComponent::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ModifiableComponent)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->class_(), output);
+  }
+
+  // .dmi.Component parent = 3;
+  if (this->has_parent()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::parent(this), output);
+  }
+
+  // int32 parent_rel_pos = 4;
+  if (this->parent_rel_pos() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->parent_rel_pos(), output);
+  }
+
+  // string alias = 5;
+  if (this->alias().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->alias().data(), static_cast<int>(this->alias().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.alias");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      5, this->alias(), output);
+  }
+
+  // string asset_id = 6;
+  if (this->asset_id().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.asset_id");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      6, this->asset_id(), output);
+  }
+
+  // .dmi.Uri uri = 7;
+  if (this->has_uri()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      7, HasBitSetters::uri(this), output);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 8;
+  if (this->admin_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      8, this->admin_state(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ModifiableComponent)
+}
+
+::google::protobuf::uint8* ModifiableComponent::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ModifiableComponent)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->class_(), target);
+  }
+
+  // .dmi.Component parent = 3;
+  if (this->has_parent()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::parent(this), target);
+  }
+
+  // int32 parent_rel_pos = 4;
+  if (this->parent_rel_pos() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->parent_rel_pos(), target);
+  }
+
+  // string alias = 5;
+  if (this->alias().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->alias().data(), static_cast<int>(this->alias().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.alias");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        5, this->alias(), target);
+  }
+
+  // string asset_id = 6;
+  if (this->asset_id().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.asset_id");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        6, this->asset_id(), target);
+  }
+
+  // .dmi.Uri uri = 7;
+  if (this->has_uri()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        7, HasBitSetters::uri(this), target);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 8;
+  if (this->admin_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      8, this->admin_state(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ModifiableComponent)
+  return target;
+}
+
+size_t ModifiableComponent::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ModifiableComponent)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->name());
+  }
+
+  // string alias = 5;
+  if (this->alias().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->alias());
+  }
+
+  // string asset_id = 6;
+  if (this->asset_id().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->asset_id());
+  }
+
+  // .dmi.Component parent = 3;
+  if (this->has_parent()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *parent_);
+  }
+
+  // .dmi.Uri uri = 7;
+  if (this->has_uri()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *uri_);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->class_());
+  }
+
+  // int32 parent_rel_pos = 4;
+  if (this->parent_rel_pos() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->parent_rel_pos());
+  }
+
+  // .dmi.ComponentAdminState admin_state = 8;
+  if (this->admin_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->admin_state());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ModifiableComponent::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ModifiableComponent)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ModifiableComponent* source =
+      ::google::protobuf::DynamicCastToGenerated<ModifiableComponent>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ModifiableComponent)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ModifiableComponent)
+    MergeFrom(*source);
+  }
+}
+
+void ModifiableComponent::MergeFrom(const ModifiableComponent& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ModifiableComponent)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.name().size() > 0) {
+
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  if (from.alias().size() > 0) {
+
+    alias_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.alias_);
+  }
+  if (from.asset_id().size() > 0) {
+
+    asset_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.asset_id_);
+  }
+  if (from.has_parent()) {
+    mutable_parent()->::dmi::Component::MergeFrom(from.parent());
+  }
+  if (from.has_uri()) {
+    mutable_uri()->::dmi::Uri::MergeFrom(from.uri());
+  }
+  if (from.class_() != 0) {
+    set_class_(from.class_());
+  }
+  if (from.parent_rel_pos() != 0) {
+    set_parent_rel_pos(from.parent_rel_pos());
+  }
+  if (from.admin_state() != 0) {
+    set_admin_state(from.admin_state());
+  }
+}
+
+void ModifiableComponent::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ModifiableComponent)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ModifiableComponent::CopyFrom(const ModifiableComponent& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ModifiableComponent)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ModifiableComponent::IsInitialized() const {
+  return true;
+}
+
+void ModifiableComponent::Swap(ModifiableComponent* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ModifiableComponent::InternalSwap(ModifiableComponent* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  alias_.Swap(&other->alias_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  asset_id_.Swap(&other->asset_id_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(parent_, other->parent_);
+  swap(uri_, other->uri_);
+  swap(class__, other->class__);
+  swap(parent_rel_pos_, other->parent_rel_pos_);
+  swap(admin_state_, other->admin_state_);
+}
+
+::google::protobuf::Metadata ModifiableComponent::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> PROTOBUF_NOINLINE ::dmi::Uuid* Arena::CreateMaybeMessage< ::dmi::Uuid >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Uuid >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::HardwareID* Arena::CreateMaybeMessage< ::dmi::HardwareID >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::HardwareID >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::Uri* Arena::CreateMaybeMessage< ::dmi::Uri >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Uri >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ComponentState* Arena::CreateMaybeMessage< ::dmi::ComponentState >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ComponentState >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ComponentSensorData* Arena::CreateMaybeMessage< ::dmi::ComponentSensorData >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ComponentSensorData >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::PortComponentAttributes* Arena::CreateMaybeMessage< ::dmi::PortComponentAttributes >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::PortComponentAttributes >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ContainerComponentAttributes* Arena::CreateMaybeMessage< ::dmi::ContainerComponentAttributes >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ContainerComponentAttributes >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::PsuComponentAttributes* Arena::CreateMaybeMessage< ::dmi::PsuComponentAttributes >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::PsuComponentAttributes >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::TransceiverComponentsAttributes* Arena::CreateMaybeMessage< ::dmi::TransceiverComponentsAttributes >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::TransceiverComponentsAttributes >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::Component* Arena::CreateMaybeMessage< ::dmi::Component >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Component >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::Hardware* Arena::CreateMaybeMessage< ::dmi::Hardware >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Hardware >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ModifiableComponent* Arena::CreateMaybeMessage< ::dmi::ModifiableComponent >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ModifiableComponent >(arena);
+}
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+#include <google/protobuf/port_undef.inc>
diff --git a/cpp/dmi/hw.pb.h b/cpp/dmi/hw.pb.h
new file mode 100644
index 0000000..f4b9c89
--- /dev/null
+++ b/cpp/dmi/hw.pb.h
@@ -0,0 +1,5215 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/hw.proto
+
+#ifndef PROTOBUF_INCLUDED_dmi_2fhw_2eproto
+#define PROTOBUF_INCLUDED_dmi_2fhw_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 <google/protobuf/timestamp.pb.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto
+
+// Internal implementation detail -- do not use these members.
+struct TableStruct_dmi_2fhw_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[12]
+    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_2eproto();
+namespace dmi {
+class Component;
+class ComponentDefaultTypeInternal;
+extern ComponentDefaultTypeInternal _Component_default_instance_;
+class ComponentSensorData;
+class ComponentSensorDataDefaultTypeInternal;
+extern ComponentSensorDataDefaultTypeInternal _ComponentSensorData_default_instance_;
+class ComponentState;
+class ComponentStateDefaultTypeInternal;
+extern ComponentStateDefaultTypeInternal _ComponentState_default_instance_;
+class ContainerComponentAttributes;
+class ContainerComponentAttributesDefaultTypeInternal;
+extern ContainerComponentAttributesDefaultTypeInternal _ContainerComponentAttributes_default_instance_;
+class Hardware;
+class HardwareDefaultTypeInternal;
+extern HardwareDefaultTypeInternal _Hardware_default_instance_;
+class HardwareID;
+class HardwareIDDefaultTypeInternal;
+extern HardwareIDDefaultTypeInternal _HardwareID_default_instance_;
+class ModifiableComponent;
+class ModifiableComponentDefaultTypeInternal;
+extern ModifiableComponentDefaultTypeInternal _ModifiableComponent_default_instance_;
+class PortComponentAttributes;
+class PortComponentAttributesDefaultTypeInternal;
+extern PortComponentAttributesDefaultTypeInternal _PortComponentAttributes_default_instance_;
+class PsuComponentAttributes;
+class PsuComponentAttributesDefaultTypeInternal;
+extern PsuComponentAttributesDefaultTypeInternal _PsuComponentAttributes_default_instance_;
+class TransceiverComponentsAttributes;
+class TransceiverComponentsAttributesDefaultTypeInternal;
+extern TransceiverComponentsAttributesDefaultTypeInternal _TransceiverComponentsAttributes_default_instance_;
+class Uri;
+class UriDefaultTypeInternal;
+extern UriDefaultTypeInternal _Uri_default_instance_;
+class Uuid;
+class UuidDefaultTypeInternal;
+extern UuidDefaultTypeInternal _Uuid_default_instance_;
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> ::dmi::Component* Arena::CreateMaybeMessage<::dmi::Component>(Arena*);
+template<> ::dmi::ComponentSensorData* Arena::CreateMaybeMessage<::dmi::ComponentSensorData>(Arena*);
+template<> ::dmi::ComponentState* Arena::CreateMaybeMessage<::dmi::ComponentState>(Arena*);
+template<> ::dmi::ContainerComponentAttributes* Arena::CreateMaybeMessage<::dmi::ContainerComponentAttributes>(Arena*);
+template<> ::dmi::Hardware* Arena::CreateMaybeMessage<::dmi::Hardware>(Arena*);
+template<> ::dmi::HardwareID* Arena::CreateMaybeMessage<::dmi::HardwareID>(Arena*);
+template<> ::dmi::ModifiableComponent* Arena::CreateMaybeMessage<::dmi::ModifiableComponent>(Arena*);
+template<> ::dmi::PortComponentAttributes* Arena::CreateMaybeMessage<::dmi::PortComponentAttributes>(Arena*);
+template<> ::dmi::PsuComponentAttributes* Arena::CreateMaybeMessage<::dmi::PsuComponentAttributes>(Arena*);
+template<> ::dmi::TransceiverComponentsAttributes* Arena::CreateMaybeMessage<::dmi::TransceiverComponentsAttributes>(Arena*);
+template<> ::dmi::Uri* Arena::CreateMaybeMessage<::dmi::Uri>(Arena*);
+template<> ::dmi::Uuid* Arena::CreateMaybeMessage<::dmi::Uuid>(Arena*);
+}  // namespace protobuf
+}  // namespace google
+namespace dmi {
+
+enum PortComponentAttributes_ConnectorType {
+  PortComponentAttributes_ConnectorType_CONNECTOR_TYPE_UNDEFINED = 0,
+  PortComponentAttributes_ConnectorType_RJ45 = 1,
+  PortComponentAttributes_ConnectorType_FIBER_LC = 2,
+  PortComponentAttributes_ConnectorType_FIBER_SC_PC = 3,
+  PortComponentAttributes_ConnectorType_FIBER_MPO = 4,
+  PortComponentAttributes_ConnectorType_RS232 = 5,
+  PortComponentAttributes_ConnectorType_PortComponentAttributes_ConnectorType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  PortComponentAttributes_ConnectorType_PortComponentAttributes_ConnectorType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool PortComponentAttributes_ConnectorType_IsValid(int value);
+const PortComponentAttributes_ConnectorType PortComponentAttributes_ConnectorType_ConnectorType_MIN = PortComponentAttributes_ConnectorType_CONNECTOR_TYPE_UNDEFINED;
+const PortComponentAttributes_ConnectorType PortComponentAttributes_ConnectorType_ConnectorType_MAX = PortComponentAttributes_ConnectorType_RS232;
+const int PortComponentAttributes_ConnectorType_ConnectorType_ARRAYSIZE = PortComponentAttributes_ConnectorType_ConnectorType_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_ConnectorType_descriptor();
+inline const ::std::string& PortComponentAttributes_ConnectorType_Name(PortComponentAttributes_ConnectorType value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    PortComponentAttributes_ConnectorType_descriptor(), value);
+}
+inline bool PortComponentAttributes_ConnectorType_Parse(
+    const ::std::string& name, PortComponentAttributes_ConnectorType* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<PortComponentAttributes_ConnectorType>(
+    PortComponentAttributes_ConnectorType_descriptor(), name, value);
+}
+enum PortComponentAttributes_Speed {
+  PortComponentAttributes_Speed_SPEED_UNDEFINED = 0,
+  PortComponentAttributes_Speed_DYNAMIC = 1,
+  PortComponentAttributes_Speed_GIGABIT_1 = 2,
+  PortComponentAttributes_Speed_GIGABIT_10 = 3,
+  PortComponentAttributes_Speed_GIGABIT_25 = 4,
+  PortComponentAttributes_Speed_GIGABIT_40 = 5,
+  PortComponentAttributes_Speed_GIGABIT_100 = 6,
+  PortComponentAttributes_Speed_GIGABIT_400 = 7,
+  PortComponentAttributes_Speed_MEGABIT_2500 = 8,
+  PortComponentAttributes_Speed_MEGABIT_1250 = 9,
+  PortComponentAttributes_Speed_PortComponentAttributes_Speed_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  PortComponentAttributes_Speed_PortComponentAttributes_Speed_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool PortComponentAttributes_Speed_IsValid(int value);
+const PortComponentAttributes_Speed PortComponentAttributes_Speed_Speed_MIN = PortComponentAttributes_Speed_SPEED_UNDEFINED;
+const PortComponentAttributes_Speed PortComponentAttributes_Speed_Speed_MAX = PortComponentAttributes_Speed_MEGABIT_1250;
+const int PortComponentAttributes_Speed_Speed_ARRAYSIZE = PortComponentAttributes_Speed_Speed_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Speed_descriptor();
+inline const ::std::string& PortComponentAttributes_Speed_Name(PortComponentAttributes_Speed value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    PortComponentAttributes_Speed_descriptor(), value);
+}
+inline bool PortComponentAttributes_Speed_Parse(
+    const ::std::string& name, PortComponentAttributes_Speed* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<PortComponentAttributes_Speed>(
+    PortComponentAttributes_Speed_descriptor(), name, value);
+}
+enum PortComponentAttributes_Protocol {
+  PortComponentAttributes_Protocol_PROTOCOL_UNDEFINED = 0,
+  PortComponentAttributes_Protocol_ETHERNET = 1,
+  PortComponentAttributes_Protocol_GPON = 2,
+  PortComponentAttributes_Protocol_XGPON = 3,
+  PortComponentAttributes_Protocol_XGSPON = 4,
+  PortComponentAttributes_Protocol_GFAST = 5,
+  PortComponentAttributes_Protocol_SERIAL = 6,
+  PortComponentAttributes_Protocol_EPON = 7,
+  PortComponentAttributes_Protocol_BITS = 8,
+  PortComponentAttributes_Protocol_PortComponentAttributes_Protocol_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  PortComponentAttributes_Protocol_PortComponentAttributes_Protocol_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool PortComponentAttributes_Protocol_IsValid(int value);
+const PortComponentAttributes_Protocol PortComponentAttributes_Protocol_Protocol_MIN = PortComponentAttributes_Protocol_PROTOCOL_UNDEFINED;
+const PortComponentAttributes_Protocol PortComponentAttributes_Protocol_Protocol_MAX = PortComponentAttributes_Protocol_BITS;
+const int PortComponentAttributes_Protocol_Protocol_ARRAYSIZE = PortComponentAttributes_Protocol_Protocol_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Protocol_descriptor();
+inline const ::std::string& PortComponentAttributes_Protocol_Name(PortComponentAttributes_Protocol value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    PortComponentAttributes_Protocol_descriptor(), value);
+}
+inline bool PortComponentAttributes_Protocol_Parse(
+    const ::std::string& name, PortComponentAttributes_Protocol* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<PortComponentAttributes_Protocol>(
+    PortComponentAttributes_Protocol_descriptor(), name, value);
+}
+enum PsuComponentAttributes_SupportedVoltage {
+  PsuComponentAttributes_SupportedVoltage_SUPPORTED_VOLTAGE_UNDEFINED = 0,
+  PsuComponentAttributes_SupportedVoltage_V48 = 1,
+  PsuComponentAttributes_SupportedVoltage_V230 = 2,
+  PsuComponentAttributes_SupportedVoltage_V115 = 3,
+  PsuComponentAttributes_SupportedVoltage_PsuComponentAttributes_SupportedVoltage_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  PsuComponentAttributes_SupportedVoltage_PsuComponentAttributes_SupportedVoltage_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool PsuComponentAttributes_SupportedVoltage_IsValid(int value);
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MIN = PsuComponentAttributes_SupportedVoltage_SUPPORTED_VOLTAGE_UNDEFINED;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MAX = PsuComponentAttributes_SupportedVoltage_V115;
+const int PsuComponentAttributes_SupportedVoltage_SupportedVoltage_ARRAYSIZE = PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* PsuComponentAttributes_SupportedVoltage_descriptor();
+inline const ::std::string& PsuComponentAttributes_SupportedVoltage_Name(PsuComponentAttributes_SupportedVoltage value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    PsuComponentAttributes_SupportedVoltage_descriptor(), value);
+}
+inline bool PsuComponentAttributes_SupportedVoltage_Parse(
+    const ::std::string& name, PsuComponentAttributes_SupportedVoltage* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<PsuComponentAttributes_SupportedVoltage>(
+    PsuComponentAttributes_SupportedVoltage_descriptor(), name, value);
+}
+enum TransceiverComponentsAttributes_FormFactor {
+  TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN = 0,
+  TransceiverComponentsAttributes_FormFactor_QSFP = 1,
+  TransceiverComponentsAttributes_FormFactor_QSFP_PLUS = 2,
+  TransceiverComponentsAttributes_FormFactor_QSFP28 = 3,
+  TransceiverComponentsAttributes_FormFactor_SFP = 4,
+  TransceiverComponentsAttributes_FormFactor_SFP_PLUS = 5,
+  TransceiverComponentsAttributes_FormFactor_XFP = 6,
+  TransceiverComponentsAttributes_FormFactor_CFP4 = 7,
+  TransceiverComponentsAttributes_FormFactor_CFP2 = 8,
+  TransceiverComponentsAttributes_FormFactor_CPAK = 9,
+  TransceiverComponentsAttributes_FormFactor_X2 = 10,
+  TransceiverComponentsAttributes_FormFactor_OTHER = 11,
+  TransceiverComponentsAttributes_FormFactor_CFP = 12,
+  TransceiverComponentsAttributes_FormFactor_CFP2_ACO = 13,
+  TransceiverComponentsAttributes_FormFactor_CFP2_DCO = 14,
+  TransceiverComponentsAttributes_FormFactor_TransceiverComponentsAttributes_FormFactor_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  TransceiverComponentsAttributes_FormFactor_TransceiverComponentsAttributes_FormFactor_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool TransceiverComponentsAttributes_FormFactor_IsValid(int value);
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes_FormFactor_FormFactor_MIN = TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes_FormFactor_FormFactor_MAX = TransceiverComponentsAttributes_FormFactor_CFP2_DCO;
+const int TransceiverComponentsAttributes_FormFactor_FormFactor_ARRAYSIZE = TransceiverComponentsAttributes_FormFactor_FormFactor_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_FormFactor_descriptor();
+inline const ::std::string& TransceiverComponentsAttributes_FormFactor_Name(TransceiverComponentsAttributes_FormFactor value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    TransceiverComponentsAttributes_FormFactor_descriptor(), value);
+}
+inline bool TransceiverComponentsAttributes_FormFactor_Parse(
+    const ::std::string& name, TransceiverComponentsAttributes_FormFactor* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<TransceiverComponentsAttributes_FormFactor>(
+    TransceiverComponentsAttributes_FormFactor_descriptor(), name, value);
+}
+enum TransceiverComponentsAttributes_Type {
+  TransceiverComponentsAttributes_Type_TYPE_UNKNOWN = 0,
+  TransceiverComponentsAttributes_Type_ETHERNET = 1,
+  TransceiverComponentsAttributes_Type_GPON = 2,
+  TransceiverComponentsAttributes_Type_XGPON = 3,
+  TransceiverComponentsAttributes_Type_XGSPON = 4,
+  TransceiverComponentsAttributes_Type_CPON = 5,
+  TransceiverComponentsAttributes_Type_NG_PON2 = 6,
+  TransceiverComponentsAttributes_Type_EPON = 7,
+  TransceiverComponentsAttributes_Type_TransceiverComponentsAttributes_Type_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  TransceiverComponentsAttributes_Type_TransceiverComponentsAttributes_Type_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool TransceiverComponentsAttributes_Type_IsValid(int value);
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes_Type_Type_MIN = TransceiverComponentsAttributes_Type_TYPE_UNKNOWN;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes_Type_Type_MAX = TransceiverComponentsAttributes_Type_EPON;
+const int TransceiverComponentsAttributes_Type_Type_ARRAYSIZE = TransceiverComponentsAttributes_Type_Type_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_Type_descriptor();
+inline const ::std::string& TransceiverComponentsAttributes_Type_Name(TransceiverComponentsAttributes_Type value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    TransceiverComponentsAttributes_Type_descriptor(), value);
+}
+inline bool TransceiverComponentsAttributes_Type_Parse(
+    const ::std::string& name, TransceiverComponentsAttributes_Type* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<TransceiverComponentsAttributes_Type>(
+    TransceiverComponentsAttributes_Type_descriptor(), name, value);
+}
+enum ComponentType {
+  COMPONENT_TYPE_UNDEFINED = 0,
+  COMPONENT_TYPE_UNKNOWN = 1,
+  COMPONENT_TYPE_CHASSIS = 2,
+  COMPONENT_TYPE_BACKPLANE = 3,
+  COMPONENT_TYPE_CONTAINER = 4,
+  COMPONENT_TYPE_POWER_SUPPLY = 5,
+  COMPONENT_TYPE_FAN = 6,
+  COMPONENT_TYPE_SENSOR = 7,
+  COMPONENT_TYPE_MODULE = 8,
+  COMPONENT_TYPE_PORT = 9,
+  COMPONENT_TYPE_CPU = 10,
+  COMPONENT_TYPE_BATTERY = 11,
+  COMPONENT_TYPE_STORAGE = 12,
+  COMPONENT_TYPE_MEMORY = 13,
+  COMPONENT_TYPE_TRANSCEIVER = 14,
+  ComponentType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentType_IsValid(int value);
+const ComponentType ComponentType_MIN = COMPONENT_TYPE_UNDEFINED;
+const ComponentType ComponentType_MAX = COMPONENT_TYPE_TRANSCEIVER;
+const int ComponentType_ARRAYSIZE = ComponentType_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentType_descriptor();
+inline const ::std::string& ComponentType_Name(ComponentType value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentType_descriptor(), value);
+}
+inline bool ComponentType_Parse(
+    const ::std::string& name, ComponentType* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentType>(
+    ComponentType_descriptor(), name, value);
+}
+enum ComponentAdminState {
+  COMP_ADMIN_STATE_UNDEFINED = 0,
+  COMP_ADMIN_STATE_UNKNOWN = 1,
+  COMP_ADMIN_STATE_LOCKED = 2,
+  COMP_ADMIN_STATE_SHUTTING_DOWN = 3,
+  COMP_ADMIN_STATE_UNLOCKED = 4,
+  ComponentAdminState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentAdminState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentAdminState_IsValid(int value);
+const ComponentAdminState ComponentAdminState_MIN = COMP_ADMIN_STATE_UNDEFINED;
+const ComponentAdminState ComponentAdminState_MAX = COMP_ADMIN_STATE_UNLOCKED;
+const int ComponentAdminState_ARRAYSIZE = ComponentAdminState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentAdminState_descriptor();
+inline const ::std::string& ComponentAdminState_Name(ComponentAdminState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentAdminState_descriptor(), value);
+}
+inline bool ComponentAdminState_Parse(
+    const ::std::string& name, ComponentAdminState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentAdminState>(
+    ComponentAdminState_descriptor(), name, value);
+}
+enum ComponentOperState {
+  COMP_OPER_STATE_UNDEFINED = 0,
+  COMP_OPER_STATE_UNKNOWN = 1,
+  COMP_OPER_STATE_DISABLED = 2,
+  COMP_OPER_STATE_ENABLED = 3,
+  COMP_OPER_STATE_TESTING = 4,
+  ComponentOperState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentOperState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentOperState_IsValid(int value);
+const ComponentOperState ComponentOperState_MIN = COMP_OPER_STATE_UNDEFINED;
+const ComponentOperState ComponentOperState_MAX = COMP_OPER_STATE_TESTING;
+const int ComponentOperState_ARRAYSIZE = ComponentOperState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentOperState_descriptor();
+inline const ::std::string& ComponentOperState_Name(ComponentOperState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentOperState_descriptor(), value);
+}
+inline bool ComponentOperState_Parse(
+    const ::std::string& name, ComponentOperState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentOperState>(
+    ComponentOperState_descriptor(), name, value);
+}
+enum ComponentUsageState {
+  COMP_USAGE_STATE_UNDEFINED = 0,
+  COMP_USAGE_STATE_UNKNOWN = 1,
+  COMP_USAGE_STATE_IDLE = 2,
+  COMP_USAGE_STATE_ACTIVE = 3,
+  COMP_USAGE_STATE_BUSY = 4,
+  ComponentUsageState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentUsageState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentUsageState_IsValid(int value);
+const ComponentUsageState ComponentUsageState_MIN = COMP_USAGE_STATE_UNDEFINED;
+const ComponentUsageState ComponentUsageState_MAX = COMP_USAGE_STATE_BUSY;
+const int ComponentUsageState_ARRAYSIZE = ComponentUsageState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentUsageState_descriptor();
+inline const ::std::string& ComponentUsageState_Name(ComponentUsageState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentUsageState_descriptor(), value);
+}
+inline bool ComponentUsageState_Parse(
+    const ::std::string& name, ComponentUsageState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentUsageState>(
+    ComponentUsageState_descriptor(), name, value);
+}
+enum ComponentAlarmState {
+  COMP_ALARM_STATE_UNDEFINED = 0,
+  COMP_ALARM_STATE_UNKNOWN = 1,
+  COMP_ALARM_STATE_UNDER_REPAIR = 2,
+  COMP_ALARM_STATE_CRITICAL = 3,
+  COMP_ALARM_STATE_MAJOR = 4,
+  COMP_ALARM_STATE_MINOR = 5,
+  COMP_ALARM_STATE_WARNING = 6,
+  COMP_ALARM_STATE_INDETERMINATE = 7,
+  ComponentAlarmState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentAlarmState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentAlarmState_IsValid(int value);
+const ComponentAlarmState ComponentAlarmState_MIN = COMP_ALARM_STATE_UNDEFINED;
+const ComponentAlarmState ComponentAlarmState_MAX = COMP_ALARM_STATE_INDETERMINATE;
+const int ComponentAlarmState_ARRAYSIZE = ComponentAlarmState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentAlarmState_descriptor();
+inline const ::std::string& ComponentAlarmState_Name(ComponentAlarmState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentAlarmState_descriptor(), value);
+}
+inline bool ComponentAlarmState_Parse(
+    const ::std::string& name, ComponentAlarmState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentAlarmState>(
+    ComponentAlarmState_descriptor(), name, value);
+}
+enum ComponentStandbyState {
+  COMP_STANDBY_STATE_UNDEFINED = 0,
+  COMP_STANDBY_STATE_UNKNOWN = 1,
+  COMP_STANDBY_STATE_HOT = 2,
+  COMP_STANDBY_STATE_COLD = 3,
+  COMP_STANDBY_STATE_PROVIDING_SERVICE = 4,
+  ComponentStandbyState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentStandbyState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentStandbyState_IsValid(int value);
+const ComponentStandbyState ComponentStandbyState_MIN = COMP_STANDBY_STATE_UNDEFINED;
+const ComponentStandbyState ComponentStandbyState_MAX = COMP_STANDBY_STATE_PROVIDING_SERVICE;
+const int ComponentStandbyState_ARRAYSIZE = ComponentStandbyState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentStandbyState_descriptor();
+inline const ::std::string& ComponentStandbyState_Name(ComponentStandbyState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentStandbyState_descriptor(), value);
+}
+inline bool ComponentStandbyState_Parse(
+    const ::std::string& name, ComponentStandbyState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentStandbyState>(
+    ComponentStandbyState_descriptor(), name, value);
+}
+enum DataValueType {
+  VALUE_TYPE_UNDEFINED = 0,
+  VALUE_TYPE_OTHER = 1,
+  VALUE_TYPE_UNKNOWN = 2,
+  VALUE_TYPE_VOLTS_AC = 3,
+  VALUE_TYPE_VOLTS_DC = 4,
+  VALUE_TYPE_AMPERES = 5,
+  VALUE_TYPE_WATTS = 6,
+  VALUE_TYPE_HERTZ = 7,
+  VALUE_TYPE_CELSIUS = 8,
+  VALUE_TYPE_PERCENT_RH = 9,
+  VALUE_TYPE_RPM = 10,
+  VALUE_TYPE_CMM = 11,
+  VALUE_TYPE_TRUTH_VALUE = 12,
+  VALUE_TYPE_PERCENT = 13,
+  VALUE_TYPE_METERS = 14,
+  VALUE_TYPE_BYTES = 15,
+  DataValueType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  DataValueType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool DataValueType_IsValid(int value);
+const DataValueType DataValueType_MIN = VALUE_TYPE_UNDEFINED;
+const DataValueType DataValueType_MAX = VALUE_TYPE_BYTES;
+const int DataValueType_ARRAYSIZE = DataValueType_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* DataValueType_descriptor();
+inline const ::std::string& DataValueType_Name(DataValueType value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    DataValueType_descriptor(), value);
+}
+inline bool DataValueType_Parse(
+    const ::std::string& name, DataValueType* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<DataValueType>(
+    DataValueType_descriptor(), name, value);
+}
+enum ValueScale {
+  VALUE_SCALE_UNDEFINED = 0,
+  VALUE_SCALE_YOCTO = 1,
+  VALUE_SCALE_ZEPTO = 2,
+  VALUE_SCALE_ATTO = 3,
+  VALUE_SCALE_FEMTO = 4,
+  VALUE_SCALE_PICO = 5,
+  VALUE_SCALE_NANO = 6,
+  VALUE_SCALE_MICRO = 7,
+  VALUE_SCALE_MILLI = 8,
+  VALUE_SCALE_UNITS = 9,
+  VALUE_SCALE_KILO = 10,
+  VALUE_SCALE_MEGA = 11,
+  VALUE_SCALE_GIGA = 12,
+  VALUE_SCALE_TERA = 13,
+  VALUE_SCALE_PETA = 14,
+  VALUE_SCALE_EXA = 15,
+  VALUE_SCALE_ZETTA = 16,
+  VALUE_SCALE_YOTTA = 17,
+  ValueScale_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ValueScale_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ValueScale_IsValid(int value);
+const ValueScale ValueScale_MIN = VALUE_SCALE_UNDEFINED;
+const ValueScale ValueScale_MAX = VALUE_SCALE_YOTTA;
+const int ValueScale_ARRAYSIZE = ValueScale_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ValueScale_descriptor();
+inline const ::std::string& ValueScale_Name(ValueScale value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ValueScale_descriptor(), value);
+}
+inline bool ValueScale_Parse(
+    const ::std::string& name, ValueScale* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ValueScale>(
+    ValueScale_descriptor(), name, value);
+}
+enum SensorStatus {
+  SENSOR_STATUS_UNDEFINED = 0,
+  SENSOR_STATUS_OK = 1,
+  SENSOR_STATUS_UNAVAILABLE = 2,
+  SENSOR_STATUS_NONOPERATIONAL = 3,
+  SensorStatus_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  SensorStatus_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool SensorStatus_IsValid(int value);
+const SensorStatus SensorStatus_MIN = SENSOR_STATUS_UNDEFINED;
+const SensorStatus SensorStatus_MAX = SENSOR_STATUS_NONOPERATIONAL;
+const int SensorStatus_ARRAYSIZE = SensorStatus_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* SensorStatus_descriptor();
+inline const ::std::string& SensorStatus_Name(SensorStatus value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    SensorStatus_descriptor(), value);
+}
+inline bool SensorStatus_Parse(
+    const ::std::string& name, SensorStatus* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<SensorStatus>(
+    SensorStatus_descriptor(), name, value);
+}
+// ===================================================================
+
+class Uuid final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Uuid) */ {
+ public:
+  Uuid();
+  virtual ~Uuid();
+
+  Uuid(const Uuid& from);
+
+  inline Uuid& operator=(const Uuid& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Uuid(Uuid&& from) noexcept
+    : Uuid() {
+    *this = ::std::move(from);
+  }
+
+  inline Uuid& operator=(Uuid&& 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 Uuid& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Uuid* internal_default_instance() {
+    return reinterpret_cast<const Uuid*>(
+               &_Uuid_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    0;
+
+  void Swap(Uuid* other);
+  friend void swap(Uuid& a, Uuid& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Uuid* New() const final {
+    return CreateMaybeMessage<Uuid>(nullptr);
+  }
+
+  Uuid* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Uuid>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Uuid& from);
+  void MergeFrom(const Uuid& 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(Uuid* 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 uuid = 1;
+  void clear_uuid();
+  static const int kUuidFieldNumber = 1;
+  const ::std::string& uuid() const;
+  void set_uuid(const ::std::string& value);
+  #if LANG_CXX11
+  void set_uuid(::std::string&& value);
+  #endif
+  void set_uuid(const char* value);
+  void set_uuid(const char* value, size_t size);
+  ::std::string* mutable_uuid();
+  ::std::string* release_uuid();
+  void set_allocated_uuid(::std::string* uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.Uuid)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class HardwareID final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.HardwareID) */ {
+ public:
+  HardwareID();
+  virtual ~HardwareID();
+
+  HardwareID(const HardwareID& from);
+
+  inline HardwareID& operator=(const HardwareID& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  HardwareID(HardwareID&& from) noexcept
+    : HardwareID() {
+    *this = ::std::move(from);
+  }
+
+  inline HardwareID& operator=(HardwareID&& 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 HardwareID& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const HardwareID* internal_default_instance() {
+    return reinterpret_cast<const HardwareID*>(
+               &_HardwareID_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    1;
+
+  void Swap(HardwareID* other);
+  friend void swap(HardwareID& a, HardwareID& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline HardwareID* New() const final {
+    return CreateMaybeMessage<HardwareID>(nullptr);
+  }
+
+  HardwareID* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<HardwareID>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const HardwareID& from);
+  void MergeFrom(const HardwareID& 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(HardwareID* 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 uuid = 1;
+  bool has_uuid() const;
+  void clear_uuid();
+  static const int kUuidFieldNumber = 1;
+  const ::dmi::Uuid& uuid() const;
+  ::dmi::Uuid* release_uuid();
+  ::dmi::Uuid* mutable_uuid();
+  void set_allocated_uuid(::dmi::Uuid* uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.HardwareID)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::Uuid* uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Uri final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Uri) */ {
+ public:
+  Uri();
+  virtual ~Uri();
+
+  Uri(const Uri& from);
+
+  inline Uri& operator=(const Uri& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Uri(Uri&& from) noexcept
+    : Uri() {
+    *this = ::std::move(from);
+  }
+
+  inline Uri& operator=(Uri&& 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 Uri& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Uri* internal_default_instance() {
+    return reinterpret_cast<const Uri*>(
+               &_Uri_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    2;
+
+  void Swap(Uri* other);
+  friend void swap(Uri& a, Uri& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Uri* New() const final {
+    return CreateMaybeMessage<Uri>(nullptr);
+  }
+
+  Uri* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Uri>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Uri& from);
+  void MergeFrom(const Uri& 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(Uri* 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 uri = 1;
+  void clear_uri();
+  static const int kUriFieldNumber = 1;
+  const ::std::string& uri() const;
+  void set_uri(const ::std::string& value);
+  #if LANG_CXX11
+  void set_uri(::std::string&& value);
+  #endif
+  void set_uri(const char* value);
+  void set_uri(const char* value, size_t size);
+  ::std::string* mutable_uri();
+  ::std::string* release_uri();
+  void set_allocated_uri(::std::string* uri);
+
+  // @@protoc_insertion_point(class_scope:dmi.Uri)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr uri_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ComponentState final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ComponentState) */ {
+ public:
+  ComponentState();
+  virtual ~ComponentState();
+
+  ComponentState(const ComponentState& from);
+
+  inline ComponentState& operator=(const ComponentState& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ComponentState(ComponentState&& from) noexcept
+    : ComponentState() {
+    *this = ::std::move(from);
+  }
+
+  inline ComponentState& operator=(ComponentState&& 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 ComponentState& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ComponentState* internal_default_instance() {
+    return reinterpret_cast<const ComponentState*>(
+               &_ComponentState_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    3;
+
+  void Swap(ComponentState* other);
+  friend void swap(ComponentState& a, ComponentState& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ComponentState* New() const final {
+    return CreateMaybeMessage<ComponentState>(nullptr);
+  }
+
+  ComponentState* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ComponentState>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ComponentState& from);
+  void MergeFrom(const ComponentState& 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(ComponentState* 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 -------------------------------------------------------
+
+  // .google.protobuf.Timestamp state_last_changed = 1;
+  bool has_state_last_changed() const;
+  void clear_state_last_changed();
+  static const int kStateLastChangedFieldNumber = 1;
+  const ::google::protobuf::Timestamp& state_last_changed() const;
+  ::google::protobuf::Timestamp* release_state_last_changed();
+  ::google::protobuf::Timestamp* mutable_state_last_changed();
+  void set_allocated_state_last_changed(::google::protobuf::Timestamp* state_last_changed);
+
+  // .dmi.ComponentAdminState admin_state = 2;
+  void clear_admin_state();
+  static const int kAdminStateFieldNumber = 2;
+  ::dmi::ComponentAdminState admin_state() const;
+  void set_admin_state(::dmi::ComponentAdminState value);
+
+  // .dmi.ComponentOperState oper_state = 3;
+  void clear_oper_state();
+  static const int kOperStateFieldNumber = 3;
+  ::dmi::ComponentOperState oper_state() const;
+  void set_oper_state(::dmi::ComponentOperState value);
+
+  // .dmi.ComponentUsageState usage_state = 4;
+  void clear_usage_state();
+  static const int kUsageStateFieldNumber = 4;
+  ::dmi::ComponentUsageState usage_state() const;
+  void set_usage_state(::dmi::ComponentUsageState value);
+
+  // .dmi.ComponentAlarmState alarm_state = 5;
+  void clear_alarm_state();
+  static const int kAlarmStateFieldNumber = 5;
+  ::dmi::ComponentAlarmState alarm_state() const;
+  void set_alarm_state(::dmi::ComponentAlarmState value);
+
+  // .dmi.ComponentStandbyState standby_state = 6;
+  void clear_standby_state();
+  static const int kStandbyStateFieldNumber = 6;
+  ::dmi::ComponentStandbyState standby_state() const;
+  void set_standby_state(::dmi::ComponentStandbyState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ComponentState)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::Timestamp* state_last_changed_;
+  int admin_state_;
+  int oper_state_;
+  int usage_state_;
+  int alarm_state_;
+  int standby_state_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ComponentSensorData final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ComponentSensorData) */ {
+ public:
+  ComponentSensorData();
+  virtual ~ComponentSensorData();
+
+  ComponentSensorData(const ComponentSensorData& from);
+
+  inline ComponentSensorData& operator=(const ComponentSensorData& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ComponentSensorData(ComponentSensorData&& from) noexcept
+    : ComponentSensorData() {
+    *this = ::std::move(from);
+  }
+
+  inline ComponentSensorData& operator=(ComponentSensorData&& 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 ComponentSensorData& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ComponentSensorData* internal_default_instance() {
+    return reinterpret_cast<const ComponentSensorData*>(
+               &_ComponentSensorData_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    4;
+
+  void Swap(ComponentSensorData* other);
+  friend void swap(ComponentSensorData& a, ComponentSensorData& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ComponentSensorData* New() const final {
+    return CreateMaybeMessage<ComponentSensorData>(nullptr);
+  }
+
+  ComponentSensorData* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ComponentSensorData>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ComponentSensorData& from);
+  void MergeFrom(const ComponentSensorData& 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(ComponentSensorData* 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 units_display = 6;
+  void clear_units_display();
+  static const int kUnitsDisplayFieldNumber = 6;
+  const ::std::string& units_display() const;
+  void set_units_display(const ::std::string& value);
+  #if LANG_CXX11
+  void set_units_display(::std::string&& value);
+  #endif
+  void set_units_display(const char* value);
+  void set_units_display(const char* value, size_t size);
+  ::std::string* mutable_units_display();
+  ::std::string* release_units_display();
+  void set_allocated_units_display(::std::string* units_display);
+
+  // string data_type = 9;
+  void clear_data_type();
+  static const int kDataTypeFieldNumber = 9;
+  const ::std::string& data_type() const;
+  void set_data_type(const ::std::string& value);
+  #if LANG_CXX11
+  void set_data_type(::std::string&& value);
+  #endif
+  void set_data_type(const char* value);
+  void set_data_type(const char* value, size_t size);
+  ::std::string* mutable_data_type();
+  ::std::string* release_data_type();
+  void set_allocated_data_type(::std::string* data_type);
+
+  // .google.protobuf.Timestamp timestamp = 7;
+  bool has_timestamp() const;
+  void clear_timestamp();
+  static const int kTimestampFieldNumber = 7;
+  const ::google::protobuf::Timestamp& timestamp() const;
+  ::google::protobuf::Timestamp* release_timestamp();
+  ::google::protobuf::Timestamp* mutable_timestamp();
+  void set_allocated_timestamp(::google::protobuf::Timestamp* timestamp);
+
+  // int32 value = 1;
+  void clear_value();
+  static const int kValueFieldNumber = 1;
+  ::google::protobuf::int32 value() const;
+  void set_value(::google::protobuf::int32 value);
+
+  // .dmi.DataValueType type = 2;
+  void clear_type();
+  static const int kTypeFieldNumber = 2;
+  ::dmi::DataValueType type() const;
+  void set_type(::dmi::DataValueType value);
+
+  // .dmi.ValueScale scale = 3;
+  void clear_scale();
+  static const int kScaleFieldNumber = 3;
+  ::dmi::ValueScale scale() const;
+  void set_scale(::dmi::ValueScale value);
+
+  // int32 precision = 4;
+  void clear_precision();
+  static const int kPrecisionFieldNumber = 4;
+  ::google::protobuf::int32 precision() const;
+  void set_precision(::google::protobuf::int32 value);
+
+  // .dmi.SensorStatus status = 5;
+  void clear_status();
+  static const int kStatusFieldNumber = 5;
+  ::dmi::SensorStatus status() const;
+  void set_status(::dmi::SensorStatus value);
+
+  // uint32 value_update_rate = 8;
+  void clear_value_update_rate();
+  static const int kValueUpdateRateFieldNumber = 8;
+  ::google::protobuf::uint32 value_update_rate() const;
+  void set_value_update_rate(::google::protobuf::uint32 value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ComponentSensorData)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr units_display_;
+  ::google::protobuf::internal::ArenaStringPtr data_type_;
+  ::google::protobuf::Timestamp* timestamp_;
+  ::google::protobuf::int32 value_;
+  int type_;
+  int scale_;
+  ::google::protobuf::int32 precision_;
+  int status_;
+  ::google::protobuf::uint32 value_update_rate_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PortComponentAttributes final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.PortComponentAttributes) */ {
+ public:
+  PortComponentAttributes();
+  virtual ~PortComponentAttributes();
+
+  PortComponentAttributes(const PortComponentAttributes& from);
+
+  inline PortComponentAttributes& operator=(const PortComponentAttributes& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  PortComponentAttributes(PortComponentAttributes&& from) noexcept
+    : PortComponentAttributes() {
+    *this = ::std::move(from);
+  }
+
+  inline PortComponentAttributes& operator=(PortComponentAttributes&& 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 PortComponentAttributes& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const PortComponentAttributes* internal_default_instance() {
+    return reinterpret_cast<const PortComponentAttributes*>(
+               &_PortComponentAttributes_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    5;
+
+  void Swap(PortComponentAttributes* other);
+  friend void swap(PortComponentAttributes& a, PortComponentAttributes& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline PortComponentAttributes* New() const final {
+    return CreateMaybeMessage<PortComponentAttributes>(nullptr);
+  }
+
+  PortComponentAttributes* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<PortComponentAttributes>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const PortComponentAttributes& from);
+  void MergeFrom(const PortComponentAttributes& 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(PortComponentAttributes* 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 PortComponentAttributes_ConnectorType ConnectorType;
+  static const ConnectorType CONNECTOR_TYPE_UNDEFINED =
+    PortComponentAttributes_ConnectorType_CONNECTOR_TYPE_UNDEFINED;
+  static const ConnectorType RJ45 =
+    PortComponentAttributes_ConnectorType_RJ45;
+  static const ConnectorType FIBER_LC =
+    PortComponentAttributes_ConnectorType_FIBER_LC;
+  static const ConnectorType FIBER_SC_PC =
+    PortComponentAttributes_ConnectorType_FIBER_SC_PC;
+  static const ConnectorType FIBER_MPO =
+    PortComponentAttributes_ConnectorType_FIBER_MPO;
+  static const ConnectorType RS232 =
+    PortComponentAttributes_ConnectorType_RS232;
+  static inline bool ConnectorType_IsValid(int value) {
+    return PortComponentAttributes_ConnectorType_IsValid(value);
+  }
+  static const ConnectorType ConnectorType_MIN =
+    PortComponentAttributes_ConnectorType_ConnectorType_MIN;
+  static const ConnectorType ConnectorType_MAX =
+    PortComponentAttributes_ConnectorType_ConnectorType_MAX;
+  static const int ConnectorType_ARRAYSIZE =
+    PortComponentAttributes_ConnectorType_ConnectorType_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  ConnectorType_descriptor() {
+    return PortComponentAttributes_ConnectorType_descriptor();
+  }
+  static inline const ::std::string& ConnectorType_Name(ConnectorType value) {
+    return PortComponentAttributes_ConnectorType_Name(value);
+  }
+  static inline bool ConnectorType_Parse(const ::std::string& name,
+      ConnectorType* value) {
+    return PortComponentAttributes_ConnectorType_Parse(name, value);
+  }
+
+  typedef PortComponentAttributes_Speed Speed;
+  static const Speed SPEED_UNDEFINED =
+    PortComponentAttributes_Speed_SPEED_UNDEFINED;
+  static const Speed DYNAMIC =
+    PortComponentAttributes_Speed_DYNAMIC;
+  static const Speed GIGABIT_1 =
+    PortComponentAttributes_Speed_GIGABIT_1;
+  static const Speed GIGABIT_10 =
+    PortComponentAttributes_Speed_GIGABIT_10;
+  static const Speed GIGABIT_25 =
+    PortComponentAttributes_Speed_GIGABIT_25;
+  static const Speed GIGABIT_40 =
+    PortComponentAttributes_Speed_GIGABIT_40;
+  static const Speed GIGABIT_100 =
+    PortComponentAttributes_Speed_GIGABIT_100;
+  static const Speed GIGABIT_400 =
+    PortComponentAttributes_Speed_GIGABIT_400;
+  static const Speed MEGABIT_2500 =
+    PortComponentAttributes_Speed_MEGABIT_2500;
+  static const Speed MEGABIT_1250 =
+    PortComponentAttributes_Speed_MEGABIT_1250;
+  static inline bool Speed_IsValid(int value) {
+    return PortComponentAttributes_Speed_IsValid(value);
+  }
+  static const Speed Speed_MIN =
+    PortComponentAttributes_Speed_Speed_MIN;
+  static const Speed Speed_MAX =
+    PortComponentAttributes_Speed_Speed_MAX;
+  static const int Speed_ARRAYSIZE =
+    PortComponentAttributes_Speed_Speed_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Speed_descriptor() {
+    return PortComponentAttributes_Speed_descriptor();
+  }
+  static inline const ::std::string& Speed_Name(Speed value) {
+    return PortComponentAttributes_Speed_Name(value);
+  }
+  static inline bool Speed_Parse(const ::std::string& name,
+      Speed* value) {
+    return PortComponentAttributes_Speed_Parse(name, value);
+  }
+
+  typedef PortComponentAttributes_Protocol Protocol;
+  static const Protocol PROTOCOL_UNDEFINED =
+    PortComponentAttributes_Protocol_PROTOCOL_UNDEFINED;
+  static const Protocol ETHERNET =
+    PortComponentAttributes_Protocol_ETHERNET;
+  static const Protocol GPON =
+    PortComponentAttributes_Protocol_GPON;
+  static const Protocol XGPON =
+    PortComponentAttributes_Protocol_XGPON;
+  static const Protocol XGSPON =
+    PortComponentAttributes_Protocol_XGSPON;
+  static const Protocol GFAST =
+    PortComponentAttributes_Protocol_GFAST;
+  static const Protocol SERIAL =
+    PortComponentAttributes_Protocol_SERIAL;
+  static const Protocol EPON =
+    PortComponentAttributes_Protocol_EPON;
+  static const Protocol BITS =
+    PortComponentAttributes_Protocol_BITS;
+  static inline bool Protocol_IsValid(int value) {
+    return PortComponentAttributes_Protocol_IsValid(value);
+  }
+  static const Protocol Protocol_MIN =
+    PortComponentAttributes_Protocol_Protocol_MIN;
+  static const Protocol Protocol_MAX =
+    PortComponentAttributes_Protocol_Protocol_MAX;
+  static const int Protocol_ARRAYSIZE =
+    PortComponentAttributes_Protocol_Protocol_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Protocol_descriptor() {
+    return PortComponentAttributes_Protocol_descriptor();
+  }
+  static inline const ::std::string& Protocol_Name(Protocol value) {
+    return PortComponentAttributes_Protocol_Name(value);
+  }
+  static inline bool Protocol_Parse(const ::std::string& name,
+      Protocol* value) {
+    return PortComponentAttributes_Protocol_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string physical_label = 4;
+  void clear_physical_label();
+  static const int kPhysicalLabelFieldNumber = 4;
+  const ::std::string& physical_label() const;
+  void set_physical_label(const ::std::string& value);
+  #if LANG_CXX11
+  void set_physical_label(::std::string&& value);
+  #endif
+  void set_physical_label(const char* value);
+  void set_physical_label(const char* value, size_t size);
+  ::std::string* mutable_physical_label();
+  ::std::string* release_physical_label();
+  void set_allocated_physical_label(::std::string* physical_label);
+
+  // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+  void clear_connector_type();
+  static const int kConnectorTypeFieldNumber = 1;
+  ::dmi::PortComponentAttributes_ConnectorType connector_type() const;
+  void set_connector_type(::dmi::PortComponentAttributes_ConnectorType value);
+
+  // .dmi.PortComponentAttributes.Speed speed = 2;
+  void clear_speed();
+  static const int kSpeedFieldNumber = 2;
+  ::dmi::PortComponentAttributes_Speed speed() const;
+  void set_speed(::dmi::PortComponentAttributes_Speed value);
+
+  // .dmi.PortComponentAttributes.Protocol protocol = 3;
+  void clear_protocol();
+  static const int kProtocolFieldNumber = 3;
+  ::dmi::PortComponentAttributes_Protocol protocol() const;
+  void set_protocol(::dmi::PortComponentAttributes_Protocol value);
+
+  // @@protoc_insertion_point(class_scope:dmi.PortComponentAttributes)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr physical_label_;
+  int connector_type_;
+  int speed_;
+  int protocol_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ContainerComponentAttributes final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ContainerComponentAttributes) */ {
+ public:
+  ContainerComponentAttributes();
+  virtual ~ContainerComponentAttributes();
+
+  ContainerComponentAttributes(const ContainerComponentAttributes& from);
+
+  inline ContainerComponentAttributes& operator=(const ContainerComponentAttributes& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ContainerComponentAttributes(ContainerComponentAttributes&& from) noexcept
+    : ContainerComponentAttributes() {
+    *this = ::std::move(from);
+  }
+
+  inline ContainerComponentAttributes& operator=(ContainerComponentAttributes&& 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 ContainerComponentAttributes& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ContainerComponentAttributes* internal_default_instance() {
+    return reinterpret_cast<const ContainerComponentAttributes*>(
+               &_ContainerComponentAttributes_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    6;
+
+  void Swap(ContainerComponentAttributes* other);
+  friend void swap(ContainerComponentAttributes& a, ContainerComponentAttributes& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ContainerComponentAttributes* New() const final {
+    return CreateMaybeMessage<ContainerComponentAttributes>(nullptr);
+  }
+
+  ContainerComponentAttributes* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ContainerComponentAttributes>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ContainerComponentAttributes& from);
+  void MergeFrom(const ContainerComponentAttributes& 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(ContainerComponentAttributes* 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 physical_label = 1;
+  void clear_physical_label();
+  static const int kPhysicalLabelFieldNumber = 1;
+  const ::std::string& physical_label() const;
+  void set_physical_label(const ::std::string& value);
+  #if LANG_CXX11
+  void set_physical_label(::std::string&& value);
+  #endif
+  void set_physical_label(const char* value);
+  void set_physical_label(const char* value, size_t size);
+  ::std::string* mutable_physical_label();
+  ::std::string* release_physical_label();
+  void set_allocated_physical_label(::std::string* physical_label);
+
+  // @@protoc_insertion_point(class_scope:dmi.ContainerComponentAttributes)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr physical_label_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PsuComponentAttributes final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.PsuComponentAttributes) */ {
+ public:
+  PsuComponentAttributes();
+  virtual ~PsuComponentAttributes();
+
+  PsuComponentAttributes(const PsuComponentAttributes& from);
+
+  inline PsuComponentAttributes& operator=(const PsuComponentAttributes& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  PsuComponentAttributes(PsuComponentAttributes&& from) noexcept
+    : PsuComponentAttributes() {
+    *this = ::std::move(from);
+  }
+
+  inline PsuComponentAttributes& operator=(PsuComponentAttributes&& 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 PsuComponentAttributes& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const PsuComponentAttributes* internal_default_instance() {
+    return reinterpret_cast<const PsuComponentAttributes*>(
+               &_PsuComponentAttributes_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    7;
+
+  void Swap(PsuComponentAttributes* other);
+  friend void swap(PsuComponentAttributes& a, PsuComponentAttributes& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline PsuComponentAttributes* New() const final {
+    return CreateMaybeMessage<PsuComponentAttributes>(nullptr);
+  }
+
+  PsuComponentAttributes* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<PsuComponentAttributes>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const PsuComponentAttributes& from);
+  void MergeFrom(const PsuComponentAttributes& 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(PsuComponentAttributes* 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 PsuComponentAttributes_SupportedVoltage SupportedVoltage;
+  static const SupportedVoltage SUPPORTED_VOLTAGE_UNDEFINED =
+    PsuComponentAttributes_SupportedVoltage_SUPPORTED_VOLTAGE_UNDEFINED;
+  static const SupportedVoltage V48 =
+    PsuComponentAttributes_SupportedVoltage_V48;
+  static const SupportedVoltage V230 =
+    PsuComponentAttributes_SupportedVoltage_V230;
+  static const SupportedVoltage V115 =
+    PsuComponentAttributes_SupportedVoltage_V115;
+  static inline bool SupportedVoltage_IsValid(int value) {
+    return PsuComponentAttributes_SupportedVoltage_IsValid(value);
+  }
+  static const SupportedVoltage SupportedVoltage_MIN =
+    PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MIN;
+  static const SupportedVoltage SupportedVoltage_MAX =
+    PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MAX;
+  static const int SupportedVoltage_ARRAYSIZE =
+    PsuComponentAttributes_SupportedVoltage_SupportedVoltage_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  SupportedVoltage_descriptor() {
+    return PsuComponentAttributes_SupportedVoltage_descriptor();
+  }
+  static inline const ::std::string& SupportedVoltage_Name(SupportedVoltage value) {
+    return PsuComponentAttributes_SupportedVoltage_Name(value);
+  }
+  static inline bool SupportedVoltage_Parse(const ::std::string& name,
+      SupportedVoltage* value) {
+    return PsuComponentAttributes_SupportedVoltage_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+  void clear_supported_voltage();
+  static const int kSupportedVoltageFieldNumber = 1;
+  ::dmi::PsuComponentAttributes_SupportedVoltage supported_voltage() const;
+  void set_supported_voltage(::dmi::PsuComponentAttributes_SupportedVoltage value);
+
+  // @@protoc_insertion_point(class_scope:dmi.PsuComponentAttributes)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  int supported_voltage_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class TransceiverComponentsAttributes final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.TransceiverComponentsAttributes) */ {
+ public:
+  TransceiverComponentsAttributes();
+  virtual ~TransceiverComponentsAttributes();
+
+  TransceiverComponentsAttributes(const TransceiverComponentsAttributes& from);
+
+  inline TransceiverComponentsAttributes& operator=(const TransceiverComponentsAttributes& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  TransceiverComponentsAttributes(TransceiverComponentsAttributes&& from) noexcept
+    : TransceiverComponentsAttributes() {
+    *this = ::std::move(from);
+  }
+
+  inline TransceiverComponentsAttributes& operator=(TransceiverComponentsAttributes&& 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 TransceiverComponentsAttributes& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const TransceiverComponentsAttributes* internal_default_instance() {
+    return reinterpret_cast<const TransceiverComponentsAttributes*>(
+               &_TransceiverComponentsAttributes_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    8;
+
+  void Swap(TransceiverComponentsAttributes* other);
+  friend void swap(TransceiverComponentsAttributes& a, TransceiverComponentsAttributes& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline TransceiverComponentsAttributes* New() const final {
+    return CreateMaybeMessage<TransceiverComponentsAttributes>(nullptr);
+  }
+
+  TransceiverComponentsAttributes* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<TransceiverComponentsAttributes>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const TransceiverComponentsAttributes& from);
+  void MergeFrom(const TransceiverComponentsAttributes& 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(TransceiverComponentsAttributes* 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 TransceiverComponentsAttributes_FormFactor FormFactor;
+  static const FormFactor FORM_FACTOR_UNKNOWN =
+    TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN;
+  static const FormFactor QSFP =
+    TransceiverComponentsAttributes_FormFactor_QSFP;
+  static const FormFactor QSFP_PLUS =
+    TransceiverComponentsAttributes_FormFactor_QSFP_PLUS;
+  static const FormFactor QSFP28 =
+    TransceiverComponentsAttributes_FormFactor_QSFP28;
+  static const FormFactor SFP =
+    TransceiverComponentsAttributes_FormFactor_SFP;
+  static const FormFactor SFP_PLUS =
+    TransceiverComponentsAttributes_FormFactor_SFP_PLUS;
+  static const FormFactor XFP =
+    TransceiverComponentsAttributes_FormFactor_XFP;
+  static const FormFactor CFP4 =
+    TransceiverComponentsAttributes_FormFactor_CFP4;
+  static const FormFactor CFP2 =
+    TransceiverComponentsAttributes_FormFactor_CFP2;
+  static const FormFactor CPAK =
+    TransceiverComponentsAttributes_FormFactor_CPAK;
+  static const FormFactor X2 =
+    TransceiverComponentsAttributes_FormFactor_X2;
+  static const FormFactor OTHER =
+    TransceiverComponentsAttributes_FormFactor_OTHER;
+  static const FormFactor CFP =
+    TransceiverComponentsAttributes_FormFactor_CFP;
+  static const FormFactor CFP2_ACO =
+    TransceiverComponentsAttributes_FormFactor_CFP2_ACO;
+  static const FormFactor CFP2_DCO =
+    TransceiverComponentsAttributes_FormFactor_CFP2_DCO;
+  static inline bool FormFactor_IsValid(int value) {
+    return TransceiverComponentsAttributes_FormFactor_IsValid(value);
+  }
+  static const FormFactor FormFactor_MIN =
+    TransceiverComponentsAttributes_FormFactor_FormFactor_MIN;
+  static const FormFactor FormFactor_MAX =
+    TransceiverComponentsAttributes_FormFactor_FormFactor_MAX;
+  static const int FormFactor_ARRAYSIZE =
+    TransceiverComponentsAttributes_FormFactor_FormFactor_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  FormFactor_descriptor() {
+    return TransceiverComponentsAttributes_FormFactor_descriptor();
+  }
+  static inline const ::std::string& FormFactor_Name(FormFactor value) {
+    return TransceiverComponentsAttributes_FormFactor_Name(value);
+  }
+  static inline bool FormFactor_Parse(const ::std::string& name,
+      FormFactor* value) {
+    return TransceiverComponentsAttributes_FormFactor_Parse(name, value);
+  }
+
+  typedef TransceiverComponentsAttributes_Type Type;
+  static const Type TYPE_UNKNOWN =
+    TransceiverComponentsAttributes_Type_TYPE_UNKNOWN;
+  static const Type ETHERNET =
+    TransceiverComponentsAttributes_Type_ETHERNET;
+  static const Type GPON =
+    TransceiverComponentsAttributes_Type_GPON;
+  static const Type XGPON =
+    TransceiverComponentsAttributes_Type_XGPON;
+  static const Type XGSPON =
+    TransceiverComponentsAttributes_Type_XGSPON;
+  static const Type CPON =
+    TransceiverComponentsAttributes_Type_CPON;
+  static const Type NG_PON2 =
+    TransceiverComponentsAttributes_Type_NG_PON2;
+  static const Type EPON =
+    TransceiverComponentsAttributes_Type_EPON;
+  static inline bool Type_IsValid(int value) {
+    return TransceiverComponentsAttributes_Type_IsValid(value);
+  }
+  static const Type Type_MIN =
+    TransceiverComponentsAttributes_Type_Type_MIN;
+  static const Type Type_MAX =
+    TransceiverComponentsAttributes_Type_Type_MAX;
+  static const int Type_ARRAYSIZE =
+    TransceiverComponentsAttributes_Type_Type_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Type_descriptor() {
+    return TransceiverComponentsAttributes_Type_descriptor();
+  }
+  static inline const ::std::string& Type_Name(Type value) {
+    return TransceiverComponentsAttributes_Type_Name(value);
+  }
+  static inline bool Type_Parse(const ::std::string& name,
+      Type* value) {
+    return TransceiverComponentsAttributes_Type_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // repeated uint32 rx_wavelength = 5;
+  int rx_wavelength_size() const;
+  void clear_rx_wavelength();
+  static const int kRxWavelengthFieldNumber = 5;
+  ::google::protobuf::uint32 rx_wavelength(int index) const;
+  void set_rx_wavelength(int index, ::google::protobuf::uint32 value);
+  void add_rx_wavelength(::google::protobuf::uint32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+      rx_wavelength() const;
+  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+      mutable_rx_wavelength();
+
+  // repeated uint32 tx_wavelength = 6;
+  int tx_wavelength_size() const;
+  void clear_tx_wavelength();
+  static const int kTxWavelengthFieldNumber = 6;
+  ::google::protobuf::uint32 tx_wavelength(int index) const;
+  void set_tx_wavelength(int index, ::google::protobuf::uint32 value);
+  void add_tx_wavelength(::google::protobuf::uint32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+      tx_wavelength() const;
+  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+      mutable_tx_wavelength();
+
+  // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+  void clear_form_factor();
+  static const int kFormFactorFieldNumber = 1;
+  ::dmi::TransceiverComponentsAttributes_FormFactor form_factor() const;
+  void set_form_factor(::dmi::TransceiverComponentsAttributes_FormFactor value);
+
+  // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+  void clear_trans_type();
+  static const int kTransTypeFieldNumber = 2;
+  ::dmi::TransceiverComponentsAttributes_Type trans_type() const;
+  void set_trans_type(::dmi::TransceiverComponentsAttributes_Type value);
+
+  // uint32 max_distance = 3;
+  void clear_max_distance();
+  static const int kMaxDistanceFieldNumber = 3;
+  ::google::protobuf::uint32 max_distance() const;
+  void set_max_distance(::google::protobuf::uint32 value);
+
+  // .dmi.ValueScale max_distance_scale = 4;
+  void clear_max_distance_scale();
+  static const int kMaxDistanceScaleFieldNumber = 4;
+  ::dmi::ValueScale max_distance_scale() const;
+  void set_max_distance_scale(::dmi::ValueScale value);
+
+  // .dmi.ValueScale wavelength_scale = 7;
+  void clear_wavelength_scale();
+  static const int kWavelengthScaleFieldNumber = 7;
+  ::dmi::ValueScale wavelength_scale() const;
+  void set_wavelength_scale(::dmi::ValueScale value);
+
+  // @@protoc_insertion_point(class_scope:dmi.TransceiverComponentsAttributes)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > rx_wavelength_;
+  mutable std::atomic<int> _rx_wavelength_cached_byte_size_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > tx_wavelength_;
+  mutable std::atomic<int> _tx_wavelength_cached_byte_size_;
+  int form_factor_;
+  int trans_type_;
+  ::google::protobuf::uint32 max_distance_;
+  int max_distance_scale_;
+  int wavelength_scale_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Component final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Component) */ {
+ public:
+  Component();
+  virtual ~Component();
+
+  Component(const Component& from);
+
+  inline Component& operator=(const Component& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Component(Component&& from) noexcept
+    : Component() {
+    *this = ::std::move(from);
+  }
+
+  inline Component& operator=(Component&& 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 Component& default_instance();
+
+  enum SpecificCase {
+    kPortAttr = 50,
+    kContainerAttr = 51,
+    kPsuAttr = 52,
+    kTransceiverAttr = 53,
+    SPECIFIC_NOT_SET = 0,
+  };
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Component* internal_default_instance() {
+    return reinterpret_cast<const Component*>(
+               &_Component_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    9;
+
+  void Swap(Component* other);
+  friend void swap(Component& a, Component& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Component* New() const final {
+    return CreateMaybeMessage<Component>(nullptr);
+  }
+
+  Component* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Component>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Component& from);
+  void MergeFrom(const Component& 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(Component* 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.Component children = 6;
+  int children_size() const;
+  void clear_children();
+  static const int kChildrenFieldNumber = 6;
+  ::dmi::Component* mutable_children(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::Component >*
+      mutable_children();
+  const ::dmi::Component& children(int index) const;
+  ::dmi::Component* add_children();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::Component >&
+      children() const;
+
+  // repeated .dmi.ComponentSensorData sensor_data = 20;
+  int sensor_data_size() const;
+  void clear_sensor_data();
+  static const int kSensorDataFieldNumber = 20;
+  ::dmi::ComponentSensorData* mutable_sensor_data(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >*
+      mutable_sensor_data();
+  const ::dmi::ComponentSensorData& sensor_data(int index) const;
+  ::dmi::ComponentSensorData* add_sensor_data();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >&
+      sensor_data() const;
+
+  // 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);
+
+  // string description = 3;
+  void clear_description();
+  static const int kDescriptionFieldNumber = 3;
+  const ::std::string& description() const;
+  void set_description(const ::std::string& value);
+  #if LANG_CXX11
+  void set_description(::std::string&& value);
+  #endif
+  void set_description(const char* value);
+  void set_description(const char* value, size_t size);
+  ::std::string* mutable_description();
+  ::std::string* release_description();
+  void set_allocated_description(::std::string* description);
+
+  // string parent = 4;
+  void clear_parent();
+  static const int kParentFieldNumber = 4;
+  const ::std::string& parent() const;
+  void set_parent(const ::std::string& value);
+  #if LANG_CXX11
+  void set_parent(::std::string&& value);
+  #endif
+  void set_parent(const char* value);
+  void set_parent(const char* value, size_t size);
+  ::std::string* mutable_parent();
+  ::std::string* release_parent();
+  void set_allocated_parent(::std::string* parent);
+
+  // string hardware_rev = 7;
+  void clear_hardware_rev();
+  static const int kHardwareRevFieldNumber = 7;
+  const ::std::string& hardware_rev() const;
+  void set_hardware_rev(const ::std::string& value);
+  #if LANG_CXX11
+  void set_hardware_rev(::std::string&& value);
+  #endif
+  void set_hardware_rev(const char* value);
+  void set_hardware_rev(const char* value, size_t size);
+  ::std::string* mutable_hardware_rev();
+  ::std::string* release_hardware_rev();
+  void set_allocated_hardware_rev(::std::string* hardware_rev);
+
+  // string firmware_rev = 8;
+  void clear_firmware_rev();
+  static const int kFirmwareRevFieldNumber = 8;
+  const ::std::string& firmware_rev() const;
+  void set_firmware_rev(const ::std::string& value);
+  #if LANG_CXX11
+  void set_firmware_rev(::std::string&& value);
+  #endif
+  void set_firmware_rev(const char* value);
+  void set_firmware_rev(const char* value, size_t size);
+  ::std::string* mutable_firmware_rev();
+  ::std::string* release_firmware_rev();
+  void set_allocated_firmware_rev(::std::string* firmware_rev);
+
+  // string software_rev = 9;
+  void clear_software_rev();
+  static const int kSoftwareRevFieldNumber = 9;
+  const ::std::string& software_rev() const;
+  void set_software_rev(const ::std::string& value);
+  #if LANG_CXX11
+  void set_software_rev(::std::string&& value);
+  #endif
+  void set_software_rev(const char* value);
+  void set_software_rev(const char* value, size_t size);
+  ::std::string* mutable_software_rev();
+  ::std::string* release_software_rev();
+  void set_allocated_software_rev(::std::string* software_rev);
+
+  // string serial_num = 10;
+  void clear_serial_num();
+  static const int kSerialNumFieldNumber = 10;
+  const ::std::string& serial_num() const;
+  void set_serial_num(const ::std::string& value);
+  #if LANG_CXX11
+  void set_serial_num(::std::string&& value);
+  #endif
+  void set_serial_num(const char* value);
+  void set_serial_num(const char* value, size_t size);
+  ::std::string* mutable_serial_num();
+  ::std::string* release_serial_num();
+  void set_allocated_serial_num(::std::string* serial_num);
+
+  // string mfg_name = 11;
+  void clear_mfg_name();
+  static const int kMfgNameFieldNumber = 11;
+  const ::std::string& mfg_name() const;
+  void set_mfg_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_mfg_name(::std::string&& value);
+  #endif
+  void set_mfg_name(const char* value);
+  void set_mfg_name(const char* value, size_t size);
+  ::std::string* mutable_mfg_name();
+  ::std::string* release_mfg_name();
+  void set_allocated_mfg_name(::std::string* mfg_name);
+
+  // string model_name = 12;
+  void clear_model_name();
+  static const int kModelNameFieldNumber = 12;
+  const ::std::string& model_name() const;
+  void set_model_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_model_name(::std::string&& value);
+  #endif
+  void set_model_name(const char* value);
+  void set_model_name(const char* value, size_t size);
+  ::std::string* mutable_model_name();
+  ::std::string* release_model_name();
+  void set_allocated_model_name(::std::string* model_name);
+
+  // string alias = 13;
+  void clear_alias();
+  static const int kAliasFieldNumber = 13;
+  const ::std::string& alias() const;
+  void set_alias(const ::std::string& value);
+  #if LANG_CXX11
+  void set_alias(::std::string&& value);
+  #endif
+  void set_alias(const char* value);
+  void set_alias(const char* value, size_t size);
+  ::std::string* mutable_alias();
+  ::std::string* release_alias();
+  void set_allocated_alias(::std::string* alias);
+
+  // string asset_id = 14;
+  void clear_asset_id();
+  static const int kAssetIdFieldNumber = 14;
+  const ::std::string& asset_id() const;
+  void set_asset_id(const ::std::string& value);
+  #if LANG_CXX11
+  void set_asset_id(::std::string&& value);
+  #endif
+  void set_asset_id(const char* value);
+  void set_asset_id(const char* value, size_t size);
+  ::std::string* mutable_asset_id();
+  ::std::string* release_asset_id();
+  void set_allocated_asset_id(::std::string* asset_id);
+
+  // .google.protobuf.Timestamp mfg_date = 16;
+  bool has_mfg_date() const;
+  void clear_mfg_date();
+  static const int kMfgDateFieldNumber = 16;
+  const ::google::protobuf::Timestamp& mfg_date() const;
+  ::google::protobuf::Timestamp* release_mfg_date();
+  ::google::protobuf::Timestamp* mutable_mfg_date();
+  void set_allocated_mfg_date(::google::protobuf::Timestamp* mfg_date);
+
+  // .dmi.Uri uri = 17;
+  bool has_uri() const;
+  void clear_uri();
+  static const int kUriFieldNumber = 17;
+  const ::dmi::Uri& uri() const;
+  ::dmi::Uri* release_uri();
+  ::dmi::Uri* mutable_uri();
+  void set_allocated_uri(::dmi::Uri* uri);
+
+  // .dmi.Uuid uuid = 18;
+  bool has_uuid() const;
+  void clear_uuid();
+  static const int kUuidFieldNumber = 18;
+  const ::dmi::Uuid& uuid() const;
+  ::dmi::Uuid* release_uuid();
+  ::dmi::Uuid* mutable_uuid();
+  void set_allocated_uuid(::dmi::Uuid* uuid);
+
+  // .dmi.ComponentState state = 19;
+  bool has_state() const;
+  void clear_state();
+  static const int kStateFieldNumber = 19;
+  const ::dmi::ComponentState& state() const;
+  ::dmi::ComponentState* release_state();
+  ::dmi::ComponentState* mutable_state();
+  void set_allocated_state(::dmi::ComponentState* state);
+
+  // .dmi.ComponentType class = 2;
+  void clear_class_();
+  static const int kClassFieldNumber = 2;
+  ::dmi::ComponentType class_() const;
+  void set_class_(::dmi::ComponentType value);
+
+  // int32 parent_rel_pos = 5;
+  void clear_parent_rel_pos();
+  static const int kParentRelPosFieldNumber = 5;
+  ::google::protobuf::int32 parent_rel_pos() const;
+  void set_parent_rel_pos(::google::protobuf::int32 value);
+
+  // bool is_fru = 15;
+  void clear_is_fru();
+  static const int kIsFruFieldNumber = 15;
+  bool is_fru() const;
+  void set_is_fru(bool value);
+
+  // .dmi.PortComponentAttributes port_attr = 50;
+  bool has_port_attr() const;
+  void clear_port_attr();
+  static const int kPortAttrFieldNumber = 50;
+  const ::dmi::PortComponentAttributes& port_attr() const;
+  ::dmi::PortComponentAttributes* release_port_attr();
+  ::dmi::PortComponentAttributes* mutable_port_attr();
+  void set_allocated_port_attr(::dmi::PortComponentAttributes* port_attr);
+
+  // .dmi.ContainerComponentAttributes container_attr = 51;
+  bool has_container_attr() const;
+  void clear_container_attr();
+  static const int kContainerAttrFieldNumber = 51;
+  const ::dmi::ContainerComponentAttributes& container_attr() const;
+  ::dmi::ContainerComponentAttributes* release_container_attr();
+  ::dmi::ContainerComponentAttributes* mutable_container_attr();
+  void set_allocated_container_attr(::dmi::ContainerComponentAttributes* container_attr);
+
+  // .dmi.PsuComponentAttributes psu_attr = 52;
+  bool has_psu_attr() const;
+  void clear_psu_attr();
+  static const int kPsuAttrFieldNumber = 52;
+  const ::dmi::PsuComponentAttributes& psu_attr() const;
+  ::dmi::PsuComponentAttributes* release_psu_attr();
+  ::dmi::PsuComponentAttributes* mutable_psu_attr();
+  void set_allocated_psu_attr(::dmi::PsuComponentAttributes* psu_attr);
+
+  // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+  bool has_transceiver_attr() const;
+  void clear_transceiver_attr();
+  static const int kTransceiverAttrFieldNumber = 53;
+  const ::dmi::TransceiverComponentsAttributes& transceiver_attr() const;
+  ::dmi::TransceiverComponentsAttributes* release_transceiver_attr();
+  ::dmi::TransceiverComponentsAttributes* mutable_transceiver_attr();
+  void set_allocated_transceiver_attr(::dmi::TransceiverComponentsAttributes* transceiver_attr);
+
+  void clear_specific();
+  SpecificCase specific_case() const;
+  // @@protoc_insertion_point(class_scope:dmi.Component)
+ private:
+  class HasBitSetters;
+  void set_has_port_attr();
+  void set_has_container_attr();
+  void set_has_psu_attr();
+  void set_has_transceiver_attr();
+
+  inline bool has_specific() const;
+  inline void clear_has_specific();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::Component > children_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData > sensor_data_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  ::google::protobuf::internal::ArenaStringPtr description_;
+  ::google::protobuf::internal::ArenaStringPtr parent_;
+  ::google::protobuf::internal::ArenaStringPtr hardware_rev_;
+  ::google::protobuf::internal::ArenaStringPtr firmware_rev_;
+  ::google::protobuf::internal::ArenaStringPtr software_rev_;
+  ::google::protobuf::internal::ArenaStringPtr serial_num_;
+  ::google::protobuf::internal::ArenaStringPtr mfg_name_;
+  ::google::protobuf::internal::ArenaStringPtr model_name_;
+  ::google::protobuf::internal::ArenaStringPtr alias_;
+  ::google::protobuf::internal::ArenaStringPtr asset_id_;
+  ::google::protobuf::Timestamp* mfg_date_;
+  ::dmi::Uri* uri_;
+  ::dmi::Uuid* uuid_;
+  ::dmi::ComponentState* state_;
+  int class__;
+  ::google::protobuf::int32 parent_rel_pos_;
+  bool is_fru_;
+  union SpecificUnion {
+    SpecificUnion() {}
+    ::dmi::PortComponentAttributes* port_attr_;
+    ::dmi::ContainerComponentAttributes* container_attr_;
+    ::dmi::PsuComponentAttributes* psu_attr_;
+    ::dmi::TransceiverComponentsAttributes* transceiver_attr_;
+  } specific_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Hardware final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Hardware) */ {
+ public:
+  Hardware();
+  virtual ~Hardware();
+
+  Hardware(const Hardware& from);
+
+  inline Hardware& operator=(const Hardware& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Hardware(Hardware&& from) noexcept
+    : Hardware() {
+    *this = ::std::move(from);
+  }
+
+  inline Hardware& operator=(Hardware&& 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 Hardware& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Hardware* internal_default_instance() {
+    return reinterpret_cast<const Hardware*>(
+               &_Hardware_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    10;
+
+  void Swap(Hardware* other);
+  friend void swap(Hardware& a, Hardware& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Hardware* New() const final {
+    return CreateMaybeMessage<Hardware>(nullptr);
+  }
+
+  Hardware* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Hardware>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Hardware& from);
+  void MergeFrom(const Hardware& 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(Hardware* 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 -------------------------------------------------------
+
+  // .google.protobuf.Timestamp last_change = 1;
+  bool has_last_change() const;
+  void clear_last_change();
+  static const int kLastChangeFieldNumber = 1;
+  const ::google::protobuf::Timestamp& last_change() const;
+  ::google::protobuf::Timestamp* release_last_change();
+  ::google::protobuf::Timestamp* mutable_last_change();
+  void set_allocated_last_change(::google::protobuf::Timestamp* last_change);
+
+  // .dmi.Component root = 2;
+  bool has_root() const;
+  void clear_root();
+  static const int kRootFieldNumber = 2;
+  const ::dmi::Component& root() const;
+  ::dmi::Component* release_root();
+  ::dmi::Component* mutable_root();
+  void set_allocated_root(::dmi::Component* root);
+
+  // .google.protobuf.Timestamp last_booted = 3;
+  bool has_last_booted() const;
+  void clear_last_booted();
+  static const int kLastBootedFieldNumber = 3;
+  const ::google::protobuf::Timestamp& last_booted() const;
+  ::google::protobuf::Timestamp* release_last_booted();
+  ::google::protobuf::Timestamp* mutable_last_booted();
+  void set_allocated_last_booted(::google::protobuf::Timestamp* last_booted);
+
+  // @@protoc_insertion_point(class_scope:dmi.Hardware)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::Timestamp* last_change_;
+  ::dmi::Component* root_;
+  ::google::protobuf::Timestamp* last_booted_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ModifiableComponent final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ModifiableComponent) */ {
+ public:
+  ModifiableComponent();
+  virtual ~ModifiableComponent();
+
+  ModifiableComponent(const ModifiableComponent& from);
+
+  inline ModifiableComponent& operator=(const ModifiableComponent& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ModifiableComponent(ModifiableComponent&& from) noexcept
+    : ModifiableComponent() {
+    *this = ::std::move(from);
+  }
+
+  inline ModifiableComponent& operator=(ModifiableComponent&& 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 ModifiableComponent& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ModifiableComponent* internal_default_instance() {
+    return reinterpret_cast<const ModifiableComponent*>(
+               &_ModifiableComponent_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    11;
+
+  void Swap(ModifiableComponent* other);
+  friend void swap(ModifiableComponent& a, ModifiableComponent& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ModifiableComponent* New() const final {
+    return CreateMaybeMessage<ModifiableComponent>(nullptr);
+  }
+
+  ModifiableComponent* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ModifiableComponent>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ModifiableComponent& from);
+  void MergeFrom(const ModifiableComponent& 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(ModifiableComponent* 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);
+
+  // string alias = 5;
+  void clear_alias();
+  static const int kAliasFieldNumber = 5;
+  const ::std::string& alias() const;
+  void set_alias(const ::std::string& value);
+  #if LANG_CXX11
+  void set_alias(::std::string&& value);
+  #endif
+  void set_alias(const char* value);
+  void set_alias(const char* value, size_t size);
+  ::std::string* mutable_alias();
+  ::std::string* release_alias();
+  void set_allocated_alias(::std::string* alias);
+
+  // string asset_id = 6;
+  void clear_asset_id();
+  static const int kAssetIdFieldNumber = 6;
+  const ::std::string& asset_id() const;
+  void set_asset_id(const ::std::string& value);
+  #if LANG_CXX11
+  void set_asset_id(::std::string&& value);
+  #endif
+  void set_asset_id(const char* value);
+  void set_asset_id(const char* value, size_t size);
+  ::std::string* mutable_asset_id();
+  ::std::string* release_asset_id();
+  void set_allocated_asset_id(::std::string* asset_id);
+
+  // .dmi.Component parent = 3;
+  bool has_parent() const;
+  void clear_parent();
+  static const int kParentFieldNumber = 3;
+  const ::dmi::Component& parent() const;
+  ::dmi::Component* release_parent();
+  ::dmi::Component* mutable_parent();
+  void set_allocated_parent(::dmi::Component* parent);
+
+  // .dmi.Uri uri = 7;
+  bool has_uri() const;
+  void clear_uri();
+  static const int kUriFieldNumber = 7;
+  const ::dmi::Uri& uri() const;
+  ::dmi::Uri* release_uri();
+  ::dmi::Uri* mutable_uri();
+  void set_allocated_uri(::dmi::Uri* uri);
+
+  // .dmi.ComponentType class = 2;
+  void clear_class_();
+  static const int kClassFieldNumber = 2;
+  ::dmi::ComponentType class_() const;
+  void set_class_(::dmi::ComponentType value);
+
+  // int32 parent_rel_pos = 4;
+  void clear_parent_rel_pos();
+  static const int kParentRelPosFieldNumber = 4;
+  ::google::protobuf::int32 parent_rel_pos() const;
+  void set_parent_rel_pos(::google::protobuf::int32 value);
+
+  // .dmi.ComponentAdminState admin_state = 8;
+  void clear_admin_state();
+  static const int kAdminStateFieldNumber = 8;
+  ::dmi::ComponentAdminState admin_state() const;
+  void set_admin_state(::dmi::ComponentAdminState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ModifiableComponent)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  ::google::protobuf::internal::ArenaStringPtr alias_;
+  ::google::protobuf::internal::ArenaStringPtr asset_id_;
+  ::dmi::Component* parent_;
+  ::dmi::Uri* uri_;
+  int class__;
+  ::google::protobuf::int32 parent_rel_pos_;
+  int admin_state_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif  // __GNUC__
+// Uuid
+
+// string uuid = 1;
+inline void Uuid::clear_uuid() {
+  uuid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Uuid::uuid() const {
+  // @@protoc_insertion_point(field_get:dmi.Uuid.uuid)
+  return uuid_.GetNoArena();
+}
+inline void Uuid::set_uuid(const ::std::string& value) {
+  
+  uuid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Uuid.uuid)
+}
+#if LANG_CXX11
+inline void Uuid::set_uuid(::std::string&& value) {
+  
+  uuid_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Uuid.uuid)
+}
+#endif
+inline void Uuid::set_uuid(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  uuid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Uuid.uuid)
+}
+inline void Uuid::set_uuid(const char* value, size_t size) {
+  
+  uuid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Uuid.uuid)
+}
+inline ::std::string* Uuid::mutable_uuid() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Uuid.uuid)
+  return uuid_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Uuid::release_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.Uuid.uuid)
+  
+  return uuid_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Uuid::set_allocated_uuid(::std::string* uuid) {
+  if (uuid != nullptr) {
+    
+  } else {
+    
+  }
+  uuid_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), uuid);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Uuid.uuid)
+}
+
+// -------------------------------------------------------------------
+
+// HardwareID
+
+// .dmi.Uuid uuid = 1;
+inline bool HardwareID::has_uuid() const {
+  return this != internal_default_instance() && uuid_ != nullptr;
+}
+inline void HardwareID::clear_uuid() {
+  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
+    delete uuid_;
+  }
+  uuid_ = nullptr;
+}
+inline const ::dmi::Uuid& HardwareID::uuid() const {
+  const ::dmi::Uuid* p = uuid_;
+  // @@protoc_insertion_point(field_get:dmi.HardwareID.uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* HardwareID::release_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.HardwareID.uuid)
+  
+  ::dmi::Uuid* temp = uuid_;
+  uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* HardwareID::mutable_uuid() {
+  
+  if (uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.HardwareID.uuid)
+  return uuid_;
+}
+inline void HardwareID::set_allocated_uuid(::dmi::Uuid* uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete uuid_;
+  }
+  if (uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  uuid_ = uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.HardwareID.uuid)
+}
+
+// -------------------------------------------------------------------
+
+// Uri
+
+// string uri = 1;
+inline void Uri::clear_uri() {
+  uri_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Uri::uri() const {
+  // @@protoc_insertion_point(field_get:dmi.Uri.uri)
+  return uri_.GetNoArena();
+}
+inline void Uri::set_uri(const ::std::string& value) {
+  
+  uri_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Uri.uri)
+}
+#if LANG_CXX11
+inline void Uri::set_uri(::std::string&& value) {
+  
+  uri_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Uri.uri)
+}
+#endif
+inline void Uri::set_uri(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  uri_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Uri.uri)
+}
+inline void Uri::set_uri(const char* value, size_t size) {
+  
+  uri_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Uri.uri)
+}
+inline ::std::string* Uri::mutable_uri() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Uri.uri)
+  return uri_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Uri::release_uri() {
+  // @@protoc_insertion_point(field_release:dmi.Uri.uri)
+  
+  return uri_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Uri::set_allocated_uri(::std::string* uri) {
+  if (uri != nullptr) {
+    
+  } else {
+    
+  }
+  uri_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), uri);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Uri.uri)
+}
+
+// -------------------------------------------------------------------
+
+// ComponentState
+
+// .google.protobuf.Timestamp state_last_changed = 1;
+inline bool ComponentState::has_state_last_changed() const {
+  return this != internal_default_instance() && state_last_changed_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& ComponentState::state_last_changed() const {
+  const ::google::protobuf::Timestamp* p = state_last_changed_;
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.state_last_changed)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* ComponentState::release_state_last_changed() {
+  // @@protoc_insertion_point(field_release:dmi.ComponentState.state_last_changed)
+  
+  ::google::protobuf::Timestamp* temp = state_last_changed_;
+  state_last_changed_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* ComponentState::mutable_state_last_changed() {
+  
+  if (state_last_changed_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    state_last_changed_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ComponentState.state_last_changed)
+  return state_last_changed_;
+}
+inline void ComponentState::set_allocated_state_last_changed(::google::protobuf::Timestamp* state_last_changed) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(state_last_changed_);
+  }
+  if (state_last_changed) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(state_last_changed)->GetArena();
+    if (message_arena != submessage_arena) {
+      state_last_changed = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, state_last_changed, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  state_last_changed_ = state_last_changed;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentState.state_last_changed)
+}
+
+// .dmi.ComponentAdminState admin_state = 2;
+inline void ComponentState::clear_admin_state() {
+  admin_state_ = 0;
+}
+inline ::dmi::ComponentAdminState ComponentState::admin_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.admin_state)
+  return static_cast< ::dmi::ComponentAdminState >(admin_state_);
+}
+inline void ComponentState::set_admin_state(::dmi::ComponentAdminState value) {
+  
+  admin_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.admin_state)
+}
+
+// .dmi.ComponentOperState oper_state = 3;
+inline void ComponentState::clear_oper_state() {
+  oper_state_ = 0;
+}
+inline ::dmi::ComponentOperState ComponentState::oper_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.oper_state)
+  return static_cast< ::dmi::ComponentOperState >(oper_state_);
+}
+inline void ComponentState::set_oper_state(::dmi::ComponentOperState value) {
+  
+  oper_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.oper_state)
+}
+
+// .dmi.ComponentUsageState usage_state = 4;
+inline void ComponentState::clear_usage_state() {
+  usage_state_ = 0;
+}
+inline ::dmi::ComponentUsageState ComponentState::usage_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.usage_state)
+  return static_cast< ::dmi::ComponentUsageState >(usage_state_);
+}
+inline void ComponentState::set_usage_state(::dmi::ComponentUsageState value) {
+  
+  usage_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.usage_state)
+}
+
+// .dmi.ComponentAlarmState alarm_state = 5;
+inline void ComponentState::clear_alarm_state() {
+  alarm_state_ = 0;
+}
+inline ::dmi::ComponentAlarmState ComponentState::alarm_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.alarm_state)
+  return static_cast< ::dmi::ComponentAlarmState >(alarm_state_);
+}
+inline void ComponentState::set_alarm_state(::dmi::ComponentAlarmState value) {
+  
+  alarm_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.alarm_state)
+}
+
+// .dmi.ComponentStandbyState standby_state = 6;
+inline void ComponentState::clear_standby_state() {
+  standby_state_ = 0;
+}
+inline ::dmi::ComponentStandbyState ComponentState::standby_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.standby_state)
+  return static_cast< ::dmi::ComponentStandbyState >(standby_state_);
+}
+inline void ComponentState::set_standby_state(::dmi::ComponentStandbyState value) {
+  
+  standby_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.standby_state)
+}
+
+// -------------------------------------------------------------------
+
+// ComponentSensorData
+
+// int32 value = 1;
+inline void ComponentSensorData::clear_value() {
+  value_ = 0;
+}
+inline ::google::protobuf::int32 ComponentSensorData::value() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.value)
+  return value_;
+}
+inline void ComponentSensorData::set_value(::google::protobuf::int32 value) {
+  
+  value_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.value)
+}
+
+// .dmi.DataValueType type = 2;
+inline void ComponentSensorData::clear_type() {
+  type_ = 0;
+}
+inline ::dmi::DataValueType ComponentSensorData::type() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.type)
+  return static_cast< ::dmi::DataValueType >(type_);
+}
+inline void ComponentSensorData::set_type(::dmi::DataValueType value) {
+  
+  type_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.type)
+}
+
+// .dmi.ValueScale scale = 3;
+inline void ComponentSensorData::clear_scale() {
+  scale_ = 0;
+}
+inline ::dmi::ValueScale ComponentSensorData::scale() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.scale)
+  return static_cast< ::dmi::ValueScale >(scale_);
+}
+inline void ComponentSensorData::set_scale(::dmi::ValueScale value) {
+  
+  scale_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.scale)
+}
+
+// int32 precision = 4;
+inline void ComponentSensorData::clear_precision() {
+  precision_ = 0;
+}
+inline ::google::protobuf::int32 ComponentSensorData::precision() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.precision)
+  return precision_;
+}
+inline void ComponentSensorData::set_precision(::google::protobuf::int32 value) {
+  
+  precision_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.precision)
+}
+
+// .dmi.SensorStatus status = 5;
+inline void ComponentSensorData::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::SensorStatus ComponentSensorData::status() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.status)
+  return static_cast< ::dmi::SensorStatus >(status_);
+}
+inline void ComponentSensorData::set_status(::dmi::SensorStatus value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.status)
+}
+
+// string units_display = 6;
+inline void ComponentSensorData::clear_units_display() {
+  units_display_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ComponentSensorData::units_display() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.units_display)
+  return units_display_.GetNoArena();
+}
+inline void ComponentSensorData::set_units_display(const ::std::string& value) {
+  
+  units_display_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.units_display)
+}
+#if LANG_CXX11
+inline void ComponentSensorData::set_units_display(::std::string&& value) {
+  
+  units_display_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ComponentSensorData.units_display)
+}
+#endif
+inline void ComponentSensorData::set_units_display(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  units_display_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ComponentSensorData.units_display)
+}
+inline void ComponentSensorData::set_units_display(const char* value, size_t size) {
+  
+  units_display_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ComponentSensorData.units_display)
+}
+inline ::std::string* ComponentSensorData::mutable_units_display() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ComponentSensorData.units_display)
+  return units_display_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ComponentSensorData::release_units_display() {
+  // @@protoc_insertion_point(field_release:dmi.ComponentSensorData.units_display)
+  
+  return units_display_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ComponentSensorData::set_allocated_units_display(::std::string* units_display) {
+  if (units_display != nullptr) {
+    
+  } else {
+    
+  }
+  units_display_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), units_display);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentSensorData.units_display)
+}
+
+// .google.protobuf.Timestamp timestamp = 7;
+inline bool ComponentSensorData::has_timestamp() const {
+  return this != internal_default_instance() && timestamp_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& ComponentSensorData::timestamp() const {
+  const ::google::protobuf::Timestamp* p = timestamp_;
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.timestamp)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* ComponentSensorData::release_timestamp() {
+  // @@protoc_insertion_point(field_release:dmi.ComponentSensorData.timestamp)
+  
+  ::google::protobuf::Timestamp* temp = timestamp_;
+  timestamp_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* ComponentSensorData::mutable_timestamp() {
+  
+  if (timestamp_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    timestamp_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ComponentSensorData.timestamp)
+  return timestamp_;
+}
+inline void ComponentSensorData::set_allocated_timestamp(::google::protobuf::Timestamp* timestamp) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(timestamp_);
+  }
+  if (timestamp) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(timestamp)->GetArena();
+    if (message_arena != submessage_arena) {
+      timestamp = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, timestamp, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  timestamp_ = timestamp;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentSensorData.timestamp)
+}
+
+// uint32 value_update_rate = 8;
+inline void ComponentSensorData::clear_value_update_rate() {
+  value_update_rate_ = 0u;
+}
+inline ::google::protobuf::uint32 ComponentSensorData::value_update_rate() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.value_update_rate)
+  return value_update_rate_;
+}
+inline void ComponentSensorData::set_value_update_rate(::google::protobuf::uint32 value) {
+  
+  value_update_rate_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.value_update_rate)
+}
+
+// string data_type = 9;
+inline void ComponentSensorData::clear_data_type() {
+  data_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ComponentSensorData::data_type() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.data_type)
+  return data_type_.GetNoArena();
+}
+inline void ComponentSensorData::set_data_type(const ::std::string& value) {
+  
+  data_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.data_type)
+}
+#if LANG_CXX11
+inline void ComponentSensorData::set_data_type(::std::string&& value) {
+  
+  data_type_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ComponentSensorData.data_type)
+}
+#endif
+inline void ComponentSensorData::set_data_type(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  data_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ComponentSensorData.data_type)
+}
+inline void ComponentSensorData::set_data_type(const char* value, size_t size) {
+  
+  data_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ComponentSensorData.data_type)
+}
+inline ::std::string* ComponentSensorData::mutable_data_type() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ComponentSensorData.data_type)
+  return data_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ComponentSensorData::release_data_type() {
+  // @@protoc_insertion_point(field_release:dmi.ComponentSensorData.data_type)
+  
+  return data_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ComponentSensorData::set_allocated_data_type(::std::string* data_type) {
+  if (data_type != nullptr) {
+    
+  } else {
+    
+  }
+  data_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), data_type);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentSensorData.data_type)
+}
+
+// -------------------------------------------------------------------
+
+// PortComponentAttributes
+
+// .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+inline void PortComponentAttributes::clear_connector_type() {
+  connector_type_ = 0;
+}
+inline ::dmi::PortComponentAttributes_ConnectorType PortComponentAttributes::connector_type() const {
+  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.connector_type)
+  return static_cast< ::dmi::PortComponentAttributes_ConnectorType >(connector_type_);
+}
+inline void PortComponentAttributes::set_connector_type(::dmi::PortComponentAttributes_ConnectorType value) {
+  
+  connector_type_ = value;
+  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.connector_type)
+}
+
+// .dmi.PortComponentAttributes.Speed speed = 2;
+inline void PortComponentAttributes::clear_speed() {
+  speed_ = 0;
+}
+inline ::dmi::PortComponentAttributes_Speed PortComponentAttributes::speed() const {
+  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.speed)
+  return static_cast< ::dmi::PortComponentAttributes_Speed >(speed_);
+}
+inline void PortComponentAttributes::set_speed(::dmi::PortComponentAttributes_Speed value) {
+  
+  speed_ = value;
+  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.speed)
+}
+
+// .dmi.PortComponentAttributes.Protocol protocol = 3;
+inline void PortComponentAttributes::clear_protocol() {
+  protocol_ = 0;
+}
+inline ::dmi::PortComponentAttributes_Protocol PortComponentAttributes::protocol() const {
+  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.protocol)
+  return static_cast< ::dmi::PortComponentAttributes_Protocol >(protocol_);
+}
+inline void PortComponentAttributes::set_protocol(::dmi::PortComponentAttributes_Protocol value) {
+  
+  protocol_ = value;
+  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.protocol)
+}
+
+// string physical_label = 4;
+inline void PortComponentAttributes::clear_physical_label() {
+  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& PortComponentAttributes::physical_label() const {
+  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.physical_label)
+  return physical_label_.GetNoArena();
+}
+inline void PortComponentAttributes::set_physical_label(const ::std::string& value) {
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.physical_label)
+}
+#if LANG_CXX11
+inline void PortComponentAttributes::set_physical_label(::std::string&& value) {
+  
+  physical_label_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.PortComponentAttributes.physical_label)
+}
+#endif
+inline void PortComponentAttributes::set_physical_label(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.PortComponentAttributes.physical_label)
+}
+inline void PortComponentAttributes::set_physical_label(const char* value, size_t size) {
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.PortComponentAttributes.physical_label)
+}
+inline ::std::string* PortComponentAttributes::mutable_physical_label() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.PortComponentAttributes.physical_label)
+  return physical_label_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* PortComponentAttributes::release_physical_label() {
+  // @@protoc_insertion_point(field_release:dmi.PortComponentAttributes.physical_label)
+  
+  return physical_label_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void PortComponentAttributes::set_allocated_physical_label(::std::string* physical_label) {
+  if (physical_label != nullptr) {
+    
+  } else {
+    
+  }
+  physical_label_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), physical_label);
+  // @@protoc_insertion_point(field_set_allocated:dmi.PortComponentAttributes.physical_label)
+}
+
+// -------------------------------------------------------------------
+
+// ContainerComponentAttributes
+
+// string physical_label = 1;
+inline void ContainerComponentAttributes::clear_physical_label() {
+  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ContainerComponentAttributes::physical_label() const {
+  // @@protoc_insertion_point(field_get:dmi.ContainerComponentAttributes.physical_label)
+  return physical_label_.GetNoArena();
+}
+inline void ContainerComponentAttributes::set_physical_label(const ::std::string& value) {
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ContainerComponentAttributes.physical_label)
+}
+#if LANG_CXX11
+inline void ContainerComponentAttributes::set_physical_label(::std::string&& value) {
+  
+  physical_label_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ContainerComponentAttributes.physical_label)
+}
+#endif
+inline void ContainerComponentAttributes::set_physical_label(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ContainerComponentAttributes.physical_label)
+}
+inline void ContainerComponentAttributes::set_physical_label(const char* value, size_t size) {
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ContainerComponentAttributes.physical_label)
+}
+inline ::std::string* ContainerComponentAttributes::mutable_physical_label() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ContainerComponentAttributes.physical_label)
+  return physical_label_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ContainerComponentAttributes::release_physical_label() {
+  // @@protoc_insertion_point(field_release:dmi.ContainerComponentAttributes.physical_label)
+  
+  return physical_label_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ContainerComponentAttributes::set_allocated_physical_label(::std::string* physical_label) {
+  if (physical_label != nullptr) {
+    
+  } else {
+    
+  }
+  physical_label_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), physical_label);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ContainerComponentAttributes.physical_label)
+}
+
+// -------------------------------------------------------------------
+
+// PsuComponentAttributes
+
+// .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+inline void PsuComponentAttributes::clear_supported_voltage() {
+  supported_voltage_ = 0;
+}
+inline ::dmi::PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::supported_voltage() const {
+  // @@protoc_insertion_point(field_get:dmi.PsuComponentAttributes.supported_voltage)
+  return static_cast< ::dmi::PsuComponentAttributes_SupportedVoltage >(supported_voltage_);
+}
+inline void PsuComponentAttributes::set_supported_voltage(::dmi::PsuComponentAttributes_SupportedVoltage value) {
+  
+  supported_voltage_ = value;
+  // @@protoc_insertion_point(field_set:dmi.PsuComponentAttributes.supported_voltage)
+}
+
+// -------------------------------------------------------------------
+
+// TransceiverComponentsAttributes
+
+// .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+inline void TransceiverComponentsAttributes::clear_form_factor() {
+  form_factor_ = 0;
+}
+inline ::dmi::TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::form_factor() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.form_factor)
+  return static_cast< ::dmi::TransceiverComponentsAttributes_FormFactor >(form_factor_);
+}
+inline void TransceiverComponentsAttributes::set_form_factor(::dmi::TransceiverComponentsAttributes_FormFactor value) {
+  
+  form_factor_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.form_factor)
+}
+
+// .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+inline void TransceiverComponentsAttributes::clear_trans_type() {
+  trans_type_ = 0;
+}
+inline ::dmi::TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::trans_type() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.trans_type)
+  return static_cast< ::dmi::TransceiverComponentsAttributes_Type >(trans_type_);
+}
+inline void TransceiverComponentsAttributes::set_trans_type(::dmi::TransceiverComponentsAttributes_Type value) {
+  
+  trans_type_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.trans_type)
+}
+
+// uint32 max_distance = 3;
+inline void TransceiverComponentsAttributes::clear_max_distance() {
+  max_distance_ = 0u;
+}
+inline ::google::protobuf::uint32 TransceiverComponentsAttributes::max_distance() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.max_distance)
+  return max_distance_;
+}
+inline void TransceiverComponentsAttributes::set_max_distance(::google::protobuf::uint32 value) {
+  
+  max_distance_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.max_distance)
+}
+
+// .dmi.ValueScale max_distance_scale = 4;
+inline void TransceiverComponentsAttributes::clear_max_distance_scale() {
+  max_distance_scale_ = 0;
+}
+inline ::dmi::ValueScale TransceiverComponentsAttributes::max_distance_scale() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.max_distance_scale)
+  return static_cast< ::dmi::ValueScale >(max_distance_scale_);
+}
+inline void TransceiverComponentsAttributes::set_max_distance_scale(::dmi::ValueScale value) {
+  
+  max_distance_scale_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.max_distance_scale)
+}
+
+// repeated uint32 rx_wavelength = 5;
+inline int TransceiverComponentsAttributes::rx_wavelength_size() const {
+  return rx_wavelength_.size();
+}
+inline void TransceiverComponentsAttributes::clear_rx_wavelength() {
+  rx_wavelength_.Clear();
+}
+inline ::google::protobuf::uint32 TransceiverComponentsAttributes::rx_wavelength(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.rx_wavelength)
+  return rx_wavelength_.Get(index);
+}
+inline void TransceiverComponentsAttributes::set_rx_wavelength(int index, ::google::protobuf::uint32 value) {
+  rx_wavelength_.Set(index, value);
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.rx_wavelength)
+}
+inline void TransceiverComponentsAttributes::add_rx_wavelength(::google::protobuf::uint32 value) {
+  rx_wavelength_.Add(value);
+  // @@protoc_insertion_point(field_add:dmi.TransceiverComponentsAttributes.rx_wavelength)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+TransceiverComponentsAttributes::rx_wavelength() const {
+  // @@protoc_insertion_point(field_list:dmi.TransceiverComponentsAttributes.rx_wavelength)
+  return rx_wavelength_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+TransceiverComponentsAttributes::mutable_rx_wavelength() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.TransceiverComponentsAttributes.rx_wavelength)
+  return &rx_wavelength_;
+}
+
+// repeated uint32 tx_wavelength = 6;
+inline int TransceiverComponentsAttributes::tx_wavelength_size() const {
+  return tx_wavelength_.size();
+}
+inline void TransceiverComponentsAttributes::clear_tx_wavelength() {
+  tx_wavelength_.Clear();
+}
+inline ::google::protobuf::uint32 TransceiverComponentsAttributes::tx_wavelength(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.tx_wavelength)
+  return tx_wavelength_.Get(index);
+}
+inline void TransceiverComponentsAttributes::set_tx_wavelength(int index, ::google::protobuf::uint32 value) {
+  tx_wavelength_.Set(index, value);
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.tx_wavelength)
+}
+inline void TransceiverComponentsAttributes::add_tx_wavelength(::google::protobuf::uint32 value) {
+  tx_wavelength_.Add(value);
+  // @@protoc_insertion_point(field_add:dmi.TransceiverComponentsAttributes.tx_wavelength)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+TransceiverComponentsAttributes::tx_wavelength() const {
+  // @@protoc_insertion_point(field_list:dmi.TransceiverComponentsAttributes.tx_wavelength)
+  return tx_wavelength_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+TransceiverComponentsAttributes::mutable_tx_wavelength() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.TransceiverComponentsAttributes.tx_wavelength)
+  return &tx_wavelength_;
+}
+
+// .dmi.ValueScale wavelength_scale = 7;
+inline void TransceiverComponentsAttributes::clear_wavelength_scale() {
+  wavelength_scale_ = 0;
+}
+inline ::dmi::ValueScale TransceiverComponentsAttributes::wavelength_scale() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.wavelength_scale)
+  return static_cast< ::dmi::ValueScale >(wavelength_scale_);
+}
+inline void TransceiverComponentsAttributes::set_wavelength_scale(::dmi::ValueScale value) {
+  
+  wavelength_scale_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.wavelength_scale)
+}
+
+// -------------------------------------------------------------------
+
+// Component
+
+// string name = 1;
+inline void Component::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::name() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.name)
+  return name_.GetNoArena();
+}
+inline void Component::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.name)
+}
+#if LANG_CXX11
+inline void Component::set_name(::std::string&& value) {
+  
+  name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.name)
+}
+#endif
+inline void Component::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.Component.name)
+}
+inline void Component::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.Component.name)
+}
+inline ::std::string* Component::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_name() {
+  // @@protoc_insertion_point(field_release:dmi.Component.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_name(::std::string* name) {
+  if (name != nullptr) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.name)
+}
+
+// .dmi.ComponentType class = 2;
+inline void Component::clear_class_() {
+  class__ = 0;
+}
+inline ::dmi::ComponentType Component::class_() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.class)
+  return static_cast< ::dmi::ComponentType >(class__);
+}
+inline void Component::set_class_(::dmi::ComponentType value) {
+  
+  class__ = value;
+  // @@protoc_insertion_point(field_set:dmi.Component.class)
+}
+
+// string description = 3;
+inline void Component::clear_description() {
+  description_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::description() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.description)
+  return description_.GetNoArena();
+}
+inline void Component::set_description(const ::std::string& value) {
+  
+  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.description)
+}
+#if LANG_CXX11
+inline void Component::set_description(::std::string&& value) {
+  
+  description_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.description)
+}
+#endif
+inline void Component::set_description(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.description)
+}
+inline void Component::set_description(const char* value, size_t size) {
+  
+  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.description)
+}
+inline ::std::string* Component::mutable_description() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.description)
+  return description_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_description() {
+  // @@protoc_insertion_point(field_release:dmi.Component.description)
+  
+  return description_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_description(::std::string* description) {
+  if (description != nullptr) {
+    
+  } else {
+    
+  }
+  description_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), description);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.description)
+}
+
+// string parent = 4;
+inline void Component::clear_parent() {
+  parent_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::parent() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.parent)
+  return parent_.GetNoArena();
+}
+inline void Component::set_parent(const ::std::string& value) {
+  
+  parent_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.parent)
+}
+#if LANG_CXX11
+inline void Component::set_parent(::std::string&& value) {
+  
+  parent_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.parent)
+}
+#endif
+inline void Component::set_parent(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  parent_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.parent)
+}
+inline void Component::set_parent(const char* value, size_t size) {
+  
+  parent_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.parent)
+}
+inline ::std::string* Component::mutable_parent() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.parent)
+  return parent_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_parent() {
+  // @@protoc_insertion_point(field_release:dmi.Component.parent)
+  
+  return parent_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_parent(::std::string* parent) {
+  if (parent != nullptr) {
+    
+  } else {
+    
+  }
+  parent_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), parent);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.parent)
+}
+
+// int32 parent_rel_pos = 5;
+inline void Component::clear_parent_rel_pos() {
+  parent_rel_pos_ = 0;
+}
+inline ::google::protobuf::int32 Component::parent_rel_pos() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.parent_rel_pos)
+  return parent_rel_pos_;
+}
+inline void Component::set_parent_rel_pos(::google::protobuf::int32 value) {
+  
+  parent_rel_pos_ = value;
+  // @@protoc_insertion_point(field_set:dmi.Component.parent_rel_pos)
+}
+
+// repeated .dmi.Component children = 6;
+inline int Component::children_size() const {
+  return children_.size();
+}
+inline void Component::clear_children() {
+  children_.Clear();
+}
+inline ::dmi::Component* Component::mutable_children(int index) {
+  // @@protoc_insertion_point(field_mutable:dmi.Component.children)
+  return children_.Mutable(index);
+}
+inline ::google::protobuf::RepeatedPtrField< ::dmi::Component >*
+Component::mutable_children() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.Component.children)
+  return &children_;
+}
+inline const ::dmi::Component& Component::children(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.Component.children)
+  return children_.Get(index);
+}
+inline ::dmi::Component* Component::add_children() {
+  // @@protoc_insertion_point(field_add:dmi.Component.children)
+  return children_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::dmi::Component >&
+Component::children() const {
+  // @@protoc_insertion_point(field_list:dmi.Component.children)
+  return children_;
+}
+
+// string hardware_rev = 7;
+inline void Component::clear_hardware_rev() {
+  hardware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::hardware_rev() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.hardware_rev)
+  return hardware_rev_.GetNoArena();
+}
+inline void Component::set_hardware_rev(const ::std::string& value) {
+  
+  hardware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.hardware_rev)
+}
+#if LANG_CXX11
+inline void Component::set_hardware_rev(::std::string&& value) {
+  
+  hardware_rev_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.hardware_rev)
+}
+#endif
+inline void Component::set_hardware_rev(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  hardware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.hardware_rev)
+}
+inline void Component::set_hardware_rev(const char* value, size_t size) {
+  
+  hardware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.hardware_rev)
+}
+inline ::std::string* Component::mutable_hardware_rev() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.hardware_rev)
+  return hardware_rev_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_hardware_rev() {
+  // @@protoc_insertion_point(field_release:dmi.Component.hardware_rev)
+  
+  return hardware_rev_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_hardware_rev(::std::string* hardware_rev) {
+  if (hardware_rev != nullptr) {
+    
+  } else {
+    
+  }
+  hardware_rev_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), hardware_rev);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.hardware_rev)
+}
+
+// string firmware_rev = 8;
+inline void Component::clear_firmware_rev() {
+  firmware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::firmware_rev() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.firmware_rev)
+  return firmware_rev_.GetNoArena();
+}
+inline void Component::set_firmware_rev(const ::std::string& value) {
+  
+  firmware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.firmware_rev)
+}
+#if LANG_CXX11
+inline void Component::set_firmware_rev(::std::string&& value) {
+  
+  firmware_rev_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.firmware_rev)
+}
+#endif
+inline void Component::set_firmware_rev(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  firmware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.firmware_rev)
+}
+inline void Component::set_firmware_rev(const char* value, size_t size) {
+  
+  firmware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.firmware_rev)
+}
+inline ::std::string* Component::mutable_firmware_rev() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.firmware_rev)
+  return firmware_rev_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_firmware_rev() {
+  // @@protoc_insertion_point(field_release:dmi.Component.firmware_rev)
+  
+  return firmware_rev_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_firmware_rev(::std::string* firmware_rev) {
+  if (firmware_rev != nullptr) {
+    
+  } else {
+    
+  }
+  firmware_rev_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), firmware_rev);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.firmware_rev)
+}
+
+// string software_rev = 9;
+inline void Component::clear_software_rev() {
+  software_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::software_rev() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.software_rev)
+  return software_rev_.GetNoArena();
+}
+inline void Component::set_software_rev(const ::std::string& value) {
+  
+  software_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.software_rev)
+}
+#if LANG_CXX11
+inline void Component::set_software_rev(::std::string&& value) {
+  
+  software_rev_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.software_rev)
+}
+#endif
+inline void Component::set_software_rev(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  software_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.software_rev)
+}
+inline void Component::set_software_rev(const char* value, size_t size) {
+  
+  software_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.software_rev)
+}
+inline ::std::string* Component::mutable_software_rev() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.software_rev)
+  return software_rev_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_software_rev() {
+  // @@protoc_insertion_point(field_release:dmi.Component.software_rev)
+  
+  return software_rev_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_software_rev(::std::string* software_rev) {
+  if (software_rev != nullptr) {
+    
+  } else {
+    
+  }
+  software_rev_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), software_rev);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.software_rev)
+}
+
+// string serial_num = 10;
+inline void Component::clear_serial_num() {
+  serial_num_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::serial_num() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.serial_num)
+  return serial_num_.GetNoArena();
+}
+inline void Component::set_serial_num(const ::std::string& value) {
+  
+  serial_num_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.serial_num)
+}
+#if LANG_CXX11
+inline void Component::set_serial_num(::std::string&& value) {
+  
+  serial_num_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.serial_num)
+}
+#endif
+inline void Component::set_serial_num(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  serial_num_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.serial_num)
+}
+inline void Component::set_serial_num(const char* value, size_t size) {
+  
+  serial_num_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.serial_num)
+}
+inline ::std::string* Component::mutable_serial_num() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.serial_num)
+  return serial_num_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_serial_num() {
+  // @@protoc_insertion_point(field_release:dmi.Component.serial_num)
+  
+  return serial_num_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_serial_num(::std::string* serial_num) {
+  if (serial_num != nullptr) {
+    
+  } else {
+    
+  }
+  serial_num_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), serial_num);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.serial_num)
+}
+
+// string mfg_name = 11;
+inline void Component::clear_mfg_name() {
+  mfg_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::mfg_name() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.mfg_name)
+  return mfg_name_.GetNoArena();
+}
+inline void Component::set_mfg_name(const ::std::string& value) {
+  
+  mfg_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.mfg_name)
+}
+#if LANG_CXX11
+inline void Component::set_mfg_name(::std::string&& value) {
+  
+  mfg_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.mfg_name)
+}
+#endif
+inline void Component::set_mfg_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  mfg_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.mfg_name)
+}
+inline void Component::set_mfg_name(const char* value, size_t size) {
+  
+  mfg_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.mfg_name)
+}
+inline ::std::string* Component::mutable_mfg_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.mfg_name)
+  return mfg_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_mfg_name() {
+  // @@protoc_insertion_point(field_release:dmi.Component.mfg_name)
+  
+  return mfg_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_mfg_name(::std::string* mfg_name) {
+  if (mfg_name != nullptr) {
+    
+  } else {
+    
+  }
+  mfg_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), mfg_name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.mfg_name)
+}
+
+// string model_name = 12;
+inline void Component::clear_model_name() {
+  model_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::model_name() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.model_name)
+  return model_name_.GetNoArena();
+}
+inline void Component::set_model_name(const ::std::string& value) {
+  
+  model_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.model_name)
+}
+#if LANG_CXX11
+inline void Component::set_model_name(::std::string&& value) {
+  
+  model_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.model_name)
+}
+#endif
+inline void Component::set_model_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  model_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.model_name)
+}
+inline void Component::set_model_name(const char* value, size_t size) {
+  
+  model_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.model_name)
+}
+inline ::std::string* Component::mutable_model_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.model_name)
+  return model_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_model_name() {
+  // @@protoc_insertion_point(field_release:dmi.Component.model_name)
+  
+  return model_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_model_name(::std::string* model_name) {
+  if (model_name != nullptr) {
+    
+  } else {
+    
+  }
+  model_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), model_name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.model_name)
+}
+
+// string alias = 13;
+inline void Component::clear_alias() {
+  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::alias() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.alias)
+  return alias_.GetNoArena();
+}
+inline void Component::set_alias(const ::std::string& value) {
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.alias)
+}
+#if LANG_CXX11
+inline void Component::set_alias(::std::string&& value) {
+  
+  alias_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.alias)
+}
+#endif
+inline void Component::set_alias(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.alias)
+}
+inline void Component::set_alias(const char* value, size_t size) {
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.alias)
+}
+inline ::std::string* Component::mutable_alias() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.alias)
+  return alias_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_alias() {
+  // @@protoc_insertion_point(field_release:dmi.Component.alias)
+  
+  return alias_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_alias(::std::string* alias) {
+  if (alias != nullptr) {
+    
+  } else {
+    
+  }
+  alias_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), alias);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.alias)
+}
+
+// string asset_id = 14;
+inline void Component::clear_asset_id() {
+  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::asset_id() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.asset_id)
+  return asset_id_.GetNoArena();
+}
+inline void Component::set_asset_id(const ::std::string& value) {
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.asset_id)
+}
+#if LANG_CXX11
+inline void Component::set_asset_id(::std::string&& value) {
+  
+  asset_id_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.asset_id)
+}
+#endif
+inline void Component::set_asset_id(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.asset_id)
+}
+inline void Component::set_asset_id(const char* value, size_t size) {
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.asset_id)
+}
+inline ::std::string* Component::mutable_asset_id() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.asset_id)
+  return asset_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_asset_id() {
+  // @@protoc_insertion_point(field_release:dmi.Component.asset_id)
+  
+  return asset_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_asset_id(::std::string* asset_id) {
+  if (asset_id != nullptr) {
+    
+  } else {
+    
+  }
+  asset_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), asset_id);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.asset_id)
+}
+
+// bool is_fru = 15;
+inline void Component::clear_is_fru() {
+  is_fru_ = false;
+}
+inline bool Component::is_fru() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.is_fru)
+  return is_fru_;
+}
+inline void Component::set_is_fru(bool value) {
+  
+  is_fru_ = value;
+  // @@protoc_insertion_point(field_set:dmi.Component.is_fru)
+}
+
+// .google.protobuf.Timestamp mfg_date = 16;
+inline bool Component::has_mfg_date() const {
+  return this != internal_default_instance() && mfg_date_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& Component::mfg_date() const {
+  const ::google::protobuf::Timestamp* p = mfg_date_;
+  // @@protoc_insertion_point(field_get:dmi.Component.mfg_date)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* Component::release_mfg_date() {
+  // @@protoc_insertion_point(field_release:dmi.Component.mfg_date)
+  
+  ::google::protobuf::Timestamp* temp = mfg_date_;
+  mfg_date_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* Component::mutable_mfg_date() {
+  
+  if (mfg_date_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    mfg_date_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.mfg_date)
+  return mfg_date_;
+}
+inline void Component::set_allocated_mfg_date(::google::protobuf::Timestamp* mfg_date) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(mfg_date_);
+  }
+  if (mfg_date) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(mfg_date)->GetArena();
+    if (message_arena != submessage_arena) {
+      mfg_date = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, mfg_date, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  mfg_date_ = mfg_date;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.mfg_date)
+}
+
+// .dmi.Uri uri = 17;
+inline bool Component::has_uri() const {
+  return this != internal_default_instance() && uri_ != nullptr;
+}
+inline void Component::clear_uri() {
+  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
+    delete uri_;
+  }
+  uri_ = nullptr;
+}
+inline const ::dmi::Uri& Component::uri() const {
+  const ::dmi::Uri* p = uri_;
+  // @@protoc_insertion_point(field_get:dmi.Component.uri)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uri*>(
+      &::dmi::_Uri_default_instance_);
+}
+inline ::dmi::Uri* Component::release_uri() {
+  // @@protoc_insertion_point(field_release:dmi.Component.uri)
+  
+  ::dmi::Uri* temp = uri_;
+  uri_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uri* Component::mutable_uri() {
+  
+  if (uri_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uri>(GetArenaNoVirtual());
+    uri_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.uri)
+  return uri_;
+}
+inline void Component::set_allocated_uri(::dmi::Uri* uri) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete uri_;
+  }
+  if (uri) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      uri = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, uri, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  uri_ = uri;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.uri)
+}
+
+// .dmi.Uuid uuid = 18;
+inline bool Component::has_uuid() const {
+  return this != internal_default_instance() && uuid_ != nullptr;
+}
+inline void Component::clear_uuid() {
+  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
+    delete uuid_;
+  }
+  uuid_ = nullptr;
+}
+inline const ::dmi::Uuid& Component::uuid() const {
+  const ::dmi::Uuid* p = uuid_;
+  // @@protoc_insertion_point(field_get:dmi.Component.uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* Component::release_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.Component.uuid)
+  
+  ::dmi::Uuid* temp = uuid_;
+  uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* Component::mutable_uuid() {
+  
+  if (uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.uuid)
+  return uuid_;
+}
+inline void Component::set_allocated_uuid(::dmi::Uuid* uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete uuid_;
+  }
+  if (uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  uuid_ = uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.uuid)
+}
+
+// .dmi.ComponentState state = 19;
+inline bool Component::has_state() const {
+  return this != internal_default_instance() && state_ != nullptr;
+}
+inline void Component::clear_state() {
+  if (GetArenaNoVirtual() == nullptr && state_ != nullptr) {
+    delete state_;
+  }
+  state_ = nullptr;
+}
+inline const ::dmi::ComponentState& Component::state() const {
+  const ::dmi::ComponentState* p = state_;
+  // @@protoc_insertion_point(field_get:dmi.Component.state)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ComponentState*>(
+      &::dmi::_ComponentState_default_instance_);
+}
+inline ::dmi::ComponentState* Component::release_state() {
+  // @@protoc_insertion_point(field_release:dmi.Component.state)
+  
+  ::dmi::ComponentState* temp = state_;
+  state_ = nullptr;
+  return temp;
+}
+inline ::dmi::ComponentState* Component::mutable_state() {
+  
+  if (state_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::ComponentState>(GetArenaNoVirtual());
+    state_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.state)
+  return state_;
+}
+inline void Component::set_allocated_state(::dmi::ComponentState* state) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete state_;
+  }
+  if (state) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      state = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, state, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  state_ = state;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.state)
+}
+
+// repeated .dmi.ComponentSensorData sensor_data = 20;
+inline int Component::sensor_data_size() const {
+  return sensor_data_.size();
+}
+inline void Component::clear_sensor_data() {
+  sensor_data_.Clear();
+}
+inline ::dmi::ComponentSensorData* Component::mutable_sensor_data(int index) {
+  // @@protoc_insertion_point(field_mutable:dmi.Component.sensor_data)
+  return sensor_data_.Mutable(index);
+}
+inline ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >*
+Component::mutable_sensor_data() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.Component.sensor_data)
+  return &sensor_data_;
+}
+inline const ::dmi::ComponentSensorData& Component::sensor_data(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.Component.sensor_data)
+  return sensor_data_.Get(index);
+}
+inline ::dmi::ComponentSensorData* Component::add_sensor_data() {
+  // @@protoc_insertion_point(field_add:dmi.Component.sensor_data)
+  return sensor_data_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >&
+Component::sensor_data() const {
+  // @@protoc_insertion_point(field_list:dmi.Component.sensor_data)
+  return sensor_data_;
+}
+
+// .dmi.PortComponentAttributes port_attr = 50;
+inline bool Component::has_port_attr() const {
+  return specific_case() == kPortAttr;
+}
+inline void Component::set_has_port_attr() {
+  _oneof_case_[0] = kPortAttr;
+}
+inline void Component::clear_port_attr() {
+  if (has_port_attr()) {
+    delete specific_.port_attr_;
+    clear_has_specific();
+  }
+}
+inline ::dmi::PortComponentAttributes* Component::release_port_attr() {
+  // @@protoc_insertion_point(field_release:dmi.Component.port_attr)
+  if (has_port_attr()) {
+    clear_has_specific();
+      ::dmi::PortComponentAttributes* temp = specific_.port_attr_;
+    specific_.port_attr_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::PortComponentAttributes& Component::port_attr() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.port_attr)
+  return has_port_attr()
+      ? *specific_.port_attr_
+      : *reinterpret_cast< ::dmi::PortComponentAttributes*>(&::dmi::_PortComponentAttributes_default_instance_);
+}
+inline ::dmi::PortComponentAttributes* Component::mutable_port_attr() {
+  if (!has_port_attr()) {
+    clear_specific();
+    set_has_port_attr();
+    specific_.port_attr_ = CreateMaybeMessage< ::dmi::PortComponentAttributes >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.port_attr)
+  return specific_.port_attr_;
+}
+
+// .dmi.ContainerComponentAttributes container_attr = 51;
+inline bool Component::has_container_attr() const {
+  return specific_case() == kContainerAttr;
+}
+inline void Component::set_has_container_attr() {
+  _oneof_case_[0] = kContainerAttr;
+}
+inline void Component::clear_container_attr() {
+  if (has_container_attr()) {
+    delete specific_.container_attr_;
+    clear_has_specific();
+  }
+}
+inline ::dmi::ContainerComponentAttributes* Component::release_container_attr() {
+  // @@protoc_insertion_point(field_release:dmi.Component.container_attr)
+  if (has_container_attr()) {
+    clear_has_specific();
+      ::dmi::ContainerComponentAttributes* temp = specific_.container_attr_;
+    specific_.container_attr_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::ContainerComponentAttributes& Component::container_attr() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.container_attr)
+  return has_container_attr()
+      ? *specific_.container_attr_
+      : *reinterpret_cast< ::dmi::ContainerComponentAttributes*>(&::dmi::_ContainerComponentAttributes_default_instance_);
+}
+inline ::dmi::ContainerComponentAttributes* Component::mutable_container_attr() {
+  if (!has_container_attr()) {
+    clear_specific();
+    set_has_container_attr();
+    specific_.container_attr_ = CreateMaybeMessage< ::dmi::ContainerComponentAttributes >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.container_attr)
+  return specific_.container_attr_;
+}
+
+// .dmi.PsuComponentAttributes psu_attr = 52;
+inline bool Component::has_psu_attr() const {
+  return specific_case() == kPsuAttr;
+}
+inline void Component::set_has_psu_attr() {
+  _oneof_case_[0] = kPsuAttr;
+}
+inline void Component::clear_psu_attr() {
+  if (has_psu_attr()) {
+    delete specific_.psu_attr_;
+    clear_has_specific();
+  }
+}
+inline ::dmi::PsuComponentAttributes* Component::release_psu_attr() {
+  // @@protoc_insertion_point(field_release:dmi.Component.psu_attr)
+  if (has_psu_attr()) {
+    clear_has_specific();
+      ::dmi::PsuComponentAttributes* temp = specific_.psu_attr_;
+    specific_.psu_attr_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::PsuComponentAttributes& Component::psu_attr() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.psu_attr)
+  return has_psu_attr()
+      ? *specific_.psu_attr_
+      : *reinterpret_cast< ::dmi::PsuComponentAttributes*>(&::dmi::_PsuComponentAttributes_default_instance_);
+}
+inline ::dmi::PsuComponentAttributes* Component::mutable_psu_attr() {
+  if (!has_psu_attr()) {
+    clear_specific();
+    set_has_psu_attr();
+    specific_.psu_attr_ = CreateMaybeMessage< ::dmi::PsuComponentAttributes >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.psu_attr)
+  return specific_.psu_attr_;
+}
+
+// .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+inline bool Component::has_transceiver_attr() const {
+  return specific_case() == kTransceiverAttr;
+}
+inline void Component::set_has_transceiver_attr() {
+  _oneof_case_[0] = kTransceiverAttr;
+}
+inline void Component::clear_transceiver_attr() {
+  if (has_transceiver_attr()) {
+    delete specific_.transceiver_attr_;
+    clear_has_specific();
+  }
+}
+inline ::dmi::TransceiverComponentsAttributes* Component::release_transceiver_attr() {
+  // @@protoc_insertion_point(field_release:dmi.Component.transceiver_attr)
+  if (has_transceiver_attr()) {
+    clear_has_specific();
+      ::dmi::TransceiverComponentsAttributes* temp = specific_.transceiver_attr_;
+    specific_.transceiver_attr_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::TransceiverComponentsAttributes& Component::transceiver_attr() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.transceiver_attr)
+  return has_transceiver_attr()
+      ? *specific_.transceiver_attr_
+      : *reinterpret_cast< ::dmi::TransceiverComponentsAttributes*>(&::dmi::_TransceiverComponentsAttributes_default_instance_);
+}
+inline ::dmi::TransceiverComponentsAttributes* Component::mutable_transceiver_attr() {
+  if (!has_transceiver_attr()) {
+    clear_specific();
+    set_has_transceiver_attr();
+    specific_.transceiver_attr_ = CreateMaybeMessage< ::dmi::TransceiverComponentsAttributes >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.transceiver_attr)
+  return specific_.transceiver_attr_;
+}
+
+inline bool Component::has_specific() const {
+  return specific_case() != SPECIFIC_NOT_SET;
+}
+inline void Component::clear_has_specific() {
+  _oneof_case_[0] = SPECIFIC_NOT_SET;
+}
+inline Component::SpecificCase Component::specific_case() const {
+  return Component::SpecificCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// Hardware
+
+// .google.protobuf.Timestamp last_change = 1;
+inline bool Hardware::has_last_change() const {
+  return this != internal_default_instance() && last_change_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& Hardware::last_change() const {
+  const ::google::protobuf::Timestamp* p = last_change_;
+  // @@protoc_insertion_point(field_get:dmi.Hardware.last_change)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* Hardware::release_last_change() {
+  // @@protoc_insertion_point(field_release:dmi.Hardware.last_change)
+  
+  ::google::protobuf::Timestamp* temp = last_change_;
+  last_change_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* Hardware::mutable_last_change() {
+  
+  if (last_change_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    last_change_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Hardware.last_change)
+  return last_change_;
+}
+inline void Hardware::set_allocated_last_change(::google::protobuf::Timestamp* last_change) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(last_change_);
+  }
+  if (last_change) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(last_change)->GetArena();
+    if (message_arena != submessage_arena) {
+      last_change = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, last_change, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  last_change_ = last_change;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Hardware.last_change)
+}
+
+// .dmi.Component root = 2;
+inline bool Hardware::has_root() const {
+  return this != internal_default_instance() && root_ != nullptr;
+}
+inline void Hardware::clear_root() {
+  if (GetArenaNoVirtual() == nullptr && root_ != nullptr) {
+    delete root_;
+  }
+  root_ = nullptr;
+}
+inline const ::dmi::Component& Hardware::root() const {
+  const ::dmi::Component* p = root_;
+  // @@protoc_insertion_point(field_get:dmi.Hardware.root)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Component*>(
+      &::dmi::_Component_default_instance_);
+}
+inline ::dmi::Component* Hardware::release_root() {
+  // @@protoc_insertion_point(field_release:dmi.Hardware.root)
+  
+  ::dmi::Component* temp = root_;
+  root_ = nullptr;
+  return temp;
+}
+inline ::dmi::Component* Hardware::mutable_root() {
+  
+  if (root_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Component>(GetArenaNoVirtual());
+    root_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Hardware.root)
+  return root_;
+}
+inline void Hardware::set_allocated_root(::dmi::Component* root) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete root_;
+  }
+  if (root) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      root = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, root, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  root_ = root;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Hardware.root)
+}
+
+// .google.protobuf.Timestamp last_booted = 3;
+inline bool Hardware::has_last_booted() const {
+  return this != internal_default_instance() && last_booted_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& Hardware::last_booted() const {
+  const ::google::protobuf::Timestamp* p = last_booted_;
+  // @@protoc_insertion_point(field_get:dmi.Hardware.last_booted)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* Hardware::release_last_booted() {
+  // @@protoc_insertion_point(field_release:dmi.Hardware.last_booted)
+  
+  ::google::protobuf::Timestamp* temp = last_booted_;
+  last_booted_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* Hardware::mutable_last_booted() {
+  
+  if (last_booted_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    last_booted_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Hardware.last_booted)
+  return last_booted_;
+}
+inline void Hardware::set_allocated_last_booted(::google::protobuf::Timestamp* last_booted) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(last_booted_);
+  }
+  if (last_booted) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(last_booted)->GetArena();
+    if (message_arena != submessage_arena) {
+      last_booted = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, last_booted, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  last_booted_ = last_booted;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Hardware.last_booted)
+}
+
+// -------------------------------------------------------------------
+
+// ModifiableComponent
+
+// string name = 1;
+inline void ModifiableComponent::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ModifiableComponent::name() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.name)
+  return name_.GetNoArena();
+}
+inline void ModifiableComponent::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.name)
+}
+#if LANG_CXX11
+inline void ModifiableComponent::set_name(::std::string&& value) {
+  
+  name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ModifiableComponent.name)
+}
+#endif
+inline void ModifiableComponent::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.ModifiableComponent.name)
+}
+inline void ModifiableComponent::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.ModifiableComponent.name)
+}
+inline ::std::string* ModifiableComponent::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ModifiableComponent::release_name() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ModifiableComponent::set_allocated_name(::std::string* name) {
+  if (name != nullptr) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.name)
+}
+
+// .dmi.ComponentType class = 2;
+inline void ModifiableComponent::clear_class_() {
+  class__ = 0;
+}
+inline ::dmi::ComponentType ModifiableComponent::class_() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.class)
+  return static_cast< ::dmi::ComponentType >(class__);
+}
+inline void ModifiableComponent::set_class_(::dmi::ComponentType value) {
+  
+  class__ = value;
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.class)
+}
+
+// .dmi.Component parent = 3;
+inline bool ModifiableComponent::has_parent() const {
+  return this != internal_default_instance() && parent_ != nullptr;
+}
+inline void ModifiableComponent::clear_parent() {
+  if (GetArenaNoVirtual() == nullptr && parent_ != nullptr) {
+    delete parent_;
+  }
+  parent_ = nullptr;
+}
+inline const ::dmi::Component& ModifiableComponent::parent() const {
+  const ::dmi::Component* p = parent_;
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.parent)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Component*>(
+      &::dmi::_Component_default_instance_);
+}
+inline ::dmi::Component* ModifiableComponent::release_parent() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.parent)
+  
+  ::dmi::Component* temp = parent_;
+  parent_ = nullptr;
+  return temp;
+}
+inline ::dmi::Component* ModifiableComponent::mutable_parent() {
+  
+  if (parent_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Component>(GetArenaNoVirtual());
+    parent_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.parent)
+  return parent_;
+}
+inline void ModifiableComponent::set_allocated_parent(::dmi::Component* parent) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete parent_;
+  }
+  if (parent) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      parent = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, parent, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  parent_ = parent;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.parent)
+}
+
+// int32 parent_rel_pos = 4;
+inline void ModifiableComponent::clear_parent_rel_pos() {
+  parent_rel_pos_ = 0;
+}
+inline ::google::protobuf::int32 ModifiableComponent::parent_rel_pos() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.parent_rel_pos)
+  return parent_rel_pos_;
+}
+inline void ModifiableComponent::set_parent_rel_pos(::google::protobuf::int32 value) {
+  
+  parent_rel_pos_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.parent_rel_pos)
+}
+
+// string alias = 5;
+inline void ModifiableComponent::clear_alias() {
+  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ModifiableComponent::alias() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.alias)
+  return alias_.GetNoArena();
+}
+inline void ModifiableComponent::set_alias(const ::std::string& value) {
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.alias)
+}
+#if LANG_CXX11
+inline void ModifiableComponent::set_alias(::std::string&& value) {
+  
+  alias_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ModifiableComponent.alias)
+}
+#endif
+inline void ModifiableComponent::set_alias(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ModifiableComponent.alias)
+}
+inline void ModifiableComponent::set_alias(const char* value, size_t size) {
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ModifiableComponent.alias)
+}
+inline ::std::string* ModifiableComponent::mutable_alias() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.alias)
+  return alias_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ModifiableComponent::release_alias() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.alias)
+  
+  return alias_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ModifiableComponent::set_allocated_alias(::std::string* alias) {
+  if (alias != nullptr) {
+    
+  } else {
+    
+  }
+  alias_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), alias);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.alias)
+}
+
+// string asset_id = 6;
+inline void ModifiableComponent::clear_asset_id() {
+  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ModifiableComponent::asset_id() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.asset_id)
+  return asset_id_.GetNoArena();
+}
+inline void ModifiableComponent::set_asset_id(const ::std::string& value) {
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.asset_id)
+}
+#if LANG_CXX11
+inline void ModifiableComponent::set_asset_id(::std::string&& value) {
+  
+  asset_id_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ModifiableComponent.asset_id)
+}
+#endif
+inline void ModifiableComponent::set_asset_id(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ModifiableComponent.asset_id)
+}
+inline void ModifiableComponent::set_asset_id(const char* value, size_t size) {
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ModifiableComponent.asset_id)
+}
+inline ::std::string* ModifiableComponent::mutable_asset_id() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.asset_id)
+  return asset_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ModifiableComponent::release_asset_id() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.asset_id)
+  
+  return asset_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ModifiableComponent::set_allocated_asset_id(::std::string* asset_id) {
+  if (asset_id != nullptr) {
+    
+  } else {
+    
+  }
+  asset_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), asset_id);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.asset_id)
+}
+
+// .dmi.Uri uri = 7;
+inline bool ModifiableComponent::has_uri() const {
+  return this != internal_default_instance() && uri_ != nullptr;
+}
+inline void ModifiableComponent::clear_uri() {
+  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
+    delete uri_;
+  }
+  uri_ = nullptr;
+}
+inline const ::dmi::Uri& ModifiableComponent::uri() const {
+  const ::dmi::Uri* p = uri_;
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.uri)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uri*>(
+      &::dmi::_Uri_default_instance_);
+}
+inline ::dmi::Uri* ModifiableComponent::release_uri() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.uri)
+  
+  ::dmi::Uri* temp = uri_;
+  uri_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uri* ModifiableComponent::mutable_uri() {
+  
+  if (uri_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uri>(GetArenaNoVirtual());
+    uri_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.uri)
+  return uri_;
+}
+inline void ModifiableComponent::set_allocated_uri(::dmi::Uri* uri) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete uri_;
+  }
+  if (uri) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      uri = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, uri, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  uri_ = uri;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.uri)
+}
+
+// .dmi.ComponentAdminState admin_state = 8;
+inline void ModifiableComponent::clear_admin_state() {
+  admin_state_ = 0;
+}
+inline ::dmi::ComponentAdminState ModifiableComponent::admin_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.admin_state)
+  return static_cast< ::dmi::ComponentAdminState >(admin_state_);
+}
+inline void ModifiableComponent::set_admin_state(::dmi::ComponentAdminState value) {
+  
+  admin_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.admin_state)
+}
+
+#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::PortComponentAttributes_ConnectorType> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PortComponentAttributes_ConnectorType>() {
+  return ::dmi::PortComponentAttributes_ConnectorType_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::PortComponentAttributes_Speed> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PortComponentAttributes_Speed>() {
+  return ::dmi::PortComponentAttributes_Speed_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::PortComponentAttributes_Protocol> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PortComponentAttributes_Protocol>() {
+  return ::dmi::PortComponentAttributes_Protocol_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::PsuComponentAttributes_SupportedVoltage> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PsuComponentAttributes_SupportedVoltage>() {
+  return ::dmi::PsuComponentAttributes_SupportedVoltage_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::TransceiverComponentsAttributes_FormFactor> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::TransceiverComponentsAttributes_FormFactor>() {
+  return ::dmi::TransceiverComponentsAttributes_FormFactor_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::TransceiverComponentsAttributes_Type> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::TransceiverComponentsAttributes_Type>() {
+  return ::dmi::TransceiverComponentsAttributes_Type_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentType> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentType>() {
+  return ::dmi::ComponentType_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentAdminState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentAdminState>() {
+  return ::dmi::ComponentAdminState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentOperState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentOperState>() {
+  return ::dmi::ComponentOperState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentUsageState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentUsageState>() {
+  return ::dmi::ComponentUsageState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentAlarmState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentAlarmState>() {
+  return ::dmi::ComponentAlarmState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentStandbyState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentStandbyState>() {
+  return ::dmi::ComponentStandbyState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::DataValueType> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::DataValueType>() {
+  return ::dmi::DataValueType_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ValueScale> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ValueScale>() {
+  return ::dmi::ValueScale_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::SensorStatus> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::SensorStatus>() {
+  return ::dmi::SensorStatus_descriptor();
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#include <google/protobuf/port_undef.inc>
+#endif  // PROTOBUF_INCLUDED_dmi_2fhw_2eproto
diff --git a/cpp/dmi/hw_events_mgmt_service.pb.cc b/cpp/dmi/hw_events_mgmt_service.pb.cc
new file mode 100644
index 0000000..4f856f0
--- /dev/null
+++ b/cpp/dmi/hw_events_mgmt_service.pb.cc
@@ -0,0 +1,5144 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/hw_events_mgmt_service.proto
+
+#include "dmi/hw_events_mgmt_service.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto;
+namespace dmi {
+class ValueTypeDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ValueType> _instance;
+  ::google::protobuf::int64 int_val_;
+  ::google::protobuf::uint64 uint_val_;
+  float float_val_;
+} _ValueType_default_instance_;
+class WaterMarksDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<WaterMarks> _instance;
+} _WaterMarks_default_instance_;
+class ThresholdsDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Thresholds> _instance;
+  const ::dmi::WaterMarks* upper_;
+  const ::dmi::WaterMarks* lower_;
+} _Thresholds_default_instance_;
+class ThresholdInformationDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ThresholdInformation> _instance;
+} _ThresholdInformation_default_instance_;
+class EventCfgDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<EventCfg> _instance;
+} _EventCfg_default_instance_;
+class EventsCfgDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<EventsCfg> _instance;
+} _EventsCfg_default_instance_;
+class ListEventsResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ListEventsResponse> _instance;
+} _ListEventsResponse_default_instance_;
+class EventsConfigurationRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<EventsConfigurationRequest> _instance;
+  const ::dmi::EventsCfg* changes_;
+  bool reset_to_default_;
+} _EventsConfigurationRequest_default_instance_;
+class EventsConfigurationResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<EventsConfigurationResponse> _instance;
+} _EventsConfigurationResponse_default_instance_;
+class EventMetaDataDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<EventMetaData> _instance;
+} _EventMetaData_default_instance_;
+class EventDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Event> _instance;
+} _Event_default_instance_;
+}  // namespace dmi
+static void InitDefaultsValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ValueType_default_instance_;
+    new (ptr) ::dmi::ValueType();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ValueType::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};
+
+static void InitDefaultsWaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_WaterMarks_default_instance_;
+    new (ptr) ::dmi::WaterMarks();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::WaterMarks::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsWaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsThresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Thresholds_default_instance_;
+    new (ptr) ::dmi::Thresholds();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Thresholds::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsThresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ThresholdInformation_default_instance_;
+    new (ptr) ::dmi::ThresholdInformation();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ThresholdInformation::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
+      &scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsEventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_EventCfg_default_instance_;
+    new (ptr) ::dmi::EventCfg();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::EventCfg::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsEventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_EventsCfg_default_instance_;
+    new (ptr) ::dmi::EventsCfg();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::EventsCfg::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ListEventsResponse_default_instance_;
+    new (ptr) ::dmi::ListEventsResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ListEventsResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsEventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_EventsConfigurationRequest_default_instance_;
+    new (ptr) ::dmi::EventsConfigurationRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::EventsConfigurationRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_EventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsEventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,
+      &scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsEventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_EventsConfigurationResponse_default_instance_;
+    new (ptr) ::dmi::EventsConfigurationResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::EventsConfigurationResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_EventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsEventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};
+
+static void InitDefaultsEventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_EventMetaData_default_instance_;
+    new (ptr) ::dmi::EventMetaData();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::EventMetaData::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsEvent_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Event_default_instance_;
+    new (ptr) ::dmi::Event();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Event::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<3> scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsEvent_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
+      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,
+      &scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+
+void InitDefaults_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+}
+
+::google::protobuf::Metadata file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[11];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[3];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = nullptr;
+
+const ::google::protobuf::uint32 TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ValueType, _internal_metadata_),
+  ~0u,  // no _extensions_
+  PROTOBUF_FIELD_OFFSET(::dmi::ValueType, _oneof_case_[0]),
+  ~0u,  // no _weak_field_map_
+  offsetof(::dmi::ValueTypeDefaultTypeInternal, int_val_),
+  offsetof(::dmi::ValueTypeDefaultTypeInternal, uint_val_),
+  offsetof(::dmi::ValueTypeDefaultTypeInternal, float_val_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ValueType, val_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::WaterMarks, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::WaterMarks, high_),
+  PROTOBUF_FIELD_OFFSET(::dmi::WaterMarks, low_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Thresholds, _internal_metadata_),
+  ~0u,  // no _extensions_
+  PROTOBUF_FIELD_OFFSET(::dmi::Thresholds, _oneof_case_[0]),
+  ~0u,  // no _weak_field_map_
+  offsetof(::dmi::ThresholdsDefaultTypeInternal, upper_),
+  offsetof(::dmi::ThresholdsDefaultTypeInternal, lower_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Thresholds, threshold_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ThresholdInformation, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ThresholdInformation, observed_value_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ThresholdInformation, thresholds_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventCfg, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventCfg, event_id_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EventCfg, is_configured_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EventCfg, thresholds_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsCfg, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsCfg, items_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, events_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ListEventsResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationRequest, _oneof_case_[0]),
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationRequest, device_uuid_),
+  offsetof(::dmi::EventsConfigurationRequestDefaultTypeInternal, changes_),
+  offsetof(::dmi::EventsConfigurationRequestDefaultTypeInternal, reset_to_default_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationRequest, operation_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EventsConfigurationResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, component_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, component_name_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Event, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Event, event_metadata_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Event, event_id_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Event, raised_ts_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Event, threshold_info_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Event, add_info_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  { 0, -1, sizeof(::dmi::ValueType)},
+  { 9, -1, sizeof(::dmi::WaterMarks)},
+  { 16, -1, sizeof(::dmi::Thresholds)},
+  { 24, -1, sizeof(::dmi::ThresholdInformation)},
+  { 31, -1, sizeof(::dmi::EventCfg)},
+  { 39, -1, sizeof(::dmi::EventsCfg)},
+  { 45, -1, sizeof(::dmi::ListEventsResponse)},
+  { 54, -1, sizeof(::dmi::EventsConfigurationRequest)},
+  { 63, -1, sizeof(::dmi::EventsConfigurationResponse)},
+  { 71, -1, sizeof(::dmi::EventMetaData)},
+  { 79, -1, sizeof(::dmi::Event)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ValueType_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_WaterMarks_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Thresholds_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ThresholdInformation_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventCfg_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventsCfg_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ListEventsResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventsConfigurationRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventsConfigurationResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventMetaData_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Event_default_instance_),
+};
+
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = {
+  {}, AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, "dmi/hw_events_mgmt_service.proto", schemas,
+  file_default_instances, TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto::offsets,
+  file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 11, file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, file_level_service_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto,
+};
+
+const char descriptor_table_protodef_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[] =
+  "\n dmi/hw_events_mgmt_service.proto\022\003dmi\032"
+  "\021dmi/commons.proto\032\014dmi/hw.proto\032\037google"
+  "/protobuf/timestamp.proto\"N\n\tValueType\022\021"
+  "\n\007int_val\030\001 \001(\003H\000\022\022\n\010uint_val\030\002 \001(\004H\000\022\023\n"
+  "\tfloat_val\030\003 \001(\002H\000B\005\n\003val\"G\n\nWaterMarks\022"
+  "\034\n\004high\030\001 \001(\0132\016.dmi.ValueType\022\033\n\003low\030\002 \001"
+  "(\0132\016.dmi.ValueType\"]\n\nThresholds\022 \n\005uppe"
+  "r\030\001 \001(\0132\017.dmi.WaterMarksH\000\022 \n\005lower\030\002 \001("
+  "\0132\017.dmi.WaterMarksH\000B\013\n\tthreshold\"c\n\024Thr"
+  "esholdInformation\022&\n\016observed_value\030\001 \001("
+  "\0132\016.dmi.ValueType\022#\n\nthresholds\030\002 \001(\0132\017."
+  "dmi.Thresholds\"g\n\010EventCfg\022\037\n\010event_id\030\001"
+  " \001(\0162\r.dmi.EventIds\022\025\n\ris_configured\030\002 \001"
+  "(\010\022#\n\nthresholds\030\003 \001(\0132\017.dmi.Thresholds\""
+  ")\n\tEventsCfg\022\034\n\005items\030\001 \003(\0132\r.dmi.EventC"
+  "fg\"\370\001\n\022ListEventsResponse\022\033\n\006status\030\001 \001("
+  "\0162\013.dmi.Status\022.\n\006reason\030\002 \001(\0162\036.dmi.Lis"
+  "tEventsResponse.Reason\022\036\n\006events\030\003 \001(\0132\016"
+  ".dmi.EventsCfg\022\025\n\rreason_detail\030\004 \001(\t\"^\n"
+  "\006Reason\022\024\n\020UNDEFINED_REASON\020\000\022\022\n\016UNKNOWN"
+  "_DEVICE\020\001\022\022\n\016INTERNAL_ERROR\020\002\022\026\n\022DEVICE_"
+  "UNREACHABLE\020\003\"\210\001\n\032EventsConfigurationReq"
+  "uest\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uuid\022!\n\007"
+  "changes\030\002 \001(\0132\016.dmi.EventsCfgH\000\022\032\n\020reset"
+  "_to_default\030\003 \001(\010H\000B\013\n\toperation\"\376\001\n\033Eve"
+  "ntsConfigurationResponse\022\033\n\006status\030\001 \001(\016"
+  "2\013.dmi.Status\0227\n\006reason\030\002 \001(\0162\'.dmi.Even"
+  "tsConfigurationResponse.Reason\022\025\n\rreason"
+  "_detail\030\003 \001(\t\"r\n\006Reason\022\024\n\020UNDEFINED_REA"
+  "SON\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INTERNAL_ER"
+  "ROR\020\002\022\022\n\016INVALID_CONFIG\020\003\022\026\n\022DEVICE_UNRE"
+  "ACHABLE\020\004\"j\n\rEventMetaData\022\036\n\013device_uui"
+  "d\030\001 \001(\0132\t.dmi.Uuid\022!\n\016component_uuid\030\002 \001"
+  "(\0132\t.dmi.Uuid\022\026\n\016component_name\030\003 \001(\t\"\310\001"
+  "\n\005Event\022*\n\016event_metadata\030\001 \001(\0132\022.dmi.Ev"
+  "entMetaData\022\037\n\010event_id\030\002 \001(\0162\r.dmi.Even"
+  "tIds\022-\n\traised_ts\030\003 \001(\0132\032.google.protobu"
+  "f.Timestamp\0221\n\016threshold_info\030\004 \001(\0132\031.dm"
+  "i.ThresholdInformation\022\020\n\010add_info\030\005 \001(\t"
+  "*\321\016\n\010EventIds\022\030\n\024EVENT_NAME_UNDEFINED\020\000\022"
+  "\036\n\032EVENT_TRANSCEIVER_PLUG_OUT\020d\022\035\n\031EVENT"
+  "_TRANSCEIVER_PLUG_IN\020e\022-\n)EVENT_TRANSCEI"
+  "VER_VOLTAGE_ABOVE_THRESHOLD\020f\022-\n)EVENT_T"
+  "RANSCEIVER_VOLTAGE_BELOW_THRESHOLD\020g\0221\n-"
+  "EVENT_TRANSCEIVER_TEMPERATURE_ABOVE_THRE"
+  "SHOLD\020h\0221\n-EVENT_TRANSCEIVER_TEMPERATURE"
+  "_BELOW_THRESHOLD\020i\022-\n)EVENT_TRANSCEIVER_"
+  "CURRENT_ABOVE_THRESHOLD\020j\022-\n)EVENT_TRANS"
+  "CEIVER_CURRENT_BELOW_THRESHOLD\020k\022.\n*EVEN"
+  "T_TRANSCEIVER_RX_POWER_ABOVE_THRESHOLD\020l"
+  "\022.\n*EVENT_TRANSCEIVER_RX_POWER_BELOW_THR"
+  "ESHOLD\020m\022.\n*EVENT_TRANSCEIVER_TX_POWER_A"
+  "BOVE_THRESHOLD\020n\022.\n*EVENT_TRANSCEIVER_TX"
+  "_POWER_BELOW_THRESHOLD\020o\022\035\n\031EVENT_TRANSC"
+  "EIVER_FAILURE\020p\0227\n3EVENT_TRANSCEIVER_VOL"
+  "TAGE_ABOVE_THRESHOLD_RECOVERED\020q\0227\n3EVEN"
+  "T_TRANSCEIVER_VOLTAGE_BELOW_THRESHOLD_RE"
+  "COVERED\020r\022;\n7EVENT_TRANSCEIVER_TEMPERATU"
+  "RE_ABOVE_THRESHOLD_RECOVERED\020s\022;\n7EVENT_"
+  "TRANSCEIVER_TEMPERATURE_BELOW_THRESHOLD_"
+  "RECOVERED\020t\0227\n3EVENT_TRANSCEIVER_CURRENT"
+  "_ABOVE_THRESHOLD_RECOVERED\020u\0227\n3EVENT_TR"
+  "ANSCEIVER_CURRENT_BELOW_THRESHOLD_RECOVE"
+  "RED\020v\0228\n4EVENT_TRANSCEIVER_RX_POWER_ABOV"
+  "E_THRESHOLD_RECOVERED\020w\0228\n4EVENT_TRANSCE"
+  "IVER_RX_POWER_BELOW_THRESHOLD_RECOVERED\020"
+  "x\0228\n4EVENT_TRANSCEIVER_TX_POWER_ABOVE_TH"
+  "RESHOLD_RECOVERED\020y\0228\n4EVENT_TRANSCEIVER"
+  "_TX_POWER_BELOW_THRESHOLD_RECOVERED\020z\022\'\n"
+  "#EVENT_TRANSCEIVER_FAILURE_RECOVERED\020{\022\027"
+  "\n\022EVENT_PSU_PLUG_OUT\020\310\001\022\026\n\021EVENT_PSU_PLU"
+  "G_IN\020\311\001\022\026\n\021EVENT_PSU_FAILURE\020\312\001\022 \n\033EVENT"
+  "_PSU_FAILURE_RECOVERED\020\313\001\022\026\n\021EVENT_FAN_F"
+  "AILURE\020\254\002\022\027\n\022EVENT_FAN_PLUG_OUT\020\255\002\022\026\n\021EV"
+  "ENT_FAN_PLUG_IN\020\256\002\022 \n\033EVENT_FAN_FAILURE_"
+  "RECOVERED\020\257\002\022)\n$EVENT_CPU_TEMPERATURE_AB"
+  "OVE_CRITICAL\020\220\003\022&\n!EVENT_CPU_TEMPERATURE"
+  "_ABOVE_FATAL\020\221\003\0223\n.EVENT_CPU_TEMPERATURE"
+  "_ABOVE_CRITICAL_RECOVERED\020\222\003\0220\n+EVENT_CP"
+  "U_TEMPERATURE_ABOVE_FATAL_RECOVERED\020\223\003\022\032"
+  "\n\025EVENT_HW_DEVICE_RESET\020\364\003\022/\n*EVENT_HW_D"
+  "EVICE_TEMPERATURE_ABOVE_CRITICAL\020\365\003\022,\n\'E"
+  "VENT_HW_DEVICE_TEMPERATURE_ABOVE_FATAL\020\366"
+  "\003\0229\n4EVENT_HW_DEVICE_TEMPERATURE_ABOVE_C"
+  "RITICAL_RECOVERED\020\367\003\0226\n1EVENT_HW_DEVICE_"
+  "TEMPERATURE_ABOVE_FATAL_RECOVERED\020\370\0032\267\001\n"
+  "\035NativeEventsManagementService\0226\n\nListEv"
+  "ents\022\017.dmi.HardwareID\032\027.dmi.ListEventsRe"
+  "sponse\022^\n\031UpdateEventsConfiguration\022\037.dm"
+  "i.EventsConfigurationRequest\032 .dmi.Event"
+  "sConfigurationResponseB;Z9github.com/ope"
+  "ncord/device-management-interface/v3/go/"
+  "dmib\006proto3"
+  ;
+::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = {
+  false, InitDefaults_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 
+  descriptor_table_protodef_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto,
+  "dmi/hw_events_mgmt_service.proto", &assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 3691,
+};
+
+void AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[3] =
+  {
+    ::AddDescriptors_dmi_2fcommons_2eproto,
+    ::AddDescriptors_dmi_2fhw_2eproto,
+    ::AddDescriptors_google_2fprotobuf_2ftimestamp_2eproto,
+  };
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, deps, 3);
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = []() { AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto(); return true; }();
+namespace dmi {
+const ::google::protobuf::EnumDescriptor* ListEventsResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[0];
+}
+bool ListEventsResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const ListEventsResponse_Reason ListEventsResponse::UNDEFINED_REASON;
+const ListEventsResponse_Reason ListEventsResponse::UNKNOWN_DEVICE;
+const ListEventsResponse_Reason ListEventsResponse::INTERNAL_ERROR;
+const ListEventsResponse_Reason ListEventsResponse::DEVICE_UNREACHABLE;
+const ListEventsResponse_Reason ListEventsResponse::Reason_MIN;
+const ListEventsResponse_Reason ListEventsResponse::Reason_MAX;
+const int ListEventsResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* EventsConfigurationResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[1];
+}
+bool EventsConfigurationResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const EventsConfigurationResponse_Reason EventsConfigurationResponse::UNDEFINED_REASON;
+const EventsConfigurationResponse_Reason EventsConfigurationResponse::UNKNOWN_DEVICE;
+const EventsConfigurationResponse_Reason EventsConfigurationResponse::INTERNAL_ERROR;
+const EventsConfigurationResponse_Reason EventsConfigurationResponse::INVALID_CONFIG;
+const EventsConfigurationResponse_Reason EventsConfigurationResponse::DEVICE_UNREACHABLE;
+const EventsConfigurationResponse_Reason EventsConfigurationResponse::Reason_MIN;
+const EventsConfigurationResponse_Reason EventsConfigurationResponse::Reason_MAX;
+const int EventsConfigurationResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* EventIds_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[2];
+}
+bool EventIds_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 100:
+    case 101:
+    case 102:
+    case 103:
+    case 104:
+    case 105:
+    case 106:
+    case 107:
+    case 108:
+    case 109:
+    case 110:
+    case 111:
+    case 112:
+    case 113:
+    case 114:
+    case 115:
+    case 116:
+    case 117:
+    case 118:
+    case 119:
+    case 120:
+    case 121:
+    case 122:
+    case 123:
+    case 200:
+    case 201:
+    case 202:
+    case 203:
+    case 300:
+    case 301:
+    case 302:
+    case 303:
+    case 400:
+    case 401:
+    case 402:
+    case 403:
+    case 500:
+    case 501:
+    case 502:
+    case 503:
+    case 504:
+      return true;
+    default:
+      return false;
+  }
+}
+
+
+// ===================================================================
+
+void ValueType::InitAsDefaultInstance() {
+  ::dmi::_ValueType_default_instance_.int_val_ = PROTOBUF_LONGLONG(0);
+  ::dmi::_ValueType_default_instance_.uint_val_ = PROTOBUF_ULONGLONG(0);
+  ::dmi::_ValueType_default_instance_.float_val_ = 0;
+}
+class ValueType::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ValueType::kIntValFieldNumber;
+const int ValueType::kUintValFieldNumber;
+const int ValueType::kFloatValFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ValueType::ValueType()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ValueType)
+}
+ValueType::ValueType(const ValueType& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  clear_has_val();
+  switch (from.val_case()) {
+    case kIntVal: {
+      set_int_val(from.int_val());
+      break;
+    }
+    case kUintVal: {
+      set_uint_val(from.uint_val());
+      break;
+    }
+    case kFloatVal: {
+      set_float_val(from.float_val());
+      break;
+    }
+    case VAL_NOT_SET: {
+      break;
+    }
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.ValueType)
+}
+
+void ValueType::SharedCtor() {
+  clear_has_val();
+}
+
+ValueType::~ValueType() {
+  // @@protoc_insertion_point(destructor:dmi.ValueType)
+  SharedDtor();
+}
+
+void ValueType::SharedDtor() {
+  if (has_val()) {
+    clear_val();
+  }
+}
+
+void ValueType::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ValueType& ValueType::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ValueType::clear_val() {
+// @@protoc_insertion_point(one_of_clear_start:dmi.ValueType)
+  switch (val_case()) {
+    case kIntVal: {
+      // No need to clear
+      break;
+    }
+    case kUintVal: {
+      // No need to clear
+      break;
+    }
+    case kFloatVal: {
+      // No need to clear
+      break;
+    }
+    case VAL_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = VAL_NOT_SET;
+}
+
+
+void ValueType::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ValueType)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  clear_val();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ValueType::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ValueType*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // int64 int_val = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        msg->set_int_val(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // uint64 uint_val = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        msg->set_uint_val(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // float float_val = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 29) goto handle_unusual;
+        msg->set_float_val(::google::protobuf::io::UnalignedLoad<float>(ptr));
+        ptr += sizeof(float);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ValueType::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ValueType)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // int64 int_val = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          clear_val();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
+                 input, &val_.int_val_)));
+          set_has_int_val();
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // uint64 uint_val = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          clear_val();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &val_.uint_val_)));
+          set_has_uint_val();
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // float float_val = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (29 & 0xFF)) {
+          clear_val();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+                 input, &val_.float_val_)));
+          set_has_float_val();
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ValueType)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ValueType)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ValueType::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ValueType)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // int64 int_val = 1;
+  if (has_int_val()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->int_val(), output);
+  }
+
+  // uint64 uint_val = 2;
+  if (has_uint_val()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->uint_val(), output);
+  }
+
+  // float float_val = 3;
+  if (has_float_val()) {
+    ::google::protobuf::internal::WireFormatLite::WriteFloat(3, this->float_val(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ValueType)
+}
+
+::google::protobuf::uint8* ValueType::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ValueType)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // int64 int_val = 1;
+  if (has_int_val()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->int_val(), target);
+  }
+
+  // uint64 uint_val = 2;
+  if (has_uint_val()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->uint_val(), target);
+  }
+
+  // float float_val = 3;
+  if (has_float_val()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(3, this->float_val(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ValueType)
+  return target;
+}
+
+size_t ValueType::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ValueType)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  switch (val_case()) {
+    // int64 int_val = 1;
+    case kIntVal: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int64Size(
+          this->int_val());
+      break;
+    }
+    // uint64 uint_val = 2;
+    case kUintVal: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->uint_val());
+      break;
+    }
+    // float float_val = 3;
+    case kFloatVal: {
+      total_size += 1 + 4;
+      break;
+    }
+    case VAL_NOT_SET: {
+      break;
+    }
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ValueType::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ValueType)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ValueType* source =
+      ::google::protobuf::DynamicCastToGenerated<ValueType>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ValueType)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ValueType)
+    MergeFrom(*source);
+  }
+}
+
+void ValueType::MergeFrom(const ValueType& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ValueType)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  switch (from.val_case()) {
+    case kIntVal: {
+      set_int_val(from.int_val());
+      break;
+    }
+    case kUintVal: {
+      set_uint_val(from.uint_val());
+      break;
+    }
+    case kFloatVal: {
+      set_float_val(from.float_val());
+      break;
+    }
+    case VAL_NOT_SET: {
+      break;
+    }
+  }
+}
+
+void ValueType::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ValueType)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ValueType::CopyFrom(const ValueType& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ValueType)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ValueType::IsInitialized() const {
+  return true;
+}
+
+void ValueType::Swap(ValueType* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ValueType::InternalSwap(ValueType* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(val_, other->val_);
+  swap(_oneof_case_[0], other->_oneof_case_[0]);
+}
+
+::google::protobuf::Metadata ValueType::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void WaterMarks::InitAsDefaultInstance() {
+  ::dmi::_WaterMarks_default_instance_._instance.get_mutable()->high_ = const_cast< ::dmi::ValueType*>(
+      ::dmi::ValueType::internal_default_instance());
+  ::dmi::_WaterMarks_default_instance_._instance.get_mutable()->low_ = const_cast< ::dmi::ValueType*>(
+      ::dmi::ValueType::internal_default_instance());
+}
+class WaterMarks::HasBitSetters {
+ public:
+  static const ::dmi::ValueType& high(const WaterMarks* msg);
+  static const ::dmi::ValueType& low(const WaterMarks* msg);
+};
+
+const ::dmi::ValueType&
+WaterMarks::HasBitSetters::high(const WaterMarks* msg) {
+  return *msg->high_;
+}
+const ::dmi::ValueType&
+WaterMarks::HasBitSetters::low(const WaterMarks* msg) {
+  return *msg->low_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int WaterMarks::kHighFieldNumber;
+const int WaterMarks::kLowFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+WaterMarks::WaterMarks()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.WaterMarks)
+}
+WaterMarks::WaterMarks(const WaterMarks& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_high()) {
+    high_ = new ::dmi::ValueType(*from.high_);
+  } else {
+    high_ = nullptr;
+  }
+  if (from.has_low()) {
+    low_ = new ::dmi::ValueType(*from.low_);
+  } else {
+    low_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.WaterMarks)
+}
+
+void WaterMarks::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::memset(&high_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&low_) -
+      reinterpret_cast<char*>(&high_)) + sizeof(low_));
+}
+
+WaterMarks::~WaterMarks() {
+  // @@protoc_insertion_point(destructor:dmi.WaterMarks)
+  SharedDtor();
+}
+
+void WaterMarks::SharedDtor() {
+  if (this != internal_default_instance()) delete high_;
+  if (this != internal_default_instance()) delete low_;
+}
+
+void WaterMarks::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const WaterMarks& WaterMarks::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void WaterMarks::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.WaterMarks)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && high_ != nullptr) {
+    delete high_;
+  }
+  high_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && low_ != nullptr) {
+    delete low_;
+  }
+  low_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* WaterMarks::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<WaterMarks*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.ValueType high = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ValueType::_InternalParse;
+        object = msg->mutable_high();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ValueType low = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ValueType::_InternalParse;
+        object = msg->mutable_low();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool WaterMarks::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.WaterMarks)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.ValueType high = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_high()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ValueType low = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_low()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.WaterMarks)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.WaterMarks)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void WaterMarks::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.WaterMarks)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ValueType high = 1;
+  if (this->has_high()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::high(this), output);
+  }
+
+  // .dmi.ValueType low = 2;
+  if (this->has_low()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::low(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.WaterMarks)
+}
+
+::google::protobuf::uint8* WaterMarks::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.WaterMarks)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ValueType high = 1;
+  if (this->has_high()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::high(this), target);
+  }
+
+  // .dmi.ValueType low = 2;
+  if (this->has_low()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::low(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.WaterMarks)
+  return target;
+}
+
+size_t WaterMarks::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.WaterMarks)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.ValueType high = 1;
+  if (this->has_high()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *high_);
+  }
+
+  // .dmi.ValueType low = 2;
+  if (this->has_low()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *low_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void WaterMarks::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.WaterMarks)
+  GOOGLE_DCHECK_NE(&from, this);
+  const WaterMarks* source =
+      ::google::protobuf::DynamicCastToGenerated<WaterMarks>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.WaterMarks)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.WaterMarks)
+    MergeFrom(*source);
+  }
+}
+
+void WaterMarks::MergeFrom(const WaterMarks& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.WaterMarks)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_high()) {
+    mutable_high()->::dmi::ValueType::MergeFrom(from.high());
+  }
+  if (from.has_low()) {
+    mutable_low()->::dmi::ValueType::MergeFrom(from.low());
+  }
+}
+
+void WaterMarks::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.WaterMarks)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void WaterMarks::CopyFrom(const WaterMarks& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.WaterMarks)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool WaterMarks::IsInitialized() const {
+  return true;
+}
+
+void WaterMarks::Swap(WaterMarks* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void WaterMarks::InternalSwap(WaterMarks* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(high_, other->high_);
+  swap(low_, other->low_);
+}
+
+::google::protobuf::Metadata WaterMarks::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void Thresholds::InitAsDefaultInstance() {
+  ::dmi::_Thresholds_default_instance_.upper_ = const_cast< ::dmi::WaterMarks*>(
+      ::dmi::WaterMarks::internal_default_instance());
+  ::dmi::_Thresholds_default_instance_.lower_ = const_cast< ::dmi::WaterMarks*>(
+      ::dmi::WaterMarks::internal_default_instance());
+}
+class Thresholds::HasBitSetters {
+ public:
+  static const ::dmi::WaterMarks& upper(const Thresholds* msg);
+  static const ::dmi::WaterMarks& lower(const Thresholds* msg);
+};
+
+const ::dmi::WaterMarks&
+Thresholds::HasBitSetters::upper(const Thresholds* msg) {
+  return *msg->threshold_.upper_;
+}
+const ::dmi::WaterMarks&
+Thresholds::HasBitSetters::lower(const Thresholds* msg) {
+  return *msg->threshold_.lower_;
+}
+void Thresholds::set_allocated_upper(::dmi::WaterMarks* upper) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_threshold();
+  if (upper) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      upper = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, upper, submessage_arena);
+    }
+    set_has_upper();
+    threshold_.upper_ = upper;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Thresholds.upper)
+}
+void Thresholds::set_allocated_lower(::dmi::WaterMarks* lower) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_threshold();
+  if (lower) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      lower = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, lower, submessage_arena);
+    }
+    set_has_lower();
+    threshold_.lower_ = lower;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Thresholds.lower)
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Thresholds::kUpperFieldNumber;
+const int Thresholds::kLowerFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Thresholds::Thresholds()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Thresholds)
+}
+Thresholds::Thresholds(const Thresholds& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  clear_has_threshold();
+  switch (from.threshold_case()) {
+    case kUpper: {
+      mutable_upper()->::dmi::WaterMarks::MergeFrom(from.upper());
+      break;
+    }
+    case kLower: {
+      mutable_lower()->::dmi::WaterMarks::MergeFrom(from.lower());
+      break;
+    }
+    case THRESHOLD_NOT_SET: {
+      break;
+    }
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.Thresholds)
+}
+
+void Thresholds::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  clear_has_threshold();
+}
+
+Thresholds::~Thresholds() {
+  // @@protoc_insertion_point(destructor:dmi.Thresholds)
+  SharedDtor();
+}
+
+void Thresholds::SharedDtor() {
+  if (has_threshold()) {
+    clear_threshold();
+  }
+}
+
+void Thresholds::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Thresholds& Thresholds::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Thresholds_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Thresholds::clear_threshold() {
+// @@protoc_insertion_point(one_of_clear_start:dmi.Thresholds)
+  switch (threshold_case()) {
+    case kUpper: {
+      delete threshold_.upper_;
+      break;
+    }
+    case kLower: {
+      delete threshold_.lower_;
+      break;
+    }
+    case THRESHOLD_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = THRESHOLD_NOT_SET;
+}
+
+
+void Thresholds::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Thresholds)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  clear_threshold();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Thresholds::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Thresholds*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.WaterMarks upper = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::WaterMarks::_InternalParse;
+        object = msg->mutable_upper();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.WaterMarks lower = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::WaterMarks::_InternalParse;
+        object = msg->mutable_lower();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Thresholds::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Thresholds)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.WaterMarks upper = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_upper()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.WaterMarks lower = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_lower()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Thresholds)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Thresholds)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Thresholds::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Thresholds)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.WaterMarks upper = 1;
+  if (has_upper()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::upper(this), output);
+  }
+
+  // .dmi.WaterMarks lower = 2;
+  if (has_lower()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::lower(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Thresholds)
+}
+
+::google::protobuf::uint8* Thresholds::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Thresholds)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.WaterMarks upper = 1;
+  if (has_upper()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::upper(this), target);
+  }
+
+  // .dmi.WaterMarks lower = 2;
+  if (has_lower()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::lower(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Thresholds)
+  return target;
+}
+
+size_t Thresholds::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Thresholds)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  switch (threshold_case()) {
+    // .dmi.WaterMarks upper = 1;
+    case kUpper: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *threshold_.upper_);
+      break;
+    }
+    // .dmi.WaterMarks lower = 2;
+    case kLower: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *threshold_.lower_);
+      break;
+    }
+    case THRESHOLD_NOT_SET: {
+      break;
+    }
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Thresholds::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Thresholds)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Thresholds* source =
+      ::google::protobuf::DynamicCastToGenerated<Thresholds>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Thresholds)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Thresholds)
+    MergeFrom(*source);
+  }
+}
+
+void Thresholds::MergeFrom(const Thresholds& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Thresholds)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  switch (from.threshold_case()) {
+    case kUpper: {
+      mutable_upper()->::dmi::WaterMarks::MergeFrom(from.upper());
+      break;
+    }
+    case kLower: {
+      mutable_lower()->::dmi::WaterMarks::MergeFrom(from.lower());
+      break;
+    }
+    case THRESHOLD_NOT_SET: {
+      break;
+    }
+  }
+}
+
+void Thresholds::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Thresholds)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Thresholds::CopyFrom(const Thresholds& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Thresholds)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Thresholds::IsInitialized() const {
+  return true;
+}
+
+void Thresholds::Swap(Thresholds* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Thresholds::InternalSwap(Thresholds* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(threshold_, other->threshold_);
+  swap(_oneof_case_[0], other->_oneof_case_[0]);
+}
+
+::google::protobuf::Metadata Thresholds::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ThresholdInformation::InitAsDefaultInstance() {
+  ::dmi::_ThresholdInformation_default_instance_._instance.get_mutable()->observed_value_ = const_cast< ::dmi::ValueType*>(
+      ::dmi::ValueType::internal_default_instance());
+  ::dmi::_ThresholdInformation_default_instance_._instance.get_mutable()->thresholds_ = const_cast< ::dmi::Thresholds*>(
+      ::dmi::Thresholds::internal_default_instance());
+}
+class ThresholdInformation::HasBitSetters {
+ public:
+  static const ::dmi::ValueType& observed_value(const ThresholdInformation* msg);
+  static const ::dmi::Thresholds& thresholds(const ThresholdInformation* msg);
+};
+
+const ::dmi::ValueType&
+ThresholdInformation::HasBitSetters::observed_value(const ThresholdInformation* msg) {
+  return *msg->observed_value_;
+}
+const ::dmi::Thresholds&
+ThresholdInformation::HasBitSetters::thresholds(const ThresholdInformation* msg) {
+  return *msg->thresholds_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ThresholdInformation::kObservedValueFieldNumber;
+const int ThresholdInformation::kThresholdsFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ThresholdInformation::ThresholdInformation()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ThresholdInformation)
+}
+ThresholdInformation::ThresholdInformation(const ThresholdInformation& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_observed_value()) {
+    observed_value_ = new ::dmi::ValueType(*from.observed_value_);
+  } else {
+    observed_value_ = nullptr;
+  }
+  if (from.has_thresholds()) {
+    thresholds_ = new ::dmi::Thresholds(*from.thresholds_);
+  } else {
+    thresholds_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.ThresholdInformation)
+}
+
+void ThresholdInformation::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::memset(&observed_value_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&thresholds_) -
+      reinterpret_cast<char*>(&observed_value_)) + sizeof(thresholds_));
+}
+
+ThresholdInformation::~ThresholdInformation() {
+  // @@protoc_insertion_point(destructor:dmi.ThresholdInformation)
+  SharedDtor();
+}
+
+void ThresholdInformation::SharedDtor() {
+  if (this != internal_default_instance()) delete observed_value_;
+  if (this != internal_default_instance()) delete thresholds_;
+}
+
+void ThresholdInformation::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ThresholdInformation& ThresholdInformation::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ThresholdInformation::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ThresholdInformation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && observed_value_ != nullptr) {
+    delete observed_value_;
+  }
+  observed_value_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && thresholds_ != nullptr) {
+    delete thresholds_;
+  }
+  thresholds_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ThresholdInformation::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ThresholdInformation*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.ValueType observed_value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ValueType::_InternalParse;
+        object = msg->mutable_observed_value();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Thresholds thresholds = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Thresholds::_InternalParse;
+        object = msg->mutable_thresholds();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ThresholdInformation::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ThresholdInformation)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.ValueType observed_value = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_observed_value()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Thresholds thresholds = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_thresholds()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ThresholdInformation)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ThresholdInformation)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ThresholdInformation::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ThresholdInformation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ValueType observed_value = 1;
+  if (this->has_observed_value()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::observed_value(this), output);
+  }
+
+  // .dmi.Thresholds thresholds = 2;
+  if (this->has_thresholds()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::thresholds(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ThresholdInformation)
+}
+
+::google::protobuf::uint8* ThresholdInformation::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ThresholdInformation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ValueType observed_value = 1;
+  if (this->has_observed_value()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::observed_value(this), target);
+  }
+
+  // .dmi.Thresholds thresholds = 2;
+  if (this->has_thresholds()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::thresholds(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ThresholdInformation)
+  return target;
+}
+
+size_t ThresholdInformation::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ThresholdInformation)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.ValueType observed_value = 1;
+  if (this->has_observed_value()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *observed_value_);
+  }
+
+  // .dmi.Thresholds thresholds = 2;
+  if (this->has_thresholds()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *thresholds_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ThresholdInformation::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ThresholdInformation)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ThresholdInformation* source =
+      ::google::protobuf::DynamicCastToGenerated<ThresholdInformation>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ThresholdInformation)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ThresholdInformation)
+    MergeFrom(*source);
+  }
+}
+
+void ThresholdInformation::MergeFrom(const ThresholdInformation& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ThresholdInformation)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_observed_value()) {
+    mutable_observed_value()->::dmi::ValueType::MergeFrom(from.observed_value());
+  }
+  if (from.has_thresholds()) {
+    mutable_thresholds()->::dmi::Thresholds::MergeFrom(from.thresholds());
+  }
+}
+
+void ThresholdInformation::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ThresholdInformation)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ThresholdInformation::CopyFrom(const ThresholdInformation& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ThresholdInformation)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ThresholdInformation::IsInitialized() const {
+  return true;
+}
+
+void ThresholdInformation::Swap(ThresholdInformation* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ThresholdInformation::InternalSwap(ThresholdInformation* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(observed_value_, other->observed_value_);
+  swap(thresholds_, other->thresholds_);
+}
+
+::google::protobuf::Metadata ThresholdInformation::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void EventCfg::InitAsDefaultInstance() {
+  ::dmi::_EventCfg_default_instance_._instance.get_mutable()->thresholds_ = const_cast< ::dmi::Thresholds*>(
+      ::dmi::Thresholds::internal_default_instance());
+}
+class EventCfg::HasBitSetters {
+ public:
+  static const ::dmi::Thresholds& thresholds(const EventCfg* msg);
+};
+
+const ::dmi::Thresholds&
+EventCfg::HasBitSetters::thresholds(const EventCfg* msg) {
+  return *msg->thresholds_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int EventCfg::kEventIdFieldNumber;
+const int EventCfg::kIsConfiguredFieldNumber;
+const int EventCfg::kThresholdsFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+EventCfg::EventCfg()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.EventCfg)
+}
+EventCfg::EventCfg(const EventCfg& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_thresholds()) {
+    thresholds_ = new ::dmi::Thresholds(*from.thresholds_);
+  } else {
+    thresholds_ = nullptr;
+  }
+  ::memcpy(&event_id_, &from.event_id_,
+    static_cast<size_t>(reinterpret_cast<char*>(&is_configured_) -
+    reinterpret_cast<char*>(&event_id_)) + sizeof(is_configured_));
+  // @@protoc_insertion_point(copy_constructor:dmi.EventCfg)
+}
+
+void EventCfg::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::memset(&thresholds_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&is_configured_) -
+      reinterpret_cast<char*>(&thresholds_)) + sizeof(is_configured_));
+}
+
+EventCfg::~EventCfg() {
+  // @@protoc_insertion_point(destructor:dmi.EventCfg)
+  SharedDtor();
+}
+
+void EventCfg::SharedDtor() {
+  if (this != internal_default_instance()) delete thresholds_;
+}
+
+void EventCfg::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const EventCfg& EventCfg::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void EventCfg::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.EventCfg)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && thresholds_ != nullptr) {
+    delete thresholds_;
+  }
+  thresholds_ = nullptr;
+  ::memset(&event_id_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&is_configured_) -
+      reinterpret_cast<char*>(&event_id_)) + sizeof(is_configured_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EventCfg::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EventCfg*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.EventIds event_id = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_event_id(static_cast<::dmi::EventIds>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // bool is_configured = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        msg->set_is_configured(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.Thresholds thresholds = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Thresholds::_InternalParse;
+        object = msg->mutable_thresholds();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool EventCfg::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.EventCfg)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.EventIds event_id = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_event_id(static_cast< ::dmi::EventIds >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // bool is_configured = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &is_configured_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Thresholds thresholds = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_thresholds()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.EventCfg)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.EventCfg)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void EventCfg::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.EventCfg)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.EventIds event_id = 1;
+  if (this->event_id() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->event_id(), output);
+  }
+
+  // bool is_configured = 2;
+  if (this->is_configured() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_configured(), output);
+  }
+
+  // .dmi.Thresholds thresholds = 3;
+  if (this->has_thresholds()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::thresholds(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.EventCfg)
+}
+
+::google::protobuf::uint8* EventCfg::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventCfg)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.EventIds event_id = 1;
+  if (this->event_id() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->event_id(), target);
+  }
+
+  // bool is_configured = 2;
+  if (this->is_configured() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_configured(), target);
+  }
+
+  // .dmi.Thresholds thresholds = 3;
+  if (this->has_thresholds()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::thresholds(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventCfg)
+  return target;
+}
+
+size_t EventCfg::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.EventCfg)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.Thresholds thresholds = 3;
+  if (this->has_thresholds()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *thresholds_);
+  }
+
+  // .dmi.EventIds event_id = 1;
+  if (this->event_id() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->event_id());
+  }
+
+  // bool is_configured = 2;
+  if (this->is_configured() != 0) {
+    total_size += 1 + 1;
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void EventCfg::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventCfg)
+  GOOGLE_DCHECK_NE(&from, this);
+  const EventCfg* source =
+      ::google::protobuf::DynamicCastToGenerated<EventCfg>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventCfg)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventCfg)
+    MergeFrom(*source);
+  }
+}
+
+void EventCfg::MergeFrom(const EventCfg& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventCfg)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_thresholds()) {
+    mutable_thresholds()->::dmi::Thresholds::MergeFrom(from.thresholds());
+  }
+  if (from.event_id() != 0) {
+    set_event_id(from.event_id());
+  }
+  if (from.is_configured() != 0) {
+    set_is_configured(from.is_configured());
+  }
+}
+
+void EventCfg::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventCfg)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EventCfg::CopyFrom(const EventCfg& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventCfg)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EventCfg::IsInitialized() const {
+  return true;
+}
+
+void EventCfg::Swap(EventCfg* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void EventCfg::InternalSwap(EventCfg* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(thresholds_, other->thresholds_);
+  swap(event_id_, other->event_id_);
+  swap(is_configured_, other->is_configured_);
+}
+
+::google::protobuf::Metadata EventCfg::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void EventsCfg::InitAsDefaultInstance() {
+}
+class EventsCfg::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int EventsCfg::kItemsFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+EventsCfg::EventsCfg()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.EventsCfg)
+}
+EventsCfg::EventsCfg(const EventsCfg& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      items_(from.items_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  // @@protoc_insertion_point(copy_constructor:dmi.EventsCfg)
+}
+
+void EventsCfg::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+}
+
+EventsCfg::~EventsCfg() {
+  // @@protoc_insertion_point(destructor:dmi.EventsCfg)
+  SharedDtor();
+}
+
+void EventsCfg::SharedDtor() {
+}
+
+void EventsCfg::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const EventsCfg& EventsCfg::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void EventsCfg::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.EventsCfg)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  items_.Clear();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EventsCfg::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EventsCfg*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // repeated .dmi.EventCfg items = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::EventCfg::_InternalParse;
+          object = msg->add_items();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool EventsCfg::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.EventsCfg)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated .dmi.EventCfg items = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_items()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.EventsCfg)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.EventsCfg)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void EventsCfg::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.EventsCfg)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // repeated .dmi.EventCfg items = 1;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->items_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1,
+      this->items(static_cast<int>(i)),
+      output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.EventsCfg)
+}
+
+::google::protobuf::uint8* EventsCfg::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventsCfg)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // repeated .dmi.EventCfg items = 1;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->items_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, this->items(static_cast<int>(i)), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventsCfg)
+  return target;
+}
+
+size_t EventsCfg::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.EventsCfg)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated .dmi.EventCfg items = 1;
+  {
+    unsigned int count = static_cast<unsigned int>(this->items_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->items(static_cast<int>(i)));
+    }
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void EventsCfg::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventsCfg)
+  GOOGLE_DCHECK_NE(&from, this);
+  const EventsCfg* source =
+      ::google::protobuf::DynamicCastToGenerated<EventsCfg>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventsCfg)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventsCfg)
+    MergeFrom(*source);
+  }
+}
+
+void EventsCfg::MergeFrom(const EventsCfg& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventsCfg)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  items_.MergeFrom(from.items_);
+}
+
+void EventsCfg::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventsCfg)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EventsCfg::CopyFrom(const EventsCfg& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventsCfg)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EventsCfg::IsInitialized() const {
+  return true;
+}
+
+void EventsCfg::Swap(EventsCfg* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void EventsCfg::InternalSwap(EventsCfg* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  CastToBase(&items_)->InternalSwap(CastToBase(&other->items_));
+}
+
+::google::protobuf::Metadata EventsCfg::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ListEventsResponse::InitAsDefaultInstance() {
+  ::dmi::_ListEventsResponse_default_instance_._instance.get_mutable()->events_ = const_cast< ::dmi::EventsCfg*>(
+      ::dmi::EventsCfg::internal_default_instance());
+}
+class ListEventsResponse::HasBitSetters {
+ public:
+  static const ::dmi::EventsCfg& events(const ListEventsResponse* msg);
+};
+
+const ::dmi::EventsCfg&
+ListEventsResponse::HasBitSetters::events(const ListEventsResponse* msg) {
+  return *msg->events_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ListEventsResponse::kStatusFieldNumber;
+const int ListEventsResponse::kReasonFieldNumber;
+const int ListEventsResponse::kEventsFieldNumber;
+const int ListEventsResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ListEventsResponse::ListEventsResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ListEventsResponse)
+}
+ListEventsResponse::ListEventsResponse(const ListEventsResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_events()) {
+    events_ = new ::dmi::EventsCfg(*from.events_);
+  } else {
+    events_ = nullptr;
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ListEventsResponse)
+}
+
+void ListEventsResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&events_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&events_)) + sizeof(reason_));
+}
+
+ListEventsResponse::~ListEventsResponse() {
+  // @@protoc_insertion_point(destructor:dmi.ListEventsResponse)
+  SharedDtor();
+}
+
+void ListEventsResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete events_;
+}
+
+void ListEventsResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ListEventsResponse& ListEventsResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ListEventsResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ListEventsResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ListEventsResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && events_ != nullptr) {
+    delete events_;
+  }
+  events_ = nullptr;
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ListEventsResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ListEventsResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ListEventsResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::ListEventsResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.EventsCfg events = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::EventsCfg::_InternalParse;
+        object = msg->mutable_events();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ListEventsResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ListEventsResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ListEventsResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ListEventsResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::ListEventsResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.EventsCfg events = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_events()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ListEventsResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ListEventsResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ListEventsResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ListEventsResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ListEventsResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.ListEventsResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // .dmi.EventsCfg events = 3;
+  if (this->has_events()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::events(this), output);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ListEventsResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ListEventsResponse)
+}
+
+::google::protobuf::uint8* ListEventsResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ListEventsResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.ListEventsResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // .dmi.EventsCfg events = 3;
+  if (this->has_events()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::events(this), target);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ListEventsResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ListEventsResponse)
+  return target;
+}
+
+size_t ListEventsResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ListEventsResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.EventsCfg events = 3;
+  if (this->has_events()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *events_);
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.ListEventsResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ListEventsResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ListEventsResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ListEventsResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<ListEventsResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ListEventsResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ListEventsResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ListEventsResponse::MergeFrom(const ListEventsResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ListEventsResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_events()) {
+    mutable_events()->::dmi::EventsCfg::MergeFrom(from.events());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void ListEventsResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ListEventsResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ListEventsResponse::CopyFrom(const ListEventsResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ListEventsResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ListEventsResponse::IsInitialized() const {
+  return true;
+}
+
+void ListEventsResponse::Swap(ListEventsResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ListEventsResponse::InternalSwap(ListEventsResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(events_, other->events_);
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata ListEventsResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void EventsConfigurationRequest::InitAsDefaultInstance() {
+  ::dmi::_EventsConfigurationRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_EventsConfigurationRequest_default_instance_.changes_ = const_cast< ::dmi::EventsCfg*>(
+      ::dmi::EventsCfg::internal_default_instance());
+  ::dmi::_EventsConfigurationRequest_default_instance_.reset_to_default_ = false;
+}
+class EventsConfigurationRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const EventsConfigurationRequest* msg);
+  static const ::dmi::EventsCfg& changes(const EventsConfigurationRequest* msg);
+};
+
+const ::dmi::Uuid&
+EventsConfigurationRequest::HasBitSetters::device_uuid(const EventsConfigurationRequest* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::EventsCfg&
+EventsConfigurationRequest::HasBitSetters::changes(const EventsConfigurationRequest* msg) {
+  return *msg->operation_.changes_;
+}
+void EventsConfigurationRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void EventsConfigurationRequest::set_allocated_changes(::dmi::EventsCfg* changes) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_operation();
+  if (changes) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      changes = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, changes, submessage_arena);
+    }
+    set_has_changes();
+    operation_.changes_ = changes;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.EventsConfigurationRequest.changes)
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int EventsConfigurationRequest::kDeviceUuidFieldNumber;
+const int EventsConfigurationRequest::kChangesFieldNumber;
+const int EventsConfigurationRequest::kResetToDefaultFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+EventsConfigurationRequest::EventsConfigurationRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.EventsConfigurationRequest)
+}
+EventsConfigurationRequest::EventsConfigurationRequest(const EventsConfigurationRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  clear_has_operation();
+  switch (from.operation_case()) {
+    case kChanges: {
+      mutable_changes()->::dmi::EventsCfg::MergeFrom(from.changes());
+      break;
+    }
+    case kResetToDefault: {
+      set_reset_to_default(from.reset_to_default());
+      break;
+    }
+    case OPERATION_NOT_SET: {
+      break;
+    }
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.EventsConfigurationRequest)
+}
+
+void EventsConfigurationRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  device_uuid_ = nullptr;
+  clear_has_operation();
+}
+
+EventsConfigurationRequest::~EventsConfigurationRequest() {
+  // @@protoc_insertion_point(destructor:dmi.EventsConfigurationRequest)
+  SharedDtor();
+}
+
+void EventsConfigurationRequest::SharedDtor() {
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (has_operation()) {
+    clear_operation();
+  }
+}
+
+void EventsConfigurationRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const EventsConfigurationRequest& EventsConfigurationRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_EventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void EventsConfigurationRequest::clear_operation() {
+// @@protoc_insertion_point(one_of_clear_start:dmi.EventsConfigurationRequest)
+  switch (operation_case()) {
+    case kChanges: {
+      delete operation_.changes_;
+      break;
+    }
+    case kResetToDefault: {
+      // No need to clear
+      break;
+    }
+    case OPERATION_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = OPERATION_NOT_SET;
+}
+
+
+void EventsConfigurationRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.EventsConfigurationRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  clear_operation();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EventsConfigurationRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EventsConfigurationRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.EventsCfg changes = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::EventsCfg::_InternalParse;
+        object = msg->mutable_changes();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // bool reset_to_default = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        msg->set_reset_to_default(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool EventsConfigurationRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.EventsConfigurationRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.EventsCfg changes = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_changes()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // bool reset_to_default = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          clear_operation();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &operation_.reset_to_default_)));
+          set_has_reset_to_default();
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.EventsConfigurationRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.EventsConfigurationRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void EventsConfigurationRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.EventsConfigurationRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.EventsCfg changes = 2;
+  if (has_changes()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::changes(this), output);
+  }
+
+  // bool reset_to_default = 3;
+  if (has_reset_to_default()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->reset_to_default(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.EventsConfigurationRequest)
+}
+
+::google::protobuf::uint8* EventsConfigurationRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventsConfigurationRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.EventsCfg changes = 2;
+  if (has_changes()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::changes(this), target);
+  }
+
+  // bool reset_to_default = 3;
+  if (has_reset_to_default()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->reset_to_default(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventsConfigurationRequest)
+  return target;
+}
+
+size_t EventsConfigurationRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.EventsConfigurationRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  switch (operation_case()) {
+    // .dmi.EventsCfg changes = 2;
+    case kChanges: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *operation_.changes_);
+      break;
+    }
+    // bool reset_to_default = 3;
+    case kResetToDefault: {
+      total_size += 1 + 1;
+      break;
+    }
+    case OPERATION_NOT_SET: {
+      break;
+    }
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void EventsConfigurationRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventsConfigurationRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const EventsConfigurationRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<EventsConfigurationRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventsConfigurationRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventsConfigurationRequest)
+    MergeFrom(*source);
+  }
+}
+
+void EventsConfigurationRequest::MergeFrom(const EventsConfigurationRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventsConfigurationRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  switch (from.operation_case()) {
+    case kChanges: {
+      mutable_changes()->::dmi::EventsCfg::MergeFrom(from.changes());
+      break;
+    }
+    case kResetToDefault: {
+      set_reset_to_default(from.reset_to_default());
+      break;
+    }
+    case OPERATION_NOT_SET: {
+      break;
+    }
+  }
+}
+
+void EventsConfigurationRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventsConfigurationRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EventsConfigurationRequest::CopyFrom(const EventsConfigurationRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventsConfigurationRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EventsConfigurationRequest::IsInitialized() const {
+  return true;
+}
+
+void EventsConfigurationRequest::Swap(EventsConfigurationRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void EventsConfigurationRequest::InternalSwap(EventsConfigurationRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(device_uuid_, other->device_uuid_);
+  swap(operation_, other->operation_);
+  swap(_oneof_case_[0], other->_oneof_case_[0]);
+}
+
+::google::protobuf::Metadata EventsConfigurationRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void EventsConfigurationResponse::InitAsDefaultInstance() {
+}
+class EventsConfigurationResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int EventsConfigurationResponse::kStatusFieldNumber;
+const int EventsConfigurationResponse::kReasonFieldNumber;
+const int EventsConfigurationResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+EventsConfigurationResponse::EventsConfigurationResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.EventsConfigurationResponse)
+}
+EventsConfigurationResponse::EventsConfigurationResponse(const EventsConfigurationResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.EventsConfigurationResponse)
+}
+
+void EventsConfigurationResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+EventsConfigurationResponse::~EventsConfigurationResponse() {
+  // @@protoc_insertion_point(destructor:dmi.EventsConfigurationResponse)
+  SharedDtor();
+}
+
+void EventsConfigurationResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void EventsConfigurationResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const EventsConfigurationResponse& EventsConfigurationResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_EventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void EventsConfigurationResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.EventsConfigurationResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EventsConfigurationResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EventsConfigurationResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.EventsConfigurationResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::EventsConfigurationResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.EventsConfigurationResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool EventsConfigurationResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.EventsConfigurationResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.EventsConfigurationResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::EventsConfigurationResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.EventsConfigurationResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.EventsConfigurationResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.EventsConfigurationResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void EventsConfigurationResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.EventsConfigurationResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.EventsConfigurationResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EventsConfigurationResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.EventsConfigurationResponse)
+}
+
+::google::protobuf::uint8* EventsConfigurationResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventsConfigurationResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.EventsConfigurationResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EventsConfigurationResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventsConfigurationResponse)
+  return target;
+}
+
+size_t EventsConfigurationResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.EventsConfigurationResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.EventsConfigurationResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void EventsConfigurationResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventsConfigurationResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const EventsConfigurationResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<EventsConfigurationResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventsConfigurationResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventsConfigurationResponse)
+    MergeFrom(*source);
+  }
+}
+
+void EventsConfigurationResponse::MergeFrom(const EventsConfigurationResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventsConfigurationResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void EventsConfigurationResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventsConfigurationResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EventsConfigurationResponse::CopyFrom(const EventsConfigurationResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventsConfigurationResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EventsConfigurationResponse::IsInitialized() const {
+  return true;
+}
+
+void EventsConfigurationResponse::Swap(EventsConfigurationResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void EventsConfigurationResponse::InternalSwap(EventsConfigurationResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata EventsConfigurationResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void EventMetaData::InitAsDefaultInstance() {
+  ::dmi::_EventMetaData_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_EventMetaData_default_instance_._instance.get_mutable()->component_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class EventMetaData::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const EventMetaData* msg);
+  static const ::dmi::Uuid& component_uuid(const EventMetaData* msg);
+};
+
+const ::dmi::Uuid&
+EventMetaData::HasBitSetters::device_uuid(const EventMetaData* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::Uuid&
+EventMetaData::HasBitSetters::component_uuid(const EventMetaData* msg) {
+  return *msg->component_uuid_;
+}
+void EventMetaData::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void EventMetaData::clear_component_uuid() {
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int EventMetaData::kDeviceUuidFieldNumber;
+const int EventMetaData::kComponentUuidFieldNumber;
+const int EventMetaData::kComponentNameFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+EventMetaData::EventMetaData()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.EventMetaData)
+}
+EventMetaData::EventMetaData(const EventMetaData& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.component_name().size() > 0) {
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  if (from.has_component_uuid()) {
+    component_uuid_ = new ::dmi::Uuid(*from.component_uuid_);
+  } else {
+    component_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.EventMetaData)
+}
+
+void EventMetaData::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&component_uuid_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(component_uuid_));
+}
+
+EventMetaData::~EventMetaData() {
+  // @@protoc_insertion_point(destructor:dmi.EventMetaData)
+  SharedDtor();
+}
+
+void EventMetaData::SharedDtor() {
+  component_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (this != internal_default_instance()) delete component_uuid_;
+}
+
+void EventMetaData::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const EventMetaData& EventMetaData::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void EventMetaData::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.EventMetaData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EventMetaData::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EventMetaData*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_component_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string component_name = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.EventMetaData.component_name");
+        object = msg->mutable_component_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool EventMetaData::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.EventMetaData)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_component_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string component_name = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_component_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->component_name().data(), static_cast<int>(this->component_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.EventMetaData.component_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.EventMetaData)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.EventMetaData)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void EventMetaData::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.EventMetaData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::component_uuid(this), output);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EventMetaData.component_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->component_name(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.EventMetaData)
+}
+
+::google::protobuf::uint8* EventMetaData::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.EventMetaData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::component_uuid(this), target);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EventMetaData.component_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->component_name(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.EventMetaData)
+  return target;
+}
+
+size_t EventMetaData::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.EventMetaData)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->component_name());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *component_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void EventMetaData::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.EventMetaData)
+  GOOGLE_DCHECK_NE(&from, this);
+  const EventMetaData* source =
+      ::google::protobuf::DynamicCastToGenerated<EventMetaData>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EventMetaData)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EventMetaData)
+    MergeFrom(*source);
+  }
+}
+
+void EventMetaData::MergeFrom(const EventMetaData& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EventMetaData)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.component_name().size() > 0) {
+
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.has_component_uuid()) {
+    mutable_component_uuid()->::dmi::Uuid::MergeFrom(from.component_uuid());
+  }
+}
+
+void EventMetaData::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.EventMetaData)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EventMetaData::CopyFrom(const EventMetaData& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EventMetaData)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EventMetaData::IsInitialized() const {
+  return true;
+}
+
+void EventMetaData::Swap(EventMetaData* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void EventMetaData::InternalSwap(EventMetaData* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  component_name_.Swap(&other->component_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(component_uuid_, other->component_uuid_);
+}
+
+::google::protobuf::Metadata EventMetaData::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void Event::InitAsDefaultInstance() {
+  ::dmi::_Event_default_instance_._instance.get_mutable()->event_metadata_ = const_cast< ::dmi::EventMetaData*>(
+      ::dmi::EventMetaData::internal_default_instance());
+  ::dmi::_Event_default_instance_._instance.get_mutable()->raised_ts_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+  ::dmi::_Event_default_instance_._instance.get_mutable()->threshold_info_ = const_cast< ::dmi::ThresholdInformation*>(
+      ::dmi::ThresholdInformation::internal_default_instance());
+}
+class Event::HasBitSetters {
+ public:
+  static const ::dmi::EventMetaData& event_metadata(const Event* msg);
+  static const ::google::protobuf::Timestamp& raised_ts(const Event* msg);
+  static const ::dmi::ThresholdInformation& threshold_info(const Event* msg);
+};
+
+const ::dmi::EventMetaData&
+Event::HasBitSetters::event_metadata(const Event* msg) {
+  return *msg->event_metadata_;
+}
+const ::google::protobuf::Timestamp&
+Event::HasBitSetters::raised_ts(const Event* msg) {
+  return *msg->raised_ts_;
+}
+const ::dmi::ThresholdInformation&
+Event::HasBitSetters::threshold_info(const Event* msg) {
+  return *msg->threshold_info_;
+}
+void Event::clear_raised_ts() {
+  if (GetArenaNoVirtual() == nullptr && raised_ts_ != nullptr) {
+    delete raised_ts_;
+  }
+  raised_ts_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Event::kEventMetadataFieldNumber;
+const int Event::kEventIdFieldNumber;
+const int Event::kRaisedTsFieldNumber;
+const int Event::kThresholdInfoFieldNumber;
+const int Event::kAddInfoFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Event::Event()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Event)
+}
+Event::Event(const Event& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  add_info_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.add_info().size() > 0) {
+    add_info_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.add_info_);
+  }
+  if (from.has_event_metadata()) {
+    event_metadata_ = new ::dmi::EventMetaData(*from.event_metadata_);
+  } else {
+    event_metadata_ = nullptr;
+  }
+  if (from.has_raised_ts()) {
+    raised_ts_ = new ::google::protobuf::Timestamp(*from.raised_ts_);
+  } else {
+    raised_ts_ = nullptr;
+  }
+  if (from.has_threshold_info()) {
+    threshold_info_ = new ::dmi::ThresholdInformation(*from.threshold_info_);
+  } else {
+    threshold_info_ = nullptr;
+  }
+  event_id_ = from.event_id_;
+  // @@protoc_insertion_point(copy_constructor:dmi.Event)
+}
+
+void Event::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  add_info_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&event_metadata_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&event_id_) -
+      reinterpret_cast<char*>(&event_metadata_)) + sizeof(event_id_));
+}
+
+Event::~Event() {
+  // @@protoc_insertion_point(destructor:dmi.Event)
+  SharedDtor();
+}
+
+void Event::SharedDtor() {
+  add_info_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete event_metadata_;
+  if (this != internal_default_instance()) delete raised_ts_;
+  if (this != internal_default_instance()) delete threshold_info_;
+}
+
+void Event::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Event& Event::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Event::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Event)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  add_info_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && event_metadata_ != nullptr) {
+    delete event_metadata_;
+  }
+  event_metadata_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && raised_ts_ != nullptr) {
+    delete raised_ts_;
+  }
+  raised_ts_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && threshold_info_ != nullptr) {
+    delete threshold_info_;
+  }
+  threshold_info_ = nullptr;
+  event_id_ = 0;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Event::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Event*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.EventMetaData event_metadata = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::EventMetaData::_InternalParse;
+        object = msg->mutable_event_metadata();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.EventIds event_id = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_event_id(static_cast<::dmi::EventIds>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .google.protobuf.Timestamp raised_ts = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_raised_ts();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ThresholdInformation threshold_info = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ThresholdInformation::_InternalParse;
+        object = msg->mutable_threshold_info();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string add_info = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Event.add_info");
+        object = msg->mutable_add_info();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Event::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Event)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.EventMetaData event_metadata = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_event_metadata()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.EventIds event_id = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_event_id(static_cast< ::dmi::EventIds >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .google.protobuf.Timestamp raised_ts = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_raised_ts()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ThresholdInformation threshold_info = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_threshold_info()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string add_info = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_add_info()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->add_info().data(), static_cast<int>(this->add_info().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Event.add_info"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Event)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Event)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Event::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Event)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.EventMetaData event_metadata = 1;
+  if (this->has_event_metadata()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::event_metadata(this), output);
+  }
+
+  // .dmi.EventIds event_id = 2;
+  if (this->event_id() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->event_id(), output);
+  }
+
+  // .google.protobuf.Timestamp raised_ts = 3;
+  if (this->has_raised_ts()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::raised_ts(this), output);
+  }
+
+  // .dmi.ThresholdInformation threshold_info = 4;
+  if (this->has_threshold_info()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      4, HasBitSetters::threshold_info(this), output);
+  }
+
+  // string add_info = 5;
+  if (this->add_info().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->add_info().data(), static_cast<int>(this->add_info().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Event.add_info");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      5, this->add_info(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Event)
+}
+
+::google::protobuf::uint8* Event::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Event)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.EventMetaData event_metadata = 1;
+  if (this->has_event_metadata()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::event_metadata(this), target);
+  }
+
+  // .dmi.EventIds event_id = 2;
+  if (this->event_id() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->event_id(), target);
+  }
+
+  // .google.protobuf.Timestamp raised_ts = 3;
+  if (this->has_raised_ts()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::raised_ts(this), target);
+  }
+
+  // .dmi.ThresholdInformation threshold_info = 4;
+  if (this->has_threshold_info()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        4, HasBitSetters::threshold_info(this), target);
+  }
+
+  // string add_info = 5;
+  if (this->add_info().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->add_info().data(), static_cast<int>(this->add_info().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Event.add_info");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        5, this->add_info(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Event)
+  return target;
+}
+
+size_t Event::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Event)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string add_info = 5;
+  if (this->add_info().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->add_info());
+  }
+
+  // .dmi.EventMetaData event_metadata = 1;
+  if (this->has_event_metadata()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *event_metadata_);
+  }
+
+  // .google.protobuf.Timestamp raised_ts = 3;
+  if (this->has_raised_ts()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *raised_ts_);
+  }
+
+  // .dmi.ThresholdInformation threshold_info = 4;
+  if (this->has_threshold_info()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *threshold_info_);
+  }
+
+  // .dmi.EventIds event_id = 2;
+  if (this->event_id() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->event_id());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Event::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Event)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Event* source =
+      ::google::protobuf::DynamicCastToGenerated<Event>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Event)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Event)
+    MergeFrom(*source);
+  }
+}
+
+void Event::MergeFrom(const Event& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Event)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.add_info().size() > 0) {
+
+    add_info_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.add_info_);
+  }
+  if (from.has_event_metadata()) {
+    mutable_event_metadata()->::dmi::EventMetaData::MergeFrom(from.event_metadata());
+  }
+  if (from.has_raised_ts()) {
+    mutable_raised_ts()->::google::protobuf::Timestamp::MergeFrom(from.raised_ts());
+  }
+  if (from.has_threshold_info()) {
+    mutable_threshold_info()->::dmi::ThresholdInformation::MergeFrom(from.threshold_info());
+  }
+  if (from.event_id() != 0) {
+    set_event_id(from.event_id());
+  }
+}
+
+void Event::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Event)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Event::CopyFrom(const Event& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Event)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Event::IsInitialized() const {
+  return true;
+}
+
+void Event::Swap(Event* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Event::InternalSwap(Event* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  add_info_.Swap(&other->add_info_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(event_metadata_, other->event_metadata_);
+  swap(raised_ts_, other->raised_ts_);
+  swap(threshold_info_, other->threshold_info_);
+  swap(event_id_, other->event_id_);
+}
+
+::google::protobuf::Metadata Event::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> PROTOBUF_NOINLINE ::dmi::ValueType* Arena::CreateMaybeMessage< ::dmi::ValueType >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ValueType >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::WaterMarks* Arena::CreateMaybeMessage< ::dmi::WaterMarks >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::WaterMarks >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::Thresholds* Arena::CreateMaybeMessage< ::dmi::Thresholds >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Thresholds >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ThresholdInformation* Arena::CreateMaybeMessage< ::dmi::ThresholdInformation >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ThresholdInformation >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::EventCfg* Arena::CreateMaybeMessage< ::dmi::EventCfg >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::EventCfg >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::EventsCfg* Arena::CreateMaybeMessage< ::dmi::EventsCfg >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::EventsCfg >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ListEventsResponse* Arena::CreateMaybeMessage< ::dmi::ListEventsResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ListEventsResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::EventsConfigurationRequest* Arena::CreateMaybeMessage< ::dmi::EventsConfigurationRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::EventsConfigurationRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::EventsConfigurationResponse* Arena::CreateMaybeMessage< ::dmi::EventsConfigurationResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::EventsConfigurationResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::EventMetaData* Arena::CreateMaybeMessage< ::dmi::EventMetaData >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::EventMetaData >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::Event* Arena::CreateMaybeMessage< ::dmi::Event >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Event >(arena);
+}
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+#include <google/protobuf/port_undef.inc>
diff --git a/cpp/dmi/hw_events_mgmt_service.pb.h b/cpp/dmi/hw_events_mgmt_service.pb.h
new file mode 100644
index 0000000..472a6a9
--- /dev/null
+++ b/cpp/dmi/hw_events_mgmt_service.pb.h
@@ -0,0 +1,3099 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/hw_events_mgmt_service.proto
+
+#ifndef PROTOBUF_INCLUDED_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto
+#define PROTOBUF_INCLUDED_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto
+
+#include <limits>
+#include <string>
+
+#include <google/protobuf/port_def.inc>
+#if PROTOBUF_VERSION < 3007000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3007000 < PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/port_undef.inc>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/inlined_string_field.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
+#include <google/protobuf/extension_set.h>  // IWYU pragma: export
+#include <google/protobuf/generated_enum_reflection.h>
+#include <google/protobuf/unknown_field_set.h>
+#include "dmi/commons.pb.h"
+#include "dmi/hw.pb.h"
+#include <google/protobuf/timestamp.pb.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto
+
+// Internal implementation detail -- do not use these members.
+struct TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[11]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+  static const ::google::protobuf::internal::SerializationTable serialization_table[];
+  static const ::google::protobuf::uint32 offsets[];
+};
+void AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto();
+namespace dmi {
+class Event;
+class EventDefaultTypeInternal;
+extern EventDefaultTypeInternal _Event_default_instance_;
+class EventCfg;
+class EventCfgDefaultTypeInternal;
+extern EventCfgDefaultTypeInternal _EventCfg_default_instance_;
+class EventMetaData;
+class EventMetaDataDefaultTypeInternal;
+extern EventMetaDataDefaultTypeInternal _EventMetaData_default_instance_;
+class EventsCfg;
+class EventsCfgDefaultTypeInternal;
+extern EventsCfgDefaultTypeInternal _EventsCfg_default_instance_;
+class EventsConfigurationRequest;
+class EventsConfigurationRequestDefaultTypeInternal;
+extern EventsConfigurationRequestDefaultTypeInternal _EventsConfigurationRequest_default_instance_;
+class EventsConfigurationResponse;
+class EventsConfigurationResponseDefaultTypeInternal;
+extern EventsConfigurationResponseDefaultTypeInternal _EventsConfigurationResponse_default_instance_;
+class ListEventsResponse;
+class ListEventsResponseDefaultTypeInternal;
+extern ListEventsResponseDefaultTypeInternal _ListEventsResponse_default_instance_;
+class ThresholdInformation;
+class ThresholdInformationDefaultTypeInternal;
+extern ThresholdInformationDefaultTypeInternal _ThresholdInformation_default_instance_;
+class Thresholds;
+class ThresholdsDefaultTypeInternal;
+extern ThresholdsDefaultTypeInternal _Thresholds_default_instance_;
+class ValueType;
+class ValueTypeDefaultTypeInternal;
+extern ValueTypeDefaultTypeInternal _ValueType_default_instance_;
+class WaterMarks;
+class WaterMarksDefaultTypeInternal;
+extern WaterMarksDefaultTypeInternal _WaterMarks_default_instance_;
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> ::dmi::Event* Arena::CreateMaybeMessage<::dmi::Event>(Arena*);
+template<> ::dmi::EventCfg* Arena::CreateMaybeMessage<::dmi::EventCfg>(Arena*);
+template<> ::dmi::EventMetaData* Arena::CreateMaybeMessage<::dmi::EventMetaData>(Arena*);
+template<> ::dmi::EventsCfg* Arena::CreateMaybeMessage<::dmi::EventsCfg>(Arena*);
+template<> ::dmi::EventsConfigurationRequest* Arena::CreateMaybeMessage<::dmi::EventsConfigurationRequest>(Arena*);
+template<> ::dmi::EventsConfigurationResponse* Arena::CreateMaybeMessage<::dmi::EventsConfigurationResponse>(Arena*);
+template<> ::dmi::ListEventsResponse* Arena::CreateMaybeMessage<::dmi::ListEventsResponse>(Arena*);
+template<> ::dmi::ThresholdInformation* Arena::CreateMaybeMessage<::dmi::ThresholdInformation>(Arena*);
+template<> ::dmi::Thresholds* Arena::CreateMaybeMessage<::dmi::Thresholds>(Arena*);
+template<> ::dmi::ValueType* Arena::CreateMaybeMessage<::dmi::ValueType>(Arena*);
+template<> ::dmi::WaterMarks* Arena::CreateMaybeMessage<::dmi::WaterMarks>(Arena*);
+}  // namespace protobuf
+}  // namespace google
+namespace dmi {
+
+enum ListEventsResponse_Reason {
+  ListEventsResponse_Reason_UNDEFINED_REASON = 0,
+  ListEventsResponse_Reason_UNKNOWN_DEVICE = 1,
+  ListEventsResponse_Reason_INTERNAL_ERROR = 2,
+  ListEventsResponse_Reason_DEVICE_UNREACHABLE = 3,
+  ListEventsResponse_Reason_ListEventsResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ListEventsResponse_Reason_ListEventsResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ListEventsResponse_Reason_IsValid(int value);
+const ListEventsResponse_Reason ListEventsResponse_Reason_Reason_MIN = ListEventsResponse_Reason_UNDEFINED_REASON;
+const ListEventsResponse_Reason ListEventsResponse_Reason_Reason_MAX = ListEventsResponse_Reason_DEVICE_UNREACHABLE;
+const int ListEventsResponse_Reason_Reason_ARRAYSIZE = ListEventsResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ListEventsResponse_Reason_descriptor();
+inline const ::std::string& ListEventsResponse_Reason_Name(ListEventsResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ListEventsResponse_Reason_descriptor(), value);
+}
+inline bool ListEventsResponse_Reason_Parse(
+    const ::std::string& name, ListEventsResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ListEventsResponse_Reason>(
+    ListEventsResponse_Reason_descriptor(), name, value);
+}
+enum EventsConfigurationResponse_Reason {
+  EventsConfigurationResponse_Reason_UNDEFINED_REASON = 0,
+  EventsConfigurationResponse_Reason_UNKNOWN_DEVICE = 1,
+  EventsConfigurationResponse_Reason_INTERNAL_ERROR = 2,
+  EventsConfigurationResponse_Reason_INVALID_CONFIG = 3,
+  EventsConfigurationResponse_Reason_DEVICE_UNREACHABLE = 4,
+  EventsConfigurationResponse_Reason_EventsConfigurationResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  EventsConfigurationResponse_Reason_EventsConfigurationResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool EventsConfigurationResponse_Reason_IsValid(int value);
+const EventsConfigurationResponse_Reason EventsConfigurationResponse_Reason_Reason_MIN = EventsConfigurationResponse_Reason_UNDEFINED_REASON;
+const EventsConfigurationResponse_Reason EventsConfigurationResponse_Reason_Reason_MAX = EventsConfigurationResponse_Reason_DEVICE_UNREACHABLE;
+const int EventsConfigurationResponse_Reason_Reason_ARRAYSIZE = EventsConfigurationResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* EventsConfigurationResponse_Reason_descriptor();
+inline const ::std::string& EventsConfigurationResponse_Reason_Name(EventsConfigurationResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    EventsConfigurationResponse_Reason_descriptor(), value);
+}
+inline bool EventsConfigurationResponse_Reason_Parse(
+    const ::std::string& name, EventsConfigurationResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<EventsConfigurationResponse_Reason>(
+    EventsConfigurationResponse_Reason_descriptor(), name, value);
+}
+enum EventIds {
+  EVENT_NAME_UNDEFINED = 0,
+  EVENT_TRANSCEIVER_PLUG_OUT = 100,
+  EVENT_TRANSCEIVER_PLUG_IN = 101,
+  EVENT_TRANSCEIVER_VOLTAGE_ABOVE_THRESHOLD = 102,
+  EVENT_TRANSCEIVER_VOLTAGE_BELOW_THRESHOLD = 103,
+  EVENT_TRANSCEIVER_TEMPERATURE_ABOVE_THRESHOLD = 104,
+  EVENT_TRANSCEIVER_TEMPERATURE_BELOW_THRESHOLD = 105,
+  EVENT_TRANSCEIVER_CURRENT_ABOVE_THRESHOLD = 106,
+  EVENT_TRANSCEIVER_CURRENT_BELOW_THRESHOLD = 107,
+  EVENT_TRANSCEIVER_RX_POWER_ABOVE_THRESHOLD = 108,
+  EVENT_TRANSCEIVER_RX_POWER_BELOW_THRESHOLD = 109,
+  EVENT_TRANSCEIVER_TX_POWER_ABOVE_THRESHOLD = 110,
+  EVENT_TRANSCEIVER_TX_POWER_BELOW_THRESHOLD = 111,
+  EVENT_TRANSCEIVER_FAILURE = 112,
+  EVENT_TRANSCEIVER_VOLTAGE_ABOVE_THRESHOLD_RECOVERED = 113,
+  EVENT_TRANSCEIVER_VOLTAGE_BELOW_THRESHOLD_RECOVERED = 114,
+  EVENT_TRANSCEIVER_TEMPERATURE_ABOVE_THRESHOLD_RECOVERED = 115,
+  EVENT_TRANSCEIVER_TEMPERATURE_BELOW_THRESHOLD_RECOVERED = 116,
+  EVENT_TRANSCEIVER_CURRENT_ABOVE_THRESHOLD_RECOVERED = 117,
+  EVENT_TRANSCEIVER_CURRENT_BELOW_THRESHOLD_RECOVERED = 118,
+  EVENT_TRANSCEIVER_RX_POWER_ABOVE_THRESHOLD_RECOVERED = 119,
+  EVENT_TRANSCEIVER_RX_POWER_BELOW_THRESHOLD_RECOVERED = 120,
+  EVENT_TRANSCEIVER_TX_POWER_ABOVE_THRESHOLD_RECOVERED = 121,
+  EVENT_TRANSCEIVER_TX_POWER_BELOW_THRESHOLD_RECOVERED = 122,
+  EVENT_TRANSCEIVER_FAILURE_RECOVERED = 123,
+  EVENT_PSU_PLUG_OUT = 200,
+  EVENT_PSU_PLUG_IN = 201,
+  EVENT_PSU_FAILURE = 202,
+  EVENT_PSU_FAILURE_RECOVERED = 203,
+  EVENT_FAN_FAILURE = 300,
+  EVENT_FAN_PLUG_OUT = 301,
+  EVENT_FAN_PLUG_IN = 302,
+  EVENT_FAN_FAILURE_RECOVERED = 303,
+  EVENT_CPU_TEMPERATURE_ABOVE_CRITICAL = 400,
+  EVENT_CPU_TEMPERATURE_ABOVE_FATAL = 401,
+  EVENT_CPU_TEMPERATURE_ABOVE_CRITICAL_RECOVERED = 402,
+  EVENT_CPU_TEMPERATURE_ABOVE_FATAL_RECOVERED = 403,
+  EVENT_HW_DEVICE_RESET = 500,
+  EVENT_HW_DEVICE_TEMPERATURE_ABOVE_CRITICAL = 501,
+  EVENT_HW_DEVICE_TEMPERATURE_ABOVE_FATAL = 502,
+  EVENT_HW_DEVICE_TEMPERATURE_ABOVE_CRITICAL_RECOVERED = 503,
+  EVENT_HW_DEVICE_TEMPERATURE_ABOVE_FATAL_RECOVERED = 504,
+  EventIds_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  EventIds_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool EventIds_IsValid(int value);
+const EventIds EventIds_MIN = EVENT_NAME_UNDEFINED;
+const EventIds EventIds_MAX = EVENT_HW_DEVICE_TEMPERATURE_ABOVE_FATAL_RECOVERED;
+const int EventIds_ARRAYSIZE = EventIds_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* EventIds_descriptor();
+inline const ::std::string& EventIds_Name(EventIds value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    EventIds_descriptor(), value);
+}
+inline bool EventIds_Parse(
+    const ::std::string& name, EventIds* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<EventIds>(
+    EventIds_descriptor(), name, value);
+}
+// ===================================================================
+
+class ValueType final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ValueType) */ {
+ public:
+  ValueType();
+  virtual ~ValueType();
+
+  ValueType(const ValueType& from);
+
+  inline ValueType& operator=(const ValueType& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ValueType(ValueType&& from) noexcept
+    : ValueType() {
+    *this = ::std::move(from);
+  }
+
+  inline ValueType& operator=(ValueType&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ValueType& default_instance();
+
+  enum ValCase {
+    kIntVal = 1,
+    kUintVal = 2,
+    kFloatVal = 3,
+    VAL_NOT_SET = 0,
+  };
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ValueType* internal_default_instance() {
+    return reinterpret_cast<const ValueType*>(
+               &_ValueType_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    0;
+
+  void Swap(ValueType* other);
+  friend void swap(ValueType& a, ValueType& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ValueType* New() const final {
+    return CreateMaybeMessage<ValueType>(nullptr);
+  }
+
+  ValueType* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ValueType>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ValueType& from);
+  void MergeFrom(const ValueType& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ValueType* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // int64 int_val = 1;
+  private:
+  bool has_int_val() const;
+  public:
+  void clear_int_val();
+  static const int kIntValFieldNumber = 1;
+  ::google::protobuf::int64 int_val() const;
+  void set_int_val(::google::protobuf::int64 value);
+
+  // uint64 uint_val = 2;
+  private:
+  bool has_uint_val() const;
+  public:
+  void clear_uint_val();
+  static const int kUintValFieldNumber = 2;
+  ::google::protobuf::uint64 uint_val() const;
+  void set_uint_val(::google::protobuf::uint64 value);
+
+  // float float_val = 3;
+  private:
+  bool has_float_val() const;
+  public:
+  void clear_float_val();
+  static const int kFloatValFieldNumber = 3;
+  float float_val() const;
+  void set_float_val(float value);
+
+  void clear_val();
+  ValCase val_case() const;
+  // @@protoc_insertion_point(class_scope:dmi.ValueType)
+ private:
+  class HasBitSetters;
+  void set_has_int_val();
+  void set_has_uint_val();
+  void set_has_float_val();
+
+  inline bool has_val() const;
+  inline void clear_has_val();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  union ValUnion {
+    ValUnion() {}
+    ::google::protobuf::int64 int_val_;
+    ::google::protobuf::uint64 uint_val_;
+    float float_val_;
+  } val_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class WaterMarks final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.WaterMarks) */ {
+ public:
+  WaterMarks();
+  virtual ~WaterMarks();
+
+  WaterMarks(const WaterMarks& from);
+
+  inline WaterMarks& operator=(const WaterMarks& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  WaterMarks(WaterMarks&& from) noexcept
+    : WaterMarks() {
+    *this = ::std::move(from);
+  }
+
+  inline WaterMarks& operator=(WaterMarks&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const WaterMarks& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const WaterMarks* internal_default_instance() {
+    return reinterpret_cast<const WaterMarks*>(
+               &_WaterMarks_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    1;
+
+  void Swap(WaterMarks* other);
+  friend void swap(WaterMarks& a, WaterMarks& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline WaterMarks* New() const final {
+    return CreateMaybeMessage<WaterMarks>(nullptr);
+  }
+
+  WaterMarks* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<WaterMarks>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const WaterMarks& from);
+  void MergeFrom(const WaterMarks& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(WaterMarks* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.ValueType high = 1;
+  bool has_high() const;
+  void clear_high();
+  static const int kHighFieldNumber = 1;
+  const ::dmi::ValueType& high() const;
+  ::dmi::ValueType* release_high();
+  ::dmi::ValueType* mutable_high();
+  void set_allocated_high(::dmi::ValueType* high);
+
+  // .dmi.ValueType low = 2;
+  bool has_low() const;
+  void clear_low();
+  static const int kLowFieldNumber = 2;
+  const ::dmi::ValueType& low() const;
+  ::dmi::ValueType* release_low();
+  ::dmi::ValueType* mutable_low();
+  void set_allocated_low(::dmi::ValueType* low);
+
+  // @@protoc_insertion_point(class_scope:dmi.WaterMarks)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::ValueType* high_;
+  ::dmi::ValueType* low_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Thresholds final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Thresholds) */ {
+ public:
+  Thresholds();
+  virtual ~Thresholds();
+
+  Thresholds(const Thresholds& from);
+
+  inline Thresholds& operator=(const Thresholds& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Thresholds(Thresholds&& from) noexcept
+    : Thresholds() {
+    *this = ::std::move(from);
+  }
+
+  inline Thresholds& operator=(Thresholds&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const Thresholds& default_instance();
+
+  enum ThresholdCase {
+    kUpper = 1,
+    kLower = 2,
+    THRESHOLD_NOT_SET = 0,
+  };
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Thresholds* internal_default_instance() {
+    return reinterpret_cast<const Thresholds*>(
+               &_Thresholds_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    2;
+
+  void Swap(Thresholds* other);
+  friend void swap(Thresholds& a, Thresholds& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Thresholds* New() const final {
+    return CreateMaybeMessage<Thresholds>(nullptr);
+  }
+
+  Thresholds* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Thresholds>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Thresholds& from);
+  void MergeFrom(const Thresholds& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(Thresholds* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.WaterMarks upper = 1;
+  bool has_upper() const;
+  void clear_upper();
+  static const int kUpperFieldNumber = 1;
+  const ::dmi::WaterMarks& upper() const;
+  ::dmi::WaterMarks* release_upper();
+  ::dmi::WaterMarks* mutable_upper();
+  void set_allocated_upper(::dmi::WaterMarks* upper);
+
+  // .dmi.WaterMarks lower = 2;
+  bool has_lower() const;
+  void clear_lower();
+  static const int kLowerFieldNumber = 2;
+  const ::dmi::WaterMarks& lower() const;
+  ::dmi::WaterMarks* release_lower();
+  ::dmi::WaterMarks* mutable_lower();
+  void set_allocated_lower(::dmi::WaterMarks* lower);
+
+  void clear_threshold();
+  ThresholdCase threshold_case() const;
+  // @@protoc_insertion_point(class_scope:dmi.Thresholds)
+ private:
+  class HasBitSetters;
+  void set_has_upper();
+  void set_has_lower();
+
+  inline bool has_threshold() const;
+  inline void clear_has_threshold();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  union ThresholdUnion {
+    ThresholdUnion() {}
+    ::dmi::WaterMarks* upper_;
+    ::dmi::WaterMarks* lower_;
+  } threshold_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ThresholdInformation final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ThresholdInformation) */ {
+ public:
+  ThresholdInformation();
+  virtual ~ThresholdInformation();
+
+  ThresholdInformation(const ThresholdInformation& from);
+
+  inline ThresholdInformation& operator=(const ThresholdInformation& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ThresholdInformation(ThresholdInformation&& from) noexcept
+    : ThresholdInformation() {
+    *this = ::std::move(from);
+  }
+
+  inline ThresholdInformation& operator=(ThresholdInformation&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ThresholdInformation& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ThresholdInformation* internal_default_instance() {
+    return reinterpret_cast<const ThresholdInformation*>(
+               &_ThresholdInformation_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    3;
+
+  void Swap(ThresholdInformation* other);
+  friend void swap(ThresholdInformation& a, ThresholdInformation& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ThresholdInformation* New() const final {
+    return CreateMaybeMessage<ThresholdInformation>(nullptr);
+  }
+
+  ThresholdInformation* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ThresholdInformation>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ThresholdInformation& from);
+  void MergeFrom(const ThresholdInformation& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ThresholdInformation* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.ValueType observed_value = 1;
+  bool has_observed_value() const;
+  void clear_observed_value();
+  static const int kObservedValueFieldNumber = 1;
+  const ::dmi::ValueType& observed_value() const;
+  ::dmi::ValueType* release_observed_value();
+  ::dmi::ValueType* mutable_observed_value();
+  void set_allocated_observed_value(::dmi::ValueType* observed_value);
+
+  // .dmi.Thresholds thresholds = 2;
+  bool has_thresholds() const;
+  void clear_thresholds();
+  static const int kThresholdsFieldNumber = 2;
+  const ::dmi::Thresholds& thresholds() const;
+  ::dmi::Thresholds* release_thresholds();
+  ::dmi::Thresholds* mutable_thresholds();
+  void set_allocated_thresholds(::dmi::Thresholds* thresholds);
+
+  // @@protoc_insertion_point(class_scope:dmi.ThresholdInformation)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::ValueType* observed_value_;
+  ::dmi::Thresholds* thresholds_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class EventCfg final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventCfg) */ {
+ public:
+  EventCfg();
+  virtual ~EventCfg();
+
+  EventCfg(const EventCfg& from);
+
+  inline EventCfg& operator=(const EventCfg& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  EventCfg(EventCfg&& from) noexcept
+    : EventCfg() {
+    *this = ::std::move(from);
+  }
+
+  inline EventCfg& operator=(EventCfg&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const EventCfg& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const EventCfg* internal_default_instance() {
+    return reinterpret_cast<const EventCfg*>(
+               &_EventCfg_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    4;
+
+  void Swap(EventCfg* other);
+  friend void swap(EventCfg& a, EventCfg& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline EventCfg* New() const final {
+    return CreateMaybeMessage<EventCfg>(nullptr);
+  }
+
+  EventCfg* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<EventCfg>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const EventCfg& from);
+  void MergeFrom(const EventCfg& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(EventCfg* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.Thresholds thresholds = 3;
+  bool has_thresholds() const;
+  void clear_thresholds();
+  static const int kThresholdsFieldNumber = 3;
+  const ::dmi::Thresholds& thresholds() const;
+  ::dmi::Thresholds* release_thresholds();
+  ::dmi::Thresholds* mutable_thresholds();
+  void set_allocated_thresholds(::dmi::Thresholds* thresholds);
+
+  // .dmi.EventIds event_id = 1;
+  void clear_event_id();
+  static const int kEventIdFieldNumber = 1;
+  ::dmi::EventIds event_id() const;
+  void set_event_id(::dmi::EventIds value);
+
+  // bool is_configured = 2;
+  void clear_is_configured();
+  static const int kIsConfiguredFieldNumber = 2;
+  bool is_configured() const;
+  void set_is_configured(bool value);
+
+  // @@protoc_insertion_point(class_scope:dmi.EventCfg)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::Thresholds* thresholds_;
+  int event_id_;
+  bool is_configured_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class EventsCfg final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventsCfg) */ {
+ public:
+  EventsCfg();
+  virtual ~EventsCfg();
+
+  EventsCfg(const EventsCfg& from);
+
+  inline EventsCfg& operator=(const EventsCfg& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  EventsCfg(EventsCfg&& from) noexcept
+    : EventsCfg() {
+    *this = ::std::move(from);
+  }
+
+  inline EventsCfg& operator=(EventsCfg&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const EventsCfg& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const EventsCfg* internal_default_instance() {
+    return reinterpret_cast<const EventsCfg*>(
+               &_EventsCfg_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    5;
+
+  void Swap(EventsCfg* other);
+  friend void swap(EventsCfg& a, EventsCfg& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline EventsCfg* New() const final {
+    return CreateMaybeMessage<EventsCfg>(nullptr);
+  }
+
+  EventsCfg* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<EventsCfg>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const EventsCfg& from);
+  void MergeFrom(const EventsCfg& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(EventsCfg* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated .dmi.EventCfg items = 1;
+  int items_size() const;
+  void clear_items();
+  static const int kItemsFieldNumber = 1;
+  ::dmi::EventCfg* mutable_items(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg >*
+      mutable_items();
+  const ::dmi::EventCfg& items(int index) const;
+  ::dmi::EventCfg* add_items();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg >&
+      items() const;
+
+  // @@protoc_insertion_point(class_scope:dmi.EventsCfg)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg > items_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ListEventsResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ListEventsResponse) */ {
+ public:
+  ListEventsResponse();
+  virtual ~ListEventsResponse();
+
+  ListEventsResponse(const ListEventsResponse& from);
+
+  inline ListEventsResponse& operator=(const ListEventsResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ListEventsResponse(ListEventsResponse&& from) noexcept
+    : ListEventsResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline ListEventsResponse& operator=(ListEventsResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ListEventsResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ListEventsResponse* internal_default_instance() {
+    return reinterpret_cast<const ListEventsResponse*>(
+               &_ListEventsResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    6;
+
+  void Swap(ListEventsResponse* other);
+  friend void swap(ListEventsResponse& a, ListEventsResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ListEventsResponse* New() const final {
+    return CreateMaybeMessage<ListEventsResponse>(nullptr);
+  }
+
+  ListEventsResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ListEventsResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ListEventsResponse& from);
+  void MergeFrom(const ListEventsResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ListEventsResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef ListEventsResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    ListEventsResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    ListEventsResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    ListEventsResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    ListEventsResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return ListEventsResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    ListEventsResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    ListEventsResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    ListEventsResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return ListEventsResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return ListEventsResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return ListEventsResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 4;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 4;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.EventsCfg events = 3;
+  bool has_events() const;
+  void clear_events();
+  static const int kEventsFieldNumber = 3;
+  const ::dmi::EventsCfg& events() const;
+  ::dmi::EventsCfg* release_events();
+  ::dmi::EventsCfg* mutable_events();
+  void set_allocated_events(::dmi::EventsCfg* events);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.ListEventsResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::ListEventsResponse_Reason reason() const;
+  void set_reason(::dmi::ListEventsResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ListEventsResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  ::dmi::EventsCfg* events_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class EventsConfigurationRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventsConfigurationRequest) */ {
+ public:
+  EventsConfigurationRequest();
+  virtual ~EventsConfigurationRequest();
+
+  EventsConfigurationRequest(const EventsConfigurationRequest& from);
+
+  inline EventsConfigurationRequest& operator=(const EventsConfigurationRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  EventsConfigurationRequest(EventsConfigurationRequest&& from) noexcept
+    : EventsConfigurationRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline EventsConfigurationRequest& operator=(EventsConfigurationRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const EventsConfigurationRequest& default_instance();
+
+  enum OperationCase {
+    kChanges = 2,
+    kResetToDefault = 3,
+    OPERATION_NOT_SET = 0,
+  };
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const EventsConfigurationRequest* internal_default_instance() {
+    return reinterpret_cast<const EventsConfigurationRequest*>(
+               &_EventsConfigurationRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    7;
+
+  void Swap(EventsConfigurationRequest* other);
+  friend void swap(EventsConfigurationRequest& a, EventsConfigurationRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline EventsConfigurationRequest* New() const final {
+    return CreateMaybeMessage<EventsConfigurationRequest>(nullptr);
+  }
+
+  EventsConfigurationRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<EventsConfigurationRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const EventsConfigurationRequest& from);
+  void MergeFrom(const EventsConfigurationRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(EventsConfigurationRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.EventsCfg changes = 2;
+  bool has_changes() const;
+  void clear_changes();
+  static const int kChangesFieldNumber = 2;
+  const ::dmi::EventsCfg& changes() const;
+  ::dmi::EventsCfg* release_changes();
+  ::dmi::EventsCfg* mutable_changes();
+  void set_allocated_changes(::dmi::EventsCfg* changes);
+
+  // bool reset_to_default = 3;
+  private:
+  bool has_reset_to_default() const;
+  public:
+  void clear_reset_to_default();
+  static const int kResetToDefaultFieldNumber = 3;
+  bool reset_to_default() const;
+  void set_reset_to_default(bool value);
+
+  void clear_operation();
+  OperationCase operation_case() const;
+  // @@protoc_insertion_point(class_scope:dmi.EventsConfigurationRequest)
+ private:
+  class HasBitSetters;
+  void set_has_changes();
+  void set_has_reset_to_default();
+
+  inline bool has_operation() const;
+  inline void clear_has_operation();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::Uuid* device_uuid_;
+  union OperationUnion {
+    OperationUnion() {}
+    ::dmi::EventsCfg* changes_;
+    bool reset_to_default_;
+  } operation_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class EventsConfigurationResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventsConfigurationResponse) */ {
+ public:
+  EventsConfigurationResponse();
+  virtual ~EventsConfigurationResponse();
+
+  EventsConfigurationResponse(const EventsConfigurationResponse& from);
+
+  inline EventsConfigurationResponse& operator=(const EventsConfigurationResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  EventsConfigurationResponse(EventsConfigurationResponse&& from) noexcept
+    : EventsConfigurationResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline EventsConfigurationResponse& operator=(EventsConfigurationResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const EventsConfigurationResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const EventsConfigurationResponse* internal_default_instance() {
+    return reinterpret_cast<const EventsConfigurationResponse*>(
+               &_EventsConfigurationResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    8;
+
+  void Swap(EventsConfigurationResponse* other);
+  friend void swap(EventsConfigurationResponse& a, EventsConfigurationResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline EventsConfigurationResponse* New() const final {
+    return CreateMaybeMessage<EventsConfigurationResponse>(nullptr);
+  }
+
+  EventsConfigurationResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<EventsConfigurationResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const EventsConfigurationResponse& from);
+  void MergeFrom(const EventsConfigurationResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(EventsConfigurationResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef EventsConfigurationResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    EventsConfigurationResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    EventsConfigurationResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    EventsConfigurationResponse_Reason_INTERNAL_ERROR;
+  static const Reason INVALID_CONFIG =
+    EventsConfigurationResponse_Reason_INVALID_CONFIG;
+  static const Reason DEVICE_UNREACHABLE =
+    EventsConfigurationResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return EventsConfigurationResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    EventsConfigurationResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    EventsConfigurationResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    EventsConfigurationResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return EventsConfigurationResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return EventsConfigurationResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return EventsConfigurationResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 3;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 3;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.EventsConfigurationResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::EventsConfigurationResponse_Reason reason() const;
+  void set_reason(::dmi::EventsConfigurationResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.EventsConfigurationResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class EventMetaData final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EventMetaData) */ {
+ public:
+  EventMetaData();
+  virtual ~EventMetaData();
+
+  EventMetaData(const EventMetaData& from);
+
+  inline EventMetaData& operator=(const EventMetaData& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  EventMetaData(EventMetaData&& from) noexcept
+    : EventMetaData() {
+    *this = ::std::move(from);
+  }
+
+  inline EventMetaData& operator=(EventMetaData&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const EventMetaData& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const EventMetaData* internal_default_instance() {
+    return reinterpret_cast<const EventMetaData*>(
+               &_EventMetaData_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    9;
+
+  void Swap(EventMetaData* other);
+  friend void swap(EventMetaData& a, EventMetaData& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline EventMetaData* New() const final {
+    return CreateMaybeMessage<EventMetaData>(nullptr);
+  }
+
+  EventMetaData* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<EventMetaData>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const EventMetaData& from);
+  void MergeFrom(const EventMetaData& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(EventMetaData* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string component_name = 3;
+  void clear_component_name();
+  static const int kComponentNameFieldNumber = 3;
+  const ::std::string& component_name() const;
+  void set_component_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_component_name(::std::string&& value);
+  #endif
+  void set_component_name(const char* value);
+  void set_component_name(const char* value, size_t size);
+  ::std::string* mutable_component_name();
+  ::std::string* release_component_name();
+  void set_allocated_component_name(::std::string* component_name);
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.Uuid component_uuid = 2;
+  bool has_component_uuid() const;
+  void clear_component_uuid();
+  static const int kComponentUuidFieldNumber = 2;
+  const ::dmi::Uuid& component_uuid() const;
+  ::dmi::Uuid* release_component_uuid();
+  ::dmi::Uuid* mutable_component_uuid();
+  void set_allocated_component_uuid(::dmi::Uuid* component_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.EventMetaData)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr component_name_;
+  ::dmi::Uuid* device_uuid_;
+  ::dmi::Uuid* component_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Event final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Event) */ {
+ public:
+  Event();
+  virtual ~Event();
+
+  Event(const Event& from);
+
+  inline Event& operator=(const Event& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Event(Event&& from) noexcept
+    : Event() {
+    *this = ::std::move(from);
+  }
+
+  inline Event& operator=(Event&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const Event& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Event* internal_default_instance() {
+    return reinterpret_cast<const Event*>(
+               &_Event_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    10;
+
+  void Swap(Event* other);
+  friend void swap(Event& a, Event& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Event* New() const final {
+    return CreateMaybeMessage<Event>(nullptr);
+  }
+
+  Event* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Event>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Event& from);
+  void MergeFrom(const Event& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(Event* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string add_info = 5;
+  void clear_add_info();
+  static const int kAddInfoFieldNumber = 5;
+  const ::std::string& add_info() const;
+  void set_add_info(const ::std::string& value);
+  #if LANG_CXX11
+  void set_add_info(::std::string&& value);
+  #endif
+  void set_add_info(const char* value);
+  void set_add_info(const char* value, size_t size);
+  ::std::string* mutable_add_info();
+  ::std::string* release_add_info();
+  void set_allocated_add_info(::std::string* add_info);
+
+  // .dmi.EventMetaData event_metadata = 1;
+  bool has_event_metadata() const;
+  void clear_event_metadata();
+  static const int kEventMetadataFieldNumber = 1;
+  const ::dmi::EventMetaData& event_metadata() const;
+  ::dmi::EventMetaData* release_event_metadata();
+  ::dmi::EventMetaData* mutable_event_metadata();
+  void set_allocated_event_metadata(::dmi::EventMetaData* event_metadata);
+
+  // .google.protobuf.Timestamp raised_ts = 3;
+  bool has_raised_ts() const;
+  void clear_raised_ts();
+  static const int kRaisedTsFieldNumber = 3;
+  const ::google::protobuf::Timestamp& raised_ts() const;
+  ::google::protobuf::Timestamp* release_raised_ts();
+  ::google::protobuf::Timestamp* mutable_raised_ts();
+  void set_allocated_raised_ts(::google::protobuf::Timestamp* raised_ts);
+
+  // .dmi.ThresholdInformation threshold_info = 4;
+  bool has_threshold_info() const;
+  void clear_threshold_info();
+  static const int kThresholdInfoFieldNumber = 4;
+  const ::dmi::ThresholdInformation& threshold_info() const;
+  ::dmi::ThresholdInformation* release_threshold_info();
+  ::dmi::ThresholdInformation* mutable_threshold_info();
+  void set_allocated_threshold_info(::dmi::ThresholdInformation* threshold_info);
+
+  // .dmi.EventIds event_id = 2;
+  void clear_event_id();
+  static const int kEventIdFieldNumber = 2;
+  ::dmi::EventIds event_id() const;
+  void set_event_id(::dmi::EventIds value);
+
+  // @@protoc_insertion_point(class_scope:dmi.Event)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr add_info_;
+  ::dmi::EventMetaData* event_metadata_;
+  ::google::protobuf::Timestamp* raised_ts_;
+  ::dmi::ThresholdInformation* threshold_info_;
+  int event_id_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif  // __GNUC__
+// ValueType
+
+// int64 int_val = 1;
+inline bool ValueType::has_int_val() const {
+  return val_case() == kIntVal;
+}
+inline void ValueType::set_has_int_val() {
+  _oneof_case_[0] = kIntVal;
+}
+inline void ValueType::clear_int_val() {
+  if (has_int_val()) {
+    val_.int_val_ = PROTOBUF_LONGLONG(0);
+    clear_has_val();
+  }
+}
+inline ::google::protobuf::int64 ValueType::int_val() const {
+  // @@protoc_insertion_point(field_get:dmi.ValueType.int_val)
+  if (has_int_val()) {
+    return val_.int_val_;
+  }
+  return PROTOBUF_LONGLONG(0);
+}
+inline void ValueType::set_int_val(::google::protobuf::int64 value) {
+  if (!has_int_val()) {
+    clear_val();
+    set_has_int_val();
+  }
+  val_.int_val_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ValueType.int_val)
+}
+
+// uint64 uint_val = 2;
+inline bool ValueType::has_uint_val() const {
+  return val_case() == kUintVal;
+}
+inline void ValueType::set_has_uint_val() {
+  _oneof_case_[0] = kUintVal;
+}
+inline void ValueType::clear_uint_val() {
+  if (has_uint_val()) {
+    val_.uint_val_ = PROTOBUF_ULONGLONG(0);
+    clear_has_val();
+  }
+}
+inline ::google::protobuf::uint64 ValueType::uint_val() const {
+  // @@protoc_insertion_point(field_get:dmi.ValueType.uint_val)
+  if (has_uint_val()) {
+    return val_.uint_val_;
+  }
+  return PROTOBUF_ULONGLONG(0);
+}
+inline void ValueType::set_uint_val(::google::protobuf::uint64 value) {
+  if (!has_uint_val()) {
+    clear_val();
+    set_has_uint_val();
+  }
+  val_.uint_val_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ValueType.uint_val)
+}
+
+// float float_val = 3;
+inline bool ValueType::has_float_val() const {
+  return val_case() == kFloatVal;
+}
+inline void ValueType::set_has_float_val() {
+  _oneof_case_[0] = kFloatVal;
+}
+inline void ValueType::clear_float_val() {
+  if (has_float_val()) {
+    val_.float_val_ = 0;
+    clear_has_val();
+  }
+}
+inline float ValueType::float_val() const {
+  // @@protoc_insertion_point(field_get:dmi.ValueType.float_val)
+  if (has_float_val()) {
+    return val_.float_val_;
+  }
+  return 0;
+}
+inline void ValueType::set_float_val(float value) {
+  if (!has_float_val()) {
+    clear_val();
+    set_has_float_val();
+  }
+  val_.float_val_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ValueType.float_val)
+}
+
+inline bool ValueType::has_val() const {
+  return val_case() != VAL_NOT_SET;
+}
+inline void ValueType::clear_has_val() {
+  _oneof_case_[0] = VAL_NOT_SET;
+}
+inline ValueType::ValCase ValueType::val_case() const {
+  return ValueType::ValCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// WaterMarks
+
+// .dmi.ValueType high = 1;
+inline bool WaterMarks::has_high() const {
+  return this != internal_default_instance() && high_ != nullptr;
+}
+inline void WaterMarks::clear_high() {
+  if (GetArenaNoVirtual() == nullptr && high_ != nullptr) {
+    delete high_;
+  }
+  high_ = nullptr;
+}
+inline const ::dmi::ValueType& WaterMarks::high() const {
+  const ::dmi::ValueType* p = high_;
+  // @@protoc_insertion_point(field_get:dmi.WaterMarks.high)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ValueType*>(
+      &::dmi::_ValueType_default_instance_);
+}
+inline ::dmi::ValueType* WaterMarks::release_high() {
+  // @@protoc_insertion_point(field_release:dmi.WaterMarks.high)
+  
+  ::dmi::ValueType* temp = high_;
+  high_ = nullptr;
+  return temp;
+}
+inline ::dmi::ValueType* WaterMarks::mutable_high() {
+  
+  if (high_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::ValueType>(GetArenaNoVirtual());
+    high_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.WaterMarks.high)
+  return high_;
+}
+inline void WaterMarks::set_allocated_high(::dmi::ValueType* high) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete high_;
+  }
+  if (high) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      high = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, high, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  high_ = high;
+  // @@protoc_insertion_point(field_set_allocated:dmi.WaterMarks.high)
+}
+
+// .dmi.ValueType low = 2;
+inline bool WaterMarks::has_low() const {
+  return this != internal_default_instance() && low_ != nullptr;
+}
+inline void WaterMarks::clear_low() {
+  if (GetArenaNoVirtual() == nullptr && low_ != nullptr) {
+    delete low_;
+  }
+  low_ = nullptr;
+}
+inline const ::dmi::ValueType& WaterMarks::low() const {
+  const ::dmi::ValueType* p = low_;
+  // @@protoc_insertion_point(field_get:dmi.WaterMarks.low)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ValueType*>(
+      &::dmi::_ValueType_default_instance_);
+}
+inline ::dmi::ValueType* WaterMarks::release_low() {
+  // @@protoc_insertion_point(field_release:dmi.WaterMarks.low)
+  
+  ::dmi::ValueType* temp = low_;
+  low_ = nullptr;
+  return temp;
+}
+inline ::dmi::ValueType* WaterMarks::mutable_low() {
+  
+  if (low_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::ValueType>(GetArenaNoVirtual());
+    low_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.WaterMarks.low)
+  return low_;
+}
+inline void WaterMarks::set_allocated_low(::dmi::ValueType* low) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete low_;
+  }
+  if (low) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      low = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, low, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  low_ = low;
+  // @@protoc_insertion_point(field_set_allocated:dmi.WaterMarks.low)
+}
+
+// -------------------------------------------------------------------
+
+// Thresholds
+
+// .dmi.WaterMarks upper = 1;
+inline bool Thresholds::has_upper() const {
+  return threshold_case() == kUpper;
+}
+inline void Thresholds::set_has_upper() {
+  _oneof_case_[0] = kUpper;
+}
+inline void Thresholds::clear_upper() {
+  if (has_upper()) {
+    delete threshold_.upper_;
+    clear_has_threshold();
+  }
+}
+inline ::dmi::WaterMarks* Thresholds::release_upper() {
+  // @@protoc_insertion_point(field_release:dmi.Thresholds.upper)
+  if (has_upper()) {
+    clear_has_threshold();
+      ::dmi::WaterMarks* temp = threshold_.upper_;
+    threshold_.upper_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::WaterMarks& Thresholds::upper() const {
+  // @@protoc_insertion_point(field_get:dmi.Thresholds.upper)
+  return has_upper()
+      ? *threshold_.upper_
+      : *reinterpret_cast< ::dmi::WaterMarks*>(&::dmi::_WaterMarks_default_instance_);
+}
+inline ::dmi::WaterMarks* Thresholds::mutable_upper() {
+  if (!has_upper()) {
+    clear_threshold();
+    set_has_upper();
+    threshold_.upper_ = CreateMaybeMessage< ::dmi::WaterMarks >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Thresholds.upper)
+  return threshold_.upper_;
+}
+
+// .dmi.WaterMarks lower = 2;
+inline bool Thresholds::has_lower() const {
+  return threshold_case() == kLower;
+}
+inline void Thresholds::set_has_lower() {
+  _oneof_case_[0] = kLower;
+}
+inline void Thresholds::clear_lower() {
+  if (has_lower()) {
+    delete threshold_.lower_;
+    clear_has_threshold();
+  }
+}
+inline ::dmi::WaterMarks* Thresholds::release_lower() {
+  // @@protoc_insertion_point(field_release:dmi.Thresholds.lower)
+  if (has_lower()) {
+    clear_has_threshold();
+      ::dmi::WaterMarks* temp = threshold_.lower_;
+    threshold_.lower_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::WaterMarks& Thresholds::lower() const {
+  // @@protoc_insertion_point(field_get:dmi.Thresholds.lower)
+  return has_lower()
+      ? *threshold_.lower_
+      : *reinterpret_cast< ::dmi::WaterMarks*>(&::dmi::_WaterMarks_default_instance_);
+}
+inline ::dmi::WaterMarks* Thresholds::mutable_lower() {
+  if (!has_lower()) {
+    clear_threshold();
+    set_has_lower();
+    threshold_.lower_ = CreateMaybeMessage< ::dmi::WaterMarks >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Thresholds.lower)
+  return threshold_.lower_;
+}
+
+inline bool Thresholds::has_threshold() const {
+  return threshold_case() != THRESHOLD_NOT_SET;
+}
+inline void Thresholds::clear_has_threshold() {
+  _oneof_case_[0] = THRESHOLD_NOT_SET;
+}
+inline Thresholds::ThresholdCase Thresholds::threshold_case() const {
+  return Thresholds::ThresholdCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// ThresholdInformation
+
+// .dmi.ValueType observed_value = 1;
+inline bool ThresholdInformation::has_observed_value() const {
+  return this != internal_default_instance() && observed_value_ != nullptr;
+}
+inline void ThresholdInformation::clear_observed_value() {
+  if (GetArenaNoVirtual() == nullptr && observed_value_ != nullptr) {
+    delete observed_value_;
+  }
+  observed_value_ = nullptr;
+}
+inline const ::dmi::ValueType& ThresholdInformation::observed_value() const {
+  const ::dmi::ValueType* p = observed_value_;
+  // @@protoc_insertion_point(field_get:dmi.ThresholdInformation.observed_value)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ValueType*>(
+      &::dmi::_ValueType_default_instance_);
+}
+inline ::dmi::ValueType* ThresholdInformation::release_observed_value() {
+  // @@protoc_insertion_point(field_release:dmi.ThresholdInformation.observed_value)
+  
+  ::dmi::ValueType* temp = observed_value_;
+  observed_value_ = nullptr;
+  return temp;
+}
+inline ::dmi::ValueType* ThresholdInformation::mutable_observed_value() {
+  
+  if (observed_value_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::ValueType>(GetArenaNoVirtual());
+    observed_value_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ThresholdInformation.observed_value)
+  return observed_value_;
+}
+inline void ThresholdInformation::set_allocated_observed_value(::dmi::ValueType* observed_value) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete observed_value_;
+  }
+  if (observed_value) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      observed_value = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, observed_value, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  observed_value_ = observed_value;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ThresholdInformation.observed_value)
+}
+
+// .dmi.Thresholds thresholds = 2;
+inline bool ThresholdInformation::has_thresholds() const {
+  return this != internal_default_instance() && thresholds_ != nullptr;
+}
+inline void ThresholdInformation::clear_thresholds() {
+  if (GetArenaNoVirtual() == nullptr && thresholds_ != nullptr) {
+    delete thresholds_;
+  }
+  thresholds_ = nullptr;
+}
+inline const ::dmi::Thresholds& ThresholdInformation::thresholds() const {
+  const ::dmi::Thresholds* p = thresholds_;
+  // @@protoc_insertion_point(field_get:dmi.ThresholdInformation.thresholds)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Thresholds*>(
+      &::dmi::_Thresholds_default_instance_);
+}
+inline ::dmi::Thresholds* ThresholdInformation::release_thresholds() {
+  // @@protoc_insertion_point(field_release:dmi.ThresholdInformation.thresholds)
+  
+  ::dmi::Thresholds* temp = thresholds_;
+  thresholds_ = nullptr;
+  return temp;
+}
+inline ::dmi::Thresholds* ThresholdInformation::mutable_thresholds() {
+  
+  if (thresholds_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Thresholds>(GetArenaNoVirtual());
+    thresholds_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ThresholdInformation.thresholds)
+  return thresholds_;
+}
+inline void ThresholdInformation::set_allocated_thresholds(::dmi::Thresholds* thresholds) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete thresholds_;
+  }
+  if (thresholds) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      thresholds = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, thresholds, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  thresholds_ = thresholds;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ThresholdInformation.thresholds)
+}
+
+// -------------------------------------------------------------------
+
+// EventCfg
+
+// .dmi.EventIds event_id = 1;
+inline void EventCfg::clear_event_id() {
+  event_id_ = 0;
+}
+inline ::dmi::EventIds EventCfg::event_id() const {
+  // @@protoc_insertion_point(field_get:dmi.EventCfg.event_id)
+  return static_cast< ::dmi::EventIds >(event_id_);
+}
+inline void EventCfg::set_event_id(::dmi::EventIds value) {
+  
+  event_id_ = value;
+  // @@protoc_insertion_point(field_set:dmi.EventCfg.event_id)
+}
+
+// bool is_configured = 2;
+inline void EventCfg::clear_is_configured() {
+  is_configured_ = false;
+}
+inline bool EventCfg::is_configured() const {
+  // @@protoc_insertion_point(field_get:dmi.EventCfg.is_configured)
+  return is_configured_;
+}
+inline void EventCfg::set_is_configured(bool value) {
+  
+  is_configured_ = value;
+  // @@protoc_insertion_point(field_set:dmi.EventCfg.is_configured)
+}
+
+// .dmi.Thresholds thresholds = 3;
+inline bool EventCfg::has_thresholds() const {
+  return this != internal_default_instance() && thresholds_ != nullptr;
+}
+inline void EventCfg::clear_thresholds() {
+  if (GetArenaNoVirtual() == nullptr && thresholds_ != nullptr) {
+    delete thresholds_;
+  }
+  thresholds_ = nullptr;
+}
+inline const ::dmi::Thresholds& EventCfg::thresholds() const {
+  const ::dmi::Thresholds* p = thresholds_;
+  // @@protoc_insertion_point(field_get:dmi.EventCfg.thresholds)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Thresholds*>(
+      &::dmi::_Thresholds_default_instance_);
+}
+inline ::dmi::Thresholds* EventCfg::release_thresholds() {
+  // @@protoc_insertion_point(field_release:dmi.EventCfg.thresholds)
+  
+  ::dmi::Thresholds* temp = thresholds_;
+  thresholds_ = nullptr;
+  return temp;
+}
+inline ::dmi::Thresholds* EventCfg::mutable_thresholds() {
+  
+  if (thresholds_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Thresholds>(GetArenaNoVirtual());
+    thresholds_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.EventCfg.thresholds)
+  return thresholds_;
+}
+inline void EventCfg::set_allocated_thresholds(::dmi::Thresholds* thresholds) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete thresholds_;
+  }
+  if (thresholds) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      thresholds = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, thresholds, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  thresholds_ = thresholds;
+  // @@protoc_insertion_point(field_set_allocated:dmi.EventCfg.thresholds)
+}
+
+// -------------------------------------------------------------------
+
+// EventsCfg
+
+// repeated .dmi.EventCfg items = 1;
+inline int EventsCfg::items_size() const {
+  return items_.size();
+}
+inline void EventsCfg::clear_items() {
+  items_.Clear();
+}
+inline ::dmi::EventCfg* EventsCfg::mutable_items(int index) {
+  // @@protoc_insertion_point(field_mutable:dmi.EventsCfg.items)
+  return items_.Mutable(index);
+}
+inline ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg >*
+EventsCfg::mutable_items() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.EventsCfg.items)
+  return &items_;
+}
+inline const ::dmi::EventCfg& EventsCfg::items(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.EventsCfg.items)
+  return items_.Get(index);
+}
+inline ::dmi::EventCfg* EventsCfg::add_items() {
+  // @@protoc_insertion_point(field_add:dmi.EventsCfg.items)
+  return items_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::dmi::EventCfg >&
+EventsCfg::items() const {
+  // @@protoc_insertion_point(field_list:dmi.EventsCfg.items)
+  return items_;
+}
+
+// -------------------------------------------------------------------
+
+// ListEventsResponse
+
+// .dmi.Status status = 1;
+inline void ListEventsResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status ListEventsResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.ListEventsResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void ListEventsResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ListEventsResponse.status)
+}
+
+// .dmi.ListEventsResponse.Reason reason = 2;
+inline void ListEventsResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::ListEventsResponse_Reason ListEventsResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.ListEventsResponse.reason)
+  return static_cast< ::dmi::ListEventsResponse_Reason >(reason_);
+}
+inline void ListEventsResponse::set_reason(::dmi::ListEventsResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ListEventsResponse.reason)
+}
+
+// .dmi.EventsCfg events = 3;
+inline bool ListEventsResponse::has_events() const {
+  return this != internal_default_instance() && events_ != nullptr;
+}
+inline void ListEventsResponse::clear_events() {
+  if (GetArenaNoVirtual() == nullptr && events_ != nullptr) {
+    delete events_;
+  }
+  events_ = nullptr;
+}
+inline const ::dmi::EventsCfg& ListEventsResponse::events() const {
+  const ::dmi::EventsCfg* p = events_;
+  // @@protoc_insertion_point(field_get:dmi.ListEventsResponse.events)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::EventsCfg*>(
+      &::dmi::_EventsCfg_default_instance_);
+}
+inline ::dmi::EventsCfg* ListEventsResponse::release_events() {
+  // @@protoc_insertion_point(field_release:dmi.ListEventsResponse.events)
+  
+  ::dmi::EventsCfg* temp = events_;
+  events_ = nullptr;
+  return temp;
+}
+inline ::dmi::EventsCfg* ListEventsResponse::mutable_events() {
+  
+  if (events_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::EventsCfg>(GetArenaNoVirtual());
+    events_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ListEventsResponse.events)
+  return events_;
+}
+inline void ListEventsResponse::set_allocated_events(::dmi::EventsCfg* events) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete events_;
+  }
+  if (events) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      events = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, events, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  events_ = events;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ListEventsResponse.events)
+}
+
+// string reason_detail = 4;
+inline void ListEventsResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ListEventsResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.ListEventsResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void ListEventsResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ListEventsResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void ListEventsResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ListEventsResponse.reason_detail)
+}
+#endif
+inline void ListEventsResponse::set_reason_detail(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ListEventsResponse.reason_detail)
+}
+inline void ListEventsResponse::set_reason_detail(const char* value, size_t size) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ListEventsResponse.reason_detail)
+}
+inline ::std::string* ListEventsResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ListEventsResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ListEventsResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.ListEventsResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ListEventsResponse::set_allocated_reason_detail(::std::string* reason_detail) {
+  if (reason_detail != nullptr) {
+    
+  } else {
+    
+  }
+  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ListEventsResponse.reason_detail)
+}
+
+// -------------------------------------------------------------------
+
+// EventsConfigurationRequest
+
+// .dmi.Uuid device_uuid = 1;
+inline bool EventsConfigurationRequest::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& EventsConfigurationRequest::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationRequest.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* EventsConfigurationRequest::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.EventsConfigurationRequest.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* EventsConfigurationRequest::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.EventsConfigurationRequest.device_uuid)
+  return device_uuid_;
+}
+inline void EventsConfigurationRequest::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
+  }
+  if (device_uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, device_uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  device_uuid_ = device_uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.EventsConfigurationRequest.device_uuid)
+}
+
+// .dmi.EventsCfg changes = 2;
+inline bool EventsConfigurationRequest::has_changes() const {
+  return operation_case() == kChanges;
+}
+inline void EventsConfigurationRequest::set_has_changes() {
+  _oneof_case_[0] = kChanges;
+}
+inline void EventsConfigurationRequest::clear_changes() {
+  if (has_changes()) {
+    delete operation_.changes_;
+    clear_has_operation();
+  }
+}
+inline ::dmi::EventsCfg* EventsConfigurationRequest::release_changes() {
+  // @@protoc_insertion_point(field_release:dmi.EventsConfigurationRequest.changes)
+  if (has_changes()) {
+    clear_has_operation();
+      ::dmi::EventsCfg* temp = operation_.changes_;
+    operation_.changes_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::EventsCfg& EventsConfigurationRequest::changes() const {
+  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationRequest.changes)
+  return has_changes()
+      ? *operation_.changes_
+      : *reinterpret_cast< ::dmi::EventsCfg*>(&::dmi::_EventsCfg_default_instance_);
+}
+inline ::dmi::EventsCfg* EventsConfigurationRequest::mutable_changes() {
+  if (!has_changes()) {
+    clear_operation();
+    set_has_changes();
+    operation_.changes_ = CreateMaybeMessage< ::dmi::EventsCfg >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.EventsConfigurationRequest.changes)
+  return operation_.changes_;
+}
+
+// bool reset_to_default = 3;
+inline bool EventsConfigurationRequest::has_reset_to_default() const {
+  return operation_case() == kResetToDefault;
+}
+inline void EventsConfigurationRequest::set_has_reset_to_default() {
+  _oneof_case_[0] = kResetToDefault;
+}
+inline void EventsConfigurationRequest::clear_reset_to_default() {
+  if (has_reset_to_default()) {
+    operation_.reset_to_default_ = false;
+    clear_has_operation();
+  }
+}
+inline bool EventsConfigurationRequest::reset_to_default() const {
+  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationRequest.reset_to_default)
+  if (has_reset_to_default()) {
+    return operation_.reset_to_default_;
+  }
+  return false;
+}
+inline void EventsConfigurationRequest::set_reset_to_default(bool value) {
+  if (!has_reset_to_default()) {
+    clear_operation();
+    set_has_reset_to_default();
+  }
+  operation_.reset_to_default_ = value;
+  // @@protoc_insertion_point(field_set:dmi.EventsConfigurationRequest.reset_to_default)
+}
+
+inline bool EventsConfigurationRequest::has_operation() const {
+  return operation_case() != OPERATION_NOT_SET;
+}
+inline void EventsConfigurationRequest::clear_has_operation() {
+  _oneof_case_[0] = OPERATION_NOT_SET;
+}
+inline EventsConfigurationRequest::OperationCase EventsConfigurationRequest::operation_case() const {
+  return EventsConfigurationRequest::OperationCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// EventsConfigurationResponse
+
+// .dmi.Status status = 1;
+inline void EventsConfigurationResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status EventsConfigurationResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void EventsConfigurationResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.EventsConfigurationResponse.status)
+}
+
+// .dmi.EventsConfigurationResponse.Reason reason = 2;
+inline void EventsConfigurationResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::EventsConfigurationResponse_Reason EventsConfigurationResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationResponse.reason)
+  return static_cast< ::dmi::EventsConfigurationResponse_Reason >(reason_);
+}
+inline void EventsConfigurationResponse::set_reason(::dmi::EventsConfigurationResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.EventsConfigurationResponse.reason)
+}
+
+// string reason_detail = 3;
+inline void EventsConfigurationResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& EventsConfigurationResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.EventsConfigurationResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void EventsConfigurationResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.EventsConfigurationResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void EventsConfigurationResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.EventsConfigurationResponse.reason_detail)
+}
+#endif
+inline void EventsConfigurationResponse::set_reason_detail(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.EventsConfigurationResponse.reason_detail)
+}
+inline void EventsConfigurationResponse::set_reason_detail(const char* value, size_t size) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.EventsConfigurationResponse.reason_detail)
+}
+inline ::std::string* EventsConfigurationResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.EventsConfigurationResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* EventsConfigurationResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.EventsConfigurationResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void EventsConfigurationResponse::set_allocated_reason_detail(::std::string* reason_detail) {
+  if (reason_detail != nullptr) {
+    
+  } else {
+    
+  }
+  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
+  // @@protoc_insertion_point(field_set_allocated:dmi.EventsConfigurationResponse.reason_detail)
+}
+
+// -------------------------------------------------------------------
+
+// EventMetaData
+
+// .dmi.Uuid device_uuid = 1;
+inline bool EventMetaData::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& EventMetaData::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.EventMetaData.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* EventMetaData::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.EventMetaData.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* EventMetaData::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.EventMetaData.device_uuid)
+  return device_uuid_;
+}
+inline void EventMetaData::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
+  }
+  if (device_uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, device_uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  device_uuid_ = device_uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.EventMetaData.device_uuid)
+}
+
+// .dmi.Uuid component_uuid = 2;
+inline bool EventMetaData::has_component_uuid() const {
+  return this != internal_default_instance() && component_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& EventMetaData::component_uuid() const {
+  const ::dmi::Uuid* p = component_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.EventMetaData.component_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* EventMetaData::release_component_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.EventMetaData.component_uuid)
+  
+  ::dmi::Uuid* temp = component_uuid_;
+  component_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* EventMetaData::mutable_component_uuid() {
+  
+  if (component_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    component_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.EventMetaData.component_uuid)
+  return component_uuid_;
+}
+inline void EventMetaData::set_allocated_component_uuid(::dmi::Uuid* component_uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(component_uuid_);
+  }
+  if (component_uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      component_uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, component_uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  component_uuid_ = component_uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.EventMetaData.component_uuid)
+}
+
+// string component_name = 3;
+inline void EventMetaData::clear_component_name() {
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& EventMetaData::component_name() const {
+  // @@protoc_insertion_point(field_get:dmi.EventMetaData.component_name)
+  return component_name_.GetNoArena();
+}
+inline void EventMetaData::set_component_name(const ::std::string& value) {
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.EventMetaData.component_name)
+}
+#if LANG_CXX11
+inline void EventMetaData::set_component_name(::std::string&& value) {
+  
+  component_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.EventMetaData.component_name)
+}
+#endif
+inline void EventMetaData::set_component_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.EventMetaData.component_name)
+}
+inline void EventMetaData::set_component_name(const char* value, size_t size) {
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.EventMetaData.component_name)
+}
+inline ::std::string* EventMetaData::mutable_component_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.EventMetaData.component_name)
+  return component_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* EventMetaData::release_component_name() {
+  // @@protoc_insertion_point(field_release:dmi.EventMetaData.component_name)
+  
+  return component_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void EventMetaData::set_allocated_component_name(::std::string* component_name) {
+  if (component_name != nullptr) {
+    
+  } else {
+    
+  }
+  component_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), component_name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.EventMetaData.component_name)
+}
+
+// -------------------------------------------------------------------
+
+// Event
+
+// .dmi.EventMetaData event_metadata = 1;
+inline bool Event::has_event_metadata() const {
+  return this != internal_default_instance() && event_metadata_ != nullptr;
+}
+inline void Event::clear_event_metadata() {
+  if (GetArenaNoVirtual() == nullptr && event_metadata_ != nullptr) {
+    delete event_metadata_;
+  }
+  event_metadata_ = nullptr;
+}
+inline const ::dmi::EventMetaData& Event::event_metadata() const {
+  const ::dmi::EventMetaData* p = event_metadata_;
+  // @@protoc_insertion_point(field_get:dmi.Event.event_metadata)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::EventMetaData*>(
+      &::dmi::_EventMetaData_default_instance_);
+}
+inline ::dmi::EventMetaData* Event::release_event_metadata() {
+  // @@protoc_insertion_point(field_release:dmi.Event.event_metadata)
+  
+  ::dmi::EventMetaData* temp = event_metadata_;
+  event_metadata_ = nullptr;
+  return temp;
+}
+inline ::dmi::EventMetaData* Event::mutable_event_metadata() {
+  
+  if (event_metadata_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::EventMetaData>(GetArenaNoVirtual());
+    event_metadata_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Event.event_metadata)
+  return event_metadata_;
+}
+inline void Event::set_allocated_event_metadata(::dmi::EventMetaData* event_metadata) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete event_metadata_;
+  }
+  if (event_metadata) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      event_metadata = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, event_metadata, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  event_metadata_ = event_metadata;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Event.event_metadata)
+}
+
+// .dmi.EventIds event_id = 2;
+inline void Event::clear_event_id() {
+  event_id_ = 0;
+}
+inline ::dmi::EventIds Event::event_id() const {
+  // @@protoc_insertion_point(field_get:dmi.Event.event_id)
+  return static_cast< ::dmi::EventIds >(event_id_);
+}
+inline void Event::set_event_id(::dmi::EventIds value) {
+  
+  event_id_ = value;
+  // @@protoc_insertion_point(field_set:dmi.Event.event_id)
+}
+
+// .google.protobuf.Timestamp raised_ts = 3;
+inline bool Event::has_raised_ts() const {
+  return this != internal_default_instance() && raised_ts_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& Event::raised_ts() const {
+  const ::google::protobuf::Timestamp* p = raised_ts_;
+  // @@protoc_insertion_point(field_get:dmi.Event.raised_ts)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* Event::release_raised_ts() {
+  // @@protoc_insertion_point(field_release:dmi.Event.raised_ts)
+  
+  ::google::protobuf::Timestamp* temp = raised_ts_;
+  raised_ts_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* Event::mutable_raised_ts() {
+  
+  if (raised_ts_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    raised_ts_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Event.raised_ts)
+  return raised_ts_;
+}
+inline void Event::set_allocated_raised_ts(::google::protobuf::Timestamp* raised_ts) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(raised_ts_);
+  }
+  if (raised_ts) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(raised_ts)->GetArena();
+    if (message_arena != submessage_arena) {
+      raised_ts = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, raised_ts, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  raised_ts_ = raised_ts;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Event.raised_ts)
+}
+
+// .dmi.ThresholdInformation threshold_info = 4;
+inline bool Event::has_threshold_info() const {
+  return this != internal_default_instance() && threshold_info_ != nullptr;
+}
+inline void Event::clear_threshold_info() {
+  if (GetArenaNoVirtual() == nullptr && threshold_info_ != nullptr) {
+    delete threshold_info_;
+  }
+  threshold_info_ = nullptr;
+}
+inline const ::dmi::ThresholdInformation& Event::threshold_info() const {
+  const ::dmi::ThresholdInformation* p = threshold_info_;
+  // @@protoc_insertion_point(field_get:dmi.Event.threshold_info)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ThresholdInformation*>(
+      &::dmi::_ThresholdInformation_default_instance_);
+}
+inline ::dmi::ThresholdInformation* Event::release_threshold_info() {
+  // @@protoc_insertion_point(field_release:dmi.Event.threshold_info)
+  
+  ::dmi::ThresholdInformation* temp = threshold_info_;
+  threshold_info_ = nullptr;
+  return temp;
+}
+inline ::dmi::ThresholdInformation* Event::mutable_threshold_info() {
+  
+  if (threshold_info_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::ThresholdInformation>(GetArenaNoVirtual());
+    threshold_info_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Event.threshold_info)
+  return threshold_info_;
+}
+inline void Event::set_allocated_threshold_info(::dmi::ThresholdInformation* threshold_info) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete threshold_info_;
+  }
+  if (threshold_info) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      threshold_info = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, threshold_info, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  threshold_info_ = threshold_info;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Event.threshold_info)
+}
+
+// string add_info = 5;
+inline void Event::clear_add_info() {
+  add_info_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Event::add_info() const {
+  // @@protoc_insertion_point(field_get:dmi.Event.add_info)
+  return add_info_.GetNoArena();
+}
+inline void Event::set_add_info(const ::std::string& value) {
+  
+  add_info_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Event.add_info)
+}
+#if LANG_CXX11
+inline void Event::set_add_info(::std::string&& value) {
+  
+  add_info_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Event.add_info)
+}
+#endif
+inline void Event::set_add_info(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  add_info_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Event.add_info)
+}
+inline void Event::set_add_info(const char* value, size_t size) {
+  
+  add_info_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Event.add_info)
+}
+inline ::std::string* Event::mutable_add_info() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Event.add_info)
+  return add_info_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Event::release_add_info() {
+  // @@protoc_insertion_point(field_release:dmi.Event.add_info)
+  
+  return add_info_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Event::set_allocated_add_info(::std::string* add_info) {
+  if (add_info != nullptr) {
+    
+  } else {
+    
+  }
+  add_info_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), add_info);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Event.add_info)
+}
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic pop
+#endif  // __GNUC__
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace dmi
+
+namespace google {
+namespace protobuf {
+
+template <> struct is_proto_enum< ::dmi::ListEventsResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ListEventsResponse_Reason>() {
+  return ::dmi::ListEventsResponse_Reason_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::EventsConfigurationResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::EventsConfigurationResponse_Reason>() {
+  return ::dmi::EventsConfigurationResponse_Reason_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::EventIds> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::EventIds>() {
+  return ::dmi::EventIds_descriptor();
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#include <google/protobuf/port_undef.inc>
+#endif  // PROTOBUF_INCLUDED_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto
diff --git a/cpp/dmi/hw_management_service.pb.cc b/cpp/dmi/hw_management_service.pb.cc
new file mode 100644
index 0000000..573645e
--- /dev/null
+++ b/cpp/dmi/hw_management_service.pb.cc
@@ -0,0 +1,10197 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/hw_management_service.proto
+
+#include "dmi/hw_management_service.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_Hardware_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_ModifiableComponent_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<9> scc_info_Component_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fmanagement_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_EntitiesLogLevel_dmi_2fhw_5fmanagement_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fmanagement_5fservice_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_ManagedDeviceInfo_dmi_2fhw_5fmanagement_5fservice_2eproto;
+namespace dmi {
+class PhysicalInventoryRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<PhysicalInventoryRequest> _instance;
+} _PhysicalInventoryRequest_default_instance_;
+class PhysicalInventoryResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<PhysicalInventoryResponse> _instance;
+} _PhysicalInventoryResponse_default_instance_;
+class HWComponentInfoGetRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<HWComponentInfoGetRequest> _instance;
+} _HWComponentInfoGetRequest_default_instance_;
+class HWComponentInfoGetResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<HWComponentInfoGetResponse> _instance;
+} _HWComponentInfoGetResponse_default_instance_;
+class HWComponentInfoSetRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<HWComponentInfoSetRequest> _instance;
+} _HWComponentInfoSetRequest_default_instance_;
+class HWComponentInfoSetResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<HWComponentInfoSetResponse> _instance;
+} _HWComponentInfoSetResponse_default_instance_;
+class StartManagingDeviceResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<StartManagingDeviceResponse> _instance;
+} _StartManagingDeviceResponse_default_instance_;
+class StopManagingDeviceRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<StopManagingDeviceRequest> _instance;
+} _StopManagingDeviceRequest_default_instance_;
+class StopManagingDeviceResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<StopManagingDeviceResponse> _instance;
+} _StopManagingDeviceResponse_default_instance_;
+class ManagedDeviceInfoDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ManagedDeviceInfo> _instance;
+} _ManagedDeviceInfo_default_instance_;
+class ManagedDevicesResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ManagedDevicesResponse> _instance;
+} _ManagedDevicesResponse_default_instance_;
+class SetLoggingEndpointRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<SetLoggingEndpointRequest> _instance;
+} _SetLoggingEndpointRequest_default_instance_;
+class SetRemoteEndpointResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<SetRemoteEndpointResponse> _instance;
+} _SetRemoteEndpointResponse_default_instance_;
+class GetLoggingEndpointResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<GetLoggingEndpointResponse> _instance;
+} _GetLoggingEndpointResponse_default_instance_;
+class SetMsgBusEndpointRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<SetMsgBusEndpointRequest> _instance;
+} _SetMsgBusEndpointRequest_default_instance_;
+class GetMsgBusEndpointResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<GetMsgBusEndpointResponse> _instance;
+} _GetMsgBusEndpointResponse_default_instance_;
+class EntitiesLogLevelDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<EntitiesLogLevel> _instance;
+} _EntitiesLogLevel_default_instance_;
+class SetLogLevelRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<SetLogLevelRequest> _instance;
+} _SetLogLevelRequest_default_instance_;
+class SetLogLevelResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<SetLogLevelResponse> _instance;
+} _SetLogLevelResponse_default_instance_;
+class GetLogLevelRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<GetLogLevelRequest> _instance;
+} _GetLogLevelRequest_default_instance_;
+class GetLogLevelResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<GetLogLevelResponse> _instance;
+} _GetLogLevelResponse_default_instance_;
+class GetLoggableEntitiesRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<GetLoggableEntitiesRequest> _instance;
+} _GetLoggableEntitiesRequest_default_instance_;
+}  // namespace dmi
+static void InitDefaultsPhysicalInventoryRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_PhysicalInventoryRequest_default_instance_;
+    new (ptr) ::dmi::PhysicalInventoryRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::PhysicalInventoryRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_PhysicalInventoryRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsPhysicalInventoryRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsPhysicalInventoryResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_PhysicalInventoryResponse_default_instance_;
+    new (ptr) ::dmi::PhysicalInventoryResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::PhysicalInventoryResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_PhysicalInventoryResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsPhysicalInventoryResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Hardware_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsHWComponentInfoGetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_HWComponentInfoGetRequest_default_instance_;
+    new (ptr) ::dmi::HWComponentInfoGetRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::HWComponentInfoGetRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_HWComponentInfoGetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsHWComponentInfoGetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsHWComponentInfoGetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_HWComponentInfoGetResponse_default_instance_;
+    new (ptr) ::dmi::HWComponentInfoGetResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::HWComponentInfoGetResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_HWComponentInfoGetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsHWComponentInfoGetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Component_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsHWComponentInfoSetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_HWComponentInfoSetRequest_default_instance_;
+    new (ptr) ::dmi::HWComponentInfoSetRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::HWComponentInfoSetRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_HWComponentInfoSetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsHWComponentInfoSetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,
+      &scc_info_ModifiableComponent_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsHWComponentInfoSetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_HWComponentInfoSetResponse_default_instance_;
+    new (ptr) ::dmi::HWComponentInfoSetResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::HWComponentInfoSetResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_HWComponentInfoSetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsHWComponentInfoSetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsStartManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_StartManagingDeviceResponse_default_instance_;
+    new (ptr) ::dmi::StartManagingDeviceResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::StartManagingDeviceResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_StartManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsStartManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsStopManagingDeviceRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_StopManagingDeviceRequest_default_instance_;
+    new (ptr) ::dmi::StopManagingDeviceRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::StopManagingDeviceRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_StopManagingDeviceRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsStopManagingDeviceRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsStopManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_StopManagingDeviceResponse_default_instance_;
+    new (ptr) ::dmi::StopManagingDeviceResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::StopManagingDeviceResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_StopManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsStopManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsManagedDeviceInfo_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ManagedDeviceInfo_default_instance_;
+    new (ptr) ::dmi::ManagedDeviceInfo();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ManagedDeviceInfo::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_ManagedDeviceInfo_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsManagedDeviceInfo_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_ModifiableComponent_dmi_2fhw_2eproto.base,
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsManagedDevicesResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ManagedDevicesResponse_default_instance_;
+    new (ptr) ::dmi::ManagedDevicesResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ManagedDevicesResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ManagedDevicesResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsManagedDevicesResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_ManagedDeviceInfo_dmi_2fhw_5fmanagement_5fservice_2eproto.base,}};
+
+static void InitDefaultsSetLoggingEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_SetLoggingEndpointRequest_default_instance_;
+    new (ptr) ::dmi::SetLoggingEndpointRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::SetLoggingEndpointRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_SetLoggingEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsSetLoggingEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsSetRemoteEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_SetRemoteEndpointResponse_default_instance_;
+    new (ptr) ::dmi::SetRemoteEndpointResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::SetRemoteEndpointResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_SetRemoteEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsSetRemoteEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsGetLoggingEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_GetLoggingEndpointResponse_default_instance_;
+    new (ptr) ::dmi::GetLoggingEndpointResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::GetLoggingEndpointResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_GetLoggingEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsGetLoggingEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsSetMsgBusEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_SetMsgBusEndpointRequest_default_instance_;
+    new (ptr) ::dmi::SetMsgBusEndpointRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::SetMsgBusEndpointRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_SetMsgBusEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsSetMsgBusEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsGetMsgBusEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_GetMsgBusEndpointResponse_default_instance_;
+    new (ptr) ::dmi::GetMsgBusEndpointResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::GetMsgBusEndpointResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_GetMsgBusEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsGetMsgBusEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsEntitiesLogLevel_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_EntitiesLogLevel_default_instance_;
+    new (ptr) ::dmi::EntitiesLogLevel();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::EntitiesLogLevel::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_EntitiesLogLevel_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsEntitiesLogLevel_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsSetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_SetLogLevelRequest_default_instance_;
+    new (ptr) ::dmi::SetLogLevelRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::SetLogLevelRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_SetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsSetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,
+      &scc_info_EntitiesLogLevel_dmi_2fhw_5fmanagement_5fservice_2eproto.base,}};
+
+static void InitDefaultsSetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_SetLogLevelResponse_default_instance_;
+    new (ptr) ::dmi::SetLogLevelResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::SetLogLevelResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_SetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsSetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsGetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_GetLogLevelRequest_default_instance_;
+    new (ptr) ::dmi::GetLogLevelRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::GetLogLevelRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_GetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsGetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsGetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_GetLogLevelResponse_default_instance_;
+    new (ptr) ::dmi::GetLogLevelResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::GetLogLevelResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_GetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsGetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,
+      &scc_info_EntitiesLogLevel_dmi_2fhw_5fmanagement_5fservice_2eproto.base,}};
+
+static void InitDefaultsGetLoggableEntitiesRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_GetLoggableEntitiesRequest_default_instance_;
+    new (ptr) ::dmi::GetLoggableEntitiesRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::GetLoggableEntitiesRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_GetLoggableEntitiesRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsGetLoggableEntitiesRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+void InitDefaults_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_PhysicalInventoryRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_PhysicalInventoryResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_HWComponentInfoGetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_HWComponentInfoGetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_HWComponentInfoSetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_HWComponentInfoSetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_StartManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_StopManagingDeviceRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_StopManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ManagedDeviceInfo_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ManagedDevicesResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_SetLoggingEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_SetRemoteEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GetLoggingEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_SetMsgBusEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GetMsgBusEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EntitiesLogLevel_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_SetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_SetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GetLoggableEntitiesRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+}
+
+::google::protobuf::Metadata file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[22];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[11];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto = nullptr;
+
+const ::google::protobuf::uint32 TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::PhysicalInventoryRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::PhysicalInventoryRequest, device_uuid_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::PhysicalInventoryResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::PhysicalInventoryResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::PhysicalInventoryResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::PhysicalInventoryResponse, inventory_),
+  PROTOBUF_FIELD_OFFSET(::dmi::PhysicalInventoryResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoGetRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoGetRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoGetRequest, component_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoGetRequest, component_name_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoGetResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoGetResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoGetResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoGetResponse, component_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoGetResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoSetRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoSetRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoSetRequest, component_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoSetRequest, component_name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoSetRequest, changes_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoSetResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoSetResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoSetResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::HWComponentInfoSetResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::StartManagingDeviceResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::StartManagingDeviceResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StartManagingDeviceResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StartManagingDeviceResponse, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StartManagingDeviceResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::StopManagingDeviceRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::StopManagingDeviceRequest, name_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::StopManagingDeviceResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::StopManagingDeviceResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StopManagingDeviceResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StopManagingDeviceResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ManagedDeviceInfo, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ManagedDeviceInfo, info_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ManagedDeviceInfo, device_uuid_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ManagedDevicesResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ManagedDevicesResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ManagedDevicesResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ManagedDevicesResponse, devices_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLoggingEndpointRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLoggingEndpointRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLoggingEndpointRequest, logging_endpoint_),
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLoggingEndpointRequest, logging_protocol_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetRemoteEndpointResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetRemoteEndpointResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::SetRemoteEndpointResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::SetRemoteEndpointResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLoggingEndpointResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLoggingEndpointResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLoggingEndpointResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLoggingEndpointResponse, logging_endpoint_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLoggingEndpointResponse, logging_protocol_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLoggingEndpointResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetMsgBusEndpointRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetMsgBusEndpointRequest, msgbus_endpoint_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMsgBusEndpointResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMsgBusEndpointResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMsgBusEndpointResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMsgBusEndpointResponse, msgbus_endpoint_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMsgBusEndpointResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::EntitiesLogLevel, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::EntitiesLogLevel, loglevel_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EntitiesLogLevel, entities_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLogLevelRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLogLevelRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLogLevelRequest, loglevels_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLogLevelResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLogLevelResponse, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLogLevelResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLogLevelResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::SetLogLevelResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLogLevelRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLogLevelRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLogLevelRequest, entities_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLogLevelResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLogLevelResponse, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLogLevelResponse, loglevels_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLogLevelResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLogLevelResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLogLevelResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLoggableEntitiesRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetLoggableEntitiesRequest, device_uuid_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  { 0, -1, sizeof(::dmi::PhysicalInventoryRequest)},
+  { 6, -1, sizeof(::dmi::PhysicalInventoryResponse)},
+  { 15, -1, sizeof(::dmi::HWComponentInfoGetRequest)},
+  { 23, -1, sizeof(::dmi::HWComponentInfoGetResponse)},
+  { 32, -1, sizeof(::dmi::HWComponentInfoSetRequest)},
+  { 41, -1, sizeof(::dmi::HWComponentInfoSetResponse)},
+  { 49, -1, sizeof(::dmi::StartManagingDeviceResponse)},
+  { 58, -1, sizeof(::dmi::StopManagingDeviceRequest)},
+  { 64, -1, sizeof(::dmi::StopManagingDeviceResponse)},
+  { 72, -1, sizeof(::dmi::ManagedDeviceInfo)},
+  { 79, -1, sizeof(::dmi::ManagedDevicesResponse)},
+  { 87, -1, sizeof(::dmi::SetLoggingEndpointRequest)},
+  { 95, -1, sizeof(::dmi::SetRemoteEndpointResponse)},
+  { 103, -1, sizeof(::dmi::GetLoggingEndpointResponse)},
+  { 113, -1, sizeof(::dmi::SetMsgBusEndpointRequest)},
+  { 119, -1, sizeof(::dmi::GetMsgBusEndpointResponse)},
+  { 128, -1, sizeof(::dmi::EntitiesLogLevel)},
+  { 135, -1, sizeof(::dmi::SetLogLevelRequest)},
+  { 142, -1, sizeof(::dmi::SetLogLevelResponse)},
+  { 151, -1, sizeof(::dmi::GetLogLevelRequest)},
+  { 158, -1, sizeof(::dmi::GetLogLevelResponse)},
+  { 168, -1, sizeof(::dmi::GetLoggableEntitiesRequest)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_PhysicalInventoryRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_PhysicalInventoryResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_HWComponentInfoGetRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_HWComponentInfoGetResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_HWComponentInfoSetRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_HWComponentInfoSetResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_StartManagingDeviceResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_StopManagingDeviceRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_StopManagingDeviceResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ManagedDeviceInfo_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ManagedDevicesResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_SetLoggingEndpointRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_SetRemoteEndpointResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_GetLoggingEndpointResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_SetMsgBusEndpointRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_GetMsgBusEndpointResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EntitiesLogLevel_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_SetLogLevelRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_SetLogLevelResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_GetLogLevelRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_GetLogLevelResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_GetLoggableEntitiesRequest_default_instance_),
+};
+
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto = {
+  {}, AddDescriptors_dmi_2fhw_5fmanagement_5fservice_2eproto, "dmi/hw_management_service.proto", schemas,
+  file_default_instances, TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto::offsets,
+  file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto, 22, file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto, file_level_service_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto,
+};
+
+const char descriptor_table_protodef_dmi_2fhw_5fmanagement_5fservice_2eproto[] =
+  "\n\037dmi/hw_management_service.proto\022\003dmi\032\021"
+  "dmi/commons.proto\032\014dmi/hw.proto\032\033google/"
+  "protobuf/empty.proto\":\n\030PhysicalInventor"
+  "yRequest\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uuid"
+  "\"\210\002\n\031PhysicalInventoryResponse\022\033\n\006status"
+  "\030\001 \001(\0162\013.dmi.Status\0225\n\006reason\030\002 \001(\0162%.dm"
+  "i.PhysicalInventoryResponse.Reason\022 \n\tin"
+  "ventory\030\003 \001(\0132\r.dmi.Hardware\022\025\n\rreason_d"
+  "etail\030\004 \001(\t\"^\n\006Reason\022\024\n\020UNDEFINED_REASO"
+  "N\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INTERNAL_ERRO"
+  "R\020\002\022\026\n\022DEVICE_UNREACHABLE\020\003\"v\n\031HWCompone"
+  "ntInfoGetRequest\022\036\n\013device_uuid\030\001 \001(\0132\t."
+  "dmi.Uuid\022!\n\016component_uuid\030\002 \001(\0132\t.dmi.U"
+  "uid\022\026\n\016component_name\030\003 \001(\t\"\242\002\n\032HWCompon"
+  "entInfoGetResponse\022\033\n\006status\030\001 \001(\0162\013.dmi"
+  ".Status\0226\n\006reason\030\002 \001(\0162&.dmi.HWComponen"
+  "tInfoGetResponse.Reason\022!\n\tcomponent\030\003 \001"
+  "(\0132\016.dmi.Component\022\025\n\rreason_detail\030\004 \001("
+  "\t\"u\n\006Reason\022\024\n\020UNDEFINED_REASON\020\000\022\022\n\016UNK"
+  "NOWN_DEVICE\020\001\022\025\n\021UNKNOWN_COMPONENT\020\002\022\022\n\016"
+  "INTERNAL_ERROR\020\003\022\026\n\022DEVICE_UNREACHABLE\020\004"
+  "\"\241\001\n\031HWComponentInfoSetRequest\022\036\n\013device"
+  "_uuid\030\001 \001(\0132\t.dmi.Uuid\022!\n\016component_uuid"
+  "\030\002 \001(\0132\t.dmi.Uuid\022\026\n\016component_name\030\003 \001("
+  "\t\022)\n\007changes\030\004 \001(\0132\030.dmi.ModifiableCompo"
+  "nent\"\224\002\n\032HWComponentInfoSetResponse\022\033\n\006s"
+  "tatus\030\001 \001(\0162\013.dmi.Status\0226\n\006reason\030\002 \001(\016"
+  "2&.dmi.HWComponentInfoSetResponse.Reason"
+  "\022\025\n\rreason_detail\030\003 \001(\t\"\211\001\n\006Reason\022\024\n\020UN"
+  "DEFINED_REASON\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\025\n\021"
+  "UNKNOWN_COMPONENT\020\002\022\022\n\016INVALID_PARAMS\020\003\022"
+  "\022\n\016INTERNAL_ERROR\020\004\022\026\n\022DEVICE_UNREACHABL"
+  "E\020\005\"\262\002\n\033StartManagingDeviceResponse\022\033\n\006s"
+  "tatus\030\001 \001(\0162\013.dmi.Status\0227\n\006reason\030\002 \001(\016"
+  "2\'.dmi.StartManagingDeviceResponse.Reaso"
+  "n\022\036\n\013device_uuid\030\003 \001(\0132\t.dmi.Uuid\022\025\n\rrea"
+  "son_detail\030\004 \001(\t\"\205\001\n\006Reason\022\024\n\020UNDEFINED"
+  "_REASON\020\000\022\032\n\026DEVICE_ALREADY_MANAGED\020\001\022!\n"
+  "\035OPERATION_ALREADY_IN_PROGRESS\020\002\022\022\n\016INVA"
+  "LID_PARAMS\020\003\022\022\n\016INTERNAL_ERROR\020\004\")\n\031Stop"
+  "ManagingDeviceRequest\022\014\n\004name\030\001 \001(\t\"\274\001\n\032"
+  "StopManagingDeviceResponse\022\033\n\006status\030\001 \001"
+  "(\0162\013.dmi.Status\0226\n\006reason\030\002 \001(\0162&.dmi.St"
+  "opManagingDeviceResponse.Reason\022\025\n\rreaso"
+  "n_detail\030\003 \001(\t\"2\n\006Reason\022\024\n\020UNDEFINED_RE"
+  "ASON\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\"[\n\021ManagedDev"
+  "iceInfo\022&\n\004info\030\001 \001(\0132\030.dmi.ModifiableCo"
+  "mponent\022\036\n\013device_uuid\030\002 \001(\0132\t.dmi.Uuid\""
+  "\306\001\n\026ManagedDevicesResponse\022\033\n\006status\030\001 \001"
+  "(\0162\013.dmi.Status\0222\n\006reason\030\002 \001(\0162\".dmi.Ma"
+  "nagedDevicesResponse.Reason\022\'\n\007devices\030\003"
+  " \003(\0132\026.dmi.ManagedDeviceInfo\"2\n\006Reason\022\024"
+  "\n\020UNDEFINED_REASON\020\000\022\022\n\016INTERNAL_ERROR\020\001"
+  "\"o\n\031SetLoggingEndpointRequest\022\036\n\013device_"
+  "uuid\030\001 \001(\0132\t.dmi.Uuid\022\030\n\020logging_endpoin"
+  "t\030\002 \001(\t\022\030\n\020logging_protocol\030\003 \001(\t\"\303\002\n\031Se"
+  "tRemoteEndpointResponse\022\033\n\006status\030\001 \001(\0162"
+  "\013.dmi.Status\0225\n\006reason\030\002 \001(\0162%.dmi.SetRe"
+  "moteEndpointResponse.Reason\022\025\n\rreason_de"
+  "tail\030\003 \001(\t\"\272\001\n\006Reason\022\024\n\020UNDEFINED_REASO"
+  "N\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INTERNAL_ERRO"
+  "R\020\002\022\032\n\026LOGGING_ENDPOINT_ERROR\020\003\022#\n\037LOGGI"
+  "NG_ENDPOINT_PROTOCOL_ERROR\020\004\022\031\n\025MSGBUS_E"
+  "NDPOINT_ERROR\020\005\022\026\n\022DEVICE_UNREACHABLE\020\006\""
+  "\234\002\n\032GetLoggingEndpointResponse\022\033\n\006status"
+  "\030\001 \001(\0162\013.dmi.Status\0226\n\006reason\030\002 \001(\0162&.dm"
+  "i.GetLoggingEndpointResponse.Reason\022\030\n\020l"
+  "ogging_endpoint\030\003 \001(\t\022\030\n\020logging_protoco"
+  "l\030\004 \001(\t\022\025\n\rreason_detail\030\005 \001(\t\"^\n\006Reason"
+  "\022\024\n\020UNDEFINED_REASON\020\000\022\022\n\016UNKNOWN_DEVICE"
+  "\020\001\022\022\n\016INTERNAL_ERROR\020\002\022\026\n\022DEVICE_UNREACH"
+  "ABLE\020\003\"3\n\030SetMsgBusEndpointRequest\022\027\n\017ms"
+  "gbus_endpoint\030\001 \001(\t\"\353\001\n\031GetMsgBusEndpoin"
+  "tResponse\022\033\n\006status\030\001 \001(\0162\013.dmi.Status\0225"
+  "\n\006reason\030\002 \001(\0162%.dmi.GetMsgBusEndpointRe"
+  "sponse.Reason\022\027\n\017msgbus_endpoint\030\003 \001(\t\022\025"
+  "\n\rreason_detail\030\004 \001(\t\"J\n\006Reason\022\024\n\020UNDEF"
+  "INED_REASON\020\000\022\022\n\016INTERNAL_ERROR\020\001\022\026\n\022DEV"
+  "ICE_UNREACHABLE\020\002\"E\n\020EntitiesLogLevel\022\037\n"
+  "\010logLevel\030\001 \001(\0162\r.dmi.LogLevel\022\020\n\010entiti"
+  "es\030\002 \003(\t\"^\n\022SetLogLevelRequest\022\036\n\013device"
+  "_uuid\030\001 \001(\0132\t.dmi.Uuid\022(\n\tloglevels\030\002 \003("
+  "\0132\025.dmi.EntitiesLogLevel\"\222\002\n\023SetLogLevel"
+  "Response\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uuid"
+  "\022\033\n\006status\030\002 \001(\0162\013.dmi.Status\022/\n\006reason\030"
+  "\003 \001(\0162\037.dmi.SetLogLevelResponse.Reason\022\025"
+  "\n\rreason_detail\030\004 \001(\t\"v\n\006Reason\022\024\n\020UNDEF"
+  "INED_REASON\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INT"
+  "ERNAL_ERROR\020\002\022\026\n\022UNKNOWN_LOG_ENTITY\020\003\022\026\n"
+  "\022DEVICE_UNREACHABLE\020\004\"F\n\022GetLogLevelRequ"
+  "est\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uuid\022\020\n\010e"
+  "ntities\030\002 \003(\t\"\274\002\n\023GetLogLevelResponse\022\036\n"
+  "\013device_uuid\030\001 \001(\0132\t.dmi.Uuid\022(\n\tlogLeve"
+  "ls\030\002 \003(\0132\025.dmi.EntitiesLogLevel\022\033\n\006statu"
+  "s\030\003 \001(\0162\013.dmi.Status\022/\n\006reason\030\004 \001(\0162\037.d"
+  "mi.GetLogLevelResponse.Reason\022\025\n\rreason_"
+  "detail\030\005 \001(\t\"v\n\006Reason\022\024\n\020UNDEFINED_REAS"
+  "ON\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INTERNAL_ERR"
+  "OR\020\002\022\026\n\022UNKNOWN_LOG_ENTITY\020\003\022\026\n\022DEVICE_U"
+  "NREACHABLE\020\004\"<\n\032GetLoggableEntitiesReque"
+  "st\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uuid2\257\010\n\031N"
+  "ativeHWManagementService\022S\n\023StartManagin"
+  "gDevice\022\030.dmi.ModifiableComponent\032 .dmi."
+  "StartManagingDeviceResponse0\001\022U\n\022StopMan"
+  "agingDevice\022\036.dmi.StopManagingDeviceRequ"
+  "est\032\037.dmi.StopManagingDeviceResponse\022H\n\021"
+  "GetManagedDevices\022\026.google.protobuf.Empt"
+  "y\032\033.dmi.ManagedDevicesResponse\022W\n\024GetPhy"
+  "sicalInventory\022\035.dmi.PhysicalInventoryRe"
+  "quest\032\036.dmi.PhysicalInventoryResponse0\001\022"
+  "W\n\022GetHWComponentInfo\022\036.dmi.HWComponentI"
+  "nfoGetRequest\032\037.dmi.HWComponentInfoGetRe"
+  "sponse0\001\022U\n\022SetHWComponentInfo\022\036.dmi.HWC"
+  "omponentInfoSetRequest\032\037.dmi.HWComponent"
+  "InfoSetResponse\022T\n\022SetLoggingEndpoint\022\036."
+  "dmi.SetLoggingEndpointRequest\032\036.dmi.SetR"
+  "emoteEndpointResponse\022F\n\022GetLoggingEndpo"
+  "int\022\017.dmi.HardwareID\032\037.dmi.GetLoggingEnd"
+  "pointResponse\022R\n\021SetMsgBusEndpoint\022\035.dmi"
+  ".SetMsgBusEndpointRequest\032\036.dmi.SetRemot"
+  "eEndpointResponse\022K\n\021GetMsgBusEndpoint\022\026"
+  ".google.protobuf.Empty\032\036.dmi.GetMsgBusEn"
+  "dpointResponse\022P\n\023GetLoggableEntities\022\037."
+  "dmi.GetLoggableEntitiesRequest\032\030.dmi.Get"
+  "LogLevelResponse\022@\n\013SetLogLevel\022\027.dmi.Se"
+  "tLogLevelRequest\032\030.dmi.SetLogLevelRespon"
+  "se\022@\n\013GetLogLevel\022\027.dmi.GetLogLevelReque"
+  "st\032\030.dmi.GetLogLevelResponseB;Z9github.c"
+  "om/opencord/device-management-interface/"
+  "v3/go/dmib\006proto3"
+  ;
+::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fhw_5fmanagement_5fservice_2eproto = {
+  false, InitDefaults_dmi_2fhw_5fmanagement_5fservice_2eproto, 
+  descriptor_table_protodef_dmi_2fhw_5fmanagement_5fservice_2eproto,
+  "dmi/hw_management_service.proto", &assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto, 5177,
+};
+
+void AddDescriptors_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[3] =
+  {
+    ::AddDescriptors_dmi_2fcommons_2eproto,
+    ::AddDescriptors_dmi_2fhw_2eproto,
+    ::AddDescriptors_google_2fprotobuf_2fempty_2eproto,
+  };
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_dmi_2fhw_5fmanagement_5fservice_2eproto, deps, 3);
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_dmi_2fhw_5fmanagement_5fservice_2eproto = []() { AddDescriptors_dmi_2fhw_5fmanagement_5fservice_2eproto(); return true; }();
+namespace dmi {
+const ::google::protobuf::EnumDescriptor* PhysicalInventoryResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[0];
+}
+bool PhysicalInventoryResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const PhysicalInventoryResponse_Reason PhysicalInventoryResponse::UNDEFINED_REASON;
+const PhysicalInventoryResponse_Reason PhysicalInventoryResponse::UNKNOWN_DEVICE;
+const PhysicalInventoryResponse_Reason PhysicalInventoryResponse::INTERNAL_ERROR;
+const PhysicalInventoryResponse_Reason PhysicalInventoryResponse::DEVICE_UNREACHABLE;
+const PhysicalInventoryResponse_Reason PhysicalInventoryResponse::Reason_MIN;
+const PhysicalInventoryResponse_Reason PhysicalInventoryResponse::Reason_MAX;
+const int PhysicalInventoryResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* HWComponentInfoGetResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[1];
+}
+bool HWComponentInfoGetResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse::UNDEFINED_REASON;
+const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse::UNKNOWN_DEVICE;
+const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse::UNKNOWN_COMPONENT;
+const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse::INTERNAL_ERROR;
+const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse::DEVICE_UNREACHABLE;
+const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse::Reason_MIN;
+const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse::Reason_MAX;
+const int HWComponentInfoGetResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* HWComponentInfoSetResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[2];
+}
+bool HWComponentInfoSetResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse::UNDEFINED_REASON;
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse::UNKNOWN_DEVICE;
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse::UNKNOWN_COMPONENT;
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse::INVALID_PARAMS;
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse::INTERNAL_ERROR;
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse::DEVICE_UNREACHABLE;
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse::Reason_MIN;
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse::Reason_MAX;
+const int HWComponentInfoSetResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* StartManagingDeviceResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[3];
+}
+bool StartManagingDeviceResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const StartManagingDeviceResponse_Reason StartManagingDeviceResponse::UNDEFINED_REASON;
+const StartManagingDeviceResponse_Reason StartManagingDeviceResponse::DEVICE_ALREADY_MANAGED;
+const StartManagingDeviceResponse_Reason StartManagingDeviceResponse::OPERATION_ALREADY_IN_PROGRESS;
+const StartManagingDeviceResponse_Reason StartManagingDeviceResponse::INVALID_PARAMS;
+const StartManagingDeviceResponse_Reason StartManagingDeviceResponse::INTERNAL_ERROR;
+const StartManagingDeviceResponse_Reason StartManagingDeviceResponse::Reason_MIN;
+const StartManagingDeviceResponse_Reason StartManagingDeviceResponse::Reason_MAX;
+const int StartManagingDeviceResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* StopManagingDeviceResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[4];
+}
+bool StopManagingDeviceResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const StopManagingDeviceResponse_Reason StopManagingDeviceResponse::UNDEFINED_REASON;
+const StopManagingDeviceResponse_Reason StopManagingDeviceResponse::UNKNOWN_DEVICE;
+const StopManagingDeviceResponse_Reason StopManagingDeviceResponse::Reason_MIN;
+const StopManagingDeviceResponse_Reason StopManagingDeviceResponse::Reason_MAX;
+const int StopManagingDeviceResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* ManagedDevicesResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[5];
+}
+bool ManagedDevicesResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const ManagedDevicesResponse_Reason ManagedDevicesResponse::UNDEFINED_REASON;
+const ManagedDevicesResponse_Reason ManagedDevicesResponse::INTERNAL_ERROR;
+const ManagedDevicesResponse_Reason ManagedDevicesResponse::Reason_MIN;
+const ManagedDevicesResponse_Reason ManagedDevicesResponse::Reason_MAX;
+const int ManagedDevicesResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* SetRemoteEndpointResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[6];
+}
+bool SetRemoteEndpointResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse::UNDEFINED_REASON;
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse::UNKNOWN_DEVICE;
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse::INTERNAL_ERROR;
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse::LOGGING_ENDPOINT_ERROR;
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse::LOGGING_ENDPOINT_PROTOCOL_ERROR;
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse::MSGBUS_ENDPOINT_ERROR;
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse::DEVICE_UNREACHABLE;
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse::Reason_MIN;
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse::Reason_MAX;
+const int SetRemoteEndpointResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* GetLoggingEndpointResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[7];
+}
+bool GetLoggingEndpointResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse::UNDEFINED_REASON;
+const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse::UNKNOWN_DEVICE;
+const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse::INTERNAL_ERROR;
+const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse::DEVICE_UNREACHABLE;
+const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse::Reason_MIN;
+const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse::Reason_MAX;
+const int GetLoggingEndpointResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* GetMsgBusEndpointResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[8];
+}
+bool GetMsgBusEndpointResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const GetMsgBusEndpointResponse_Reason GetMsgBusEndpointResponse::UNDEFINED_REASON;
+const GetMsgBusEndpointResponse_Reason GetMsgBusEndpointResponse::INTERNAL_ERROR;
+const GetMsgBusEndpointResponse_Reason GetMsgBusEndpointResponse::DEVICE_UNREACHABLE;
+const GetMsgBusEndpointResponse_Reason GetMsgBusEndpointResponse::Reason_MIN;
+const GetMsgBusEndpointResponse_Reason GetMsgBusEndpointResponse::Reason_MAX;
+const int GetMsgBusEndpointResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* SetLogLevelResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[9];
+}
+bool SetLogLevelResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const SetLogLevelResponse_Reason SetLogLevelResponse::UNDEFINED_REASON;
+const SetLogLevelResponse_Reason SetLogLevelResponse::UNKNOWN_DEVICE;
+const SetLogLevelResponse_Reason SetLogLevelResponse::INTERNAL_ERROR;
+const SetLogLevelResponse_Reason SetLogLevelResponse::UNKNOWN_LOG_ENTITY;
+const SetLogLevelResponse_Reason SetLogLevelResponse::DEVICE_UNREACHABLE;
+const SetLogLevelResponse_Reason SetLogLevelResponse::Reason_MIN;
+const SetLogLevelResponse_Reason SetLogLevelResponse::Reason_MAX;
+const int SetLogLevelResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* GetLogLevelResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[10];
+}
+bool GetLogLevelResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const GetLogLevelResponse_Reason GetLogLevelResponse::UNDEFINED_REASON;
+const GetLogLevelResponse_Reason GetLogLevelResponse::UNKNOWN_DEVICE;
+const GetLogLevelResponse_Reason GetLogLevelResponse::INTERNAL_ERROR;
+const GetLogLevelResponse_Reason GetLogLevelResponse::UNKNOWN_LOG_ENTITY;
+const GetLogLevelResponse_Reason GetLogLevelResponse::DEVICE_UNREACHABLE;
+const GetLogLevelResponse_Reason GetLogLevelResponse::Reason_MIN;
+const GetLogLevelResponse_Reason GetLogLevelResponse::Reason_MAX;
+const int GetLogLevelResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+// ===================================================================
+
+void PhysicalInventoryRequest::InitAsDefaultInstance() {
+  ::dmi::_PhysicalInventoryRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class PhysicalInventoryRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const PhysicalInventoryRequest* msg);
+};
+
+const ::dmi::Uuid&
+PhysicalInventoryRequest::HasBitSetters::device_uuid(const PhysicalInventoryRequest* msg) {
+  return *msg->device_uuid_;
+}
+void PhysicalInventoryRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int PhysicalInventoryRequest::kDeviceUuidFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+PhysicalInventoryRequest::PhysicalInventoryRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.PhysicalInventoryRequest)
+}
+PhysicalInventoryRequest::PhysicalInventoryRequest(const PhysicalInventoryRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.PhysicalInventoryRequest)
+}
+
+void PhysicalInventoryRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_PhysicalInventoryRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  device_uuid_ = nullptr;
+}
+
+PhysicalInventoryRequest::~PhysicalInventoryRequest() {
+  // @@protoc_insertion_point(destructor:dmi.PhysicalInventoryRequest)
+  SharedDtor();
+}
+
+void PhysicalInventoryRequest::SharedDtor() {
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void PhysicalInventoryRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const PhysicalInventoryRequest& PhysicalInventoryRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_PhysicalInventoryRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void PhysicalInventoryRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.PhysicalInventoryRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* PhysicalInventoryRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<PhysicalInventoryRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool PhysicalInventoryRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.PhysicalInventoryRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.PhysicalInventoryRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.PhysicalInventoryRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void PhysicalInventoryRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.PhysicalInventoryRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.PhysicalInventoryRequest)
+}
+
+::google::protobuf::uint8* PhysicalInventoryRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.PhysicalInventoryRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.PhysicalInventoryRequest)
+  return target;
+}
+
+size_t PhysicalInventoryRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.PhysicalInventoryRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void PhysicalInventoryRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.PhysicalInventoryRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const PhysicalInventoryRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<PhysicalInventoryRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.PhysicalInventoryRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.PhysicalInventoryRequest)
+    MergeFrom(*source);
+  }
+}
+
+void PhysicalInventoryRequest::MergeFrom(const PhysicalInventoryRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.PhysicalInventoryRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+}
+
+void PhysicalInventoryRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.PhysicalInventoryRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void PhysicalInventoryRequest::CopyFrom(const PhysicalInventoryRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.PhysicalInventoryRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool PhysicalInventoryRequest::IsInitialized() const {
+  return true;
+}
+
+void PhysicalInventoryRequest::Swap(PhysicalInventoryRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void PhysicalInventoryRequest::InternalSwap(PhysicalInventoryRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(device_uuid_, other->device_uuid_);
+}
+
+::google::protobuf::Metadata PhysicalInventoryRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void PhysicalInventoryResponse::InitAsDefaultInstance() {
+  ::dmi::_PhysicalInventoryResponse_default_instance_._instance.get_mutable()->inventory_ = const_cast< ::dmi::Hardware*>(
+      ::dmi::Hardware::internal_default_instance());
+}
+class PhysicalInventoryResponse::HasBitSetters {
+ public:
+  static const ::dmi::Hardware& inventory(const PhysicalInventoryResponse* msg);
+};
+
+const ::dmi::Hardware&
+PhysicalInventoryResponse::HasBitSetters::inventory(const PhysicalInventoryResponse* msg) {
+  return *msg->inventory_;
+}
+void PhysicalInventoryResponse::clear_inventory() {
+  if (GetArenaNoVirtual() == nullptr && inventory_ != nullptr) {
+    delete inventory_;
+  }
+  inventory_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int PhysicalInventoryResponse::kStatusFieldNumber;
+const int PhysicalInventoryResponse::kReasonFieldNumber;
+const int PhysicalInventoryResponse::kInventoryFieldNumber;
+const int PhysicalInventoryResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+PhysicalInventoryResponse::PhysicalInventoryResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.PhysicalInventoryResponse)
+}
+PhysicalInventoryResponse::PhysicalInventoryResponse(const PhysicalInventoryResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_inventory()) {
+    inventory_ = new ::dmi::Hardware(*from.inventory_);
+  } else {
+    inventory_ = nullptr;
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.PhysicalInventoryResponse)
+}
+
+void PhysicalInventoryResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_PhysicalInventoryResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&inventory_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&inventory_)) + sizeof(reason_));
+}
+
+PhysicalInventoryResponse::~PhysicalInventoryResponse() {
+  // @@protoc_insertion_point(destructor:dmi.PhysicalInventoryResponse)
+  SharedDtor();
+}
+
+void PhysicalInventoryResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete inventory_;
+}
+
+void PhysicalInventoryResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const PhysicalInventoryResponse& PhysicalInventoryResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_PhysicalInventoryResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void PhysicalInventoryResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.PhysicalInventoryResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && inventory_ != nullptr) {
+    delete inventory_;
+  }
+  inventory_ = nullptr;
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* PhysicalInventoryResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<PhysicalInventoryResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.PhysicalInventoryResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::PhysicalInventoryResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.Hardware inventory = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Hardware::_InternalParse;
+        object = msg->mutable_inventory();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.PhysicalInventoryResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool PhysicalInventoryResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.PhysicalInventoryResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.PhysicalInventoryResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::PhysicalInventoryResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Hardware inventory = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_inventory()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.PhysicalInventoryResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.PhysicalInventoryResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.PhysicalInventoryResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void PhysicalInventoryResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.PhysicalInventoryResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.PhysicalInventoryResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // .dmi.Hardware inventory = 3;
+  if (this->has_inventory()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::inventory(this), output);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.PhysicalInventoryResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.PhysicalInventoryResponse)
+}
+
+::google::protobuf::uint8* PhysicalInventoryResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.PhysicalInventoryResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.PhysicalInventoryResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // .dmi.Hardware inventory = 3;
+  if (this->has_inventory()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::inventory(this), target);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.PhysicalInventoryResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.PhysicalInventoryResponse)
+  return target;
+}
+
+size_t PhysicalInventoryResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.PhysicalInventoryResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Hardware inventory = 3;
+  if (this->has_inventory()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *inventory_);
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.PhysicalInventoryResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void PhysicalInventoryResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.PhysicalInventoryResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const PhysicalInventoryResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<PhysicalInventoryResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.PhysicalInventoryResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.PhysicalInventoryResponse)
+    MergeFrom(*source);
+  }
+}
+
+void PhysicalInventoryResponse::MergeFrom(const PhysicalInventoryResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.PhysicalInventoryResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_inventory()) {
+    mutable_inventory()->::dmi::Hardware::MergeFrom(from.inventory());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void PhysicalInventoryResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.PhysicalInventoryResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void PhysicalInventoryResponse::CopyFrom(const PhysicalInventoryResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.PhysicalInventoryResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool PhysicalInventoryResponse::IsInitialized() const {
+  return true;
+}
+
+void PhysicalInventoryResponse::Swap(PhysicalInventoryResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void PhysicalInventoryResponse::InternalSwap(PhysicalInventoryResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(inventory_, other->inventory_);
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata PhysicalInventoryResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void HWComponentInfoGetRequest::InitAsDefaultInstance() {
+  ::dmi::_HWComponentInfoGetRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_HWComponentInfoGetRequest_default_instance_._instance.get_mutable()->component_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class HWComponentInfoGetRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const HWComponentInfoGetRequest* msg);
+  static const ::dmi::Uuid& component_uuid(const HWComponentInfoGetRequest* msg);
+};
+
+const ::dmi::Uuid&
+HWComponentInfoGetRequest::HasBitSetters::device_uuid(const HWComponentInfoGetRequest* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::Uuid&
+HWComponentInfoGetRequest::HasBitSetters::component_uuid(const HWComponentInfoGetRequest* msg) {
+  return *msg->component_uuid_;
+}
+void HWComponentInfoGetRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void HWComponentInfoGetRequest::clear_component_uuid() {
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int HWComponentInfoGetRequest::kDeviceUuidFieldNumber;
+const int HWComponentInfoGetRequest::kComponentUuidFieldNumber;
+const int HWComponentInfoGetRequest::kComponentNameFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+HWComponentInfoGetRequest::HWComponentInfoGetRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.HWComponentInfoGetRequest)
+}
+HWComponentInfoGetRequest::HWComponentInfoGetRequest(const HWComponentInfoGetRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.component_name().size() > 0) {
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  if (from.has_component_uuid()) {
+    component_uuid_ = new ::dmi::Uuid(*from.component_uuid_);
+  } else {
+    component_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.HWComponentInfoGetRequest)
+}
+
+void HWComponentInfoGetRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_HWComponentInfoGetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&component_uuid_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(component_uuid_));
+}
+
+HWComponentInfoGetRequest::~HWComponentInfoGetRequest() {
+  // @@protoc_insertion_point(destructor:dmi.HWComponentInfoGetRequest)
+  SharedDtor();
+}
+
+void HWComponentInfoGetRequest::SharedDtor() {
+  component_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (this != internal_default_instance()) delete component_uuid_;
+}
+
+void HWComponentInfoGetRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const HWComponentInfoGetRequest& HWComponentInfoGetRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_HWComponentInfoGetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void HWComponentInfoGetRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.HWComponentInfoGetRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* HWComponentInfoGetRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<HWComponentInfoGetRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_component_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string component_name = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.HWComponentInfoGetRequest.component_name");
+        object = msg->mutable_component_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool HWComponentInfoGetRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.HWComponentInfoGetRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_component_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string component_name = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_component_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->component_name().data(), static_cast<int>(this->component_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.HWComponentInfoGetRequest.component_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.HWComponentInfoGetRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.HWComponentInfoGetRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void HWComponentInfoGetRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.HWComponentInfoGetRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::component_uuid(this), output);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.HWComponentInfoGetRequest.component_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->component_name(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.HWComponentInfoGetRequest)
+}
+
+::google::protobuf::uint8* HWComponentInfoGetRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.HWComponentInfoGetRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::component_uuid(this), target);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.HWComponentInfoGetRequest.component_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->component_name(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.HWComponentInfoGetRequest)
+  return target;
+}
+
+size_t HWComponentInfoGetRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.HWComponentInfoGetRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->component_name());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *component_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void HWComponentInfoGetRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.HWComponentInfoGetRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const HWComponentInfoGetRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<HWComponentInfoGetRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.HWComponentInfoGetRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.HWComponentInfoGetRequest)
+    MergeFrom(*source);
+  }
+}
+
+void HWComponentInfoGetRequest::MergeFrom(const HWComponentInfoGetRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.HWComponentInfoGetRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.component_name().size() > 0) {
+
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.has_component_uuid()) {
+    mutable_component_uuid()->::dmi::Uuid::MergeFrom(from.component_uuid());
+  }
+}
+
+void HWComponentInfoGetRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.HWComponentInfoGetRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void HWComponentInfoGetRequest::CopyFrom(const HWComponentInfoGetRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.HWComponentInfoGetRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool HWComponentInfoGetRequest::IsInitialized() const {
+  return true;
+}
+
+void HWComponentInfoGetRequest::Swap(HWComponentInfoGetRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void HWComponentInfoGetRequest::InternalSwap(HWComponentInfoGetRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  component_name_.Swap(&other->component_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(component_uuid_, other->component_uuid_);
+}
+
+::google::protobuf::Metadata HWComponentInfoGetRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void HWComponentInfoGetResponse::InitAsDefaultInstance() {
+  ::dmi::_HWComponentInfoGetResponse_default_instance_._instance.get_mutable()->component_ = const_cast< ::dmi::Component*>(
+      ::dmi::Component::internal_default_instance());
+}
+class HWComponentInfoGetResponse::HasBitSetters {
+ public:
+  static const ::dmi::Component& component(const HWComponentInfoGetResponse* msg);
+};
+
+const ::dmi::Component&
+HWComponentInfoGetResponse::HasBitSetters::component(const HWComponentInfoGetResponse* msg) {
+  return *msg->component_;
+}
+void HWComponentInfoGetResponse::clear_component() {
+  if (GetArenaNoVirtual() == nullptr && component_ != nullptr) {
+    delete component_;
+  }
+  component_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int HWComponentInfoGetResponse::kStatusFieldNumber;
+const int HWComponentInfoGetResponse::kReasonFieldNumber;
+const int HWComponentInfoGetResponse::kComponentFieldNumber;
+const int HWComponentInfoGetResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+HWComponentInfoGetResponse::HWComponentInfoGetResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.HWComponentInfoGetResponse)
+}
+HWComponentInfoGetResponse::HWComponentInfoGetResponse(const HWComponentInfoGetResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_component()) {
+    component_ = new ::dmi::Component(*from.component_);
+  } else {
+    component_ = nullptr;
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.HWComponentInfoGetResponse)
+}
+
+void HWComponentInfoGetResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_HWComponentInfoGetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&component_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&component_)) + sizeof(reason_));
+}
+
+HWComponentInfoGetResponse::~HWComponentInfoGetResponse() {
+  // @@protoc_insertion_point(destructor:dmi.HWComponentInfoGetResponse)
+  SharedDtor();
+}
+
+void HWComponentInfoGetResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete component_;
+}
+
+void HWComponentInfoGetResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const HWComponentInfoGetResponse& HWComponentInfoGetResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_HWComponentInfoGetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void HWComponentInfoGetResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.HWComponentInfoGetResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && component_ != nullptr) {
+    delete component_;
+  }
+  component_ = nullptr;
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* HWComponentInfoGetResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<HWComponentInfoGetResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.HWComponentInfoGetResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::HWComponentInfoGetResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.Component component = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Component::_InternalParse;
+        object = msg->mutable_component();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.HWComponentInfoGetResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool HWComponentInfoGetResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.HWComponentInfoGetResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.HWComponentInfoGetResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::HWComponentInfoGetResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Component component = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_component()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.HWComponentInfoGetResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.HWComponentInfoGetResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.HWComponentInfoGetResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void HWComponentInfoGetResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.HWComponentInfoGetResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.HWComponentInfoGetResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // .dmi.Component component = 3;
+  if (this->has_component()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::component(this), output);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.HWComponentInfoGetResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.HWComponentInfoGetResponse)
+}
+
+::google::protobuf::uint8* HWComponentInfoGetResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.HWComponentInfoGetResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.HWComponentInfoGetResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // .dmi.Component component = 3;
+  if (this->has_component()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::component(this), target);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.HWComponentInfoGetResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.HWComponentInfoGetResponse)
+  return target;
+}
+
+size_t HWComponentInfoGetResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.HWComponentInfoGetResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Component component = 3;
+  if (this->has_component()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *component_);
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.HWComponentInfoGetResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void HWComponentInfoGetResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.HWComponentInfoGetResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const HWComponentInfoGetResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<HWComponentInfoGetResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.HWComponentInfoGetResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.HWComponentInfoGetResponse)
+    MergeFrom(*source);
+  }
+}
+
+void HWComponentInfoGetResponse::MergeFrom(const HWComponentInfoGetResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.HWComponentInfoGetResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_component()) {
+    mutable_component()->::dmi::Component::MergeFrom(from.component());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void HWComponentInfoGetResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.HWComponentInfoGetResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void HWComponentInfoGetResponse::CopyFrom(const HWComponentInfoGetResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.HWComponentInfoGetResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool HWComponentInfoGetResponse::IsInitialized() const {
+  return true;
+}
+
+void HWComponentInfoGetResponse::Swap(HWComponentInfoGetResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void HWComponentInfoGetResponse::InternalSwap(HWComponentInfoGetResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(component_, other->component_);
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata HWComponentInfoGetResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void HWComponentInfoSetRequest::InitAsDefaultInstance() {
+  ::dmi::_HWComponentInfoSetRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_HWComponentInfoSetRequest_default_instance_._instance.get_mutable()->component_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_HWComponentInfoSetRequest_default_instance_._instance.get_mutable()->changes_ = const_cast< ::dmi::ModifiableComponent*>(
+      ::dmi::ModifiableComponent::internal_default_instance());
+}
+class HWComponentInfoSetRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const HWComponentInfoSetRequest* msg);
+  static const ::dmi::Uuid& component_uuid(const HWComponentInfoSetRequest* msg);
+  static const ::dmi::ModifiableComponent& changes(const HWComponentInfoSetRequest* msg);
+};
+
+const ::dmi::Uuid&
+HWComponentInfoSetRequest::HasBitSetters::device_uuid(const HWComponentInfoSetRequest* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::Uuid&
+HWComponentInfoSetRequest::HasBitSetters::component_uuid(const HWComponentInfoSetRequest* msg) {
+  return *msg->component_uuid_;
+}
+const ::dmi::ModifiableComponent&
+HWComponentInfoSetRequest::HasBitSetters::changes(const HWComponentInfoSetRequest* msg) {
+  return *msg->changes_;
+}
+void HWComponentInfoSetRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void HWComponentInfoSetRequest::clear_component_uuid() {
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+}
+void HWComponentInfoSetRequest::clear_changes() {
+  if (GetArenaNoVirtual() == nullptr && changes_ != nullptr) {
+    delete changes_;
+  }
+  changes_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int HWComponentInfoSetRequest::kDeviceUuidFieldNumber;
+const int HWComponentInfoSetRequest::kComponentUuidFieldNumber;
+const int HWComponentInfoSetRequest::kComponentNameFieldNumber;
+const int HWComponentInfoSetRequest::kChangesFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+HWComponentInfoSetRequest::HWComponentInfoSetRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.HWComponentInfoSetRequest)
+}
+HWComponentInfoSetRequest::HWComponentInfoSetRequest(const HWComponentInfoSetRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.component_name().size() > 0) {
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  if (from.has_component_uuid()) {
+    component_uuid_ = new ::dmi::Uuid(*from.component_uuid_);
+  } else {
+    component_uuid_ = nullptr;
+  }
+  if (from.has_changes()) {
+    changes_ = new ::dmi::ModifiableComponent(*from.changes_);
+  } else {
+    changes_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.HWComponentInfoSetRequest)
+}
+
+void HWComponentInfoSetRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_HWComponentInfoSetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&changes_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(changes_));
+}
+
+HWComponentInfoSetRequest::~HWComponentInfoSetRequest() {
+  // @@protoc_insertion_point(destructor:dmi.HWComponentInfoSetRequest)
+  SharedDtor();
+}
+
+void HWComponentInfoSetRequest::SharedDtor() {
+  component_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (this != internal_default_instance()) delete component_uuid_;
+  if (this != internal_default_instance()) delete changes_;
+}
+
+void HWComponentInfoSetRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const HWComponentInfoSetRequest& HWComponentInfoSetRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_HWComponentInfoSetRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void HWComponentInfoSetRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.HWComponentInfoSetRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && changes_ != nullptr) {
+    delete changes_;
+  }
+  changes_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* HWComponentInfoSetRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<HWComponentInfoSetRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_component_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string component_name = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.HWComponentInfoSetRequest.component_name");
+        object = msg->mutable_component_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // .dmi.ModifiableComponent changes = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ModifiableComponent::_InternalParse;
+        object = msg->mutable_changes();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool HWComponentInfoSetRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.HWComponentInfoSetRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_component_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string component_name = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_component_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->component_name().data(), static_cast<int>(this->component_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.HWComponentInfoSetRequest.component_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ModifiableComponent changes = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_changes()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.HWComponentInfoSetRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.HWComponentInfoSetRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void HWComponentInfoSetRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.HWComponentInfoSetRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::component_uuid(this), output);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.HWComponentInfoSetRequest.component_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->component_name(), output);
+  }
+
+  // .dmi.ModifiableComponent changes = 4;
+  if (this->has_changes()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      4, HasBitSetters::changes(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.HWComponentInfoSetRequest)
+}
+
+::google::protobuf::uint8* HWComponentInfoSetRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.HWComponentInfoSetRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::component_uuid(this), target);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.HWComponentInfoSetRequest.component_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->component_name(), target);
+  }
+
+  // .dmi.ModifiableComponent changes = 4;
+  if (this->has_changes()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        4, HasBitSetters::changes(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.HWComponentInfoSetRequest)
+  return target;
+}
+
+size_t HWComponentInfoSetRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.HWComponentInfoSetRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->component_name());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *component_uuid_);
+  }
+
+  // .dmi.ModifiableComponent changes = 4;
+  if (this->has_changes()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *changes_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void HWComponentInfoSetRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.HWComponentInfoSetRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const HWComponentInfoSetRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<HWComponentInfoSetRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.HWComponentInfoSetRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.HWComponentInfoSetRequest)
+    MergeFrom(*source);
+  }
+}
+
+void HWComponentInfoSetRequest::MergeFrom(const HWComponentInfoSetRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.HWComponentInfoSetRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.component_name().size() > 0) {
+
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.has_component_uuid()) {
+    mutable_component_uuid()->::dmi::Uuid::MergeFrom(from.component_uuid());
+  }
+  if (from.has_changes()) {
+    mutable_changes()->::dmi::ModifiableComponent::MergeFrom(from.changes());
+  }
+}
+
+void HWComponentInfoSetRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.HWComponentInfoSetRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void HWComponentInfoSetRequest::CopyFrom(const HWComponentInfoSetRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.HWComponentInfoSetRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool HWComponentInfoSetRequest::IsInitialized() const {
+  return true;
+}
+
+void HWComponentInfoSetRequest::Swap(HWComponentInfoSetRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void HWComponentInfoSetRequest::InternalSwap(HWComponentInfoSetRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  component_name_.Swap(&other->component_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(component_uuid_, other->component_uuid_);
+  swap(changes_, other->changes_);
+}
+
+::google::protobuf::Metadata HWComponentInfoSetRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void HWComponentInfoSetResponse::InitAsDefaultInstance() {
+}
+class HWComponentInfoSetResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int HWComponentInfoSetResponse::kStatusFieldNumber;
+const int HWComponentInfoSetResponse::kReasonFieldNumber;
+const int HWComponentInfoSetResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+HWComponentInfoSetResponse::HWComponentInfoSetResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.HWComponentInfoSetResponse)
+}
+HWComponentInfoSetResponse::HWComponentInfoSetResponse(const HWComponentInfoSetResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.HWComponentInfoSetResponse)
+}
+
+void HWComponentInfoSetResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_HWComponentInfoSetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+HWComponentInfoSetResponse::~HWComponentInfoSetResponse() {
+  // @@protoc_insertion_point(destructor:dmi.HWComponentInfoSetResponse)
+  SharedDtor();
+}
+
+void HWComponentInfoSetResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void HWComponentInfoSetResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const HWComponentInfoSetResponse& HWComponentInfoSetResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_HWComponentInfoSetResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void HWComponentInfoSetResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.HWComponentInfoSetResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* HWComponentInfoSetResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<HWComponentInfoSetResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.HWComponentInfoSetResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::HWComponentInfoSetResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.HWComponentInfoSetResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool HWComponentInfoSetResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.HWComponentInfoSetResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.HWComponentInfoSetResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::HWComponentInfoSetResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.HWComponentInfoSetResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.HWComponentInfoSetResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.HWComponentInfoSetResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void HWComponentInfoSetResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.HWComponentInfoSetResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.HWComponentInfoSetResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.HWComponentInfoSetResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.HWComponentInfoSetResponse)
+}
+
+::google::protobuf::uint8* HWComponentInfoSetResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.HWComponentInfoSetResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.HWComponentInfoSetResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.HWComponentInfoSetResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.HWComponentInfoSetResponse)
+  return target;
+}
+
+size_t HWComponentInfoSetResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.HWComponentInfoSetResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.HWComponentInfoSetResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void HWComponentInfoSetResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.HWComponentInfoSetResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const HWComponentInfoSetResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<HWComponentInfoSetResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.HWComponentInfoSetResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.HWComponentInfoSetResponse)
+    MergeFrom(*source);
+  }
+}
+
+void HWComponentInfoSetResponse::MergeFrom(const HWComponentInfoSetResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.HWComponentInfoSetResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void HWComponentInfoSetResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.HWComponentInfoSetResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void HWComponentInfoSetResponse::CopyFrom(const HWComponentInfoSetResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.HWComponentInfoSetResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool HWComponentInfoSetResponse::IsInitialized() const {
+  return true;
+}
+
+void HWComponentInfoSetResponse::Swap(HWComponentInfoSetResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void HWComponentInfoSetResponse::InternalSwap(HWComponentInfoSetResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata HWComponentInfoSetResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void StartManagingDeviceResponse::InitAsDefaultInstance() {
+  ::dmi::_StartManagingDeviceResponse_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class StartManagingDeviceResponse::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const StartManagingDeviceResponse* msg);
+};
+
+const ::dmi::Uuid&
+StartManagingDeviceResponse::HasBitSetters::device_uuid(const StartManagingDeviceResponse* msg) {
+  return *msg->device_uuid_;
+}
+void StartManagingDeviceResponse::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int StartManagingDeviceResponse::kStatusFieldNumber;
+const int StartManagingDeviceResponse::kReasonFieldNumber;
+const int StartManagingDeviceResponse::kDeviceUuidFieldNumber;
+const int StartManagingDeviceResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+StartManagingDeviceResponse::StartManagingDeviceResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.StartManagingDeviceResponse)
+}
+StartManagingDeviceResponse::StartManagingDeviceResponse(const StartManagingDeviceResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.StartManagingDeviceResponse)
+}
+
+void StartManagingDeviceResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_StartManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(reason_));
+}
+
+StartManagingDeviceResponse::~StartManagingDeviceResponse() {
+  // @@protoc_insertion_point(destructor:dmi.StartManagingDeviceResponse)
+  SharedDtor();
+}
+
+void StartManagingDeviceResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void StartManagingDeviceResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const StartManagingDeviceResponse& StartManagingDeviceResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_StartManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void StartManagingDeviceResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.StartManagingDeviceResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* StartManagingDeviceResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<StartManagingDeviceResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.StartManagingDeviceResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::StartManagingDeviceResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.Uuid device_uuid = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.StartManagingDeviceResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool StartManagingDeviceResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.StartManagingDeviceResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.StartManagingDeviceResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::StartManagingDeviceResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid device_uuid = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.StartManagingDeviceResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.StartManagingDeviceResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.StartManagingDeviceResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void StartManagingDeviceResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.StartManagingDeviceResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.StartManagingDeviceResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // .dmi.Uuid device_uuid = 3;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::device_uuid(this), output);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StartManagingDeviceResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.StartManagingDeviceResponse)
+}
+
+::google::protobuf::uint8* StartManagingDeviceResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.StartManagingDeviceResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.StartManagingDeviceResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // .dmi.Uuid device_uuid = 3;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::device_uuid(this), target);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StartManagingDeviceResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.StartManagingDeviceResponse)
+  return target;
+}
+
+size_t StartManagingDeviceResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.StartManagingDeviceResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Uuid device_uuid = 3;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.StartManagingDeviceResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void StartManagingDeviceResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.StartManagingDeviceResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const StartManagingDeviceResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<StartManagingDeviceResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.StartManagingDeviceResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.StartManagingDeviceResponse)
+    MergeFrom(*source);
+  }
+}
+
+void StartManagingDeviceResponse::MergeFrom(const StartManagingDeviceResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.StartManagingDeviceResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void StartManagingDeviceResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.StartManagingDeviceResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void StartManagingDeviceResponse::CopyFrom(const StartManagingDeviceResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.StartManagingDeviceResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool StartManagingDeviceResponse::IsInitialized() const {
+  return true;
+}
+
+void StartManagingDeviceResponse::Swap(StartManagingDeviceResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void StartManagingDeviceResponse::InternalSwap(StartManagingDeviceResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata StartManagingDeviceResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void StopManagingDeviceRequest::InitAsDefaultInstance() {
+}
+class StopManagingDeviceRequest::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int StopManagingDeviceRequest::kNameFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+StopManagingDeviceRequest::StopManagingDeviceRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.StopManagingDeviceRequest)
+}
+StopManagingDeviceRequest::StopManagingDeviceRequest(const StopManagingDeviceRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.name().size() > 0) {
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.StopManagingDeviceRequest)
+}
+
+void StopManagingDeviceRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_StopManagingDeviceRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+StopManagingDeviceRequest::~StopManagingDeviceRequest() {
+  // @@protoc_insertion_point(destructor:dmi.StopManagingDeviceRequest)
+  SharedDtor();
+}
+
+void StopManagingDeviceRequest::SharedDtor() {
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void StopManagingDeviceRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const StopManagingDeviceRequest& StopManagingDeviceRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_StopManagingDeviceRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void StopManagingDeviceRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.StopManagingDeviceRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* StopManagingDeviceRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<StopManagingDeviceRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.StopManagingDeviceRequest.name");
+        object = msg->mutable_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool StopManagingDeviceRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.StopManagingDeviceRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string name = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->name().data(), static_cast<int>(this->name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.StopManagingDeviceRequest.name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.StopManagingDeviceRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.StopManagingDeviceRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void StopManagingDeviceRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.StopManagingDeviceRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StopManagingDeviceRequest.name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.StopManagingDeviceRequest)
+}
+
+::google::protobuf::uint8* StopManagingDeviceRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.StopManagingDeviceRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StopManagingDeviceRequest.name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.StopManagingDeviceRequest)
+  return target;
+}
+
+size_t StopManagingDeviceRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.StopManagingDeviceRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->name());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void StopManagingDeviceRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.StopManagingDeviceRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const StopManagingDeviceRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<StopManagingDeviceRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.StopManagingDeviceRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.StopManagingDeviceRequest)
+    MergeFrom(*source);
+  }
+}
+
+void StopManagingDeviceRequest::MergeFrom(const StopManagingDeviceRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.StopManagingDeviceRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.name().size() > 0) {
+
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+}
+
+void StopManagingDeviceRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.StopManagingDeviceRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void StopManagingDeviceRequest::CopyFrom(const StopManagingDeviceRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.StopManagingDeviceRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool StopManagingDeviceRequest::IsInitialized() const {
+  return true;
+}
+
+void StopManagingDeviceRequest::Swap(StopManagingDeviceRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void StopManagingDeviceRequest::InternalSwap(StopManagingDeviceRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+}
+
+::google::protobuf::Metadata StopManagingDeviceRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void StopManagingDeviceResponse::InitAsDefaultInstance() {
+}
+class StopManagingDeviceResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int StopManagingDeviceResponse::kStatusFieldNumber;
+const int StopManagingDeviceResponse::kReasonFieldNumber;
+const int StopManagingDeviceResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+StopManagingDeviceResponse::StopManagingDeviceResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.StopManagingDeviceResponse)
+}
+StopManagingDeviceResponse::StopManagingDeviceResponse(const StopManagingDeviceResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.StopManagingDeviceResponse)
+}
+
+void StopManagingDeviceResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_StopManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+StopManagingDeviceResponse::~StopManagingDeviceResponse() {
+  // @@protoc_insertion_point(destructor:dmi.StopManagingDeviceResponse)
+  SharedDtor();
+}
+
+void StopManagingDeviceResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void StopManagingDeviceResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const StopManagingDeviceResponse& StopManagingDeviceResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_StopManagingDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void StopManagingDeviceResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.StopManagingDeviceResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* StopManagingDeviceResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<StopManagingDeviceResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.StopManagingDeviceResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::StopManagingDeviceResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.StopManagingDeviceResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool StopManagingDeviceResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.StopManagingDeviceResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.StopManagingDeviceResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::StopManagingDeviceResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.StopManagingDeviceResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.StopManagingDeviceResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.StopManagingDeviceResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void StopManagingDeviceResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.StopManagingDeviceResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.StopManagingDeviceResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StopManagingDeviceResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.StopManagingDeviceResponse)
+}
+
+::google::protobuf::uint8* StopManagingDeviceResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.StopManagingDeviceResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.StopManagingDeviceResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StopManagingDeviceResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.StopManagingDeviceResponse)
+  return target;
+}
+
+size_t StopManagingDeviceResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.StopManagingDeviceResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.StopManagingDeviceResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void StopManagingDeviceResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.StopManagingDeviceResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const StopManagingDeviceResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<StopManagingDeviceResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.StopManagingDeviceResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.StopManagingDeviceResponse)
+    MergeFrom(*source);
+  }
+}
+
+void StopManagingDeviceResponse::MergeFrom(const StopManagingDeviceResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.StopManagingDeviceResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void StopManagingDeviceResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.StopManagingDeviceResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void StopManagingDeviceResponse::CopyFrom(const StopManagingDeviceResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.StopManagingDeviceResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool StopManagingDeviceResponse::IsInitialized() const {
+  return true;
+}
+
+void StopManagingDeviceResponse::Swap(StopManagingDeviceResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void StopManagingDeviceResponse::InternalSwap(StopManagingDeviceResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata StopManagingDeviceResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ManagedDeviceInfo::InitAsDefaultInstance() {
+  ::dmi::_ManagedDeviceInfo_default_instance_._instance.get_mutable()->info_ = const_cast< ::dmi::ModifiableComponent*>(
+      ::dmi::ModifiableComponent::internal_default_instance());
+  ::dmi::_ManagedDeviceInfo_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class ManagedDeviceInfo::HasBitSetters {
+ public:
+  static const ::dmi::ModifiableComponent& info(const ManagedDeviceInfo* msg);
+  static const ::dmi::Uuid& device_uuid(const ManagedDeviceInfo* msg);
+};
+
+const ::dmi::ModifiableComponent&
+ManagedDeviceInfo::HasBitSetters::info(const ManagedDeviceInfo* msg) {
+  return *msg->info_;
+}
+const ::dmi::Uuid&
+ManagedDeviceInfo::HasBitSetters::device_uuid(const ManagedDeviceInfo* msg) {
+  return *msg->device_uuid_;
+}
+void ManagedDeviceInfo::clear_info() {
+  if (GetArenaNoVirtual() == nullptr && info_ != nullptr) {
+    delete info_;
+  }
+  info_ = nullptr;
+}
+void ManagedDeviceInfo::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ManagedDeviceInfo::kInfoFieldNumber;
+const int ManagedDeviceInfo::kDeviceUuidFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ManagedDeviceInfo::ManagedDeviceInfo()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ManagedDeviceInfo)
+}
+ManagedDeviceInfo::ManagedDeviceInfo(const ManagedDeviceInfo& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_info()) {
+    info_ = new ::dmi::ModifiableComponent(*from.info_);
+  } else {
+    info_ = nullptr;
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.ManagedDeviceInfo)
+}
+
+void ManagedDeviceInfo::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ManagedDeviceInfo_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::memset(&info_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&device_uuid_) -
+      reinterpret_cast<char*>(&info_)) + sizeof(device_uuid_));
+}
+
+ManagedDeviceInfo::~ManagedDeviceInfo() {
+  // @@protoc_insertion_point(destructor:dmi.ManagedDeviceInfo)
+  SharedDtor();
+}
+
+void ManagedDeviceInfo::SharedDtor() {
+  if (this != internal_default_instance()) delete info_;
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void ManagedDeviceInfo::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ManagedDeviceInfo& ManagedDeviceInfo::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ManagedDeviceInfo_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ManagedDeviceInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ManagedDeviceInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && info_ != nullptr) {
+    delete info_;
+  }
+  info_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ManagedDeviceInfo::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ManagedDeviceInfo*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.ModifiableComponent info = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ModifiableComponent::_InternalParse;
+        object = msg->mutable_info();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid device_uuid = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ManagedDeviceInfo::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ManagedDeviceInfo)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.ModifiableComponent info = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_info()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid device_uuid = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ManagedDeviceInfo)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ManagedDeviceInfo)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ManagedDeviceInfo::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ManagedDeviceInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ModifiableComponent info = 1;
+  if (this->has_info()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::info(this), output);
+  }
+
+  // .dmi.Uuid device_uuid = 2;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::device_uuid(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ManagedDeviceInfo)
+}
+
+::google::protobuf::uint8* ManagedDeviceInfo::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ManagedDeviceInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ModifiableComponent info = 1;
+  if (this->has_info()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::info(this), target);
+  }
+
+  // .dmi.Uuid device_uuid = 2;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::device_uuid(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ManagedDeviceInfo)
+  return target;
+}
+
+size_t ManagedDeviceInfo::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ManagedDeviceInfo)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.ModifiableComponent info = 1;
+  if (this->has_info()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *info_);
+  }
+
+  // .dmi.Uuid device_uuid = 2;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ManagedDeviceInfo::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ManagedDeviceInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ManagedDeviceInfo* source =
+      ::google::protobuf::DynamicCastToGenerated<ManagedDeviceInfo>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ManagedDeviceInfo)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ManagedDeviceInfo)
+    MergeFrom(*source);
+  }
+}
+
+void ManagedDeviceInfo::MergeFrom(const ManagedDeviceInfo& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ManagedDeviceInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_info()) {
+    mutable_info()->::dmi::ModifiableComponent::MergeFrom(from.info());
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+}
+
+void ManagedDeviceInfo::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ManagedDeviceInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ManagedDeviceInfo::CopyFrom(const ManagedDeviceInfo& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ManagedDeviceInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ManagedDeviceInfo::IsInitialized() const {
+  return true;
+}
+
+void ManagedDeviceInfo::Swap(ManagedDeviceInfo* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ManagedDeviceInfo::InternalSwap(ManagedDeviceInfo* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(info_, other->info_);
+  swap(device_uuid_, other->device_uuid_);
+}
+
+::google::protobuf::Metadata ManagedDeviceInfo::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ManagedDevicesResponse::InitAsDefaultInstance() {
+}
+class ManagedDevicesResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ManagedDevicesResponse::kStatusFieldNumber;
+const int ManagedDevicesResponse::kReasonFieldNumber;
+const int ManagedDevicesResponse::kDevicesFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ManagedDevicesResponse::ManagedDevicesResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ManagedDevicesResponse)
+}
+ManagedDevicesResponse::ManagedDevicesResponse(const ManagedDevicesResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      devices_(from.devices_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ManagedDevicesResponse)
+}
+
+void ManagedDevicesResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ManagedDevicesResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+ManagedDevicesResponse::~ManagedDevicesResponse() {
+  // @@protoc_insertion_point(destructor:dmi.ManagedDevicesResponse)
+  SharedDtor();
+}
+
+void ManagedDevicesResponse::SharedDtor() {
+}
+
+void ManagedDevicesResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ManagedDevicesResponse& ManagedDevicesResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ManagedDevicesResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ManagedDevicesResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ManagedDevicesResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  devices_.Clear();
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ManagedDevicesResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ManagedDevicesResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ManagedDevicesResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::ManagedDevicesResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // repeated .dmi.ManagedDeviceInfo devices = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::ManagedDeviceInfo::_InternalParse;
+          object = msg->add_devices();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ManagedDevicesResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ManagedDevicesResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ManagedDevicesResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::ManagedDevicesResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated .dmi.ManagedDeviceInfo devices = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_devices()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ManagedDevicesResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ManagedDevicesResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ManagedDevicesResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ManagedDevicesResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.ManagedDevicesResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // repeated .dmi.ManagedDeviceInfo devices = 3;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->devices_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3,
+      this->devices(static_cast<int>(i)),
+      output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ManagedDevicesResponse)
+}
+
+::google::protobuf::uint8* ManagedDevicesResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ManagedDevicesResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.ManagedDevicesResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // repeated .dmi.ManagedDeviceInfo devices = 3;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->devices_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, this->devices(static_cast<int>(i)), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ManagedDevicesResponse)
+  return target;
+}
+
+size_t ManagedDevicesResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ManagedDevicesResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated .dmi.ManagedDeviceInfo devices = 3;
+  {
+    unsigned int count = static_cast<unsigned int>(this->devices_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->devices(static_cast<int>(i)));
+    }
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.ManagedDevicesResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ManagedDevicesResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ManagedDevicesResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ManagedDevicesResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<ManagedDevicesResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ManagedDevicesResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ManagedDevicesResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ManagedDevicesResponse::MergeFrom(const ManagedDevicesResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ManagedDevicesResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  devices_.MergeFrom(from.devices_);
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void ManagedDevicesResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ManagedDevicesResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ManagedDevicesResponse::CopyFrom(const ManagedDevicesResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ManagedDevicesResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ManagedDevicesResponse::IsInitialized() const {
+  return true;
+}
+
+void ManagedDevicesResponse::Swap(ManagedDevicesResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ManagedDevicesResponse::InternalSwap(ManagedDevicesResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  CastToBase(&devices_)->InternalSwap(CastToBase(&other->devices_));
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata ManagedDevicesResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void SetLoggingEndpointRequest::InitAsDefaultInstance() {
+  ::dmi::_SetLoggingEndpointRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class SetLoggingEndpointRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const SetLoggingEndpointRequest* msg);
+};
+
+const ::dmi::Uuid&
+SetLoggingEndpointRequest::HasBitSetters::device_uuid(const SetLoggingEndpointRequest* msg) {
+  return *msg->device_uuid_;
+}
+void SetLoggingEndpointRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int SetLoggingEndpointRequest::kDeviceUuidFieldNumber;
+const int SetLoggingEndpointRequest::kLoggingEndpointFieldNumber;
+const int SetLoggingEndpointRequest::kLoggingProtocolFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+SetLoggingEndpointRequest::SetLoggingEndpointRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.SetLoggingEndpointRequest)
+}
+SetLoggingEndpointRequest::SetLoggingEndpointRequest(const SetLoggingEndpointRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  logging_endpoint_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.logging_endpoint().size() > 0) {
+    logging_endpoint_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.logging_endpoint_);
+  }
+  logging_protocol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.logging_protocol().size() > 0) {
+    logging_protocol_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.logging_protocol_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.SetLoggingEndpointRequest)
+}
+
+void SetLoggingEndpointRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_SetLoggingEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  logging_endpoint_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  logging_protocol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  device_uuid_ = nullptr;
+}
+
+SetLoggingEndpointRequest::~SetLoggingEndpointRequest() {
+  // @@protoc_insertion_point(destructor:dmi.SetLoggingEndpointRequest)
+  SharedDtor();
+}
+
+void SetLoggingEndpointRequest::SharedDtor() {
+  logging_endpoint_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  logging_protocol_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void SetLoggingEndpointRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const SetLoggingEndpointRequest& SetLoggingEndpointRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_SetLoggingEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void SetLoggingEndpointRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.SetLoggingEndpointRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  logging_endpoint_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  logging_protocol_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* SetLoggingEndpointRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<SetLoggingEndpointRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string logging_endpoint = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.SetLoggingEndpointRequest.logging_endpoint");
+        object = msg->mutable_logging_endpoint();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string logging_protocol = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.SetLoggingEndpointRequest.logging_protocol");
+        object = msg->mutable_logging_protocol();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool SetLoggingEndpointRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.SetLoggingEndpointRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string logging_endpoint = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_logging_endpoint()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->logging_endpoint().data(), static_cast<int>(this->logging_endpoint().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.SetLoggingEndpointRequest.logging_endpoint"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string logging_protocol = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_logging_protocol()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->logging_protocol().data(), static_cast<int>(this->logging_protocol().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.SetLoggingEndpointRequest.logging_protocol"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.SetLoggingEndpointRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.SetLoggingEndpointRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void SetLoggingEndpointRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.SetLoggingEndpointRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // string logging_endpoint = 2;
+  if (this->logging_endpoint().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->logging_endpoint().data(), static_cast<int>(this->logging_endpoint().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetLoggingEndpointRequest.logging_endpoint");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->logging_endpoint(), output);
+  }
+
+  // string logging_protocol = 3;
+  if (this->logging_protocol().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->logging_protocol().data(), static_cast<int>(this->logging_protocol().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetLoggingEndpointRequest.logging_protocol");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->logging_protocol(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.SetLoggingEndpointRequest)
+}
+
+::google::protobuf::uint8* SetLoggingEndpointRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.SetLoggingEndpointRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // string logging_endpoint = 2;
+  if (this->logging_endpoint().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->logging_endpoint().data(), static_cast<int>(this->logging_endpoint().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetLoggingEndpointRequest.logging_endpoint");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->logging_endpoint(), target);
+  }
+
+  // string logging_protocol = 3;
+  if (this->logging_protocol().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->logging_protocol().data(), static_cast<int>(this->logging_protocol().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetLoggingEndpointRequest.logging_protocol");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->logging_protocol(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.SetLoggingEndpointRequest)
+  return target;
+}
+
+size_t SetLoggingEndpointRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.SetLoggingEndpointRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string logging_endpoint = 2;
+  if (this->logging_endpoint().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->logging_endpoint());
+  }
+
+  // string logging_protocol = 3;
+  if (this->logging_protocol().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->logging_protocol());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void SetLoggingEndpointRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.SetLoggingEndpointRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const SetLoggingEndpointRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<SetLoggingEndpointRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.SetLoggingEndpointRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.SetLoggingEndpointRequest)
+    MergeFrom(*source);
+  }
+}
+
+void SetLoggingEndpointRequest::MergeFrom(const SetLoggingEndpointRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.SetLoggingEndpointRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.logging_endpoint().size() > 0) {
+
+    logging_endpoint_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.logging_endpoint_);
+  }
+  if (from.logging_protocol().size() > 0) {
+
+    logging_protocol_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.logging_protocol_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+}
+
+void SetLoggingEndpointRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.SetLoggingEndpointRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void SetLoggingEndpointRequest::CopyFrom(const SetLoggingEndpointRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.SetLoggingEndpointRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool SetLoggingEndpointRequest::IsInitialized() const {
+  return true;
+}
+
+void SetLoggingEndpointRequest::Swap(SetLoggingEndpointRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void SetLoggingEndpointRequest::InternalSwap(SetLoggingEndpointRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  logging_endpoint_.Swap(&other->logging_endpoint_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  logging_protocol_.Swap(&other->logging_protocol_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+}
+
+::google::protobuf::Metadata SetLoggingEndpointRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void SetRemoteEndpointResponse::InitAsDefaultInstance() {
+}
+class SetRemoteEndpointResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int SetRemoteEndpointResponse::kStatusFieldNumber;
+const int SetRemoteEndpointResponse::kReasonFieldNumber;
+const int SetRemoteEndpointResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+SetRemoteEndpointResponse::SetRemoteEndpointResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.SetRemoteEndpointResponse)
+}
+SetRemoteEndpointResponse::SetRemoteEndpointResponse(const SetRemoteEndpointResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.SetRemoteEndpointResponse)
+}
+
+void SetRemoteEndpointResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_SetRemoteEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+SetRemoteEndpointResponse::~SetRemoteEndpointResponse() {
+  // @@protoc_insertion_point(destructor:dmi.SetRemoteEndpointResponse)
+  SharedDtor();
+}
+
+void SetRemoteEndpointResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void SetRemoteEndpointResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const SetRemoteEndpointResponse& SetRemoteEndpointResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_SetRemoteEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void SetRemoteEndpointResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.SetRemoteEndpointResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* SetRemoteEndpointResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<SetRemoteEndpointResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.SetRemoteEndpointResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::SetRemoteEndpointResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.SetRemoteEndpointResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool SetRemoteEndpointResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.SetRemoteEndpointResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.SetRemoteEndpointResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::SetRemoteEndpointResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.SetRemoteEndpointResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.SetRemoteEndpointResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.SetRemoteEndpointResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void SetRemoteEndpointResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.SetRemoteEndpointResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.SetRemoteEndpointResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetRemoteEndpointResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.SetRemoteEndpointResponse)
+}
+
+::google::protobuf::uint8* SetRemoteEndpointResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.SetRemoteEndpointResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.SetRemoteEndpointResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetRemoteEndpointResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.SetRemoteEndpointResponse)
+  return target;
+}
+
+size_t SetRemoteEndpointResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.SetRemoteEndpointResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.SetRemoteEndpointResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void SetRemoteEndpointResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.SetRemoteEndpointResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const SetRemoteEndpointResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<SetRemoteEndpointResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.SetRemoteEndpointResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.SetRemoteEndpointResponse)
+    MergeFrom(*source);
+  }
+}
+
+void SetRemoteEndpointResponse::MergeFrom(const SetRemoteEndpointResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.SetRemoteEndpointResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void SetRemoteEndpointResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.SetRemoteEndpointResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void SetRemoteEndpointResponse::CopyFrom(const SetRemoteEndpointResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.SetRemoteEndpointResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool SetRemoteEndpointResponse::IsInitialized() const {
+  return true;
+}
+
+void SetRemoteEndpointResponse::Swap(SetRemoteEndpointResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void SetRemoteEndpointResponse::InternalSwap(SetRemoteEndpointResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata SetRemoteEndpointResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void GetLoggingEndpointResponse::InitAsDefaultInstance() {
+}
+class GetLoggingEndpointResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GetLoggingEndpointResponse::kStatusFieldNumber;
+const int GetLoggingEndpointResponse::kReasonFieldNumber;
+const int GetLoggingEndpointResponse::kLoggingEndpointFieldNumber;
+const int GetLoggingEndpointResponse::kLoggingProtocolFieldNumber;
+const int GetLoggingEndpointResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GetLoggingEndpointResponse::GetLoggingEndpointResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.GetLoggingEndpointResponse)
+}
+GetLoggingEndpointResponse::GetLoggingEndpointResponse(const GetLoggingEndpointResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  logging_endpoint_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.logging_endpoint().size() > 0) {
+    logging_endpoint_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.logging_endpoint_);
+  }
+  logging_protocol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.logging_protocol().size() > 0) {
+    logging_protocol_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.logging_protocol_);
+  }
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.GetLoggingEndpointResponse)
+}
+
+void GetLoggingEndpointResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GetLoggingEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  logging_endpoint_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  logging_protocol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+GetLoggingEndpointResponse::~GetLoggingEndpointResponse() {
+  // @@protoc_insertion_point(destructor:dmi.GetLoggingEndpointResponse)
+  SharedDtor();
+}
+
+void GetLoggingEndpointResponse::SharedDtor() {
+  logging_endpoint_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  logging_protocol_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void GetLoggingEndpointResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const GetLoggingEndpointResponse& GetLoggingEndpointResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_GetLoggingEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void GetLoggingEndpointResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.GetLoggingEndpointResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  logging_endpoint_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  logging_protocol_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GetLoggingEndpointResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GetLoggingEndpointResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.GetLoggingEndpointResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::GetLoggingEndpointResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string logging_endpoint = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.GetLoggingEndpointResponse.logging_endpoint");
+        object = msg->mutable_logging_endpoint();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string logging_protocol = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.GetLoggingEndpointResponse.logging_protocol");
+        object = msg->mutable_logging_protocol();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string reason_detail = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.GetLoggingEndpointResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool GetLoggingEndpointResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.GetLoggingEndpointResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.GetLoggingEndpointResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::GetLoggingEndpointResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string logging_endpoint = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_logging_endpoint()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->logging_endpoint().data(), static_cast<int>(this->logging_endpoint().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.GetLoggingEndpointResponse.logging_endpoint"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string logging_protocol = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_logging_protocol()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->logging_protocol().data(), static_cast<int>(this->logging_protocol().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.GetLoggingEndpointResponse.logging_protocol"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.GetLoggingEndpointResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.GetLoggingEndpointResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.GetLoggingEndpointResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void GetLoggingEndpointResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.GetLoggingEndpointResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.GetLoggingEndpointResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string logging_endpoint = 3;
+  if (this->logging_endpoint().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->logging_endpoint().data(), static_cast<int>(this->logging_endpoint().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLoggingEndpointResponse.logging_endpoint");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->logging_endpoint(), output);
+  }
+
+  // string logging_protocol = 4;
+  if (this->logging_protocol().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->logging_protocol().data(), static_cast<int>(this->logging_protocol().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLoggingEndpointResponse.logging_protocol");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->logging_protocol(), output);
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLoggingEndpointResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      5, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.GetLoggingEndpointResponse)
+}
+
+::google::protobuf::uint8* GetLoggingEndpointResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.GetLoggingEndpointResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.GetLoggingEndpointResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string logging_endpoint = 3;
+  if (this->logging_endpoint().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->logging_endpoint().data(), static_cast<int>(this->logging_endpoint().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLoggingEndpointResponse.logging_endpoint");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->logging_endpoint(), target);
+  }
+
+  // string logging_protocol = 4;
+  if (this->logging_protocol().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->logging_protocol().data(), static_cast<int>(this->logging_protocol().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLoggingEndpointResponse.logging_protocol");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->logging_protocol(), target);
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLoggingEndpointResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        5, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.GetLoggingEndpointResponse)
+  return target;
+}
+
+size_t GetLoggingEndpointResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.GetLoggingEndpointResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string logging_endpoint = 3;
+  if (this->logging_endpoint().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->logging_endpoint());
+  }
+
+  // string logging_protocol = 4;
+  if (this->logging_protocol().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->logging_protocol());
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.GetLoggingEndpointResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void GetLoggingEndpointResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.GetLoggingEndpointResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const GetLoggingEndpointResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<GetLoggingEndpointResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.GetLoggingEndpointResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.GetLoggingEndpointResponse)
+    MergeFrom(*source);
+  }
+}
+
+void GetLoggingEndpointResponse::MergeFrom(const GetLoggingEndpointResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.GetLoggingEndpointResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.logging_endpoint().size() > 0) {
+
+    logging_endpoint_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.logging_endpoint_);
+  }
+  if (from.logging_protocol().size() > 0) {
+
+    logging_protocol_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.logging_protocol_);
+  }
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void GetLoggingEndpointResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.GetLoggingEndpointResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void GetLoggingEndpointResponse::CopyFrom(const GetLoggingEndpointResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.GetLoggingEndpointResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GetLoggingEndpointResponse::IsInitialized() const {
+  return true;
+}
+
+void GetLoggingEndpointResponse::Swap(GetLoggingEndpointResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void GetLoggingEndpointResponse::InternalSwap(GetLoggingEndpointResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  logging_endpoint_.Swap(&other->logging_endpoint_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  logging_protocol_.Swap(&other->logging_protocol_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata GetLoggingEndpointResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void SetMsgBusEndpointRequest::InitAsDefaultInstance() {
+}
+class SetMsgBusEndpointRequest::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int SetMsgBusEndpointRequest::kMsgbusEndpointFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+SetMsgBusEndpointRequest::SetMsgBusEndpointRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.SetMsgBusEndpointRequest)
+}
+SetMsgBusEndpointRequest::SetMsgBusEndpointRequest(const SetMsgBusEndpointRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  msgbus_endpoint_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.msgbus_endpoint().size() > 0) {
+    msgbus_endpoint_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.msgbus_endpoint_);
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.SetMsgBusEndpointRequest)
+}
+
+void SetMsgBusEndpointRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_SetMsgBusEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  msgbus_endpoint_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+SetMsgBusEndpointRequest::~SetMsgBusEndpointRequest() {
+  // @@protoc_insertion_point(destructor:dmi.SetMsgBusEndpointRequest)
+  SharedDtor();
+}
+
+void SetMsgBusEndpointRequest::SharedDtor() {
+  msgbus_endpoint_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void SetMsgBusEndpointRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const SetMsgBusEndpointRequest& SetMsgBusEndpointRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_SetMsgBusEndpointRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void SetMsgBusEndpointRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.SetMsgBusEndpointRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  msgbus_endpoint_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* SetMsgBusEndpointRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<SetMsgBusEndpointRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string msgbus_endpoint = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.SetMsgBusEndpointRequest.msgbus_endpoint");
+        object = msg->mutable_msgbus_endpoint();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool SetMsgBusEndpointRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.SetMsgBusEndpointRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string msgbus_endpoint = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_msgbus_endpoint()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->msgbus_endpoint().data(), static_cast<int>(this->msgbus_endpoint().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.SetMsgBusEndpointRequest.msgbus_endpoint"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.SetMsgBusEndpointRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.SetMsgBusEndpointRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void SetMsgBusEndpointRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.SetMsgBusEndpointRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string msgbus_endpoint = 1;
+  if (this->msgbus_endpoint().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->msgbus_endpoint().data(), static_cast<int>(this->msgbus_endpoint().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetMsgBusEndpointRequest.msgbus_endpoint");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->msgbus_endpoint(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.SetMsgBusEndpointRequest)
+}
+
+::google::protobuf::uint8* SetMsgBusEndpointRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.SetMsgBusEndpointRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string msgbus_endpoint = 1;
+  if (this->msgbus_endpoint().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->msgbus_endpoint().data(), static_cast<int>(this->msgbus_endpoint().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetMsgBusEndpointRequest.msgbus_endpoint");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->msgbus_endpoint(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.SetMsgBusEndpointRequest)
+  return target;
+}
+
+size_t SetMsgBusEndpointRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.SetMsgBusEndpointRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string msgbus_endpoint = 1;
+  if (this->msgbus_endpoint().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->msgbus_endpoint());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void SetMsgBusEndpointRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.SetMsgBusEndpointRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const SetMsgBusEndpointRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<SetMsgBusEndpointRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.SetMsgBusEndpointRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.SetMsgBusEndpointRequest)
+    MergeFrom(*source);
+  }
+}
+
+void SetMsgBusEndpointRequest::MergeFrom(const SetMsgBusEndpointRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.SetMsgBusEndpointRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.msgbus_endpoint().size() > 0) {
+
+    msgbus_endpoint_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.msgbus_endpoint_);
+  }
+}
+
+void SetMsgBusEndpointRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.SetMsgBusEndpointRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void SetMsgBusEndpointRequest::CopyFrom(const SetMsgBusEndpointRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.SetMsgBusEndpointRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool SetMsgBusEndpointRequest::IsInitialized() const {
+  return true;
+}
+
+void SetMsgBusEndpointRequest::Swap(SetMsgBusEndpointRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void SetMsgBusEndpointRequest::InternalSwap(SetMsgBusEndpointRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  msgbus_endpoint_.Swap(&other->msgbus_endpoint_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+}
+
+::google::protobuf::Metadata SetMsgBusEndpointRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void GetMsgBusEndpointResponse::InitAsDefaultInstance() {
+}
+class GetMsgBusEndpointResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GetMsgBusEndpointResponse::kStatusFieldNumber;
+const int GetMsgBusEndpointResponse::kReasonFieldNumber;
+const int GetMsgBusEndpointResponse::kMsgbusEndpointFieldNumber;
+const int GetMsgBusEndpointResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GetMsgBusEndpointResponse::GetMsgBusEndpointResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.GetMsgBusEndpointResponse)
+}
+GetMsgBusEndpointResponse::GetMsgBusEndpointResponse(const GetMsgBusEndpointResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  msgbus_endpoint_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.msgbus_endpoint().size() > 0) {
+    msgbus_endpoint_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.msgbus_endpoint_);
+  }
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.GetMsgBusEndpointResponse)
+}
+
+void GetMsgBusEndpointResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GetMsgBusEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  msgbus_endpoint_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+GetMsgBusEndpointResponse::~GetMsgBusEndpointResponse() {
+  // @@protoc_insertion_point(destructor:dmi.GetMsgBusEndpointResponse)
+  SharedDtor();
+}
+
+void GetMsgBusEndpointResponse::SharedDtor() {
+  msgbus_endpoint_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void GetMsgBusEndpointResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const GetMsgBusEndpointResponse& GetMsgBusEndpointResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_GetMsgBusEndpointResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void GetMsgBusEndpointResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.GetMsgBusEndpointResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  msgbus_endpoint_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GetMsgBusEndpointResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GetMsgBusEndpointResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.GetMsgBusEndpointResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::GetMsgBusEndpointResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string msgbus_endpoint = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.GetMsgBusEndpointResponse.msgbus_endpoint");
+        object = msg->mutable_msgbus_endpoint();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.GetMsgBusEndpointResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool GetMsgBusEndpointResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.GetMsgBusEndpointResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.GetMsgBusEndpointResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::GetMsgBusEndpointResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string msgbus_endpoint = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_msgbus_endpoint()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->msgbus_endpoint().data(), static_cast<int>(this->msgbus_endpoint().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.GetMsgBusEndpointResponse.msgbus_endpoint"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.GetMsgBusEndpointResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.GetMsgBusEndpointResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.GetMsgBusEndpointResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void GetMsgBusEndpointResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.GetMsgBusEndpointResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.GetMsgBusEndpointResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string msgbus_endpoint = 3;
+  if (this->msgbus_endpoint().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->msgbus_endpoint().data(), static_cast<int>(this->msgbus_endpoint().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetMsgBusEndpointResponse.msgbus_endpoint");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->msgbus_endpoint(), output);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetMsgBusEndpointResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.GetMsgBusEndpointResponse)
+}
+
+::google::protobuf::uint8* GetMsgBusEndpointResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.GetMsgBusEndpointResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.GetMsgBusEndpointResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string msgbus_endpoint = 3;
+  if (this->msgbus_endpoint().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->msgbus_endpoint().data(), static_cast<int>(this->msgbus_endpoint().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetMsgBusEndpointResponse.msgbus_endpoint");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->msgbus_endpoint(), target);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetMsgBusEndpointResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.GetMsgBusEndpointResponse)
+  return target;
+}
+
+size_t GetMsgBusEndpointResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.GetMsgBusEndpointResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string msgbus_endpoint = 3;
+  if (this->msgbus_endpoint().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->msgbus_endpoint());
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.GetMsgBusEndpointResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void GetMsgBusEndpointResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.GetMsgBusEndpointResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const GetMsgBusEndpointResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<GetMsgBusEndpointResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.GetMsgBusEndpointResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.GetMsgBusEndpointResponse)
+    MergeFrom(*source);
+  }
+}
+
+void GetMsgBusEndpointResponse::MergeFrom(const GetMsgBusEndpointResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.GetMsgBusEndpointResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.msgbus_endpoint().size() > 0) {
+
+    msgbus_endpoint_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.msgbus_endpoint_);
+  }
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void GetMsgBusEndpointResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.GetMsgBusEndpointResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void GetMsgBusEndpointResponse::CopyFrom(const GetMsgBusEndpointResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.GetMsgBusEndpointResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GetMsgBusEndpointResponse::IsInitialized() const {
+  return true;
+}
+
+void GetMsgBusEndpointResponse::Swap(GetMsgBusEndpointResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void GetMsgBusEndpointResponse::InternalSwap(GetMsgBusEndpointResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  msgbus_endpoint_.Swap(&other->msgbus_endpoint_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata GetMsgBusEndpointResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void EntitiesLogLevel::InitAsDefaultInstance() {
+}
+class EntitiesLogLevel::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int EntitiesLogLevel::kLogLevelFieldNumber;
+const int EntitiesLogLevel::kEntitiesFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+EntitiesLogLevel::EntitiesLogLevel()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.EntitiesLogLevel)
+}
+EntitiesLogLevel::EntitiesLogLevel(const EntitiesLogLevel& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      entities_(from.entities_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  loglevel_ = from.loglevel_;
+  // @@protoc_insertion_point(copy_constructor:dmi.EntitiesLogLevel)
+}
+
+void EntitiesLogLevel::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EntitiesLogLevel_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  loglevel_ = 0;
+}
+
+EntitiesLogLevel::~EntitiesLogLevel() {
+  // @@protoc_insertion_point(destructor:dmi.EntitiesLogLevel)
+  SharedDtor();
+}
+
+void EntitiesLogLevel::SharedDtor() {
+}
+
+void EntitiesLogLevel::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const EntitiesLogLevel& EntitiesLogLevel::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_EntitiesLogLevel_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void EntitiesLogLevel::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.EntitiesLogLevel)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  entities_.Clear();
+  loglevel_ = 0;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EntitiesLogLevel::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EntitiesLogLevel*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.LogLevel logLevel = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_loglevel(static_cast<::dmi::LogLevel>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // repeated string entities = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          ctx->extra_parse_data().SetFieldName("dmi.EntitiesLogLevel.entities");
+          object = msg->add_entities();
+          if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+            parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+            goto string_till_end;
+          }
+          GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+          ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+          ptr += size;
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool EntitiesLogLevel::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.EntitiesLogLevel)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.LogLevel logLevel = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_loglevel(static_cast< ::dmi::LogLevel >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated string entities = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->add_entities()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->entities(this->entities_size() - 1).data(),
+            static_cast<int>(this->entities(this->entities_size() - 1).length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.EntitiesLogLevel.entities"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.EntitiesLogLevel)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.EntitiesLogLevel)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void EntitiesLogLevel::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.EntitiesLogLevel)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.LogLevel logLevel = 1;
+  if (this->loglevel() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->loglevel(), output);
+  }
+
+  // repeated string entities = 2;
+  for (int i = 0, n = this->entities_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->entities(i).data(), static_cast<int>(this->entities(i).length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EntitiesLogLevel.entities");
+    ::google::protobuf::internal::WireFormatLite::WriteString(
+      2, this->entities(i), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.EntitiesLogLevel)
+}
+
+::google::protobuf::uint8* EntitiesLogLevel::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.EntitiesLogLevel)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.LogLevel logLevel = 1;
+  if (this->loglevel() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->loglevel(), target);
+  }
+
+  // repeated string entities = 2;
+  for (int i = 0, n = this->entities_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->entities(i).data(), static_cast<int>(this->entities(i).length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EntitiesLogLevel.entities");
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteStringToArray(2, this->entities(i), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.EntitiesLogLevel)
+  return target;
+}
+
+size_t EntitiesLogLevel::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.EntitiesLogLevel)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated string entities = 2;
+  total_size += 1 *
+      ::google::protobuf::internal::FromIntSize(this->entities_size());
+  for (int i = 0, n = this->entities_size(); i < n; i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
+      this->entities(i));
+  }
+
+  // .dmi.LogLevel logLevel = 1;
+  if (this->loglevel() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->loglevel());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void EntitiesLogLevel::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.EntitiesLogLevel)
+  GOOGLE_DCHECK_NE(&from, this);
+  const EntitiesLogLevel* source =
+      ::google::protobuf::DynamicCastToGenerated<EntitiesLogLevel>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EntitiesLogLevel)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EntitiesLogLevel)
+    MergeFrom(*source);
+  }
+}
+
+void EntitiesLogLevel::MergeFrom(const EntitiesLogLevel& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EntitiesLogLevel)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  entities_.MergeFrom(from.entities_);
+  if (from.loglevel() != 0) {
+    set_loglevel(from.loglevel());
+  }
+}
+
+void EntitiesLogLevel::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.EntitiesLogLevel)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EntitiesLogLevel::CopyFrom(const EntitiesLogLevel& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EntitiesLogLevel)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EntitiesLogLevel::IsInitialized() const {
+  return true;
+}
+
+void EntitiesLogLevel::Swap(EntitiesLogLevel* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void EntitiesLogLevel::InternalSwap(EntitiesLogLevel* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  entities_.InternalSwap(CastToBase(&other->entities_));
+  swap(loglevel_, other->loglevel_);
+}
+
+::google::protobuf::Metadata EntitiesLogLevel::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void SetLogLevelRequest::InitAsDefaultInstance() {
+  ::dmi::_SetLogLevelRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class SetLogLevelRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const SetLogLevelRequest* msg);
+};
+
+const ::dmi::Uuid&
+SetLogLevelRequest::HasBitSetters::device_uuid(const SetLogLevelRequest* msg) {
+  return *msg->device_uuid_;
+}
+void SetLogLevelRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int SetLogLevelRequest::kDeviceUuidFieldNumber;
+const int SetLogLevelRequest::kLoglevelsFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+SetLogLevelRequest::SetLogLevelRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.SetLogLevelRequest)
+}
+SetLogLevelRequest::SetLogLevelRequest(const SetLogLevelRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      loglevels_(from.loglevels_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.SetLogLevelRequest)
+}
+
+void SetLogLevelRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_SetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  device_uuid_ = nullptr;
+}
+
+SetLogLevelRequest::~SetLogLevelRequest() {
+  // @@protoc_insertion_point(destructor:dmi.SetLogLevelRequest)
+  SharedDtor();
+}
+
+void SetLogLevelRequest::SharedDtor() {
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void SetLogLevelRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const SetLogLevelRequest& SetLogLevelRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_SetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void SetLogLevelRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.SetLogLevelRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  loglevels_.Clear();
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* SetLogLevelRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<SetLogLevelRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // repeated .dmi.EntitiesLogLevel loglevels = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::EntitiesLogLevel::_InternalParse;
+          object = msg->add_loglevels();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool SetLogLevelRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.SetLogLevelRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated .dmi.EntitiesLogLevel loglevels = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_loglevels()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.SetLogLevelRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.SetLogLevelRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void SetLogLevelRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.SetLogLevelRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // repeated .dmi.EntitiesLogLevel loglevels = 2;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->loglevels_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2,
+      this->loglevels(static_cast<int>(i)),
+      output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.SetLogLevelRequest)
+}
+
+::google::protobuf::uint8* SetLogLevelRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.SetLogLevelRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // repeated .dmi.EntitiesLogLevel loglevels = 2;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->loglevels_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, this->loglevels(static_cast<int>(i)), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.SetLogLevelRequest)
+  return target;
+}
+
+size_t SetLogLevelRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.SetLogLevelRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated .dmi.EntitiesLogLevel loglevels = 2;
+  {
+    unsigned int count = static_cast<unsigned int>(this->loglevels_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->loglevels(static_cast<int>(i)));
+    }
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void SetLogLevelRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.SetLogLevelRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const SetLogLevelRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<SetLogLevelRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.SetLogLevelRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.SetLogLevelRequest)
+    MergeFrom(*source);
+  }
+}
+
+void SetLogLevelRequest::MergeFrom(const SetLogLevelRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.SetLogLevelRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  loglevels_.MergeFrom(from.loglevels_);
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+}
+
+void SetLogLevelRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.SetLogLevelRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void SetLogLevelRequest::CopyFrom(const SetLogLevelRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.SetLogLevelRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool SetLogLevelRequest::IsInitialized() const {
+  return true;
+}
+
+void SetLogLevelRequest::Swap(SetLogLevelRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void SetLogLevelRequest::InternalSwap(SetLogLevelRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  CastToBase(&loglevels_)->InternalSwap(CastToBase(&other->loglevels_));
+  swap(device_uuid_, other->device_uuid_);
+}
+
+::google::protobuf::Metadata SetLogLevelRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void SetLogLevelResponse::InitAsDefaultInstance() {
+  ::dmi::_SetLogLevelResponse_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class SetLogLevelResponse::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const SetLogLevelResponse* msg);
+};
+
+const ::dmi::Uuid&
+SetLogLevelResponse::HasBitSetters::device_uuid(const SetLogLevelResponse* msg) {
+  return *msg->device_uuid_;
+}
+void SetLogLevelResponse::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int SetLogLevelResponse::kDeviceUuidFieldNumber;
+const int SetLogLevelResponse::kStatusFieldNumber;
+const int SetLogLevelResponse::kReasonFieldNumber;
+const int SetLogLevelResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+SetLogLevelResponse::SetLogLevelResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.SetLogLevelResponse)
+}
+SetLogLevelResponse::SetLogLevelResponse(const SetLogLevelResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.SetLogLevelResponse)
+}
+
+void SetLogLevelResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_SetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(reason_));
+}
+
+SetLogLevelResponse::~SetLogLevelResponse() {
+  // @@protoc_insertion_point(destructor:dmi.SetLogLevelResponse)
+  SharedDtor();
+}
+
+void SetLogLevelResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void SetLogLevelResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const SetLogLevelResponse& SetLogLevelResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_SetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void SetLogLevelResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.SetLogLevelResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* SetLogLevelResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<SetLogLevelResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Status status = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.SetLogLevelResponse.Reason reason = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::SetLogLevelResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.SetLogLevelResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool SetLogLevelResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.SetLogLevelResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Status status = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.SetLogLevelResponse.Reason reason = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::SetLogLevelResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.SetLogLevelResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.SetLogLevelResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.SetLogLevelResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void SetLogLevelResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.SetLogLevelResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.Status status = 2;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->status(), output);
+  }
+
+  // .dmi.SetLogLevelResponse.Reason reason = 3;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      3, this->reason(), output);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetLogLevelResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.SetLogLevelResponse)
+}
+
+::google::protobuf::uint8* SetLogLevelResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.SetLogLevelResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.Status status = 2;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->status(), target);
+  }
+
+  // .dmi.SetLogLevelResponse.Reason reason = 3;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      3, this->reason(), target);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.SetLogLevelResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.SetLogLevelResponse)
+  return target;
+}
+
+size_t SetLogLevelResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.SetLogLevelResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Status status = 2;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.SetLogLevelResponse.Reason reason = 3;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void SetLogLevelResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.SetLogLevelResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const SetLogLevelResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<SetLogLevelResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.SetLogLevelResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.SetLogLevelResponse)
+    MergeFrom(*source);
+  }
+}
+
+void SetLogLevelResponse::MergeFrom(const SetLogLevelResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.SetLogLevelResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void SetLogLevelResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.SetLogLevelResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void SetLogLevelResponse::CopyFrom(const SetLogLevelResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.SetLogLevelResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool SetLogLevelResponse::IsInitialized() const {
+  return true;
+}
+
+void SetLogLevelResponse::Swap(SetLogLevelResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void SetLogLevelResponse::InternalSwap(SetLogLevelResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata SetLogLevelResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void GetLogLevelRequest::InitAsDefaultInstance() {
+  ::dmi::_GetLogLevelRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class GetLogLevelRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const GetLogLevelRequest* msg);
+};
+
+const ::dmi::Uuid&
+GetLogLevelRequest::HasBitSetters::device_uuid(const GetLogLevelRequest* msg) {
+  return *msg->device_uuid_;
+}
+void GetLogLevelRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GetLogLevelRequest::kDeviceUuidFieldNumber;
+const int GetLogLevelRequest::kEntitiesFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GetLogLevelRequest::GetLogLevelRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.GetLogLevelRequest)
+}
+GetLogLevelRequest::GetLogLevelRequest(const GetLogLevelRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      entities_(from.entities_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.GetLogLevelRequest)
+}
+
+void GetLogLevelRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  device_uuid_ = nullptr;
+}
+
+GetLogLevelRequest::~GetLogLevelRequest() {
+  // @@protoc_insertion_point(destructor:dmi.GetLogLevelRequest)
+  SharedDtor();
+}
+
+void GetLogLevelRequest::SharedDtor() {
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void GetLogLevelRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const GetLogLevelRequest& GetLogLevelRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_GetLogLevelRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void GetLogLevelRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.GetLogLevelRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  entities_.Clear();
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GetLogLevelRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GetLogLevelRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // repeated string entities = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          ctx->extra_parse_data().SetFieldName("dmi.GetLogLevelRequest.entities");
+          object = msg->add_entities();
+          if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+            parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+            goto string_till_end;
+          }
+          GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+          ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+          ptr += size;
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool GetLogLevelRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.GetLogLevelRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated string entities = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->add_entities()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->entities(this->entities_size() - 1).data(),
+            static_cast<int>(this->entities(this->entities_size() - 1).length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.GetLogLevelRequest.entities"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.GetLogLevelRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.GetLogLevelRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void GetLogLevelRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.GetLogLevelRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // repeated string entities = 2;
+  for (int i = 0, n = this->entities_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->entities(i).data(), static_cast<int>(this->entities(i).length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLogLevelRequest.entities");
+    ::google::protobuf::internal::WireFormatLite::WriteString(
+      2, this->entities(i), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.GetLogLevelRequest)
+}
+
+::google::protobuf::uint8* GetLogLevelRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.GetLogLevelRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // repeated string entities = 2;
+  for (int i = 0, n = this->entities_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->entities(i).data(), static_cast<int>(this->entities(i).length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLogLevelRequest.entities");
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteStringToArray(2, this->entities(i), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.GetLogLevelRequest)
+  return target;
+}
+
+size_t GetLogLevelRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.GetLogLevelRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated string entities = 2;
+  total_size += 1 *
+      ::google::protobuf::internal::FromIntSize(this->entities_size());
+  for (int i = 0, n = this->entities_size(); i < n; i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
+      this->entities(i));
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void GetLogLevelRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.GetLogLevelRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const GetLogLevelRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<GetLogLevelRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.GetLogLevelRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.GetLogLevelRequest)
+    MergeFrom(*source);
+  }
+}
+
+void GetLogLevelRequest::MergeFrom(const GetLogLevelRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.GetLogLevelRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  entities_.MergeFrom(from.entities_);
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+}
+
+void GetLogLevelRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.GetLogLevelRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void GetLogLevelRequest::CopyFrom(const GetLogLevelRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.GetLogLevelRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GetLogLevelRequest::IsInitialized() const {
+  return true;
+}
+
+void GetLogLevelRequest::Swap(GetLogLevelRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void GetLogLevelRequest::InternalSwap(GetLogLevelRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  entities_.InternalSwap(CastToBase(&other->entities_));
+  swap(device_uuid_, other->device_uuid_);
+}
+
+::google::protobuf::Metadata GetLogLevelRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void GetLogLevelResponse::InitAsDefaultInstance() {
+  ::dmi::_GetLogLevelResponse_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class GetLogLevelResponse::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const GetLogLevelResponse* msg);
+};
+
+const ::dmi::Uuid&
+GetLogLevelResponse::HasBitSetters::device_uuid(const GetLogLevelResponse* msg) {
+  return *msg->device_uuid_;
+}
+void GetLogLevelResponse::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GetLogLevelResponse::kDeviceUuidFieldNumber;
+const int GetLogLevelResponse::kLogLevelsFieldNumber;
+const int GetLogLevelResponse::kStatusFieldNumber;
+const int GetLogLevelResponse::kReasonFieldNumber;
+const int GetLogLevelResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GetLogLevelResponse::GetLogLevelResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.GetLogLevelResponse)
+}
+GetLogLevelResponse::GetLogLevelResponse(const GetLogLevelResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      loglevels_(from.loglevels_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.GetLogLevelResponse)
+}
+
+void GetLogLevelResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(reason_));
+}
+
+GetLogLevelResponse::~GetLogLevelResponse() {
+  // @@protoc_insertion_point(destructor:dmi.GetLogLevelResponse)
+  SharedDtor();
+}
+
+void GetLogLevelResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void GetLogLevelResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const GetLogLevelResponse& GetLogLevelResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_GetLogLevelResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void GetLogLevelResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.GetLogLevelResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  loglevels_.Clear();
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GetLogLevelResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GetLogLevelResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // repeated .dmi.EntitiesLogLevel logLevels = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::EntitiesLogLevel::_InternalParse;
+          object = msg->add_loglevels();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      // .dmi.Status status = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.GetLogLevelResponse.Reason reason = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::GetLogLevelResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.GetLogLevelResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool GetLogLevelResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.GetLogLevelResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated .dmi.EntitiesLogLevel logLevels = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_loglevels()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Status status = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.GetLogLevelResponse.Reason reason = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::GetLogLevelResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.GetLogLevelResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.GetLogLevelResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.GetLogLevelResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void GetLogLevelResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.GetLogLevelResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // repeated .dmi.EntitiesLogLevel logLevels = 2;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->loglevels_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2,
+      this->loglevels(static_cast<int>(i)),
+      output);
+  }
+
+  // .dmi.Status status = 3;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      3, this->status(), output);
+  }
+
+  // .dmi.GetLogLevelResponse.Reason reason = 4;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      4, this->reason(), output);
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLogLevelResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      5, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.GetLogLevelResponse)
+}
+
+::google::protobuf::uint8* GetLogLevelResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.GetLogLevelResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // repeated .dmi.EntitiesLogLevel logLevels = 2;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->loglevels_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, this->loglevels(static_cast<int>(i)), target);
+  }
+
+  // .dmi.Status status = 3;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      3, this->status(), target);
+  }
+
+  // .dmi.GetLogLevelResponse.Reason reason = 4;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      4, this->reason(), target);
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetLogLevelResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        5, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.GetLogLevelResponse)
+  return target;
+}
+
+size_t GetLogLevelResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.GetLogLevelResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated .dmi.EntitiesLogLevel logLevels = 2;
+  {
+    unsigned int count = static_cast<unsigned int>(this->loglevels_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->loglevels(static_cast<int>(i)));
+    }
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Status status = 3;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.GetLogLevelResponse.Reason reason = 4;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void GetLogLevelResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.GetLogLevelResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const GetLogLevelResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<GetLogLevelResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.GetLogLevelResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.GetLogLevelResponse)
+    MergeFrom(*source);
+  }
+}
+
+void GetLogLevelResponse::MergeFrom(const GetLogLevelResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.GetLogLevelResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  loglevels_.MergeFrom(from.loglevels_);
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void GetLogLevelResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.GetLogLevelResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void GetLogLevelResponse::CopyFrom(const GetLogLevelResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.GetLogLevelResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GetLogLevelResponse::IsInitialized() const {
+  return true;
+}
+
+void GetLogLevelResponse::Swap(GetLogLevelResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void GetLogLevelResponse::InternalSwap(GetLogLevelResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  CastToBase(&loglevels_)->InternalSwap(CastToBase(&other->loglevels_));
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata GetLogLevelResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void GetLoggableEntitiesRequest::InitAsDefaultInstance() {
+  ::dmi::_GetLoggableEntitiesRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class GetLoggableEntitiesRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const GetLoggableEntitiesRequest* msg);
+};
+
+const ::dmi::Uuid&
+GetLoggableEntitiesRequest::HasBitSetters::device_uuid(const GetLoggableEntitiesRequest* msg) {
+  return *msg->device_uuid_;
+}
+void GetLoggableEntitiesRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GetLoggableEntitiesRequest::kDeviceUuidFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GetLoggableEntitiesRequest::GetLoggableEntitiesRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.GetLoggableEntitiesRequest)
+}
+GetLoggableEntitiesRequest::GetLoggableEntitiesRequest(const GetLoggableEntitiesRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.GetLoggableEntitiesRequest)
+}
+
+void GetLoggableEntitiesRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GetLoggableEntitiesRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  device_uuid_ = nullptr;
+}
+
+GetLoggableEntitiesRequest::~GetLoggableEntitiesRequest() {
+  // @@protoc_insertion_point(destructor:dmi.GetLoggableEntitiesRequest)
+  SharedDtor();
+}
+
+void GetLoggableEntitiesRequest::SharedDtor() {
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void GetLoggableEntitiesRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const GetLoggableEntitiesRequest& GetLoggableEntitiesRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_GetLoggableEntitiesRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void GetLoggableEntitiesRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.GetLoggableEntitiesRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GetLoggableEntitiesRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GetLoggableEntitiesRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool GetLoggableEntitiesRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.GetLoggableEntitiesRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.GetLoggableEntitiesRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.GetLoggableEntitiesRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void GetLoggableEntitiesRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.GetLoggableEntitiesRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.GetLoggableEntitiesRequest)
+}
+
+::google::protobuf::uint8* GetLoggableEntitiesRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.GetLoggableEntitiesRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.GetLoggableEntitiesRequest)
+  return target;
+}
+
+size_t GetLoggableEntitiesRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.GetLoggableEntitiesRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void GetLoggableEntitiesRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.GetLoggableEntitiesRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const GetLoggableEntitiesRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<GetLoggableEntitiesRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.GetLoggableEntitiesRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.GetLoggableEntitiesRequest)
+    MergeFrom(*source);
+  }
+}
+
+void GetLoggableEntitiesRequest::MergeFrom(const GetLoggableEntitiesRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.GetLoggableEntitiesRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+}
+
+void GetLoggableEntitiesRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.GetLoggableEntitiesRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void GetLoggableEntitiesRequest::CopyFrom(const GetLoggableEntitiesRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.GetLoggableEntitiesRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GetLoggableEntitiesRequest::IsInitialized() const {
+  return true;
+}
+
+void GetLoggableEntitiesRequest::Swap(GetLoggableEntitiesRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void GetLoggableEntitiesRequest::InternalSwap(GetLoggableEntitiesRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(device_uuid_, other->device_uuid_);
+}
+
+::google::protobuf::Metadata GetLoggableEntitiesRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> PROTOBUF_NOINLINE ::dmi::PhysicalInventoryRequest* Arena::CreateMaybeMessage< ::dmi::PhysicalInventoryRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::PhysicalInventoryRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::PhysicalInventoryResponse* Arena::CreateMaybeMessage< ::dmi::PhysicalInventoryResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::PhysicalInventoryResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::HWComponentInfoGetRequest* Arena::CreateMaybeMessage< ::dmi::HWComponentInfoGetRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::HWComponentInfoGetRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::HWComponentInfoGetResponse* Arena::CreateMaybeMessage< ::dmi::HWComponentInfoGetResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::HWComponentInfoGetResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::HWComponentInfoSetRequest* Arena::CreateMaybeMessage< ::dmi::HWComponentInfoSetRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::HWComponentInfoSetRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::HWComponentInfoSetResponse* Arena::CreateMaybeMessage< ::dmi::HWComponentInfoSetResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::HWComponentInfoSetResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::StartManagingDeviceResponse* Arena::CreateMaybeMessage< ::dmi::StartManagingDeviceResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::StartManagingDeviceResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::StopManagingDeviceRequest* Arena::CreateMaybeMessage< ::dmi::StopManagingDeviceRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::StopManagingDeviceRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::StopManagingDeviceResponse* Arena::CreateMaybeMessage< ::dmi::StopManagingDeviceResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::StopManagingDeviceResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ManagedDeviceInfo* Arena::CreateMaybeMessage< ::dmi::ManagedDeviceInfo >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ManagedDeviceInfo >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ManagedDevicesResponse* Arena::CreateMaybeMessage< ::dmi::ManagedDevicesResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ManagedDevicesResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::SetLoggingEndpointRequest* Arena::CreateMaybeMessage< ::dmi::SetLoggingEndpointRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::SetLoggingEndpointRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::SetRemoteEndpointResponse* Arena::CreateMaybeMessage< ::dmi::SetRemoteEndpointResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::SetRemoteEndpointResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::GetLoggingEndpointResponse* Arena::CreateMaybeMessage< ::dmi::GetLoggingEndpointResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::GetLoggingEndpointResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::SetMsgBusEndpointRequest* Arena::CreateMaybeMessage< ::dmi::SetMsgBusEndpointRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::SetMsgBusEndpointRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::GetMsgBusEndpointResponse* Arena::CreateMaybeMessage< ::dmi::GetMsgBusEndpointResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::GetMsgBusEndpointResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::EntitiesLogLevel* Arena::CreateMaybeMessage< ::dmi::EntitiesLogLevel >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::EntitiesLogLevel >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::SetLogLevelRequest* Arena::CreateMaybeMessage< ::dmi::SetLogLevelRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::SetLogLevelRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::SetLogLevelResponse* Arena::CreateMaybeMessage< ::dmi::SetLogLevelResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::SetLogLevelResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::GetLogLevelRequest* Arena::CreateMaybeMessage< ::dmi::GetLogLevelRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::GetLogLevelRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::GetLogLevelResponse* Arena::CreateMaybeMessage< ::dmi::GetLogLevelResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::GetLogLevelResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::GetLoggableEntitiesRequest* Arena::CreateMaybeMessage< ::dmi::GetLoggableEntitiesRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::GetLoggableEntitiesRequest >(arena);
+}
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+#include <google/protobuf/port_undef.inc>
diff --git a/cpp/dmi/hw_management_service.pb.h b/cpp/dmi/hw_management_service.pb.h
new file mode 100644
index 0000000..a304aa1
--- /dev/null
+++ b/cpp/dmi/hw_management_service.pb.h
@@ -0,0 +1,6289 @@
+// 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[22]
+    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 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 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::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::SetLogLevelRequest* Arena::CreateMaybeMessage<::dmi::SetLogLevelRequest>(Arena*);
+template<> ::dmi::SetLogLevelResponse* Arena::CreateMaybeMessage<::dmi::SetLogLevelResponse>(Arena*);
+template<> ::dmi::SetLoggingEndpointRequest* Arena::CreateMaybeMessage<::dmi::SetLoggingEndpointRequest>(Arena*);
+template<> ::dmi::SetMsgBusEndpointRequest* Arena::CreateMaybeMessage<::dmi::SetMsgBusEndpointRequest>(Arena*);
+template<> ::dmi::SetRemoteEndpointResponse* Arena::CreateMaybeMessage<::dmi::SetRemoteEndpointResponse>(Arena*);
+template<> ::dmi::StartManagingDeviceResponse* Arena::CreateMaybeMessage<::dmi::StartManagingDeviceResponse>(Arena*);
+template<> ::dmi::StopManagingDeviceRequest* Arena::CreateMaybeMessage<::dmi::StopManagingDeviceRequest>(Arena*);
+template<> ::dmi::StopManagingDeviceResponse* Arena::CreateMaybeMessage<::dmi::StopManagingDeviceResponse>(Arena*);
+}  // namespace protobuf
+}  // namespace google
+namespace dmi {
+
+enum PhysicalInventoryResponse_Reason {
+  PhysicalInventoryResponse_Reason_UNDEFINED_REASON = 0,
+  PhysicalInventoryResponse_Reason_UNKNOWN_DEVICE = 1,
+  PhysicalInventoryResponse_Reason_INTERNAL_ERROR = 2,
+  PhysicalInventoryResponse_Reason_DEVICE_UNREACHABLE = 3,
+  PhysicalInventoryResponse_Reason_PhysicalInventoryResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  PhysicalInventoryResponse_Reason_PhysicalInventoryResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool PhysicalInventoryResponse_Reason_IsValid(int value);
+const PhysicalInventoryResponse_Reason PhysicalInventoryResponse_Reason_Reason_MIN = PhysicalInventoryResponse_Reason_UNDEFINED_REASON;
+const PhysicalInventoryResponse_Reason PhysicalInventoryResponse_Reason_Reason_MAX = PhysicalInventoryResponse_Reason_DEVICE_UNREACHABLE;
+const int PhysicalInventoryResponse_Reason_Reason_ARRAYSIZE = PhysicalInventoryResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* PhysicalInventoryResponse_Reason_descriptor();
+inline const ::std::string& PhysicalInventoryResponse_Reason_Name(PhysicalInventoryResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    PhysicalInventoryResponse_Reason_descriptor(), value);
+}
+inline bool PhysicalInventoryResponse_Reason_Parse(
+    const ::std::string& name, PhysicalInventoryResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<PhysicalInventoryResponse_Reason>(
+    PhysicalInventoryResponse_Reason_descriptor(), name, value);
+}
+enum HWComponentInfoGetResponse_Reason {
+  HWComponentInfoGetResponse_Reason_UNDEFINED_REASON = 0,
+  HWComponentInfoGetResponse_Reason_UNKNOWN_DEVICE = 1,
+  HWComponentInfoGetResponse_Reason_UNKNOWN_COMPONENT = 2,
+  HWComponentInfoGetResponse_Reason_INTERNAL_ERROR = 3,
+  HWComponentInfoGetResponse_Reason_DEVICE_UNREACHABLE = 4,
+  HWComponentInfoGetResponse_Reason_HWComponentInfoGetResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  HWComponentInfoGetResponse_Reason_HWComponentInfoGetResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool HWComponentInfoGetResponse_Reason_IsValid(int value);
+const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse_Reason_Reason_MIN = HWComponentInfoGetResponse_Reason_UNDEFINED_REASON;
+const HWComponentInfoGetResponse_Reason HWComponentInfoGetResponse_Reason_Reason_MAX = HWComponentInfoGetResponse_Reason_DEVICE_UNREACHABLE;
+const int HWComponentInfoGetResponse_Reason_Reason_ARRAYSIZE = HWComponentInfoGetResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* HWComponentInfoGetResponse_Reason_descriptor();
+inline const ::std::string& HWComponentInfoGetResponse_Reason_Name(HWComponentInfoGetResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    HWComponentInfoGetResponse_Reason_descriptor(), value);
+}
+inline bool HWComponentInfoGetResponse_Reason_Parse(
+    const ::std::string& name, HWComponentInfoGetResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<HWComponentInfoGetResponse_Reason>(
+    HWComponentInfoGetResponse_Reason_descriptor(), name, value);
+}
+enum HWComponentInfoSetResponse_Reason {
+  HWComponentInfoSetResponse_Reason_UNDEFINED_REASON = 0,
+  HWComponentInfoSetResponse_Reason_UNKNOWN_DEVICE = 1,
+  HWComponentInfoSetResponse_Reason_UNKNOWN_COMPONENT = 2,
+  HWComponentInfoSetResponse_Reason_INVALID_PARAMS = 3,
+  HWComponentInfoSetResponse_Reason_INTERNAL_ERROR = 4,
+  HWComponentInfoSetResponse_Reason_DEVICE_UNREACHABLE = 5,
+  HWComponentInfoSetResponse_Reason_HWComponentInfoSetResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  HWComponentInfoSetResponse_Reason_HWComponentInfoSetResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool HWComponentInfoSetResponse_Reason_IsValid(int value);
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse_Reason_Reason_MIN = HWComponentInfoSetResponse_Reason_UNDEFINED_REASON;
+const HWComponentInfoSetResponse_Reason HWComponentInfoSetResponse_Reason_Reason_MAX = HWComponentInfoSetResponse_Reason_DEVICE_UNREACHABLE;
+const int HWComponentInfoSetResponse_Reason_Reason_ARRAYSIZE = HWComponentInfoSetResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* HWComponentInfoSetResponse_Reason_descriptor();
+inline const ::std::string& HWComponentInfoSetResponse_Reason_Name(HWComponentInfoSetResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    HWComponentInfoSetResponse_Reason_descriptor(), value);
+}
+inline bool HWComponentInfoSetResponse_Reason_Parse(
+    const ::std::string& name, HWComponentInfoSetResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<HWComponentInfoSetResponse_Reason>(
+    HWComponentInfoSetResponse_Reason_descriptor(), name, value);
+}
+enum StartManagingDeviceResponse_Reason {
+  StartManagingDeviceResponse_Reason_UNDEFINED_REASON = 0,
+  StartManagingDeviceResponse_Reason_DEVICE_ALREADY_MANAGED = 1,
+  StartManagingDeviceResponse_Reason_OPERATION_ALREADY_IN_PROGRESS = 2,
+  StartManagingDeviceResponse_Reason_INVALID_PARAMS = 3,
+  StartManagingDeviceResponse_Reason_INTERNAL_ERROR = 4,
+  StartManagingDeviceResponse_Reason_StartManagingDeviceResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  StartManagingDeviceResponse_Reason_StartManagingDeviceResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool StartManagingDeviceResponse_Reason_IsValid(int value);
+const StartManagingDeviceResponse_Reason StartManagingDeviceResponse_Reason_Reason_MIN = StartManagingDeviceResponse_Reason_UNDEFINED_REASON;
+const StartManagingDeviceResponse_Reason StartManagingDeviceResponse_Reason_Reason_MAX = StartManagingDeviceResponse_Reason_INTERNAL_ERROR;
+const int StartManagingDeviceResponse_Reason_Reason_ARRAYSIZE = StartManagingDeviceResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* StartManagingDeviceResponse_Reason_descriptor();
+inline const ::std::string& StartManagingDeviceResponse_Reason_Name(StartManagingDeviceResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    StartManagingDeviceResponse_Reason_descriptor(), value);
+}
+inline bool StartManagingDeviceResponse_Reason_Parse(
+    const ::std::string& name, StartManagingDeviceResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<StartManagingDeviceResponse_Reason>(
+    StartManagingDeviceResponse_Reason_descriptor(), name, value);
+}
+enum StopManagingDeviceResponse_Reason {
+  StopManagingDeviceResponse_Reason_UNDEFINED_REASON = 0,
+  StopManagingDeviceResponse_Reason_UNKNOWN_DEVICE = 1,
+  StopManagingDeviceResponse_Reason_StopManagingDeviceResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  StopManagingDeviceResponse_Reason_StopManagingDeviceResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool StopManagingDeviceResponse_Reason_IsValid(int value);
+const StopManagingDeviceResponse_Reason StopManagingDeviceResponse_Reason_Reason_MIN = StopManagingDeviceResponse_Reason_UNDEFINED_REASON;
+const StopManagingDeviceResponse_Reason StopManagingDeviceResponse_Reason_Reason_MAX = StopManagingDeviceResponse_Reason_UNKNOWN_DEVICE;
+const int StopManagingDeviceResponse_Reason_Reason_ARRAYSIZE = StopManagingDeviceResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* StopManagingDeviceResponse_Reason_descriptor();
+inline const ::std::string& StopManagingDeviceResponse_Reason_Name(StopManagingDeviceResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    StopManagingDeviceResponse_Reason_descriptor(), value);
+}
+inline bool StopManagingDeviceResponse_Reason_Parse(
+    const ::std::string& name, StopManagingDeviceResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<StopManagingDeviceResponse_Reason>(
+    StopManagingDeviceResponse_Reason_descriptor(), name, value);
+}
+enum ManagedDevicesResponse_Reason {
+  ManagedDevicesResponse_Reason_UNDEFINED_REASON = 0,
+  ManagedDevicesResponse_Reason_INTERNAL_ERROR = 1,
+  ManagedDevicesResponse_Reason_ManagedDevicesResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ManagedDevicesResponse_Reason_ManagedDevicesResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ManagedDevicesResponse_Reason_IsValid(int value);
+const ManagedDevicesResponse_Reason ManagedDevicesResponse_Reason_Reason_MIN = ManagedDevicesResponse_Reason_UNDEFINED_REASON;
+const ManagedDevicesResponse_Reason ManagedDevicesResponse_Reason_Reason_MAX = ManagedDevicesResponse_Reason_INTERNAL_ERROR;
+const int ManagedDevicesResponse_Reason_Reason_ARRAYSIZE = ManagedDevicesResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ManagedDevicesResponse_Reason_descriptor();
+inline const ::std::string& ManagedDevicesResponse_Reason_Name(ManagedDevicesResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ManagedDevicesResponse_Reason_descriptor(), value);
+}
+inline bool ManagedDevicesResponse_Reason_Parse(
+    const ::std::string& name, ManagedDevicesResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ManagedDevicesResponse_Reason>(
+    ManagedDevicesResponse_Reason_descriptor(), name, value);
+}
+enum SetRemoteEndpointResponse_Reason {
+  SetRemoteEndpointResponse_Reason_UNDEFINED_REASON = 0,
+  SetRemoteEndpointResponse_Reason_UNKNOWN_DEVICE = 1,
+  SetRemoteEndpointResponse_Reason_INTERNAL_ERROR = 2,
+  SetRemoteEndpointResponse_Reason_LOGGING_ENDPOINT_ERROR = 3,
+  SetRemoteEndpointResponse_Reason_LOGGING_ENDPOINT_PROTOCOL_ERROR = 4,
+  SetRemoteEndpointResponse_Reason_MSGBUS_ENDPOINT_ERROR = 5,
+  SetRemoteEndpointResponse_Reason_DEVICE_UNREACHABLE = 6,
+  SetRemoteEndpointResponse_Reason_SetRemoteEndpointResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  SetRemoteEndpointResponse_Reason_SetRemoteEndpointResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool SetRemoteEndpointResponse_Reason_IsValid(int value);
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse_Reason_Reason_MIN = SetRemoteEndpointResponse_Reason_UNDEFINED_REASON;
+const SetRemoteEndpointResponse_Reason SetRemoteEndpointResponse_Reason_Reason_MAX = SetRemoteEndpointResponse_Reason_DEVICE_UNREACHABLE;
+const int SetRemoteEndpointResponse_Reason_Reason_ARRAYSIZE = SetRemoteEndpointResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* SetRemoteEndpointResponse_Reason_descriptor();
+inline const ::std::string& SetRemoteEndpointResponse_Reason_Name(SetRemoteEndpointResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    SetRemoteEndpointResponse_Reason_descriptor(), value);
+}
+inline bool SetRemoteEndpointResponse_Reason_Parse(
+    const ::std::string& name, SetRemoteEndpointResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<SetRemoteEndpointResponse_Reason>(
+    SetRemoteEndpointResponse_Reason_descriptor(), name, value);
+}
+enum GetLoggingEndpointResponse_Reason {
+  GetLoggingEndpointResponse_Reason_UNDEFINED_REASON = 0,
+  GetLoggingEndpointResponse_Reason_UNKNOWN_DEVICE = 1,
+  GetLoggingEndpointResponse_Reason_INTERNAL_ERROR = 2,
+  GetLoggingEndpointResponse_Reason_DEVICE_UNREACHABLE = 3,
+  GetLoggingEndpointResponse_Reason_GetLoggingEndpointResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  GetLoggingEndpointResponse_Reason_GetLoggingEndpointResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool GetLoggingEndpointResponse_Reason_IsValid(int value);
+const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse_Reason_Reason_MIN = GetLoggingEndpointResponse_Reason_UNDEFINED_REASON;
+const GetLoggingEndpointResponse_Reason GetLoggingEndpointResponse_Reason_Reason_MAX = GetLoggingEndpointResponse_Reason_DEVICE_UNREACHABLE;
+const int GetLoggingEndpointResponse_Reason_Reason_ARRAYSIZE = GetLoggingEndpointResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* GetLoggingEndpointResponse_Reason_descriptor();
+inline const ::std::string& GetLoggingEndpointResponse_Reason_Name(GetLoggingEndpointResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    GetLoggingEndpointResponse_Reason_descriptor(), value);
+}
+inline bool GetLoggingEndpointResponse_Reason_Parse(
+    const ::std::string& name, GetLoggingEndpointResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<GetLoggingEndpointResponse_Reason>(
+    GetLoggingEndpointResponse_Reason_descriptor(), name, value);
+}
+enum GetMsgBusEndpointResponse_Reason {
+  GetMsgBusEndpointResponse_Reason_UNDEFINED_REASON = 0,
+  GetMsgBusEndpointResponse_Reason_INTERNAL_ERROR = 1,
+  GetMsgBusEndpointResponse_Reason_DEVICE_UNREACHABLE = 2,
+  GetMsgBusEndpointResponse_Reason_GetMsgBusEndpointResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  GetMsgBusEndpointResponse_Reason_GetMsgBusEndpointResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool GetMsgBusEndpointResponse_Reason_IsValid(int value);
+const GetMsgBusEndpointResponse_Reason GetMsgBusEndpointResponse_Reason_Reason_MIN = GetMsgBusEndpointResponse_Reason_UNDEFINED_REASON;
+const GetMsgBusEndpointResponse_Reason GetMsgBusEndpointResponse_Reason_Reason_MAX = GetMsgBusEndpointResponse_Reason_DEVICE_UNREACHABLE;
+const int GetMsgBusEndpointResponse_Reason_Reason_ARRAYSIZE = GetMsgBusEndpointResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* GetMsgBusEndpointResponse_Reason_descriptor();
+inline const ::std::string& GetMsgBusEndpointResponse_Reason_Name(GetMsgBusEndpointResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    GetMsgBusEndpointResponse_Reason_descriptor(), value);
+}
+inline bool GetMsgBusEndpointResponse_Reason_Parse(
+    const ::std::string& name, GetMsgBusEndpointResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<GetMsgBusEndpointResponse_Reason>(
+    GetMsgBusEndpointResponse_Reason_descriptor(), name, value);
+}
+enum SetLogLevelResponse_Reason {
+  SetLogLevelResponse_Reason_UNDEFINED_REASON = 0,
+  SetLogLevelResponse_Reason_UNKNOWN_DEVICE = 1,
+  SetLogLevelResponse_Reason_INTERNAL_ERROR = 2,
+  SetLogLevelResponse_Reason_UNKNOWN_LOG_ENTITY = 3,
+  SetLogLevelResponse_Reason_DEVICE_UNREACHABLE = 4,
+  SetLogLevelResponse_Reason_SetLogLevelResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  SetLogLevelResponse_Reason_SetLogLevelResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool SetLogLevelResponse_Reason_IsValid(int value);
+const SetLogLevelResponse_Reason SetLogLevelResponse_Reason_Reason_MIN = SetLogLevelResponse_Reason_UNDEFINED_REASON;
+const SetLogLevelResponse_Reason SetLogLevelResponse_Reason_Reason_MAX = SetLogLevelResponse_Reason_DEVICE_UNREACHABLE;
+const int SetLogLevelResponse_Reason_Reason_ARRAYSIZE = SetLogLevelResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* SetLogLevelResponse_Reason_descriptor();
+inline const ::std::string& SetLogLevelResponse_Reason_Name(SetLogLevelResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    SetLogLevelResponse_Reason_descriptor(), value);
+}
+inline bool SetLogLevelResponse_Reason_Parse(
+    const ::std::string& name, SetLogLevelResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<SetLogLevelResponse_Reason>(
+    SetLogLevelResponse_Reason_descriptor(), name, value);
+}
+enum GetLogLevelResponse_Reason {
+  GetLogLevelResponse_Reason_UNDEFINED_REASON = 0,
+  GetLogLevelResponse_Reason_UNKNOWN_DEVICE = 1,
+  GetLogLevelResponse_Reason_INTERNAL_ERROR = 2,
+  GetLogLevelResponse_Reason_UNKNOWN_LOG_ENTITY = 3,
+  GetLogLevelResponse_Reason_DEVICE_UNREACHABLE = 4,
+  GetLogLevelResponse_Reason_GetLogLevelResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  GetLogLevelResponse_Reason_GetLogLevelResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool GetLogLevelResponse_Reason_IsValid(int value);
+const GetLogLevelResponse_Reason GetLogLevelResponse_Reason_Reason_MIN = GetLogLevelResponse_Reason_UNDEFINED_REASON;
+const GetLogLevelResponse_Reason GetLogLevelResponse_Reason_Reason_MAX = GetLogLevelResponse_Reason_DEVICE_UNREACHABLE;
+const int GetLogLevelResponse_Reason_Reason_ARRAYSIZE = GetLogLevelResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* GetLogLevelResponse_Reason_descriptor();
+inline const ::std::string& GetLogLevelResponse_Reason_Name(GetLogLevelResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    GetLogLevelResponse_Reason_descriptor(), value);
+}
+inline bool GetLogLevelResponse_Reason_Parse(
+    const ::std::string& name, GetLogLevelResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<GetLogLevelResponse_Reason>(
+    GetLogLevelResponse_Reason_descriptor(), name, value);
+}
+// ===================================================================
+
+class PhysicalInventoryRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.PhysicalInventoryRequest) */ {
+ public:
+  PhysicalInventoryRequest();
+  virtual ~PhysicalInventoryRequest();
+
+  PhysicalInventoryRequest(const PhysicalInventoryRequest& from);
+
+  inline PhysicalInventoryRequest& operator=(const PhysicalInventoryRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  PhysicalInventoryRequest(PhysicalInventoryRequest&& from) noexcept
+    : PhysicalInventoryRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline PhysicalInventoryRequest& operator=(PhysicalInventoryRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const PhysicalInventoryRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const PhysicalInventoryRequest* internal_default_instance() {
+    return reinterpret_cast<const PhysicalInventoryRequest*>(
+               &_PhysicalInventoryRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    0;
+
+  void Swap(PhysicalInventoryRequest* other);
+  friend void swap(PhysicalInventoryRequest& a, PhysicalInventoryRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline PhysicalInventoryRequest* New() const final {
+    return CreateMaybeMessage<PhysicalInventoryRequest>(nullptr);
+  }
+
+  PhysicalInventoryRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<PhysicalInventoryRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const PhysicalInventoryRequest& from);
+  void MergeFrom(const PhysicalInventoryRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(PhysicalInventoryRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.PhysicalInventoryRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::Uuid* device_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PhysicalInventoryResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.PhysicalInventoryResponse) */ {
+ public:
+  PhysicalInventoryResponse();
+  virtual ~PhysicalInventoryResponse();
+
+  PhysicalInventoryResponse(const PhysicalInventoryResponse& from);
+
+  inline PhysicalInventoryResponse& operator=(const PhysicalInventoryResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  PhysicalInventoryResponse(PhysicalInventoryResponse&& from) noexcept
+    : PhysicalInventoryResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline PhysicalInventoryResponse& operator=(PhysicalInventoryResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const PhysicalInventoryResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const PhysicalInventoryResponse* internal_default_instance() {
+    return reinterpret_cast<const PhysicalInventoryResponse*>(
+               &_PhysicalInventoryResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    1;
+
+  void Swap(PhysicalInventoryResponse* other);
+  friend void swap(PhysicalInventoryResponse& a, PhysicalInventoryResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline PhysicalInventoryResponse* New() const final {
+    return CreateMaybeMessage<PhysicalInventoryResponse>(nullptr);
+  }
+
+  PhysicalInventoryResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<PhysicalInventoryResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const PhysicalInventoryResponse& from);
+  void MergeFrom(const PhysicalInventoryResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(PhysicalInventoryResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef PhysicalInventoryResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    PhysicalInventoryResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    PhysicalInventoryResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    PhysicalInventoryResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    PhysicalInventoryResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return PhysicalInventoryResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    PhysicalInventoryResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    PhysicalInventoryResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    PhysicalInventoryResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return PhysicalInventoryResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return PhysicalInventoryResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return PhysicalInventoryResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 4;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 4;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Hardware inventory = 3;
+  bool has_inventory() const;
+  void clear_inventory();
+  static const int kInventoryFieldNumber = 3;
+  const ::dmi::Hardware& inventory() const;
+  ::dmi::Hardware* release_inventory();
+  ::dmi::Hardware* mutable_inventory();
+  void set_allocated_inventory(::dmi::Hardware* inventory);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.PhysicalInventoryResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::PhysicalInventoryResponse_Reason reason() const;
+  void set_reason(::dmi::PhysicalInventoryResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.PhysicalInventoryResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  ::dmi::Hardware* inventory_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class HWComponentInfoGetRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.HWComponentInfoGetRequest) */ {
+ public:
+  HWComponentInfoGetRequest();
+  virtual ~HWComponentInfoGetRequest();
+
+  HWComponentInfoGetRequest(const HWComponentInfoGetRequest& from);
+
+  inline HWComponentInfoGetRequest& operator=(const HWComponentInfoGetRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  HWComponentInfoGetRequest(HWComponentInfoGetRequest&& from) noexcept
+    : HWComponentInfoGetRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline HWComponentInfoGetRequest& operator=(HWComponentInfoGetRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const HWComponentInfoGetRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const HWComponentInfoGetRequest* internal_default_instance() {
+    return reinterpret_cast<const HWComponentInfoGetRequest*>(
+               &_HWComponentInfoGetRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    2;
+
+  void Swap(HWComponentInfoGetRequest* other);
+  friend void swap(HWComponentInfoGetRequest& a, HWComponentInfoGetRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline HWComponentInfoGetRequest* New() const final {
+    return CreateMaybeMessage<HWComponentInfoGetRequest>(nullptr);
+  }
+
+  HWComponentInfoGetRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<HWComponentInfoGetRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const HWComponentInfoGetRequest& from);
+  void MergeFrom(const HWComponentInfoGetRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(HWComponentInfoGetRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string component_name = 3;
+  void clear_component_name();
+  static const int kComponentNameFieldNumber = 3;
+  const ::std::string& component_name() const;
+  void set_component_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_component_name(::std::string&& value);
+  #endif
+  void set_component_name(const char* value);
+  void set_component_name(const char* value, size_t size);
+  ::std::string* mutable_component_name();
+  ::std::string* release_component_name();
+  void set_allocated_component_name(::std::string* component_name);
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.Uuid component_uuid = 2;
+  bool has_component_uuid() const;
+  void clear_component_uuid();
+  static const int kComponentUuidFieldNumber = 2;
+  const ::dmi::Uuid& component_uuid() const;
+  ::dmi::Uuid* release_component_uuid();
+  ::dmi::Uuid* mutable_component_uuid();
+  void set_allocated_component_uuid(::dmi::Uuid* component_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.HWComponentInfoGetRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr component_name_;
+  ::dmi::Uuid* device_uuid_;
+  ::dmi::Uuid* component_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class HWComponentInfoGetResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.HWComponentInfoGetResponse) */ {
+ public:
+  HWComponentInfoGetResponse();
+  virtual ~HWComponentInfoGetResponse();
+
+  HWComponentInfoGetResponse(const HWComponentInfoGetResponse& from);
+
+  inline HWComponentInfoGetResponse& operator=(const HWComponentInfoGetResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  HWComponentInfoGetResponse(HWComponentInfoGetResponse&& from) noexcept
+    : HWComponentInfoGetResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline HWComponentInfoGetResponse& operator=(HWComponentInfoGetResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const HWComponentInfoGetResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const HWComponentInfoGetResponse* internal_default_instance() {
+    return reinterpret_cast<const HWComponentInfoGetResponse*>(
+               &_HWComponentInfoGetResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    3;
+
+  void Swap(HWComponentInfoGetResponse* other);
+  friend void swap(HWComponentInfoGetResponse& a, HWComponentInfoGetResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline HWComponentInfoGetResponse* New() const final {
+    return CreateMaybeMessage<HWComponentInfoGetResponse>(nullptr);
+  }
+
+  HWComponentInfoGetResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<HWComponentInfoGetResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const HWComponentInfoGetResponse& from);
+  void MergeFrom(const HWComponentInfoGetResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(HWComponentInfoGetResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef HWComponentInfoGetResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    HWComponentInfoGetResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    HWComponentInfoGetResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason UNKNOWN_COMPONENT =
+    HWComponentInfoGetResponse_Reason_UNKNOWN_COMPONENT;
+  static const Reason INTERNAL_ERROR =
+    HWComponentInfoGetResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    HWComponentInfoGetResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return HWComponentInfoGetResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    HWComponentInfoGetResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    HWComponentInfoGetResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    HWComponentInfoGetResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return HWComponentInfoGetResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return HWComponentInfoGetResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return HWComponentInfoGetResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 4;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 4;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Component component = 3;
+  bool has_component() const;
+  void clear_component();
+  static const int kComponentFieldNumber = 3;
+  const ::dmi::Component& component() const;
+  ::dmi::Component* release_component();
+  ::dmi::Component* mutable_component();
+  void set_allocated_component(::dmi::Component* component);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.HWComponentInfoGetResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::HWComponentInfoGetResponse_Reason reason() const;
+  void set_reason(::dmi::HWComponentInfoGetResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.HWComponentInfoGetResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  ::dmi::Component* component_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class HWComponentInfoSetRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.HWComponentInfoSetRequest) */ {
+ public:
+  HWComponentInfoSetRequest();
+  virtual ~HWComponentInfoSetRequest();
+
+  HWComponentInfoSetRequest(const HWComponentInfoSetRequest& from);
+
+  inline HWComponentInfoSetRequest& operator=(const HWComponentInfoSetRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  HWComponentInfoSetRequest(HWComponentInfoSetRequest&& from) noexcept
+    : HWComponentInfoSetRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline HWComponentInfoSetRequest& operator=(HWComponentInfoSetRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const HWComponentInfoSetRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const HWComponentInfoSetRequest* internal_default_instance() {
+    return reinterpret_cast<const HWComponentInfoSetRequest*>(
+               &_HWComponentInfoSetRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    4;
+
+  void Swap(HWComponentInfoSetRequest* other);
+  friend void swap(HWComponentInfoSetRequest& a, HWComponentInfoSetRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline HWComponentInfoSetRequest* New() const final {
+    return CreateMaybeMessage<HWComponentInfoSetRequest>(nullptr);
+  }
+
+  HWComponentInfoSetRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<HWComponentInfoSetRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const HWComponentInfoSetRequest& from);
+  void MergeFrom(const HWComponentInfoSetRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(HWComponentInfoSetRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string component_name = 3;
+  void clear_component_name();
+  static const int kComponentNameFieldNumber = 3;
+  const ::std::string& component_name() const;
+  void set_component_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_component_name(::std::string&& value);
+  #endif
+  void set_component_name(const char* value);
+  void set_component_name(const char* value, size_t size);
+  ::std::string* mutable_component_name();
+  ::std::string* release_component_name();
+  void set_allocated_component_name(::std::string* component_name);
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.Uuid component_uuid = 2;
+  bool has_component_uuid() const;
+  void clear_component_uuid();
+  static const int kComponentUuidFieldNumber = 2;
+  const ::dmi::Uuid& component_uuid() const;
+  ::dmi::Uuid* release_component_uuid();
+  ::dmi::Uuid* mutable_component_uuid();
+  void set_allocated_component_uuid(::dmi::Uuid* component_uuid);
+
+  // .dmi.ModifiableComponent changes = 4;
+  bool has_changes() const;
+  void clear_changes();
+  static const int kChangesFieldNumber = 4;
+  const ::dmi::ModifiableComponent& changes() const;
+  ::dmi::ModifiableComponent* release_changes();
+  ::dmi::ModifiableComponent* mutable_changes();
+  void set_allocated_changes(::dmi::ModifiableComponent* changes);
+
+  // @@protoc_insertion_point(class_scope:dmi.HWComponentInfoSetRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr component_name_;
+  ::dmi::Uuid* device_uuid_;
+  ::dmi::Uuid* component_uuid_;
+  ::dmi::ModifiableComponent* changes_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class HWComponentInfoSetResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.HWComponentInfoSetResponse) */ {
+ public:
+  HWComponentInfoSetResponse();
+  virtual ~HWComponentInfoSetResponse();
+
+  HWComponentInfoSetResponse(const HWComponentInfoSetResponse& from);
+
+  inline HWComponentInfoSetResponse& operator=(const HWComponentInfoSetResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  HWComponentInfoSetResponse(HWComponentInfoSetResponse&& from) noexcept
+    : HWComponentInfoSetResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline HWComponentInfoSetResponse& operator=(HWComponentInfoSetResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const HWComponentInfoSetResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const HWComponentInfoSetResponse* internal_default_instance() {
+    return reinterpret_cast<const HWComponentInfoSetResponse*>(
+               &_HWComponentInfoSetResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    5;
+
+  void Swap(HWComponentInfoSetResponse* other);
+  friend void swap(HWComponentInfoSetResponse& a, HWComponentInfoSetResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline HWComponentInfoSetResponse* New() const final {
+    return CreateMaybeMessage<HWComponentInfoSetResponse>(nullptr);
+  }
+
+  HWComponentInfoSetResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<HWComponentInfoSetResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const HWComponentInfoSetResponse& from);
+  void MergeFrom(const HWComponentInfoSetResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(HWComponentInfoSetResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef HWComponentInfoSetResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    HWComponentInfoSetResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    HWComponentInfoSetResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason UNKNOWN_COMPONENT =
+    HWComponentInfoSetResponse_Reason_UNKNOWN_COMPONENT;
+  static const Reason INVALID_PARAMS =
+    HWComponentInfoSetResponse_Reason_INVALID_PARAMS;
+  static const Reason INTERNAL_ERROR =
+    HWComponentInfoSetResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    HWComponentInfoSetResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return HWComponentInfoSetResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    HWComponentInfoSetResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    HWComponentInfoSetResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    HWComponentInfoSetResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return HWComponentInfoSetResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return HWComponentInfoSetResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return HWComponentInfoSetResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 3;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 3;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.HWComponentInfoSetResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::HWComponentInfoSetResponse_Reason reason() const;
+  void set_reason(::dmi::HWComponentInfoSetResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.HWComponentInfoSetResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class StartManagingDeviceResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.StartManagingDeviceResponse) */ {
+ public:
+  StartManagingDeviceResponse();
+  virtual ~StartManagingDeviceResponse();
+
+  StartManagingDeviceResponse(const StartManagingDeviceResponse& from);
+
+  inline StartManagingDeviceResponse& operator=(const StartManagingDeviceResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  StartManagingDeviceResponse(StartManagingDeviceResponse&& from) noexcept
+    : StartManagingDeviceResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline StartManagingDeviceResponse& operator=(StartManagingDeviceResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const StartManagingDeviceResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const StartManagingDeviceResponse* internal_default_instance() {
+    return reinterpret_cast<const StartManagingDeviceResponse*>(
+               &_StartManagingDeviceResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    6;
+
+  void Swap(StartManagingDeviceResponse* other);
+  friend void swap(StartManagingDeviceResponse& a, StartManagingDeviceResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline StartManagingDeviceResponse* New() const final {
+    return CreateMaybeMessage<StartManagingDeviceResponse>(nullptr);
+  }
+
+  StartManagingDeviceResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<StartManagingDeviceResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const StartManagingDeviceResponse& from);
+  void MergeFrom(const StartManagingDeviceResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(StartManagingDeviceResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef StartManagingDeviceResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    StartManagingDeviceResponse_Reason_UNDEFINED_REASON;
+  static const Reason DEVICE_ALREADY_MANAGED =
+    StartManagingDeviceResponse_Reason_DEVICE_ALREADY_MANAGED;
+  static const Reason OPERATION_ALREADY_IN_PROGRESS =
+    StartManagingDeviceResponse_Reason_OPERATION_ALREADY_IN_PROGRESS;
+  static const Reason INVALID_PARAMS =
+    StartManagingDeviceResponse_Reason_INVALID_PARAMS;
+  static const Reason INTERNAL_ERROR =
+    StartManagingDeviceResponse_Reason_INTERNAL_ERROR;
+  static inline bool Reason_IsValid(int value) {
+    return StartManagingDeviceResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    StartManagingDeviceResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    StartManagingDeviceResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    StartManagingDeviceResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return StartManagingDeviceResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return StartManagingDeviceResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return StartManagingDeviceResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 4;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 4;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Uuid device_uuid = 3;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 3;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.StartManagingDeviceResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::StartManagingDeviceResponse_Reason reason() const;
+  void set_reason(::dmi::StartManagingDeviceResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.StartManagingDeviceResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  ::dmi::Uuid* device_uuid_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class StopManagingDeviceRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.StopManagingDeviceRequest) */ {
+ public:
+  StopManagingDeviceRequest();
+  virtual ~StopManagingDeviceRequest();
+
+  StopManagingDeviceRequest(const StopManagingDeviceRequest& from);
+
+  inline StopManagingDeviceRequest& operator=(const StopManagingDeviceRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  StopManagingDeviceRequest(StopManagingDeviceRequest&& from) noexcept
+    : StopManagingDeviceRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline StopManagingDeviceRequest& operator=(StopManagingDeviceRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const StopManagingDeviceRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const StopManagingDeviceRequest* internal_default_instance() {
+    return reinterpret_cast<const StopManagingDeviceRequest*>(
+               &_StopManagingDeviceRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    7;
+
+  void Swap(StopManagingDeviceRequest* other);
+  friend void swap(StopManagingDeviceRequest& a, StopManagingDeviceRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline StopManagingDeviceRequest* New() const final {
+    return CreateMaybeMessage<StopManagingDeviceRequest>(nullptr);
+  }
+
+  StopManagingDeviceRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<StopManagingDeviceRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const StopManagingDeviceRequest& from);
+  void MergeFrom(const StopManagingDeviceRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(StopManagingDeviceRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string name = 1;
+  void clear_name();
+  static const int kNameFieldNumber = 1;
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_name(::std::string&& value);
+  #endif
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
+
+  // @@protoc_insertion_point(class_scope:dmi.StopManagingDeviceRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class StopManagingDeviceResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.StopManagingDeviceResponse) */ {
+ public:
+  StopManagingDeviceResponse();
+  virtual ~StopManagingDeviceResponse();
+
+  StopManagingDeviceResponse(const StopManagingDeviceResponse& from);
+
+  inline StopManagingDeviceResponse& operator=(const StopManagingDeviceResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  StopManagingDeviceResponse(StopManagingDeviceResponse&& from) noexcept
+    : StopManagingDeviceResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline StopManagingDeviceResponse& operator=(StopManagingDeviceResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const StopManagingDeviceResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const StopManagingDeviceResponse* internal_default_instance() {
+    return reinterpret_cast<const StopManagingDeviceResponse*>(
+               &_StopManagingDeviceResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    8;
+
+  void Swap(StopManagingDeviceResponse* other);
+  friend void swap(StopManagingDeviceResponse& a, StopManagingDeviceResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline StopManagingDeviceResponse* New() const final {
+    return CreateMaybeMessage<StopManagingDeviceResponse>(nullptr);
+  }
+
+  StopManagingDeviceResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<StopManagingDeviceResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const StopManagingDeviceResponse& from);
+  void MergeFrom(const StopManagingDeviceResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(StopManagingDeviceResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef StopManagingDeviceResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    StopManagingDeviceResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    StopManagingDeviceResponse_Reason_UNKNOWN_DEVICE;
+  static inline bool Reason_IsValid(int value) {
+    return StopManagingDeviceResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    StopManagingDeviceResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    StopManagingDeviceResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    StopManagingDeviceResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return StopManagingDeviceResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return StopManagingDeviceResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return StopManagingDeviceResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 3;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 3;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.StopManagingDeviceResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::StopManagingDeviceResponse_Reason reason() const;
+  void set_reason(::dmi::StopManagingDeviceResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.StopManagingDeviceResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ManagedDeviceInfo final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ManagedDeviceInfo) */ {
+ public:
+  ManagedDeviceInfo();
+  virtual ~ManagedDeviceInfo();
+
+  ManagedDeviceInfo(const ManagedDeviceInfo& from);
+
+  inline ManagedDeviceInfo& operator=(const ManagedDeviceInfo& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ManagedDeviceInfo(ManagedDeviceInfo&& from) noexcept
+    : ManagedDeviceInfo() {
+    *this = ::std::move(from);
+  }
+
+  inline ManagedDeviceInfo& operator=(ManagedDeviceInfo&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ManagedDeviceInfo& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ManagedDeviceInfo* internal_default_instance() {
+    return reinterpret_cast<const ManagedDeviceInfo*>(
+               &_ManagedDeviceInfo_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    9;
+
+  void Swap(ManagedDeviceInfo* other);
+  friend void swap(ManagedDeviceInfo& a, ManagedDeviceInfo& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ManagedDeviceInfo* New() const final {
+    return CreateMaybeMessage<ManagedDeviceInfo>(nullptr);
+  }
+
+  ManagedDeviceInfo* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ManagedDeviceInfo>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ManagedDeviceInfo& from);
+  void MergeFrom(const ManagedDeviceInfo& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ManagedDeviceInfo* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.ModifiableComponent info = 1;
+  bool has_info() const;
+  void clear_info();
+  static const int kInfoFieldNumber = 1;
+  const ::dmi::ModifiableComponent& info() const;
+  ::dmi::ModifiableComponent* release_info();
+  ::dmi::ModifiableComponent* mutable_info();
+  void set_allocated_info(::dmi::ModifiableComponent* info);
+
+  // .dmi.Uuid device_uuid = 2;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 2;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.ManagedDeviceInfo)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::ModifiableComponent* info_;
+  ::dmi::Uuid* device_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ManagedDevicesResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ManagedDevicesResponse) */ {
+ public:
+  ManagedDevicesResponse();
+  virtual ~ManagedDevicesResponse();
+
+  ManagedDevicesResponse(const ManagedDevicesResponse& from);
+
+  inline ManagedDevicesResponse& operator=(const ManagedDevicesResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ManagedDevicesResponse(ManagedDevicesResponse&& from) noexcept
+    : ManagedDevicesResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline ManagedDevicesResponse& operator=(ManagedDevicesResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ManagedDevicesResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ManagedDevicesResponse* internal_default_instance() {
+    return reinterpret_cast<const ManagedDevicesResponse*>(
+               &_ManagedDevicesResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    10;
+
+  void Swap(ManagedDevicesResponse* other);
+  friend void swap(ManagedDevicesResponse& a, ManagedDevicesResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ManagedDevicesResponse* New() const final {
+    return CreateMaybeMessage<ManagedDevicesResponse>(nullptr);
+  }
+
+  ManagedDevicesResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ManagedDevicesResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ManagedDevicesResponse& from);
+  void MergeFrom(const ManagedDevicesResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ManagedDevicesResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef ManagedDevicesResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    ManagedDevicesResponse_Reason_UNDEFINED_REASON;
+  static const Reason INTERNAL_ERROR =
+    ManagedDevicesResponse_Reason_INTERNAL_ERROR;
+  static inline bool Reason_IsValid(int value) {
+    return ManagedDevicesResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    ManagedDevicesResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    ManagedDevicesResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    ManagedDevicesResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return ManagedDevicesResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return ManagedDevicesResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return ManagedDevicesResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // repeated .dmi.ManagedDeviceInfo devices = 3;
+  int devices_size() const;
+  void clear_devices();
+  static const int kDevicesFieldNumber = 3;
+  ::dmi::ManagedDeviceInfo* mutable_devices(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::ManagedDeviceInfo >*
+      mutable_devices();
+  const ::dmi::ManagedDeviceInfo& devices(int index) const;
+  ::dmi::ManagedDeviceInfo* add_devices();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::ManagedDeviceInfo >&
+      devices() const;
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.ManagedDevicesResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::ManagedDevicesResponse_Reason reason() const;
+  void set_reason(::dmi::ManagedDevicesResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ManagedDevicesResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::ManagedDeviceInfo > devices_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class SetLoggingEndpointRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.SetLoggingEndpointRequest) */ {
+ public:
+  SetLoggingEndpointRequest();
+  virtual ~SetLoggingEndpointRequest();
+
+  SetLoggingEndpointRequest(const SetLoggingEndpointRequest& from);
+
+  inline SetLoggingEndpointRequest& operator=(const SetLoggingEndpointRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  SetLoggingEndpointRequest(SetLoggingEndpointRequest&& from) noexcept
+    : SetLoggingEndpointRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline SetLoggingEndpointRequest& operator=(SetLoggingEndpointRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const SetLoggingEndpointRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const SetLoggingEndpointRequest* internal_default_instance() {
+    return reinterpret_cast<const SetLoggingEndpointRequest*>(
+               &_SetLoggingEndpointRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    11;
+
+  void Swap(SetLoggingEndpointRequest* other);
+  friend void swap(SetLoggingEndpointRequest& a, SetLoggingEndpointRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline SetLoggingEndpointRequest* New() const final {
+    return CreateMaybeMessage<SetLoggingEndpointRequest>(nullptr);
+  }
+
+  SetLoggingEndpointRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<SetLoggingEndpointRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const SetLoggingEndpointRequest& from);
+  void MergeFrom(const SetLoggingEndpointRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(SetLoggingEndpointRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string logging_endpoint = 2;
+  void clear_logging_endpoint();
+  static const int kLoggingEndpointFieldNumber = 2;
+  const ::std::string& logging_endpoint() const;
+  void set_logging_endpoint(const ::std::string& value);
+  #if LANG_CXX11
+  void set_logging_endpoint(::std::string&& value);
+  #endif
+  void set_logging_endpoint(const char* value);
+  void set_logging_endpoint(const char* value, size_t size);
+  ::std::string* mutable_logging_endpoint();
+  ::std::string* release_logging_endpoint();
+  void set_allocated_logging_endpoint(::std::string* logging_endpoint);
+
+  // string logging_protocol = 3;
+  void clear_logging_protocol();
+  static const int kLoggingProtocolFieldNumber = 3;
+  const ::std::string& logging_protocol() const;
+  void set_logging_protocol(const ::std::string& value);
+  #if LANG_CXX11
+  void set_logging_protocol(::std::string&& value);
+  #endif
+  void set_logging_protocol(const char* value);
+  void set_logging_protocol(const char* value, size_t size);
+  ::std::string* mutable_logging_protocol();
+  ::std::string* release_logging_protocol();
+  void set_allocated_logging_protocol(::std::string* logging_protocol);
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.SetLoggingEndpointRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr logging_endpoint_;
+  ::google::protobuf::internal::ArenaStringPtr logging_protocol_;
+  ::dmi::Uuid* device_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class SetRemoteEndpointResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.SetRemoteEndpointResponse) */ {
+ public:
+  SetRemoteEndpointResponse();
+  virtual ~SetRemoteEndpointResponse();
+
+  SetRemoteEndpointResponse(const SetRemoteEndpointResponse& from);
+
+  inline SetRemoteEndpointResponse& operator=(const SetRemoteEndpointResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  SetRemoteEndpointResponse(SetRemoteEndpointResponse&& from) noexcept
+    : SetRemoteEndpointResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline SetRemoteEndpointResponse& operator=(SetRemoteEndpointResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const SetRemoteEndpointResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const SetRemoteEndpointResponse* internal_default_instance() {
+    return reinterpret_cast<const SetRemoteEndpointResponse*>(
+               &_SetRemoteEndpointResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    12;
+
+  void Swap(SetRemoteEndpointResponse* other);
+  friend void swap(SetRemoteEndpointResponse& a, SetRemoteEndpointResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline SetRemoteEndpointResponse* New() const final {
+    return CreateMaybeMessage<SetRemoteEndpointResponse>(nullptr);
+  }
+
+  SetRemoteEndpointResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<SetRemoteEndpointResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const SetRemoteEndpointResponse& from);
+  void MergeFrom(const SetRemoteEndpointResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(SetRemoteEndpointResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef SetRemoteEndpointResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    SetRemoteEndpointResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    SetRemoteEndpointResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    SetRemoteEndpointResponse_Reason_INTERNAL_ERROR;
+  static const Reason LOGGING_ENDPOINT_ERROR =
+    SetRemoteEndpointResponse_Reason_LOGGING_ENDPOINT_ERROR;
+  static const Reason LOGGING_ENDPOINT_PROTOCOL_ERROR =
+    SetRemoteEndpointResponse_Reason_LOGGING_ENDPOINT_PROTOCOL_ERROR;
+  static const Reason MSGBUS_ENDPOINT_ERROR =
+    SetRemoteEndpointResponse_Reason_MSGBUS_ENDPOINT_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    SetRemoteEndpointResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return SetRemoteEndpointResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    SetRemoteEndpointResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    SetRemoteEndpointResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    SetRemoteEndpointResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return SetRemoteEndpointResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return SetRemoteEndpointResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return SetRemoteEndpointResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 3;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 3;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.SetRemoteEndpointResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::SetRemoteEndpointResponse_Reason reason() const;
+  void set_reason(::dmi::SetRemoteEndpointResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.SetRemoteEndpointResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class GetLoggingEndpointResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.GetLoggingEndpointResponse) */ {
+ public:
+  GetLoggingEndpointResponse();
+  virtual ~GetLoggingEndpointResponse();
+
+  GetLoggingEndpointResponse(const GetLoggingEndpointResponse& from);
+
+  inline GetLoggingEndpointResponse& operator=(const GetLoggingEndpointResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  GetLoggingEndpointResponse(GetLoggingEndpointResponse&& from) noexcept
+    : GetLoggingEndpointResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline GetLoggingEndpointResponse& operator=(GetLoggingEndpointResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const GetLoggingEndpointResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const GetLoggingEndpointResponse* internal_default_instance() {
+    return reinterpret_cast<const GetLoggingEndpointResponse*>(
+               &_GetLoggingEndpointResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    13;
+
+  void Swap(GetLoggingEndpointResponse* other);
+  friend void swap(GetLoggingEndpointResponse& a, GetLoggingEndpointResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline GetLoggingEndpointResponse* New() const final {
+    return CreateMaybeMessage<GetLoggingEndpointResponse>(nullptr);
+  }
+
+  GetLoggingEndpointResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<GetLoggingEndpointResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const GetLoggingEndpointResponse& from);
+  void MergeFrom(const GetLoggingEndpointResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(GetLoggingEndpointResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef GetLoggingEndpointResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    GetLoggingEndpointResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    GetLoggingEndpointResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    GetLoggingEndpointResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    GetLoggingEndpointResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return GetLoggingEndpointResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    GetLoggingEndpointResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    GetLoggingEndpointResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    GetLoggingEndpointResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return GetLoggingEndpointResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return GetLoggingEndpointResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return GetLoggingEndpointResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string logging_endpoint = 3;
+  void clear_logging_endpoint();
+  static const int kLoggingEndpointFieldNumber = 3;
+  const ::std::string& logging_endpoint() const;
+  void set_logging_endpoint(const ::std::string& value);
+  #if LANG_CXX11
+  void set_logging_endpoint(::std::string&& value);
+  #endif
+  void set_logging_endpoint(const char* value);
+  void set_logging_endpoint(const char* value, size_t size);
+  ::std::string* mutable_logging_endpoint();
+  ::std::string* release_logging_endpoint();
+  void set_allocated_logging_endpoint(::std::string* logging_endpoint);
+
+  // string logging_protocol = 4;
+  void clear_logging_protocol();
+  static const int kLoggingProtocolFieldNumber = 4;
+  const ::std::string& logging_protocol() const;
+  void set_logging_protocol(const ::std::string& value);
+  #if LANG_CXX11
+  void set_logging_protocol(::std::string&& value);
+  #endif
+  void set_logging_protocol(const char* value);
+  void set_logging_protocol(const char* value, size_t size);
+  ::std::string* mutable_logging_protocol();
+  ::std::string* release_logging_protocol();
+  void set_allocated_logging_protocol(::std::string* logging_protocol);
+
+  // string reason_detail = 5;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 5;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.GetLoggingEndpointResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::GetLoggingEndpointResponse_Reason reason() const;
+  void set_reason(::dmi::GetLoggingEndpointResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.GetLoggingEndpointResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr logging_endpoint_;
+  ::google::protobuf::internal::ArenaStringPtr logging_protocol_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class SetMsgBusEndpointRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.SetMsgBusEndpointRequest) */ {
+ public:
+  SetMsgBusEndpointRequest();
+  virtual ~SetMsgBusEndpointRequest();
+
+  SetMsgBusEndpointRequest(const SetMsgBusEndpointRequest& from);
+
+  inline SetMsgBusEndpointRequest& operator=(const SetMsgBusEndpointRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  SetMsgBusEndpointRequest(SetMsgBusEndpointRequest&& from) noexcept
+    : SetMsgBusEndpointRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline SetMsgBusEndpointRequest& operator=(SetMsgBusEndpointRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const SetMsgBusEndpointRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const SetMsgBusEndpointRequest* internal_default_instance() {
+    return reinterpret_cast<const SetMsgBusEndpointRequest*>(
+               &_SetMsgBusEndpointRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    14;
+
+  void Swap(SetMsgBusEndpointRequest* other);
+  friend void swap(SetMsgBusEndpointRequest& a, SetMsgBusEndpointRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline SetMsgBusEndpointRequest* New() const final {
+    return CreateMaybeMessage<SetMsgBusEndpointRequest>(nullptr);
+  }
+
+  SetMsgBusEndpointRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<SetMsgBusEndpointRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const SetMsgBusEndpointRequest& from);
+  void MergeFrom(const SetMsgBusEndpointRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(SetMsgBusEndpointRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string msgbus_endpoint = 1;
+  void clear_msgbus_endpoint();
+  static const int kMsgbusEndpointFieldNumber = 1;
+  const ::std::string& msgbus_endpoint() const;
+  void set_msgbus_endpoint(const ::std::string& value);
+  #if LANG_CXX11
+  void set_msgbus_endpoint(::std::string&& value);
+  #endif
+  void set_msgbus_endpoint(const char* value);
+  void set_msgbus_endpoint(const char* value, size_t size);
+  ::std::string* mutable_msgbus_endpoint();
+  ::std::string* release_msgbus_endpoint();
+  void set_allocated_msgbus_endpoint(::std::string* msgbus_endpoint);
+
+  // @@protoc_insertion_point(class_scope:dmi.SetMsgBusEndpointRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr msgbus_endpoint_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class GetMsgBusEndpointResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.GetMsgBusEndpointResponse) */ {
+ public:
+  GetMsgBusEndpointResponse();
+  virtual ~GetMsgBusEndpointResponse();
+
+  GetMsgBusEndpointResponse(const GetMsgBusEndpointResponse& from);
+
+  inline GetMsgBusEndpointResponse& operator=(const GetMsgBusEndpointResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  GetMsgBusEndpointResponse(GetMsgBusEndpointResponse&& from) noexcept
+    : GetMsgBusEndpointResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline GetMsgBusEndpointResponse& operator=(GetMsgBusEndpointResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const GetMsgBusEndpointResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const GetMsgBusEndpointResponse* internal_default_instance() {
+    return reinterpret_cast<const GetMsgBusEndpointResponse*>(
+               &_GetMsgBusEndpointResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    15;
+
+  void Swap(GetMsgBusEndpointResponse* other);
+  friend void swap(GetMsgBusEndpointResponse& a, GetMsgBusEndpointResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline GetMsgBusEndpointResponse* New() const final {
+    return CreateMaybeMessage<GetMsgBusEndpointResponse>(nullptr);
+  }
+
+  GetMsgBusEndpointResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<GetMsgBusEndpointResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const GetMsgBusEndpointResponse& from);
+  void MergeFrom(const GetMsgBusEndpointResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(GetMsgBusEndpointResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef GetMsgBusEndpointResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    GetMsgBusEndpointResponse_Reason_UNDEFINED_REASON;
+  static const Reason INTERNAL_ERROR =
+    GetMsgBusEndpointResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    GetMsgBusEndpointResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return GetMsgBusEndpointResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    GetMsgBusEndpointResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    GetMsgBusEndpointResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    GetMsgBusEndpointResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return GetMsgBusEndpointResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return GetMsgBusEndpointResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return GetMsgBusEndpointResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string msgbus_endpoint = 3;
+  void clear_msgbus_endpoint();
+  static const int kMsgbusEndpointFieldNumber = 3;
+  const ::std::string& msgbus_endpoint() const;
+  void set_msgbus_endpoint(const ::std::string& value);
+  #if LANG_CXX11
+  void set_msgbus_endpoint(::std::string&& value);
+  #endif
+  void set_msgbus_endpoint(const char* value);
+  void set_msgbus_endpoint(const char* value, size_t size);
+  ::std::string* mutable_msgbus_endpoint();
+  ::std::string* release_msgbus_endpoint();
+  void set_allocated_msgbus_endpoint(::std::string* msgbus_endpoint);
+
+  // string reason_detail = 4;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 4;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.GetMsgBusEndpointResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::GetMsgBusEndpointResponse_Reason reason() const;
+  void set_reason(::dmi::GetMsgBusEndpointResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.GetMsgBusEndpointResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr msgbus_endpoint_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class EntitiesLogLevel final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EntitiesLogLevel) */ {
+ public:
+  EntitiesLogLevel();
+  virtual ~EntitiesLogLevel();
+
+  EntitiesLogLevel(const EntitiesLogLevel& from);
+
+  inline EntitiesLogLevel& operator=(const EntitiesLogLevel& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  EntitiesLogLevel(EntitiesLogLevel&& from) noexcept
+    : EntitiesLogLevel() {
+    *this = ::std::move(from);
+  }
+
+  inline EntitiesLogLevel& operator=(EntitiesLogLevel&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const EntitiesLogLevel& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const EntitiesLogLevel* internal_default_instance() {
+    return reinterpret_cast<const EntitiesLogLevel*>(
+               &_EntitiesLogLevel_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    16;
+
+  void Swap(EntitiesLogLevel* other);
+  friend void swap(EntitiesLogLevel& a, EntitiesLogLevel& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline EntitiesLogLevel* New() const final {
+    return CreateMaybeMessage<EntitiesLogLevel>(nullptr);
+  }
+
+  EntitiesLogLevel* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<EntitiesLogLevel>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const EntitiesLogLevel& from);
+  void MergeFrom(const EntitiesLogLevel& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(EntitiesLogLevel* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated string entities = 2;
+  int entities_size() const;
+  void clear_entities();
+  static const int kEntitiesFieldNumber = 2;
+  const ::std::string& entities(int index) const;
+  ::std::string* mutable_entities(int index);
+  void set_entities(int index, const ::std::string& value);
+  #if LANG_CXX11
+  void set_entities(int index, ::std::string&& value);
+  #endif
+  void set_entities(int index, const char* value);
+  void set_entities(int index, const char* value, size_t size);
+  ::std::string* add_entities();
+  void add_entities(const ::std::string& value);
+  #if LANG_CXX11
+  void add_entities(::std::string&& value);
+  #endif
+  void add_entities(const char* value);
+  void add_entities(const char* value, size_t size);
+  const ::google::protobuf::RepeatedPtrField<::std::string>& entities() const;
+  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_entities();
+
+  // .dmi.LogLevel logLevel = 1;
+  void clear_loglevel();
+  static const int kLogLevelFieldNumber = 1;
+  ::dmi::LogLevel loglevel() const;
+  void set_loglevel(::dmi::LogLevel value);
+
+  // @@protoc_insertion_point(class_scope:dmi.EntitiesLogLevel)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField<::std::string> entities_;
+  int loglevel_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class SetLogLevelRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.SetLogLevelRequest) */ {
+ public:
+  SetLogLevelRequest();
+  virtual ~SetLogLevelRequest();
+
+  SetLogLevelRequest(const SetLogLevelRequest& from);
+
+  inline SetLogLevelRequest& operator=(const SetLogLevelRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  SetLogLevelRequest(SetLogLevelRequest&& from) noexcept
+    : SetLogLevelRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline SetLogLevelRequest& operator=(SetLogLevelRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const SetLogLevelRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const SetLogLevelRequest* internal_default_instance() {
+    return reinterpret_cast<const SetLogLevelRequest*>(
+               &_SetLogLevelRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    17;
+
+  void Swap(SetLogLevelRequest* other);
+  friend void swap(SetLogLevelRequest& a, SetLogLevelRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline SetLogLevelRequest* New() const final {
+    return CreateMaybeMessage<SetLogLevelRequest>(nullptr);
+  }
+
+  SetLogLevelRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<SetLogLevelRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const SetLogLevelRequest& from);
+  void MergeFrom(const SetLogLevelRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(SetLogLevelRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated .dmi.EntitiesLogLevel loglevels = 2;
+  int loglevels_size() const;
+  void clear_loglevels();
+  static const int kLoglevelsFieldNumber = 2;
+  ::dmi::EntitiesLogLevel* mutable_loglevels(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >*
+      mutable_loglevels();
+  const ::dmi::EntitiesLogLevel& loglevels(int index) const;
+  ::dmi::EntitiesLogLevel* add_loglevels();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >&
+      loglevels() const;
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.SetLogLevelRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel > loglevels_;
+  ::dmi::Uuid* device_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class SetLogLevelResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.SetLogLevelResponse) */ {
+ public:
+  SetLogLevelResponse();
+  virtual ~SetLogLevelResponse();
+
+  SetLogLevelResponse(const SetLogLevelResponse& from);
+
+  inline SetLogLevelResponse& operator=(const SetLogLevelResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  SetLogLevelResponse(SetLogLevelResponse&& from) noexcept
+    : SetLogLevelResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline SetLogLevelResponse& operator=(SetLogLevelResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const SetLogLevelResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const SetLogLevelResponse* internal_default_instance() {
+    return reinterpret_cast<const SetLogLevelResponse*>(
+               &_SetLogLevelResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    18;
+
+  void Swap(SetLogLevelResponse* other);
+  friend void swap(SetLogLevelResponse& a, SetLogLevelResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline SetLogLevelResponse* New() const final {
+    return CreateMaybeMessage<SetLogLevelResponse>(nullptr);
+  }
+
+  SetLogLevelResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<SetLogLevelResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const SetLogLevelResponse& from);
+  void MergeFrom(const SetLogLevelResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(SetLogLevelResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef SetLogLevelResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    SetLogLevelResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    SetLogLevelResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    SetLogLevelResponse_Reason_INTERNAL_ERROR;
+  static const Reason UNKNOWN_LOG_ENTITY =
+    SetLogLevelResponse_Reason_UNKNOWN_LOG_ENTITY;
+  static const Reason DEVICE_UNREACHABLE =
+    SetLogLevelResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return SetLogLevelResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    SetLogLevelResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    SetLogLevelResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    SetLogLevelResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return SetLogLevelResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return SetLogLevelResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return SetLogLevelResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 4;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 4;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.Status status = 2;
+  void clear_status();
+  static const int kStatusFieldNumber = 2;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.SetLogLevelResponse.Reason reason = 3;
+  void clear_reason();
+  static const int kReasonFieldNumber = 3;
+  ::dmi::SetLogLevelResponse_Reason reason() const;
+  void set_reason(::dmi::SetLogLevelResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.SetLogLevelResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  ::dmi::Uuid* device_uuid_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class GetLogLevelRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.GetLogLevelRequest) */ {
+ public:
+  GetLogLevelRequest();
+  virtual ~GetLogLevelRequest();
+
+  GetLogLevelRequest(const GetLogLevelRequest& from);
+
+  inline GetLogLevelRequest& operator=(const GetLogLevelRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  GetLogLevelRequest(GetLogLevelRequest&& from) noexcept
+    : GetLogLevelRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline GetLogLevelRequest& operator=(GetLogLevelRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const GetLogLevelRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const GetLogLevelRequest* internal_default_instance() {
+    return reinterpret_cast<const GetLogLevelRequest*>(
+               &_GetLogLevelRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    19;
+
+  void Swap(GetLogLevelRequest* other);
+  friend void swap(GetLogLevelRequest& a, GetLogLevelRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline GetLogLevelRequest* New() const final {
+    return CreateMaybeMessage<GetLogLevelRequest>(nullptr);
+  }
+
+  GetLogLevelRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<GetLogLevelRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const GetLogLevelRequest& from);
+  void MergeFrom(const GetLogLevelRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(GetLogLevelRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated string entities = 2;
+  int entities_size() const;
+  void clear_entities();
+  static const int kEntitiesFieldNumber = 2;
+  const ::std::string& entities(int index) const;
+  ::std::string* mutable_entities(int index);
+  void set_entities(int index, const ::std::string& value);
+  #if LANG_CXX11
+  void set_entities(int index, ::std::string&& value);
+  #endif
+  void set_entities(int index, const char* value);
+  void set_entities(int index, const char* value, size_t size);
+  ::std::string* add_entities();
+  void add_entities(const ::std::string& value);
+  #if LANG_CXX11
+  void add_entities(::std::string&& value);
+  #endif
+  void add_entities(const char* value);
+  void add_entities(const char* value, size_t size);
+  const ::google::protobuf::RepeatedPtrField<::std::string>& entities() const;
+  ::google::protobuf::RepeatedPtrField<::std::string>* mutable_entities();
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.GetLogLevelRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField<::std::string> entities_;
+  ::dmi::Uuid* device_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class GetLogLevelResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.GetLogLevelResponse) */ {
+ public:
+  GetLogLevelResponse();
+  virtual ~GetLogLevelResponse();
+
+  GetLogLevelResponse(const GetLogLevelResponse& from);
+
+  inline GetLogLevelResponse& operator=(const GetLogLevelResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  GetLogLevelResponse(GetLogLevelResponse&& from) noexcept
+    : GetLogLevelResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline GetLogLevelResponse& operator=(GetLogLevelResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const GetLogLevelResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const GetLogLevelResponse* internal_default_instance() {
+    return reinterpret_cast<const GetLogLevelResponse*>(
+               &_GetLogLevelResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    20;
+
+  void Swap(GetLogLevelResponse* other);
+  friend void swap(GetLogLevelResponse& a, GetLogLevelResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline GetLogLevelResponse* New() const final {
+    return CreateMaybeMessage<GetLogLevelResponse>(nullptr);
+  }
+
+  GetLogLevelResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<GetLogLevelResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const GetLogLevelResponse& from);
+  void MergeFrom(const GetLogLevelResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(GetLogLevelResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef GetLogLevelResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    GetLogLevelResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    GetLogLevelResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    GetLogLevelResponse_Reason_INTERNAL_ERROR;
+  static const Reason UNKNOWN_LOG_ENTITY =
+    GetLogLevelResponse_Reason_UNKNOWN_LOG_ENTITY;
+  static const Reason DEVICE_UNREACHABLE =
+    GetLogLevelResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return GetLogLevelResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    GetLogLevelResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    GetLogLevelResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    GetLogLevelResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return GetLogLevelResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return GetLogLevelResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return GetLogLevelResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // repeated .dmi.EntitiesLogLevel logLevels = 2;
+  int loglevels_size() const;
+  void clear_loglevels();
+  static const int kLogLevelsFieldNumber = 2;
+  ::dmi::EntitiesLogLevel* mutable_loglevels(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >*
+      mutable_loglevels();
+  const ::dmi::EntitiesLogLevel& loglevels(int index) const;
+  ::dmi::EntitiesLogLevel* add_loglevels();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel >&
+      loglevels() const;
+
+  // string reason_detail = 5;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 5;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.Status status = 3;
+  void clear_status();
+  static const int kStatusFieldNumber = 3;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.GetLogLevelResponse.Reason reason = 4;
+  void clear_reason();
+  static const int kReasonFieldNumber = 4;
+  ::dmi::GetLogLevelResponse_Reason reason() const;
+  void set_reason(::dmi::GetLogLevelResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.GetLogLevelResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::EntitiesLogLevel > loglevels_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  ::dmi::Uuid* device_uuid_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class GetLoggableEntitiesRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.GetLoggableEntitiesRequest) */ {
+ public:
+  GetLoggableEntitiesRequest();
+  virtual ~GetLoggableEntitiesRequest();
+
+  GetLoggableEntitiesRequest(const GetLoggableEntitiesRequest& from);
+
+  inline GetLoggableEntitiesRequest& operator=(const GetLoggableEntitiesRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  GetLoggableEntitiesRequest(GetLoggableEntitiesRequest&& from) noexcept
+    : GetLoggableEntitiesRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline GetLoggableEntitiesRequest& operator=(GetLoggableEntitiesRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const GetLoggableEntitiesRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const GetLoggableEntitiesRequest* internal_default_instance() {
+    return reinterpret_cast<const GetLoggableEntitiesRequest*>(
+               &_GetLoggableEntitiesRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    21;
+
+  void Swap(GetLoggableEntitiesRequest* other);
+  friend void swap(GetLoggableEntitiesRequest& a, GetLoggableEntitiesRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline GetLoggableEntitiesRequest* New() const final {
+    return CreateMaybeMessage<GetLoggableEntitiesRequest>(nullptr);
+  }
+
+  GetLoggableEntitiesRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<GetLoggableEntitiesRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const GetLoggableEntitiesRequest& from);
+  void MergeFrom(const GetLoggableEntitiesRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(GetLoggableEntitiesRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.GetLoggableEntitiesRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::Uuid* device_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#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)
+}
+
+#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();
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#include <google/protobuf/port_undef.inc>
+#endif  // PROTOBUF_INCLUDED_dmi_2fhw_5fmanagement_5fservice_2eproto
diff --git a/cpp/dmi/hw_metrics_mgmt_service.pb.cc b/cpp/dmi/hw_metrics_mgmt_service.pb.cc
new file mode 100644
index 0000000..389e53d
--- /dev/null
+++ b/cpp/dmi/hw_metrics_mgmt_service.pb.cc
@@ -0,0 +1,4155 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/hw_metrics_mgmt_service.proto
+
+#include "dmi/hw_metrics_mgmt_service.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ComponentSensorData_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_MetricConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MetricMetaData_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_MetricsConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_Metric_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+namespace dmi {
+class MetricConfigDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<MetricConfig> _instance;
+} _MetricConfig_default_instance_;
+class MetricsConfigDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<MetricsConfig> _instance;
+} _MetricsConfig_default_instance_;
+class ListMetricsResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ListMetricsResponse> _instance;
+} _ListMetricsResponse_default_instance_;
+class MetricsConfigurationRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<MetricsConfigurationRequest> _instance;
+  const ::dmi::MetricsConfig* changes_;
+  bool reset_to_default_;
+} _MetricsConfigurationRequest_default_instance_;
+class MetricsConfigurationResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<MetricsConfigurationResponse> _instance;
+} _MetricsConfigurationResponse_default_instance_;
+class MetricMetaDataDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<MetricMetaData> _instance;
+} _MetricMetaData_default_instance_;
+class MetricDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Metric> _instance;
+} _Metric_default_instance_;
+class GetMetricRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<GetMetricRequest> _instance;
+} _GetMetricRequest_default_instance_;
+class GetMetricResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<GetMetricResponse> _instance;
+} _GetMetricResponse_default_instance_;
+}  // namespace dmi
+static void InitDefaultsMetricConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_MetricConfig_default_instance_;
+    new (ptr) ::dmi::MetricConfig();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::MetricConfig::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_MetricConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsMetricConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto}, {}};
+
+static void InitDefaultsMetricsConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_MetricsConfig_default_instance_;
+    new (ptr) ::dmi::MetricsConfig();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::MetricsConfig::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_MetricsConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMetricsConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto}, {
+      &scc_info_MetricConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsListMetricsResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ListMetricsResponse_default_instance_;
+    new (ptr) ::dmi::ListMetricsResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ListMetricsResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ListMetricsResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsListMetricsResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto}, {
+      &scc_info_MetricsConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsMetricsConfigurationRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_MetricsConfigurationRequest_default_instance_;
+    new (ptr) ::dmi::MetricsConfigurationRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::MetricsConfigurationRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_MetricsConfigurationRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsMetricsConfigurationRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,
+      &scc_info_MetricsConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsMetricsConfigurationResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_MetricsConfigurationResponse_default_instance_;
+    new (ptr) ::dmi::MetricsConfigurationResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::MetricsConfigurationResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_MetricsConfigurationResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsMetricsConfigurationResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto}, {}};
+
+static void InitDefaultsMetricMetaData_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_MetricMetaData_default_instance_;
+    new (ptr) ::dmi::MetricMetaData();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::MetricMetaData::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_MetricMetaData_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsMetricMetaData_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsMetric_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Metric_default_instance_;
+    new (ptr) ::dmi::Metric();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Metric::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_Metric_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsMetric_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto}, {
+      &scc_info_MetricMetaData_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base,
+      &scc_info_ComponentSensorData_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsGetMetricRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_GetMetricRequest_default_instance_;
+    new (ptr) ::dmi::GetMetricRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::GetMetricRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_GetMetricRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsGetMetricRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto}, {
+      &scc_info_MetricMetaData_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base,}};
+
+static void InitDefaultsGetMetricResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_GetMetricResponse_default_instance_;
+    new (ptr) ::dmi::GetMetricResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::GetMetricResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_GetMetricResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsGetMetricResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto}, {
+      &scc_info_Metric_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base,}};
+
+void InitDefaults_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_MetricConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_MetricsConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ListMetricsResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_MetricsConfigurationRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_MetricsConfigurationResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_MetricMetaData_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Metric_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GetMetricRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GetMetricResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+}
+
+::google::protobuf::Metadata file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[9];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[4];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto = nullptr;
+
+const ::google::protobuf::uint32 TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricConfig, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricConfig, metric_id_),
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricConfig, is_configured_),
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricConfig, poll_interval_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfig, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfig, metrics_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ListMetricsResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ListMetricsResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ListMetricsResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ListMetricsResponse, metrics_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ListMetricsResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfigurationRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfigurationRequest, _oneof_case_[0]),
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfigurationRequest, device_uuid_),
+  offsetof(::dmi::MetricsConfigurationRequestDefaultTypeInternal, changes_),
+  offsetof(::dmi::MetricsConfigurationRequestDefaultTypeInternal, reset_to_default_),
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfigurationRequest, operation_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfigurationResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfigurationResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfigurationResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricsConfigurationResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricMetaData, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricMetaData, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricMetaData, component_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::MetricMetaData, component_name_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Metric, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Metric, metric_id_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Metric, metric_metadata_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Metric, value_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMetricRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMetricRequest, meta_data_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMetricRequest, metric_id_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMetricResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMetricResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMetricResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMetricResponse, metric_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetMetricResponse, reason_detail_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  { 0, -1, sizeof(::dmi::MetricConfig)},
+  { 8, -1, sizeof(::dmi::MetricsConfig)},
+  { 14, -1, sizeof(::dmi::ListMetricsResponse)},
+  { 23, -1, sizeof(::dmi::MetricsConfigurationRequest)},
+  { 32, -1, sizeof(::dmi::MetricsConfigurationResponse)},
+  { 40, -1, sizeof(::dmi::MetricMetaData)},
+  { 48, -1, sizeof(::dmi::Metric)},
+  { 56, -1, sizeof(::dmi::GetMetricRequest)},
+  { 63, -1, sizeof(::dmi::GetMetricResponse)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_MetricConfig_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_MetricsConfig_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ListMetricsResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_MetricsConfigurationRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_MetricsConfigurationResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_MetricMetaData_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Metric_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_GetMetricRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_GetMetricResponse_default_instance_),
+};
+
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto = {
+  {}, AddDescriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto, "dmi/hw_metrics_mgmt_service.proto", schemas,
+  file_default_instances, TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto::offsets,
+  file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto, 9, file_level_enum_descriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto, file_level_service_descriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto,
+};
+
+const char descriptor_table_protodef_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[] =
+  "\n!dmi/hw_metrics_mgmt_service.proto\022\003dmi"
+  "\032\021dmi/commons.proto\032\014dmi/hw.proto\"a\n\014Met"
+  "ricConfig\022#\n\tmetric_id\030\001 \001(\0162\020.dmi.Metri"
+  "cNames\022\025\n\ris_configured\030\002 \001(\010\022\025\n\rpoll_in"
+  "terval\030\003 \001(\r\"3\n\rMetricsConfig\022\"\n\007metrics"
+  "\030\001 \003(\0132\021.dmi.MetricConfig\"\377\001\n\023ListMetric"
+  "sResponse\022\033\n\006status\030\001 \001(\0162\013.dmi.Status\022/"
+  "\n\006reason\030\002 \001(\0162\037.dmi.ListMetricsResponse"
+  ".Reason\022#\n\007metrics\030\003 \001(\0132\022.dmi.MetricsCo"
+  "nfig\022\025\n\rreason_detail\030\004 \001(\t\"^\n\006Reason\022\024\n"
+  "\020UNDEFINED_REASON\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022"
+  "\022\n\016INTERNAL_ERROR\020\002\022\026\n\022DEVICE_UNREACHABL"
+  "E\020\003\"\215\001\n\033MetricsConfigurationRequest\022\036\n\013d"
+  "evice_uuid\030\001 \001(\0132\t.dmi.Uuid\022%\n\007changes\030\002"
+  " \001(\0132\022.dmi.MetricsConfigH\000\022\032\n\020reset_to_d"
+  "efault\030\003 \001(\010H\000B\013\n\toperation\"\240\002\n\034MetricsC"
+  "onfigurationResponse\022\033\n\006status\030\001 \001(\0162\013.d"
+  "mi.Status\0228\n\006reason\030\002 \001(\0162(.dmi.MetricsC"
+  "onfigurationResponse.Reason\022\025\n\rreason_de"
+  "tail\030\003 \001(\t\"\221\001\n\006Reason\022\024\n\020UNDEFINED_REASO"
+  "N\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INTERNAL_ERRO"
+  "R\020\002\022\035\n\031POLL_INTERVAL_UNSUPPORTED\020\003\022\022\n\016IN"
+  "VALID_METRIC\020\004\022\026\n\022DEVICE_UNREACHABLE\020\005\"k"
+  "\n\016MetricMetaData\022\036\n\013device_uuid\030\001 \001(\0132\t."
+  "dmi.Uuid\022!\n\016component_uuid\030\002 \001(\0132\t.dmi.U"
+  "uid\022\026\n\016component_name\030\003 \001(\t\"\204\001\n\006Metric\022#"
+  "\n\tmetric_id\030\001 \001(\0162\020.dmi.MetricNames\022,\n\017m"
+  "etric_metadata\030\002 \001(\0132\023.dmi.MetricMetaDat"
+  "a\022\'\n\005value\030\003 \001(\0132\030.dmi.ComponentSensorDa"
+  "ta\"_\n\020GetMetricRequest\022&\n\tmeta_data\030\001 \001("
+  "\0132\023.dmi.MetricMetaData\022#\n\tmetric_id\030\002 \001("
+  "\0162\020.dmi.MetricNames\"\237\002\n\021GetMetricRespons"
+  "e\022\033\n\006status\030\001 \001(\0162\013.dmi.Status\022-\n\006reason"
+  "\030\002 \001(\0162\035.dmi.GetMetricResponse.Reason\022\033\n"
+  "\006metric\030\003 \001(\0132\013.dmi.Metric\022\025\n\rreason_det"
+  "ail\030\004 \001(\t\"\211\001\n\006Reason\022\024\n\020UNDEFINED_REASON"
+  "\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\025\n\021UNKNOWN_COMPON"
+  "ENT\020\002\022\022\n\016INTERNAL_ERROR\020\003\022\022\n\016INVALID_MET"
+  "RIC\020\004\022\026\n\022DEVICE_UNREACHABLE\020\005*\331\005\n\013Metric"
+  "Names\022\031\n\025METRIC_NAME_UNDEFINED\020\000\022\024\n\020METR"
+  "IC_FAN_SPEED\020\001\022\023\n\017METRIC_CPU_TEMP\020d\022\037\n\033M"
+  "ETRIC_CPU_USAGE_PERCENTAGE\020e\022\034\n\027METRIC_T"
+  "RANSCEIVER_TEMP\020\310\001\022\037\n\032METRIC_TRANSCEIVER"
+  "_VOLTAGE\020\311\001\022\034\n\027METRIC_TRANSCEIVER_BIAS\020\312"
+  "\001\022 \n\033METRIC_TRANSCEIVER_RX_POWER\020\313\001\022 \n\033M"
+  "ETRIC_TRANSCEIVER_TX_POWER\020\314\001\022\"\n\035METRIC_"
+  "TRANSCEIVER_WAVELENGTH\020\315\001\022\025\n\020METRIC_DISK"
+  "_TEMP\020\254\002\022\031\n\024METRIC_DISK_CAPACITY\020\255\002\022\026\n\021M"
+  "ETRIC_DISK_USAGE\020\256\002\022!\n\034METRIC_DISK_USAGE"
+  "_PERCENTAGE\020\257\002\022&\n!METRIC_DISK_READ_WRITE"
+  "_PERCENTAGE\020\260\002\022(\n#METRIC_DISK_FAULTY_CEL"
+  "LS_PERCENTAGE\020\261\002\022\024\n\017METRIC_RAM_TEMP\020\220\003\022\030"
+  "\n\023METRIC_RAM_CAPACITY\020\221\003\022\025\n\020METRIC_RAM_U"
+  "SAGE\020\222\003\022 \n\033METRIC_RAM_USAGE_PERCENTAGE\020\223"
+  "\003\022\025\n\020METRIC_POWER_MAX\020\364\003\022\027\n\022METRIC_POWER"
+  "_USAGE\020\365\003\022\"\n\035METRIC_POWER_USAGE_PERCENTA"
+  "GE\020\366\003\022\"\n\035METRIC_INNER_SURROUNDING_TEMP\020\330"
+  "\0042\371\001\n\036NativeMetricsManagementService\0228\n\013"
+  "ListMetrics\022\017.dmi.HardwareID\032\030.dmi.ListM"
+  "etricsResponse\022a\n\032UpdateMetricsConfigura"
+  "tion\022 .dmi.MetricsConfigurationRequest\032!"
+  ".dmi.MetricsConfigurationResponse\022:\n\tGet"
+  "Metric\022\025.dmi.GetMetricRequest\032\026.dmi.GetM"
+  "etricResponseB;Z9github.com/opencord/dev"
+  "ice-management-interface/v3/go/dmib\006prot"
+  "o3"
+  ;
+::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto = {
+  false, InitDefaults_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto, 
+  descriptor_table_protodef_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto,
+  "dmi/hw_metrics_mgmt_service.proto", &assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto, 2602,
+};
+
+void AddDescriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[2] =
+  {
+    ::AddDescriptors_dmi_2fcommons_2eproto,
+    ::AddDescriptors_dmi_2fhw_2eproto,
+  };
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto, deps, 2);
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto = []() { AddDescriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto(); return true; }();
+namespace dmi {
+const ::google::protobuf::EnumDescriptor* ListMetricsResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[0];
+}
+bool ListMetricsResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const ListMetricsResponse_Reason ListMetricsResponse::UNDEFINED_REASON;
+const ListMetricsResponse_Reason ListMetricsResponse::UNKNOWN_DEVICE;
+const ListMetricsResponse_Reason ListMetricsResponse::INTERNAL_ERROR;
+const ListMetricsResponse_Reason ListMetricsResponse::DEVICE_UNREACHABLE;
+const ListMetricsResponse_Reason ListMetricsResponse::Reason_MIN;
+const ListMetricsResponse_Reason ListMetricsResponse::Reason_MAX;
+const int ListMetricsResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* MetricsConfigurationResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[1];
+}
+bool MetricsConfigurationResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse::UNDEFINED_REASON;
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse::UNKNOWN_DEVICE;
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse::INTERNAL_ERROR;
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse::POLL_INTERVAL_UNSUPPORTED;
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse::INVALID_METRIC;
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse::DEVICE_UNREACHABLE;
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse::Reason_MIN;
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse::Reason_MAX;
+const int MetricsConfigurationResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* GetMetricResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[2];
+}
+bool GetMetricResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const GetMetricResponse_Reason GetMetricResponse::UNDEFINED_REASON;
+const GetMetricResponse_Reason GetMetricResponse::UNKNOWN_DEVICE;
+const GetMetricResponse_Reason GetMetricResponse::UNKNOWN_COMPONENT;
+const GetMetricResponse_Reason GetMetricResponse::INTERNAL_ERROR;
+const GetMetricResponse_Reason GetMetricResponse::INVALID_METRIC;
+const GetMetricResponse_Reason GetMetricResponse::DEVICE_UNREACHABLE;
+const GetMetricResponse_Reason GetMetricResponse::Reason_MIN;
+const GetMetricResponse_Reason GetMetricResponse::Reason_MAX;
+const int GetMetricResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* MetricNames_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[3];
+}
+bool MetricNames_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 100:
+    case 101:
+    case 200:
+    case 201:
+    case 202:
+    case 203:
+    case 204:
+    case 205:
+    case 300:
+    case 301:
+    case 302:
+    case 303:
+    case 304:
+    case 305:
+    case 400:
+    case 401:
+    case 402:
+    case 403:
+    case 500:
+    case 501:
+    case 502:
+    case 600:
+      return true;
+    default:
+      return false;
+  }
+}
+
+
+// ===================================================================
+
+void MetricConfig::InitAsDefaultInstance() {
+}
+class MetricConfig::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int MetricConfig::kMetricIdFieldNumber;
+const int MetricConfig::kIsConfiguredFieldNumber;
+const int MetricConfig::kPollIntervalFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+MetricConfig::MetricConfig()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.MetricConfig)
+}
+MetricConfig::MetricConfig(const MetricConfig& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::memcpy(&metric_id_, &from.metric_id_,
+    static_cast<size_t>(reinterpret_cast<char*>(&poll_interval_) -
+    reinterpret_cast<char*>(&metric_id_)) + sizeof(poll_interval_));
+  // @@protoc_insertion_point(copy_constructor:dmi.MetricConfig)
+}
+
+void MetricConfig::SharedCtor() {
+  ::memset(&metric_id_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&poll_interval_) -
+      reinterpret_cast<char*>(&metric_id_)) + sizeof(poll_interval_));
+}
+
+MetricConfig::~MetricConfig() {
+  // @@protoc_insertion_point(destructor:dmi.MetricConfig)
+  SharedDtor();
+}
+
+void MetricConfig::SharedDtor() {
+}
+
+void MetricConfig::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const MetricConfig& MetricConfig::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_MetricConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void MetricConfig::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.MetricConfig)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  ::memset(&metric_id_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&poll_interval_) -
+      reinterpret_cast<char*>(&metric_id_)) + sizeof(poll_interval_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* MetricConfig::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<MetricConfig*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.MetricNames metric_id = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_metric_id(static_cast<::dmi::MetricNames>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // bool is_configured = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        msg->set_is_configured(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // uint32 poll_interval = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        msg->set_poll_interval(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool MetricConfig::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.MetricConfig)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.MetricNames metric_id = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_metric_id(static_cast< ::dmi::MetricNames >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // bool is_configured = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &is_configured_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // uint32 poll_interval = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, &poll_interval_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.MetricConfig)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.MetricConfig)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void MetricConfig::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.MetricConfig)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.MetricNames metric_id = 1;
+  if (this->metric_id() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->metric_id(), output);
+  }
+
+  // bool is_configured = 2;
+  if (this->is_configured() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_configured(), output);
+  }
+
+  // uint32 poll_interval = 3;
+  if (this->poll_interval() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->poll_interval(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.MetricConfig)
+}
+
+::google::protobuf::uint8* MetricConfig::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.MetricConfig)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.MetricNames metric_id = 1;
+  if (this->metric_id() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->metric_id(), target);
+  }
+
+  // bool is_configured = 2;
+  if (this->is_configured() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_configured(), target);
+  }
+
+  // uint32 poll_interval = 3;
+  if (this->poll_interval() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->poll_interval(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.MetricConfig)
+  return target;
+}
+
+size_t MetricConfig::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.MetricConfig)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.MetricNames metric_id = 1;
+  if (this->metric_id() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->metric_id());
+  }
+
+  // bool is_configured = 2;
+  if (this->is_configured() != 0) {
+    total_size += 1 + 1;
+  }
+
+  // uint32 poll_interval = 3;
+  if (this->poll_interval() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::UInt32Size(
+        this->poll_interval());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void MetricConfig::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.MetricConfig)
+  GOOGLE_DCHECK_NE(&from, this);
+  const MetricConfig* source =
+      ::google::protobuf::DynamicCastToGenerated<MetricConfig>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.MetricConfig)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.MetricConfig)
+    MergeFrom(*source);
+  }
+}
+
+void MetricConfig::MergeFrom(const MetricConfig& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.MetricConfig)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.metric_id() != 0) {
+    set_metric_id(from.metric_id());
+  }
+  if (from.is_configured() != 0) {
+    set_is_configured(from.is_configured());
+  }
+  if (from.poll_interval() != 0) {
+    set_poll_interval(from.poll_interval());
+  }
+}
+
+void MetricConfig::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.MetricConfig)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void MetricConfig::CopyFrom(const MetricConfig& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.MetricConfig)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool MetricConfig::IsInitialized() const {
+  return true;
+}
+
+void MetricConfig::Swap(MetricConfig* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void MetricConfig::InternalSwap(MetricConfig* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(metric_id_, other->metric_id_);
+  swap(is_configured_, other->is_configured_);
+  swap(poll_interval_, other->poll_interval_);
+}
+
+::google::protobuf::Metadata MetricConfig::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void MetricsConfig::InitAsDefaultInstance() {
+}
+class MetricsConfig::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int MetricsConfig::kMetricsFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+MetricsConfig::MetricsConfig()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.MetricsConfig)
+}
+MetricsConfig::MetricsConfig(const MetricsConfig& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      metrics_(from.metrics_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  // @@protoc_insertion_point(copy_constructor:dmi.MetricsConfig)
+}
+
+void MetricsConfig::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_MetricsConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+}
+
+MetricsConfig::~MetricsConfig() {
+  // @@protoc_insertion_point(destructor:dmi.MetricsConfig)
+  SharedDtor();
+}
+
+void MetricsConfig::SharedDtor() {
+}
+
+void MetricsConfig::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const MetricsConfig& MetricsConfig::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_MetricsConfig_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void MetricsConfig::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.MetricsConfig)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  metrics_.Clear();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* MetricsConfig::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<MetricsConfig*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // repeated .dmi.MetricConfig metrics = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::MetricConfig::_InternalParse;
+          object = msg->add_metrics();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool MetricsConfig::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.MetricsConfig)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated .dmi.MetricConfig metrics = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_metrics()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.MetricsConfig)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.MetricsConfig)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void MetricsConfig::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.MetricsConfig)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // repeated .dmi.MetricConfig metrics = 1;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->metrics_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1,
+      this->metrics(static_cast<int>(i)),
+      output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.MetricsConfig)
+}
+
+::google::protobuf::uint8* MetricsConfig::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.MetricsConfig)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // repeated .dmi.MetricConfig metrics = 1;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->metrics_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, this->metrics(static_cast<int>(i)), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.MetricsConfig)
+  return target;
+}
+
+size_t MetricsConfig::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.MetricsConfig)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated .dmi.MetricConfig metrics = 1;
+  {
+    unsigned int count = static_cast<unsigned int>(this->metrics_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->metrics(static_cast<int>(i)));
+    }
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void MetricsConfig::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.MetricsConfig)
+  GOOGLE_DCHECK_NE(&from, this);
+  const MetricsConfig* source =
+      ::google::protobuf::DynamicCastToGenerated<MetricsConfig>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.MetricsConfig)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.MetricsConfig)
+    MergeFrom(*source);
+  }
+}
+
+void MetricsConfig::MergeFrom(const MetricsConfig& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.MetricsConfig)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  metrics_.MergeFrom(from.metrics_);
+}
+
+void MetricsConfig::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.MetricsConfig)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void MetricsConfig::CopyFrom(const MetricsConfig& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.MetricsConfig)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool MetricsConfig::IsInitialized() const {
+  return true;
+}
+
+void MetricsConfig::Swap(MetricsConfig* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void MetricsConfig::InternalSwap(MetricsConfig* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  CastToBase(&metrics_)->InternalSwap(CastToBase(&other->metrics_));
+}
+
+::google::protobuf::Metadata MetricsConfig::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ListMetricsResponse::InitAsDefaultInstance() {
+  ::dmi::_ListMetricsResponse_default_instance_._instance.get_mutable()->metrics_ = const_cast< ::dmi::MetricsConfig*>(
+      ::dmi::MetricsConfig::internal_default_instance());
+}
+class ListMetricsResponse::HasBitSetters {
+ public:
+  static const ::dmi::MetricsConfig& metrics(const ListMetricsResponse* msg);
+};
+
+const ::dmi::MetricsConfig&
+ListMetricsResponse::HasBitSetters::metrics(const ListMetricsResponse* msg) {
+  return *msg->metrics_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ListMetricsResponse::kStatusFieldNumber;
+const int ListMetricsResponse::kReasonFieldNumber;
+const int ListMetricsResponse::kMetricsFieldNumber;
+const int ListMetricsResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ListMetricsResponse::ListMetricsResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ListMetricsResponse)
+}
+ListMetricsResponse::ListMetricsResponse(const ListMetricsResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_metrics()) {
+    metrics_ = new ::dmi::MetricsConfig(*from.metrics_);
+  } else {
+    metrics_ = nullptr;
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ListMetricsResponse)
+}
+
+void ListMetricsResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ListMetricsResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&metrics_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&metrics_)) + sizeof(reason_));
+}
+
+ListMetricsResponse::~ListMetricsResponse() {
+  // @@protoc_insertion_point(destructor:dmi.ListMetricsResponse)
+  SharedDtor();
+}
+
+void ListMetricsResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete metrics_;
+}
+
+void ListMetricsResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ListMetricsResponse& ListMetricsResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ListMetricsResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ListMetricsResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ListMetricsResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && metrics_ != nullptr) {
+    delete metrics_;
+  }
+  metrics_ = nullptr;
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ListMetricsResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ListMetricsResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ListMetricsResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::ListMetricsResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.MetricsConfig metrics = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::MetricsConfig::_InternalParse;
+        object = msg->mutable_metrics();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ListMetricsResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ListMetricsResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ListMetricsResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ListMetricsResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::ListMetricsResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.MetricsConfig metrics = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_metrics()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ListMetricsResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ListMetricsResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ListMetricsResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ListMetricsResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ListMetricsResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.ListMetricsResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // .dmi.MetricsConfig metrics = 3;
+  if (this->has_metrics()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::metrics(this), output);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ListMetricsResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ListMetricsResponse)
+}
+
+::google::protobuf::uint8* ListMetricsResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ListMetricsResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.ListMetricsResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // .dmi.MetricsConfig metrics = 3;
+  if (this->has_metrics()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::metrics(this), target);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ListMetricsResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ListMetricsResponse)
+  return target;
+}
+
+size_t ListMetricsResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ListMetricsResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.MetricsConfig metrics = 3;
+  if (this->has_metrics()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *metrics_);
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.ListMetricsResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ListMetricsResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ListMetricsResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ListMetricsResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<ListMetricsResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ListMetricsResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ListMetricsResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ListMetricsResponse::MergeFrom(const ListMetricsResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ListMetricsResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_metrics()) {
+    mutable_metrics()->::dmi::MetricsConfig::MergeFrom(from.metrics());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void ListMetricsResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ListMetricsResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ListMetricsResponse::CopyFrom(const ListMetricsResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ListMetricsResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ListMetricsResponse::IsInitialized() const {
+  return true;
+}
+
+void ListMetricsResponse::Swap(ListMetricsResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ListMetricsResponse::InternalSwap(ListMetricsResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(metrics_, other->metrics_);
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata ListMetricsResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void MetricsConfigurationRequest::InitAsDefaultInstance() {
+  ::dmi::_MetricsConfigurationRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_MetricsConfigurationRequest_default_instance_.changes_ = const_cast< ::dmi::MetricsConfig*>(
+      ::dmi::MetricsConfig::internal_default_instance());
+  ::dmi::_MetricsConfigurationRequest_default_instance_.reset_to_default_ = false;
+}
+class MetricsConfigurationRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const MetricsConfigurationRequest* msg);
+  static const ::dmi::MetricsConfig& changes(const MetricsConfigurationRequest* msg);
+};
+
+const ::dmi::Uuid&
+MetricsConfigurationRequest::HasBitSetters::device_uuid(const MetricsConfigurationRequest* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::MetricsConfig&
+MetricsConfigurationRequest::HasBitSetters::changes(const MetricsConfigurationRequest* msg) {
+  return *msg->operation_.changes_;
+}
+void MetricsConfigurationRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void MetricsConfigurationRequest::set_allocated_changes(::dmi::MetricsConfig* changes) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_operation();
+  if (changes) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      changes = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, changes, submessage_arena);
+    }
+    set_has_changes();
+    operation_.changes_ = changes;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.MetricsConfigurationRequest.changes)
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int MetricsConfigurationRequest::kDeviceUuidFieldNumber;
+const int MetricsConfigurationRequest::kChangesFieldNumber;
+const int MetricsConfigurationRequest::kResetToDefaultFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+MetricsConfigurationRequest::MetricsConfigurationRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.MetricsConfigurationRequest)
+}
+MetricsConfigurationRequest::MetricsConfigurationRequest(const MetricsConfigurationRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  clear_has_operation();
+  switch (from.operation_case()) {
+    case kChanges: {
+      mutable_changes()->::dmi::MetricsConfig::MergeFrom(from.changes());
+      break;
+    }
+    case kResetToDefault: {
+      set_reset_to_default(from.reset_to_default());
+      break;
+    }
+    case OPERATION_NOT_SET: {
+      break;
+    }
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.MetricsConfigurationRequest)
+}
+
+void MetricsConfigurationRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_MetricsConfigurationRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  device_uuid_ = nullptr;
+  clear_has_operation();
+}
+
+MetricsConfigurationRequest::~MetricsConfigurationRequest() {
+  // @@protoc_insertion_point(destructor:dmi.MetricsConfigurationRequest)
+  SharedDtor();
+}
+
+void MetricsConfigurationRequest::SharedDtor() {
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (has_operation()) {
+    clear_operation();
+  }
+}
+
+void MetricsConfigurationRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const MetricsConfigurationRequest& MetricsConfigurationRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_MetricsConfigurationRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void MetricsConfigurationRequest::clear_operation() {
+// @@protoc_insertion_point(one_of_clear_start:dmi.MetricsConfigurationRequest)
+  switch (operation_case()) {
+    case kChanges: {
+      delete operation_.changes_;
+      break;
+    }
+    case kResetToDefault: {
+      // No need to clear
+      break;
+    }
+    case OPERATION_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = OPERATION_NOT_SET;
+}
+
+
+void MetricsConfigurationRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.MetricsConfigurationRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  clear_operation();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* MetricsConfigurationRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<MetricsConfigurationRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.MetricsConfig changes = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::MetricsConfig::_InternalParse;
+        object = msg->mutable_changes();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // bool reset_to_default = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        msg->set_reset_to_default(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool MetricsConfigurationRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.MetricsConfigurationRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.MetricsConfig changes = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_changes()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // bool reset_to_default = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          clear_operation();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &operation_.reset_to_default_)));
+          set_has_reset_to_default();
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.MetricsConfigurationRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.MetricsConfigurationRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void MetricsConfigurationRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.MetricsConfigurationRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.MetricsConfig changes = 2;
+  if (has_changes()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::changes(this), output);
+  }
+
+  // bool reset_to_default = 3;
+  if (has_reset_to_default()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->reset_to_default(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.MetricsConfigurationRequest)
+}
+
+::google::protobuf::uint8* MetricsConfigurationRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.MetricsConfigurationRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.MetricsConfig changes = 2;
+  if (has_changes()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::changes(this), target);
+  }
+
+  // bool reset_to_default = 3;
+  if (has_reset_to_default()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->reset_to_default(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.MetricsConfigurationRequest)
+  return target;
+}
+
+size_t MetricsConfigurationRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.MetricsConfigurationRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  switch (operation_case()) {
+    // .dmi.MetricsConfig changes = 2;
+    case kChanges: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *operation_.changes_);
+      break;
+    }
+    // bool reset_to_default = 3;
+    case kResetToDefault: {
+      total_size += 1 + 1;
+      break;
+    }
+    case OPERATION_NOT_SET: {
+      break;
+    }
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void MetricsConfigurationRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.MetricsConfigurationRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const MetricsConfigurationRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<MetricsConfigurationRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.MetricsConfigurationRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.MetricsConfigurationRequest)
+    MergeFrom(*source);
+  }
+}
+
+void MetricsConfigurationRequest::MergeFrom(const MetricsConfigurationRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.MetricsConfigurationRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  switch (from.operation_case()) {
+    case kChanges: {
+      mutable_changes()->::dmi::MetricsConfig::MergeFrom(from.changes());
+      break;
+    }
+    case kResetToDefault: {
+      set_reset_to_default(from.reset_to_default());
+      break;
+    }
+    case OPERATION_NOT_SET: {
+      break;
+    }
+  }
+}
+
+void MetricsConfigurationRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.MetricsConfigurationRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void MetricsConfigurationRequest::CopyFrom(const MetricsConfigurationRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.MetricsConfigurationRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool MetricsConfigurationRequest::IsInitialized() const {
+  return true;
+}
+
+void MetricsConfigurationRequest::Swap(MetricsConfigurationRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void MetricsConfigurationRequest::InternalSwap(MetricsConfigurationRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(device_uuid_, other->device_uuid_);
+  swap(operation_, other->operation_);
+  swap(_oneof_case_[0], other->_oneof_case_[0]);
+}
+
+::google::protobuf::Metadata MetricsConfigurationRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void MetricsConfigurationResponse::InitAsDefaultInstance() {
+}
+class MetricsConfigurationResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int MetricsConfigurationResponse::kStatusFieldNumber;
+const int MetricsConfigurationResponse::kReasonFieldNumber;
+const int MetricsConfigurationResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+MetricsConfigurationResponse::MetricsConfigurationResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.MetricsConfigurationResponse)
+}
+MetricsConfigurationResponse::MetricsConfigurationResponse(const MetricsConfigurationResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.MetricsConfigurationResponse)
+}
+
+void MetricsConfigurationResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_MetricsConfigurationResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+MetricsConfigurationResponse::~MetricsConfigurationResponse() {
+  // @@protoc_insertion_point(destructor:dmi.MetricsConfigurationResponse)
+  SharedDtor();
+}
+
+void MetricsConfigurationResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void MetricsConfigurationResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const MetricsConfigurationResponse& MetricsConfigurationResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_MetricsConfigurationResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void MetricsConfigurationResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.MetricsConfigurationResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* MetricsConfigurationResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<MetricsConfigurationResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.MetricsConfigurationResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::MetricsConfigurationResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.MetricsConfigurationResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool MetricsConfigurationResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.MetricsConfigurationResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.MetricsConfigurationResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::MetricsConfigurationResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.MetricsConfigurationResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.MetricsConfigurationResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.MetricsConfigurationResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void MetricsConfigurationResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.MetricsConfigurationResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.MetricsConfigurationResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.MetricsConfigurationResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.MetricsConfigurationResponse)
+}
+
+::google::protobuf::uint8* MetricsConfigurationResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.MetricsConfigurationResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.MetricsConfigurationResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.MetricsConfigurationResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.MetricsConfigurationResponse)
+  return target;
+}
+
+size_t MetricsConfigurationResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.MetricsConfigurationResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.MetricsConfigurationResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void MetricsConfigurationResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.MetricsConfigurationResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const MetricsConfigurationResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<MetricsConfigurationResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.MetricsConfigurationResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.MetricsConfigurationResponse)
+    MergeFrom(*source);
+  }
+}
+
+void MetricsConfigurationResponse::MergeFrom(const MetricsConfigurationResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.MetricsConfigurationResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void MetricsConfigurationResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.MetricsConfigurationResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void MetricsConfigurationResponse::CopyFrom(const MetricsConfigurationResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.MetricsConfigurationResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool MetricsConfigurationResponse::IsInitialized() const {
+  return true;
+}
+
+void MetricsConfigurationResponse::Swap(MetricsConfigurationResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void MetricsConfigurationResponse::InternalSwap(MetricsConfigurationResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata MetricsConfigurationResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void MetricMetaData::InitAsDefaultInstance() {
+  ::dmi::_MetricMetaData_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_MetricMetaData_default_instance_._instance.get_mutable()->component_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class MetricMetaData::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const MetricMetaData* msg);
+  static const ::dmi::Uuid& component_uuid(const MetricMetaData* msg);
+};
+
+const ::dmi::Uuid&
+MetricMetaData::HasBitSetters::device_uuid(const MetricMetaData* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::Uuid&
+MetricMetaData::HasBitSetters::component_uuid(const MetricMetaData* msg) {
+  return *msg->component_uuid_;
+}
+void MetricMetaData::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void MetricMetaData::clear_component_uuid() {
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int MetricMetaData::kDeviceUuidFieldNumber;
+const int MetricMetaData::kComponentUuidFieldNumber;
+const int MetricMetaData::kComponentNameFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+MetricMetaData::MetricMetaData()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.MetricMetaData)
+}
+MetricMetaData::MetricMetaData(const MetricMetaData& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.component_name().size() > 0) {
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  if (from.has_component_uuid()) {
+    component_uuid_ = new ::dmi::Uuid(*from.component_uuid_);
+  } else {
+    component_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.MetricMetaData)
+}
+
+void MetricMetaData::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_MetricMetaData_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&component_uuid_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(component_uuid_));
+}
+
+MetricMetaData::~MetricMetaData() {
+  // @@protoc_insertion_point(destructor:dmi.MetricMetaData)
+  SharedDtor();
+}
+
+void MetricMetaData::SharedDtor() {
+  component_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (this != internal_default_instance()) delete component_uuid_;
+}
+
+void MetricMetaData::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const MetricMetaData& MetricMetaData::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_MetricMetaData_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void MetricMetaData::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.MetricMetaData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* MetricMetaData::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<MetricMetaData*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_component_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string component_name = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.MetricMetaData.component_name");
+        object = msg->mutable_component_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool MetricMetaData::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.MetricMetaData)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_component_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string component_name = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_component_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->component_name().data(), static_cast<int>(this->component_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.MetricMetaData.component_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.MetricMetaData)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.MetricMetaData)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void MetricMetaData::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.MetricMetaData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::component_uuid(this), output);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.MetricMetaData.component_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->component_name(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.MetricMetaData)
+}
+
+::google::protobuf::uint8* MetricMetaData::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.MetricMetaData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::component_uuid(this), target);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.MetricMetaData.component_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->component_name(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.MetricMetaData)
+  return target;
+}
+
+size_t MetricMetaData::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.MetricMetaData)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->component_name());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *component_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void MetricMetaData::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.MetricMetaData)
+  GOOGLE_DCHECK_NE(&from, this);
+  const MetricMetaData* source =
+      ::google::protobuf::DynamicCastToGenerated<MetricMetaData>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.MetricMetaData)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.MetricMetaData)
+    MergeFrom(*source);
+  }
+}
+
+void MetricMetaData::MergeFrom(const MetricMetaData& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.MetricMetaData)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.component_name().size() > 0) {
+
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.has_component_uuid()) {
+    mutable_component_uuid()->::dmi::Uuid::MergeFrom(from.component_uuid());
+  }
+}
+
+void MetricMetaData::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.MetricMetaData)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void MetricMetaData::CopyFrom(const MetricMetaData& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.MetricMetaData)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool MetricMetaData::IsInitialized() const {
+  return true;
+}
+
+void MetricMetaData::Swap(MetricMetaData* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void MetricMetaData::InternalSwap(MetricMetaData* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  component_name_.Swap(&other->component_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(component_uuid_, other->component_uuid_);
+}
+
+::google::protobuf::Metadata MetricMetaData::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void Metric::InitAsDefaultInstance() {
+  ::dmi::_Metric_default_instance_._instance.get_mutable()->metric_metadata_ = const_cast< ::dmi::MetricMetaData*>(
+      ::dmi::MetricMetaData::internal_default_instance());
+  ::dmi::_Metric_default_instance_._instance.get_mutable()->value_ = const_cast< ::dmi::ComponentSensorData*>(
+      ::dmi::ComponentSensorData::internal_default_instance());
+}
+class Metric::HasBitSetters {
+ public:
+  static const ::dmi::MetricMetaData& metric_metadata(const Metric* msg);
+  static const ::dmi::ComponentSensorData& value(const Metric* msg);
+};
+
+const ::dmi::MetricMetaData&
+Metric::HasBitSetters::metric_metadata(const Metric* msg) {
+  return *msg->metric_metadata_;
+}
+const ::dmi::ComponentSensorData&
+Metric::HasBitSetters::value(const Metric* msg) {
+  return *msg->value_;
+}
+void Metric::clear_value() {
+  if (GetArenaNoVirtual() == nullptr && value_ != nullptr) {
+    delete value_;
+  }
+  value_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Metric::kMetricIdFieldNumber;
+const int Metric::kMetricMetadataFieldNumber;
+const int Metric::kValueFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Metric::Metric()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Metric)
+}
+Metric::Metric(const Metric& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_metric_metadata()) {
+    metric_metadata_ = new ::dmi::MetricMetaData(*from.metric_metadata_);
+  } else {
+    metric_metadata_ = nullptr;
+  }
+  if (from.has_value()) {
+    value_ = new ::dmi::ComponentSensorData(*from.value_);
+  } else {
+    value_ = nullptr;
+  }
+  metric_id_ = from.metric_id_;
+  // @@protoc_insertion_point(copy_constructor:dmi.Metric)
+}
+
+void Metric::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Metric_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::memset(&metric_metadata_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&metric_id_) -
+      reinterpret_cast<char*>(&metric_metadata_)) + sizeof(metric_id_));
+}
+
+Metric::~Metric() {
+  // @@protoc_insertion_point(destructor:dmi.Metric)
+  SharedDtor();
+}
+
+void Metric::SharedDtor() {
+  if (this != internal_default_instance()) delete metric_metadata_;
+  if (this != internal_default_instance()) delete value_;
+}
+
+void Metric::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Metric& Metric::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Metric_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Metric::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Metric)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && metric_metadata_ != nullptr) {
+    delete metric_metadata_;
+  }
+  metric_metadata_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && value_ != nullptr) {
+    delete value_;
+  }
+  value_ = nullptr;
+  metric_id_ = 0;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Metric::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Metric*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.MetricNames metric_id = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_metric_id(static_cast<::dmi::MetricNames>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.MetricMetaData metric_metadata = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::MetricMetaData::_InternalParse;
+        object = msg->mutable_metric_metadata();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ComponentSensorData value = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ComponentSensorData::_InternalParse;
+        object = msg->mutable_value();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Metric::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Metric)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.MetricNames metric_id = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_metric_id(static_cast< ::dmi::MetricNames >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.MetricMetaData metric_metadata = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_metric_metadata()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentSensorData value = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_value()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Metric)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Metric)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Metric::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Metric)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.MetricNames metric_id = 1;
+  if (this->metric_id() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->metric_id(), output);
+  }
+
+  // .dmi.MetricMetaData metric_metadata = 2;
+  if (this->has_metric_metadata()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::metric_metadata(this), output);
+  }
+
+  // .dmi.ComponentSensorData value = 3;
+  if (this->has_value()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::value(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Metric)
+}
+
+::google::protobuf::uint8* Metric::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Metric)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.MetricNames metric_id = 1;
+  if (this->metric_id() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->metric_id(), target);
+  }
+
+  // .dmi.MetricMetaData metric_metadata = 2;
+  if (this->has_metric_metadata()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::metric_metadata(this), target);
+  }
+
+  // .dmi.ComponentSensorData value = 3;
+  if (this->has_value()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::value(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Metric)
+  return target;
+}
+
+size_t Metric::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Metric)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.MetricMetaData metric_metadata = 2;
+  if (this->has_metric_metadata()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *metric_metadata_);
+  }
+
+  // .dmi.ComponentSensorData value = 3;
+  if (this->has_value()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *value_);
+  }
+
+  // .dmi.MetricNames metric_id = 1;
+  if (this->metric_id() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->metric_id());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Metric::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Metric)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Metric* source =
+      ::google::protobuf::DynamicCastToGenerated<Metric>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Metric)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Metric)
+    MergeFrom(*source);
+  }
+}
+
+void Metric::MergeFrom(const Metric& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Metric)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_metric_metadata()) {
+    mutable_metric_metadata()->::dmi::MetricMetaData::MergeFrom(from.metric_metadata());
+  }
+  if (from.has_value()) {
+    mutable_value()->::dmi::ComponentSensorData::MergeFrom(from.value());
+  }
+  if (from.metric_id() != 0) {
+    set_metric_id(from.metric_id());
+  }
+}
+
+void Metric::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Metric)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Metric::CopyFrom(const Metric& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Metric)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Metric::IsInitialized() const {
+  return true;
+}
+
+void Metric::Swap(Metric* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Metric::InternalSwap(Metric* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(metric_metadata_, other->metric_metadata_);
+  swap(value_, other->value_);
+  swap(metric_id_, other->metric_id_);
+}
+
+::google::protobuf::Metadata Metric::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void GetMetricRequest::InitAsDefaultInstance() {
+  ::dmi::_GetMetricRequest_default_instance_._instance.get_mutable()->meta_data_ = const_cast< ::dmi::MetricMetaData*>(
+      ::dmi::MetricMetaData::internal_default_instance());
+}
+class GetMetricRequest::HasBitSetters {
+ public:
+  static const ::dmi::MetricMetaData& meta_data(const GetMetricRequest* msg);
+};
+
+const ::dmi::MetricMetaData&
+GetMetricRequest::HasBitSetters::meta_data(const GetMetricRequest* msg) {
+  return *msg->meta_data_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GetMetricRequest::kMetaDataFieldNumber;
+const int GetMetricRequest::kMetricIdFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GetMetricRequest::GetMetricRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.GetMetricRequest)
+}
+GetMetricRequest::GetMetricRequest(const GetMetricRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_meta_data()) {
+    meta_data_ = new ::dmi::MetricMetaData(*from.meta_data_);
+  } else {
+    meta_data_ = nullptr;
+  }
+  metric_id_ = from.metric_id_;
+  // @@protoc_insertion_point(copy_constructor:dmi.GetMetricRequest)
+}
+
+void GetMetricRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GetMetricRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  ::memset(&meta_data_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&metric_id_) -
+      reinterpret_cast<char*>(&meta_data_)) + sizeof(metric_id_));
+}
+
+GetMetricRequest::~GetMetricRequest() {
+  // @@protoc_insertion_point(destructor:dmi.GetMetricRequest)
+  SharedDtor();
+}
+
+void GetMetricRequest::SharedDtor() {
+  if (this != internal_default_instance()) delete meta_data_;
+}
+
+void GetMetricRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const GetMetricRequest& GetMetricRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_GetMetricRequest_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void GetMetricRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.GetMetricRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && meta_data_ != nullptr) {
+    delete meta_data_;
+  }
+  meta_data_ = nullptr;
+  metric_id_ = 0;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GetMetricRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GetMetricRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.MetricMetaData meta_data = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::MetricMetaData::_InternalParse;
+        object = msg->mutable_meta_data();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.MetricNames metric_id = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_metric_id(static_cast<::dmi::MetricNames>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool GetMetricRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.GetMetricRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.MetricMetaData meta_data = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_meta_data()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.MetricNames metric_id = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_metric_id(static_cast< ::dmi::MetricNames >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.GetMetricRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.GetMetricRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void GetMetricRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.GetMetricRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.MetricMetaData meta_data = 1;
+  if (this->has_meta_data()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::meta_data(this), output);
+  }
+
+  // .dmi.MetricNames metric_id = 2;
+  if (this->metric_id() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->metric_id(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.GetMetricRequest)
+}
+
+::google::protobuf::uint8* GetMetricRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.GetMetricRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.MetricMetaData meta_data = 1;
+  if (this->has_meta_data()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::meta_data(this), target);
+  }
+
+  // .dmi.MetricNames metric_id = 2;
+  if (this->metric_id() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->metric_id(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.GetMetricRequest)
+  return target;
+}
+
+size_t GetMetricRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.GetMetricRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.MetricMetaData meta_data = 1;
+  if (this->has_meta_data()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *meta_data_);
+  }
+
+  // .dmi.MetricNames metric_id = 2;
+  if (this->metric_id() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->metric_id());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void GetMetricRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.GetMetricRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const GetMetricRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<GetMetricRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.GetMetricRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.GetMetricRequest)
+    MergeFrom(*source);
+  }
+}
+
+void GetMetricRequest::MergeFrom(const GetMetricRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.GetMetricRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_meta_data()) {
+    mutable_meta_data()->::dmi::MetricMetaData::MergeFrom(from.meta_data());
+  }
+  if (from.metric_id() != 0) {
+    set_metric_id(from.metric_id());
+  }
+}
+
+void GetMetricRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.GetMetricRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void GetMetricRequest::CopyFrom(const GetMetricRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.GetMetricRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GetMetricRequest::IsInitialized() const {
+  return true;
+}
+
+void GetMetricRequest::Swap(GetMetricRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void GetMetricRequest::InternalSwap(GetMetricRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(meta_data_, other->meta_data_);
+  swap(metric_id_, other->metric_id_);
+}
+
+::google::protobuf::Metadata GetMetricRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void GetMetricResponse::InitAsDefaultInstance() {
+  ::dmi::_GetMetricResponse_default_instance_._instance.get_mutable()->metric_ = const_cast< ::dmi::Metric*>(
+      ::dmi::Metric::internal_default_instance());
+}
+class GetMetricResponse::HasBitSetters {
+ public:
+  static const ::dmi::Metric& metric(const GetMetricResponse* msg);
+};
+
+const ::dmi::Metric&
+GetMetricResponse::HasBitSetters::metric(const GetMetricResponse* msg) {
+  return *msg->metric_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GetMetricResponse::kStatusFieldNumber;
+const int GetMetricResponse::kReasonFieldNumber;
+const int GetMetricResponse::kMetricFieldNumber;
+const int GetMetricResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GetMetricResponse::GetMetricResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.GetMetricResponse)
+}
+GetMetricResponse::GetMetricResponse(const GetMetricResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_metric()) {
+    metric_ = new ::dmi::Metric(*from.metric_);
+  } else {
+    metric_ = nullptr;
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.GetMetricResponse)
+}
+
+void GetMetricResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GetMetricResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&metric_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&metric_)) + sizeof(reason_));
+}
+
+GetMetricResponse::~GetMetricResponse() {
+  // @@protoc_insertion_point(destructor:dmi.GetMetricResponse)
+  SharedDtor();
+}
+
+void GetMetricResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete metric_;
+}
+
+void GetMetricResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const GetMetricResponse& GetMetricResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_GetMetricResponse_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void GetMetricResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.GetMetricResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && metric_ != nullptr) {
+    delete metric_;
+  }
+  metric_ = nullptr;
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GetMetricResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GetMetricResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.GetMetricResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::GetMetricResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.Metric metric = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Metric::_InternalParse;
+        object = msg->mutable_metric();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.GetMetricResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool GetMetricResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.GetMetricResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.GetMetricResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::GetMetricResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Metric metric = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_metric()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.GetMetricResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.GetMetricResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.GetMetricResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void GetMetricResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.GetMetricResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.GetMetricResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // .dmi.Metric metric = 3;
+  if (this->has_metric()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::metric(this), output);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetMetricResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.GetMetricResponse)
+}
+
+::google::protobuf::uint8* GetMetricResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.GetMetricResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.GetMetricResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // .dmi.Metric metric = 3;
+  if (this->has_metric()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::metric(this), target);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetMetricResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.GetMetricResponse)
+  return target;
+}
+
+size_t GetMetricResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.GetMetricResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Metric metric = 3;
+  if (this->has_metric()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *metric_);
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.GetMetricResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void GetMetricResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.GetMetricResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const GetMetricResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<GetMetricResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.GetMetricResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.GetMetricResponse)
+    MergeFrom(*source);
+  }
+}
+
+void GetMetricResponse::MergeFrom(const GetMetricResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.GetMetricResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_metric()) {
+    mutable_metric()->::dmi::Metric::MergeFrom(from.metric());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void GetMetricResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.GetMetricResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void GetMetricResponse::CopyFrom(const GetMetricResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.GetMetricResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GetMetricResponse::IsInitialized() const {
+  return true;
+}
+
+void GetMetricResponse::Swap(GetMetricResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void GetMetricResponse::InternalSwap(GetMetricResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(metric_, other->metric_);
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata GetMetricResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> PROTOBUF_NOINLINE ::dmi::MetricConfig* Arena::CreateMaybeMessage< ::dmi::MetricConfig >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::MetricConfig >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::MetricsConfig* Arena::CreateMaybeMessage< ::dmi::MetricsConfig >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::MetricsConfig >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ListMetricsResponse* Arena::CreateMaybeMessage< ::dmi::ListMetricsResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ListMetricsResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::MetricsConfigurationRequest* Arena::CreateMaybeMessage< ::dmi::MetricsConfigurationRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::MetricsConfigurationRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::MetricsConfigurationResponse* Arena::CreateMaybeMessage< ::dmi::MetricsConfigurationResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::MetricsConfigurationResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::MetricMetaData* Arena::CreateMaybeMessage< ::dmi::MetricMetaData >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::MetricMetaData >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::Metric* Arena::CreateMaybeMessage< ::dmi::Metric >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Metric >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::GetMetricRequest* Arena::CreateMaybeMessage< ::dmi::GetMetricRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::GetMetricRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::GetMetricResponse* Arena::CreateMaybeMessage< ::dmi::GetMetricResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::GetMetricResponse >(arena);
+}
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+#include <google/protobuf/port_undef.inc>
diff --git a/cpp/dmi/hw_metrics_mgmt_service.pb.h b/cpp/dmi/hw_metrics_mgmt_service.pb.h
new file mode 100644
index 0000000..5967faa
--- /dev/null
+++ b/cpp/dmi/hw_metrics_mgmt_service.pb.h
@@ -0,0 +1,2481 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/hw_metrics_mgmt_service.proto
+
+#ifndef PROTOBUF_INCLUDED_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto
+#define PROTOBUF_INCLUDED_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto
+
+#include <limits>
+#include <string>
+
+#include <google/protobuf/port_def.inc>
+#if PROTOBUF_VERSION < 3007000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3007000 < PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/port_undef.inc>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/inlined_string_field.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
+#include <google/protobuf/extension_set.h>  // IWYU pragma: export
+#include <google/protobuf/generated_enum_reflection.h>
+#include <google/protobuf/unknown_field_set.h>
+#include "dmi/commons.pb.h"
+#include "dmi/hw.pb.h"
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto
+
+// Internal implementation detail -- do not use these members.
+struct TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[9]
+    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_5fmetrics_5fmgmt_5fservice_2eproto();
+namespace dmi {
+class GetMetricRequest;
+class GetMetricRequestDefaultTypeInternal;
+extern GetMetricRequestDefaultTypeInternal _GetMetricRequest_default_instance_;
+class GetMetricResponse;
+class GetMetricResponseDefaultTypeInternal;
+extern GetMetricResponseDefaultTypeInternal _GetMetricResponse_default_instance_;
+class ListMetricsResponse;
+class ListMetricsResponseDefaultTypeInternal;
+extern ListMetricsResponseDefaultTypeInternal _ListMetricsResponse_default_instance_;
+class Metric;
+class MetricDefaultTypeInternal;
+extern MetricDefaultTypeInternal _Metric_default_instance_;
+class MetricConfig;
+class MetricConfigDefaultTypeInternal;
+extern MetricConfigDefaultTypeInternal _MetricConfig_default_instance_;
+class MetricMetaData;
+class MetricMetaDataDefaultTypeInternal;
+extern MetricMetaDataDefaultTypeInternal _MetricMetaData_default_instance_;
+class MetricsConfig;
+class MetricsConfigDefaultTypeInternal;
+extern MetricsConfigDefaultTypeInternal _MetricsConfig_default_instance_;
+class MetricsConfigurationRequest;
+class MetricsConfigurationRequestDefaultTypeInternal;
+extern MetricsConfigurationRequestDefaultTypeInternal _MetricsConfigurationRequest_default_instance_;
+class MetricsConfigurationResponse;
+class MetricsConfigurationResponseDefaultTypeInternal;
+extern MetricsConfigurationResponseDefaultTypeInternal _MetricsConfigurationResponse_default_instance_;
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> ::dmi::GetMetricRequest* Arena::CreateMaybeMessage<::dmi::GetMetricRequest>(Arena*);
+template<> ::dmi::GetMetricResponse* Arena::CreateMaybeMessage<::dmi::GetMetricResponse>(Arena*);
+template<> ::dmi::ListMetricsResponse* Arena::CreateMaybeMessage<::dmi::ListMetricsResponse>(Arena*);
+template<> ::dmi::Metric* Arena::CreateMaybeMessage<::dmi::Metric>(Arena*);
+template<> ::dmi::MetricConfig* Arena::CreateMaybeMessage<::dmi::MetricConfig>(Arena*);
+template<> ::dmi::MetricMetaData* Arena::CreateMaybeMessage<::dmi::MetricMetaData>(Arena*);
+template<> ::dmi::MetricsConfig* Arena::CreateMaybeMessage<::dmi::MetricsConfig>(Arena*);
+template<> ::dmi::MetricsConfigurationRequest* Arena::CreateMaybeMessage<::dmi::MetricsConfigurationRequest>(Arena*);
+template<> ::dmi::MetricsConfigurationResponse* Arena::CreateMaybeMessage<::dmi::MetricsConfigurationResponse>(Arena*);
+}  // namespace protobuf
+}  // namespace google
+namespace dmi {
+
+enum ListMetricsResponse_Reason {
+  ListMetricsResponse_Reason_UNDEFINED_REASON = 0,
+  ListMetricsResponse_Reason_UNKNOWN_DEVICE = 1,
+  ListMetricsResponse_Reason_INTERNAL_ERROR = 2,
+  ListMetricsResponse_Reason_DEVICE_UNREACHABLE = 3,
+  ListMetricsResponse_Reason_ListMetricsResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ListMetricsResponse_Reason_ListMetricsResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ListMetricsResponse_Reason_IsValid(int value);
+const ListMetricsResponse_Reason ListMetricsResponse_Reason_Reason_MIN = ListMetricsResponse_Reason_UNDEFINED_REASON;
+const ListMetricsResponse_Reason ListMetricsResponse_Reason_Reason_MAX = ListMetricsResponse_Reason_DEVICE_UNREACHABLE;
+const int ListMetricsResponse_Reason_Reason_ARRAYSIZE = ListMetricsResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ListMetricsResponse_Reason_descriptor();
+inline const ::std::string& ListMetricsResponse_Reason_Name(ListMetricsResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ListMetricsResponse_Reason_descriptor(), value);
+}
+inline bool ListMetricsResponse_Reason_Parse(
+    const ::std::string& name, ListMetricsResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ListMetricsResponse_Reason>(
+    ListMetricsResponse_Reason_descriptor(), name, value);
+}
+enum MetricsConfigurationResponse_Reason {
+  MetricsConfigurationResponse_Reason_UNDEFINED_REASON = 0,
+  MetricsConfigurationResponse_Reason_UNKNOWN_DEVICE = 1,
+  MetricsConfigurationResponse_Reason_INTERNAL_ERROR = 2,
+  MetricsConfigurationResponse_Reason_POLL_INTERVAL_UNSUPPORTED = 3,
+  MetricsConfigurationResponse_Reason_INVALID_METRIC = 4,
+  MetricsConfigurationResponse_Reason_DEVICE_UNREACHABLE = 5,
+  MetricsConfigurationResponse_Reason_MetricsConfigurationResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  MetricsConfigurationResponse_Reason_MetricsConfigurationResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool MetricsConfigurationResponse_Reason_IsValid(int value);
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse_Reason_Reason_MIN = MetricsConfigurationResponse_Reason_UNDEFINED_REASON;
+const MetricsConfigurationResponse_Reason MetricsConfigurationResponse_Reason_Reason_MAX = MetricsConfigurationResponse_Reason_DEVICE_UNREACHABLE;
+const int MetricsConfigurationResponse_Reason_Reason_ARRAYSIZE = MetricsConfigurationResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* MetricsConfigurationResponse_Reason_descriptor();
+inline const ::std::string& MetricsConfigurationResponse_Reason_Name(MetricsConfigurationResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    MetricsConfigurationResponse_Reason_descriptor(), value);
+}
+inline bool MetricsConfigurationResponse_Reason_Parse(
+    const ::std::string& name, MetricsConfigurationResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<MetricsConfigurationResponse_Reason>(
+    MetricsConfigurationResponse_Reason_descriptor(), name, value);
+}
+enum GetMetricResponse_Reason {
+  GetMetricResponse_Reason_UNDEFINED_REASON = 0,
+  GetMetricResponse_Reason_UNKNOWN_DEVICE = 1,
+  GetMetricResponse_Reason_UNKNOWN_COMPONENT = 2,
+  GetMetricResponse_Reason_INTERNAL_ERROR = 3,
+  GetMetricResponse_Reason_INVALID_METRIC = 4,
+  GetMetricResponse_Reason_DEVICE_UNREACHABLE = 5,
+  GetMetricResponse_Reason_GetMetricResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  GetMetricResponse_Reason_GetMetricResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool GetMetricResponse_Reason_IsValid(int value);
+const GetMetricResponse_Reason GetMetricResponse_Reason_Reason_MIN = GetMetricResponse_Reason_UNDEFINED_REASON;
+const GetMetricResponse_Reason GetMetricResponse_Reason_Reason_MAX = GetMetricResponse_Reason_DEVICE_UNREACHABLE;
+const int GetMetricResponse_Reason_Reason_ARRAYSIZE = GetMetricResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* GetMetricResponse_Reason_descriptor();
+inline const ::std::string& GetMetricResponse_Reason_Name(GetMetricResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    GetMetricResponse_Reason_descriptor(), value);
+}
+inline bool GetMetricResponse_Reason_Parse(
+    const ::std::string& name, GetMetricResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<GetMetricResponse_Reason>(
+    GetMetricResponse_Reason_descriptor(), name, value);
+}
+enum MetricNames {
+  METRIC_NAME_UNDEFINED = 0,
+  METRIC_FAN_SPEED = 1,
+  METRIC_CPU_TEMP = 100,
+  METRIC_CPU_USAGE_PERCENTAGE = 101,
+  METRIC_TRANSCEIVER_TEMP = 200,
+  METRIC_TRANSCEIVER_VOLTAGE = 201,
+  METRIC_TRANSCEIVER_BIAS = 202,
+  METRIC_TRANSCEIVER_RX_POWER = 203,
+  METRIC_TRANSCEIVER_TX_POWER = 204,
+  METRIC_TRANSCEIVER_WAVELENGTH = 205,
+  METRIC_DISK_TEMP = 300,
+  METRIC_DISK_CAPACITY = 301,
+  METRIC_DISK_USAGE = 302,
+  METRIC_DISK_USAGE_PERCENTAGE = 303,
+  METRIC_DISK_READ_WRITE_PERCENTAGE = 304,
+  METRIC_DISK_FAULTY_CELLS_PERCENTAGE = 305,
+  METRIC_RAM_TEMP = 400,
+  METRIC_RAM_CAPACITY = 401,
+  METRIC_RAM_USAGE = 402,
+  METRIC_RAM_USAGE_PERCENTAGE = 403,
+  METRIC_POWER_MAX = 500,
+  METRIC_POWER_USAGE = 501,
+  METRIC_POWER_USAGE_PERCENTAGE = 502,
+  METRIC_INNER_SURROUNDING_TEMP = 600,
+  MetricNames_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  MetricNames_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool MetricNames_IsValid(int value);
+const MetricNames MetricNames_MIN = METRIC_NAME_UNDEFINED;
+const MetricNames MetricNames_MAX = METRIC_INNER_SURROUNDING_TEMP;
+const int MetricNames_ARRAYSIZE = MetricNames_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* MetricNames_descriptor();
+inline const ::std::string& MetricNames_Name(MetricNames value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    MetricNames_descriptor(), value);
+}
+inline bool MetricNames_Parse(
+    const ::std::string& name, MetricNames* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<MetricNames>(
+    MetricNames_descriptor(), name, value);
+}
+// ===================================================================
+
+class MetricConfig final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.MetricConfig) */ {
+ public:
+  MetricConfig();
+  virtual ~MetricConfig();
+
+  MetricConfig(const MetricConfig& from);
+
+  inline MetricConfig& operator=(const MetricConfig& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  MetricConfig(MetricConfig&& from) noexcept
+    : MetricConfig() {
+    *this = ::std::move(from);
+  }
+
+  inline MetricConfig& operator=(MetricConfig&& 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 MetricConfig& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const MetricConfig* internal_default_instance() {
+    return reinterpret_cast<const MetricConfig*>(
+               &_MetricConfig_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    0;
+
+  void Swap(MetricConfig* other);
+  friend void swap(MetricConfig& a, MetricConfig& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline MetricConfig* New() const final {
+    return CreateMaybeMessage<MetricConfig>(nullptr);
+  }
+
+  MetricConfig* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<MetricConfig>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const MetricConfig& from);
+  void MergeFrom(const MetricConfig& 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(MetricConfig* 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.MetricNames metric_id = 1;
+  void clear_metric_id();
+  static const int kMetricIdFieldNumber = 1;
+  ::dmi::MetricNames metric_id() const;
+  void set_metric_id(::dmi::MetricNames value);
+
+  // bool is_configured = 2;
+  void clear_is_configured();
+  static const int kIsConfiguredFieldNumber = 2;
+  bool is_configured() const;
+  void set_is_configured(bool value);
+
+  // uint32 poll_interval = 3;
+  void clear_poll_interval();
+  static const int kPollIntervalFieldNumber = 3;
+  ::google::protobuf::uint32 poll_interval() const;
+  void set_poll_interval(::google::protobuf::uint32 value);
+
+  // @@protoc_insertion_point(class_scope:dmi.MetricConfig)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  int metric_id_;
+  bool is_configured_;
+  ::google::protobuf::uint32 poll_interval_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class MetricsConfig final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.MetricsConfig) */ {
+ public:
+  MetricsConfig();
+  virtual ~MetricsConfig();
+
+  MetricsConfig(const MetricsConfig& from);
+
+  inline MetricsConfig& operator=(const MetricsConfig& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  MetricsConfig(MetricsConfig&& from) noexcept
+    : MetricsConfig() {
+    *this = ::std::move(from);
+  }
+
+  inline MetricsConfig& operator=(MetricsConfig&& 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 MetricsConfig& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const MetricsConfig* internal_default_instance() {
+    return reinterpret_cast<const MetricsConfig*>(
+               &_MetricsConfig_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    1;
+
+  void Swap(MetricsConfig* other);
+  friend void swap(MetricsConfig& a, MetricsConfig& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline MetricsConfig* New() const final {
+    return CreateMaybeMessage<MetricsConfig>(nullptr);
+  }
+
+  MetricsConfig* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<MetricsConfig>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const MetricsConfig& from);
+  void MergeFrom(const MetricsConfig& 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(MetricsConfig* 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.MetricConfig metrics = 1;
+  int metrics_size() const;
+  void clear_metrics();
+  static const int kMetricsFieldNumber = 1;
+  ::dmi::MetricConfig* mutable_metrics(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::MetricConfig >*
+      mutable_metrics();
+  const ::dmi::MetricConfig& metrics(int index) const;
+  ::dmi::MetricConfig* add_metrics();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::MetricConfig >&
+      metrics() const;
+
+  // @@protoc_insertion_point(class_scope:dmi.MetricsConfig)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::MetricConfig > metrics_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ListMetricsResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ListMetricsResponse) */ {
+ public:
+  ListMetricsResponse();
+  virtual ~ListMetricsResponse();
+
+  ListMetricsResponse(const ListMetricsResponse& from);
+
+  inline ListMetricsResponse& operator=(const ListMetricsResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ListMetricsResponse(ListMetricsResponse&& from) noexcept
+    : ListMetricsResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline ListMetricsResponse& operator=(ListMetricsResponse&& 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 ListMetricsResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ListMetricsResponse* internal_default_instance() {
+    return reinterpret_cast<const ListMetricsResponse*>(
+               &_ListMetricsResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    2;
+
+  void Swap(ListMetricsResponse* other);
+  friend void swap(ListMetricsResponse& a, ListMetricsResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ListMetricsResponse* New() const final {
+    return CreateMaybeMessage<ListMetricsResponse>(nullptr);
+  }
+
+  ListMetricsResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ListMetricsResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ListMetricsResponse& from);
+  void MergeFrom(const ListMetricsResponse& 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(ListMetricsResponse* 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 ListMetricsResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    ListMetricsResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    ListMetricsResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    ListMetricsResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    ListMetricsResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return ListMetricsResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    ListMetricsResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    ListMetricsResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    ListMetricsResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return ListMetricsResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return ListMetricsResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return ListMetricsResponse_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.MetricsConfig metrics = 3;
+  bool has_metrics() const;
+  void clear_metrics();
+  static const int kMetricsFieldNumber = 3;
+  const ::dmi::MetricsConfig& metrics() const;
+  ::dmi::MetricsConfig* release_metrics();
+  ::dmi::MetricsConfig* mutable_metrics();
+  void set_allocated_metrics(::dmi::MetricsConfig* metrics);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.ListMetricsResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::ListMetricsResponse_Reason reason() const;
+  void set_reason(::dmi::ListMetricsResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ListMetricsResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  ::dmi::MetricsConfig* metrics_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class MetricsConfigurationRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.MetricsConfigurationRequest) */ {
+ public:
+  MetricsConfigurationRequest();
+  virtual ~MetricsConfigurationRequest();
+
+  MetricsConfigurationRequest(const MetricsConfigurationRequest& from);
+
+  inline MetricsConfigurationRequest& operator=(const MetricsConfigurationRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  MetricsConfigurationRequest(MetricsConfigurationRequest&& from) noexcept
+    : MetricsConfigurationRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline MetricsConfigurationRequest& operator=(MetricsConfigurationRequest&& 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 MetricsConfigurationRequest& default_instance();
+
+  enum OperationCase {
+    kChanges = 2,
+    kResetToDefault = 3,
+    OPERATION_NOT_SET = 0,
+  };
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const MetricsConfigurationRequest* internal_default_instance() {
+    return reinterpret_cast<const MetricsConfigurationRequest*>(
+               &_MetricsConfigurationRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    3;
+
+  void Swap(MetricsConfigurationRequest* other);
+  friend void swap(MetricsConfigurationRequest& a, MetricsConfigurationRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline MetricsConfigurationRequest* New() const final {
+    return CreateMaybeMessage<MetricsConfigurationRequest>(nullptr);
+  }
+
+  MetricsConfigurationRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<MetricsConfigurationRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const MetricsConfigurationRequest& from);
+  void MergeFrom(const MetricsConfigurationRequest& 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(MetricsConfigurationRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.MetricsConfig changes = 2;
+  bool has_changes() const;
+  void clear_changes();
+  static const int kChangesFieldNumber = 2;
+  const ::dmi::MetricsConfig& changes() const;
+  ::dmi::MetricsConfig* release_changes();
+  ::dmi::MetricsConfig* mutable_changes();
+  void set_allocated_changes(::dmi::MetricsConfig* changes);
+
+  // bool reset_to_default = 3;
+  private:
+  bool has_reset_to_default() const;
+  public:
+  void clear_reset_to_default();
+  static const int kResetToDefaultFieldNumber = 3;
+  bool reset_to_default() const;
+  void set_reset_to_default(bool value);
+
+  void clear_operation();
+  OperationCase operation_case() const;
+  // @@protoc_insertion_point(class_scope:dmi.MetricsConfigurationRequest)
+ private:
+  class HasBitSetters;
+  void set_has_changes();
+  void set_has_reset_to_default();
+
+  inline bool has_operation() const;
+  inline void clear_has_operation();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::Uuid* device_uuid_;
+  union OperationUnion {
+    OperationUnion() {}
+    ::dmi::MetricsConfig* changes_;
+    bool reset_to_default_;
+  } operation_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
+  friend struct ::TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class MetricsConfigurationResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.MetricsConfigurationResponse) */ {
+ public:
+  MetricsConfigurationResponse();
+  virtual ~MetricsConfigurationResponse();
+
+  MetricsConfigurationResponse(const MetricsConfigurationResponse& from);
+
+  inline MetricsConfigurationResponse& operator=(const MetricsConfigurationResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  MetricsConfigurationResponse(MetricsConfigurationResponse&& from) noexcept
+    : MetricsConfigurationResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline MetricsConfigurationResponse& operator=(MetricsConfigurationResponse&& 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 MetricsConfigurationResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const MetricsConfigurationResponse* internal_default_instance() {
+    return reinterpret_cast<const MetricsConfigurationResponse*>(
+               &_MetricsConfigurationResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    4;
+
+  void Swap(MetricsConfigurationResponse* other);
+  friend void swap(MetricsConfigurationResponse& a, MetricsConfigurationResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline MetricsConfigurationResponse* New() const final {
+    return CreateMaybeMessage<MetricsConfigurationResponse>(nullptr);
+  }
+
+  MetricsConfigurationResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<MetricsConfigurationResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const MetricsConfigurationResponse& from);
+  void MergeFrom(const MetricsConfigurationResponse& 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(MetricsConfigurationResponse* 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 MetricsConfigurationResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    MetricsConfigurationResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    MetricsConfigurationResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    MetricsConfigurationResponse_Reason_INTERNAL_ERROR;
+  static const Reason POLL_INTERVAL_UNSUPPORTED =
+    MetricsConfigurationResponse_Reason_POLL_INTERVAL_UNSUPPORTED;
+  static const Reason INVALID_METRIC =
+    MetricsConfigurationResponse_Reason_INVALID_METRIC;
+  static const Reason DEVICE_UNREACHABLE =
+    MetricsConfigurationResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return MetricsConfigurationResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    MetricsConfigurationResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    MetricsConfigurationResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    MetricsConfigurationResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return MetricsConfigurationResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return MetricsConfigurationResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return MetricsConfigurationResponse_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.MetricsConfigurationResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::MetricsConfigurationResponse_Reason reason() const;
+  void set_reason(::dmi::MetricsConfigurationResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.MetricsConfigurationResponse)
+ 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_5fmetrics_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class MetricMetaData final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.MetricMetaData) */ {
+ public:
+  MetricMetaData();
+  virtual ~MetricMetaData();
+
+  MetricMetaData(const MetricMetaData& from);
+
+  inline MetricMetaData& operator=(const MetricMetaData& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  MetricMetaData(MetricMetaData&& from) noexcept
+    : MetricMetaData() {
+    *this = ::std::move(from);
+  }
+
+  inline MetricMetaData& operator=(MetricMetaData&& 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 MetricMetaData& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const MetricMetaData* internal_default_instance() {
+    return reinterpret_cast<const MetricMetaData*>(
+               &_MetricMetaData_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    5;
+
+  void Swap(MetricMetaData* other);
+  friend void swap(MetricMetaData& a, MetricMetaData& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline MetricMetaData* New() const final {
+    return CreateMaybeMessage<MetricMetaData>(nullptr);
+  }
+
+  MetricMetaData* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<MetricMetaData>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const MetricMetaData& from);
+  void MergeFrom(const MetricMetaData& 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(MetricMetaData* 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.MetricMetaData)
+ 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_5fmetrics_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Metric final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Metric) */ {
+ public:
+  Metric();
+  virtual ~Metric();
+
+  Metric(const Metric& from);
+
+  inline Metric& operator=(const Metric& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Metric(Metric&& from) noexcept
+    : Metric() {
+    *this = ::std::move(from);
+  }
+
+  inline Metric& operator=(Metric&& 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 Metric& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Metric* internal_default_instance() {
+    return reinterpret_cast<const Metric*>(
+               &_Metric_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    6;
+
+  void Swap(Metric* other);
+  friend void swap(Metric& a, Metric& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Metric* New() const final {
+    return CreateMaybeMessage<Metric>(nullptr);
+  }
+
+  Metric* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Metric>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Metric& from);
+  void MergeFrom(const Metric& 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(Metric* 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.MetricMetaData metric_metadata = 2;
+  bool has_metric_metadata() const;
+  void clear_metric_metadata();
+  static const int kMetricMetadataFieldNumber = 2;
+  const ::dmi::MetricMetaData& metric_metadata() const;
+  ::dmi::MetricMetaData* release_metric_metadata();
+  ::dmi::MetricMetaData* mutable_metric_metadata();
+  void set_allocated_metric_metadata(::dmi::MetricMetaData* metric_metadata);
+
+  // .dmi.ComponentSensorData value = 3;
+  bool has_value() const;
+  void clear_value();
+  static const int kValueFieldNumber = 3;
+  const ::dmi::ComponentSensorData& value() const;
+  ::dmi::ComponentSensorData* release_value();
+  ::dmi::ComponentSensorData* mutable_value();
+  void set_allocated_value(::dmi::ComponentSensorData* value);
+
+  // .dmi.MetricNames metric_id = 1;
+  void clear_metric_id();
+  static const int kMetricIdFieldNumber = 1;
+  ::dmi::MetricNames metric_id() const;
+  void set_metric_id(::dmi::MetricNames value);
+
+  // @@protoc_insertion_point(class_scope:dmi.Metric)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::MetricMetaData* metric_metadata_;
+  ::dmi::ComponentSensorData* value_;
+  int metric_id_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class GetMetricRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.GetMetricRequest) */ {
+ public:
+  GetMetricRequest();
+  virtual ~GetMetricRequest();
+
+  GetMetricRequest(const GetMetricRequest& from);
+
+  inline GetMetricRequest& operator=(const GetMetricRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  GetMetricRequest(GetMetricRequest&& from) noexcept
+    : GetMetricRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline GetMetricRequest& operator=(GetMetricRequest&& 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 GetMetricRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const GetMetricRequest* internal_default_instance() {
+    return reinterpret_cast<const GetMetricRequest*>(
+               &_GetMetricRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    7;
+
+  void Swap(GetMetricRequest* other);
+  friend void swap(GetMetricRequest& a, GetMetricRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline GetMetricRequest* New() const final {
+    return CreateMaybeMessage<GetMetricRequest>(nullptr);
+  }
+
+  GetMetricRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<GetMetricRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const GetMetricRequest& from);
+  void MergeFrom(const GetMetricRequest& 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(GetMetricRequest* 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.MetricMetaData meta_data = 1;
+  bool has_meta_data() const;
+  void clear_meta_data();
+  static const int kMetaDataFieldNumber = 1;
+  const ::dmi::MetricMetaData& meta_data() const;
+  ::dmi::MetricMetaData* release_meta_data();
+  ::dmi::MetricMetaData* mutable_meta_data();
+  void set_allocated_meta_data(::dmi::MetricMetaData* meta_data);
+
+  // .dmi.MetricNames metric_id = 2;
+  void clear_metric_id();
+  static const int kMetricIdFieldNumber = 2;
+  ::dmi::MetricNames metric_id() const;
+  void set_metric_id(::dmi::MetricNames value);
+
+  // @@protoc_insertion_point(class_scope:dmi.GetMetricRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::MetricMetaData* meta_data_;
+  int metric_id_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class GetMetricResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.GetMetricResponse) */ {
+ public:
+  GetMetricResponse();
+  virtual ~GetMetricResponse();
+
+  GetMetricResponse(const GetMetricResponse& from);
+
+  inline GetMetricResponse& operator=(const GetMetricResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  GetMetricResponse(GetMetricResponse&& from) noexcept
+    : GetMetricResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline GetMetricResponse& operator=(GetMetricResponse&& 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 GetMetricResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const GetMetricResponse* internal_default_instance() {
+    return reinterpret_cast<const GetMetricResponse*>(
+               &_GetMetricResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    8;
+
+  void Swap(GetMetricResponse* other);
+  friend void swap(GetMetricResponse& a, GetMetricResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline GetMetricResponse* New() const final {
+    return CreateMaybeMessage<GetMetricResponse>(nullptr);
+  }
+
+  GetMetricResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<GetMetricResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const GetMetricResponse& from);
+  void MergeFrom(const GetMetricResponse& 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(GetMetricResponse* 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 GetMetricResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    GetMetricResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    GetMetricResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason UNKNOWN_COMPONENT =
+    GetMetricResponse_Reason_UNKNOWN_COMPONENT;
+  static const Reason INTERNAL_ERROR =
+    GetMetricResponse_Reason_INTERNAL_ERROR;
+  static const Reason INVALID_METRIC =
+    GetMetricResponse_Reason_INVALID_METRIC;
+  static const Reason DEVICE_UNREACHABLE =
+    GetMetricResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return GetMetricResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    GetMetricResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    GetMetricResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    GetMetricResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return GetMetricResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return GetMetricResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return GetMetricResponse_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.Metric metric = 3;
+  bool has_metric() const;
+  void clear_metric();
+  static const int kMetricFieldNumber = 3;
+  const ::dmi::Metric& metric() const;
+  ::dmi::Metric* release_metric();
+  ::dmi::Metric* mutable_metric();
+  void set_allocated_metric(::dmi::Metric* metric);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.GetMetricResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::GetMetricResponse_Reason reason() const;
+  void set_reason(::dmi::GetMetricResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.GetMetricResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  ::dmi::Metric* metric_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif  // __GNUC__
+// MetricConfig
+
+// .dmi.MetricNames metric_id = 1;
+inline void MetricConfig::clear_metric_id() {
+  metric_id_ = 0;
+}
+inline ::dmi::MetricNames MetricConfig::metric_id() const {
+  // @@protoc_insertion_point(field_get:dmi.MetricConfig.metric_id)
+  return static_cast< ::dmi::MetricNames >(metric_id_);
+}
+inline void MetricConfig::set_metric_id(::dmi::MetricNames value) {
+  
+  metric_id_ = value;
+  // @@protoc_insertion_point(field_set:dmi.MetricConfig.metric_id)
+}
+
+// bool is_configured = 2;
+inline void MetricConfig::clear_is_configured() {
+  is_configured_ = false;
+}
+inline bool MetricConfig::is_configured() const {
+  // @@protoc_insertion_point(field_get:dmi.MetricConfig.is_configured)
+  return is_configured_;
+}
+inline void MetricConfig::set_is_configured(bool value) {
+  
+  is_configured_ = value;
+  // @@protoc_insertion_point(field_set:dmi.MetricConfig.is_configured)
+}
+
+// uint32 poll_interval = 3;
+inline void MetricConfig::clear_poll_interval() {
+  poll_interval_ = 0u;
+}
+inline ::google::protobuf::uint32 MetricConfig::poll_interval() const {
+  // @@protoc_insertion_point(field_get:dmi.MetricConfig.poll_interval)
+  return poll_interval_;
+}
+inline void MetricConfig::set_poll_interval(::google::protobuf::uint32 value) {
+  
+  poll_interval_ = value;
+  // @@protoc_insertion_point(field_set:dmi.MetricConfig.poll_interval)
+}
+
+// -------------------------------------------------------------------
+
+// MetricsConfig
+
+// repeated .dmi.MetricConfig metrics = 1;
+inline int MetricsConfig::metrics_size() const {
+  return metrics_.size();
+}
+inline void MetricsConfig::clear_metrics() {
+  metrics_.Clear();
+}
+inline ::dmi::MetricConfig* MetricsConfig::mutable_metrics(int index) {
+  // @@protoc_insertion_point(field_mutable:dmi.MetricsConfig.metrics)
+  return metrics_.Mutable(index);
+}
+inline ::google::protobuf::RepeatedPtrField< ::dmi::MetricConfig >*
+MetricsConfig::mutable_metrics() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.MetricsConfig.metrics)
+  return &metrics_;
+}
+inline const ::dmi::MetricConfig& MetricsConfig::metrics(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.MetricsConfig.metrics)
+  return metrics_.Get(index);
+}
+inline ::dmi::MetricConfig* MetricsConfig::add_metrics() {
+  // @@protoc_insertion_point(field_add:dmi.MetricsConfig.metrics)
+  return metrics_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::dmi::MetricConfig >&
+MetricsConfig::metrics() const {
+  // @@protoc_insertion_point(field_list:dmi.MetricsConfig.metrics)
+  return metrics_;
+}
+
+// -------------------------------------------------------------------
+
+// ListMetricsResponse
+
+// .dmi.Status status = 1;
+inline void ListMetricsResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status ListMetricsResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.ListMetricsResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void ListMetricsResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ListMetricsResponse.status)
+}
+
+// .dmi.ListMetricsResponse.Reason reason = 2;
+inline void ListMetricsResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::ListMetricsResponse_Reason ListMetricsResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.ListMetricsResponse.reason)
+  return static_cast< ::dmi::ListMetricsResponse_Reason >(reason_);
+}
+inline void ListMetricsResponse::set_reason(::dmi::ListMetricsResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ListMetricsResponse.reason)
+}
+
+// .dmi.MetricsConfig metrics = 3;
+inline bool ListMetricsResponse::has_metrics() const {
+  return this != internal_default_instance() && metrics_ != nullptr;
+}
+inline void ListMetricsResponse::clear_metrics() {
+  if (GetArenaNoVirtual() == nullptr && metrics_ != nullptr) {
+    delete metrics_;
+  }
+  metrics_ = nullptr;
+}
+inline const ::dmi::MetricsConfig& ListMetricsResponse::metrics() const {
+  const ::dmi::MetricsConfig* p = metrics_;
+  // @@protoc_insertion_point(field_get:dmi.ListMetricsResponse.metrics)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::MetricsConfig*>(
+      &::dmi::_MetricsConfig_default_instance_);
+}
+inline ::dmi::MetricsConfig* ListMetricsResponse::release_metrics() {
+  // @@protoc_insertion_point(field_release:dmi.ListMetricsResponse.metrics)
+  
+  ::dmi::MetricsConfig* temp = metrics_;
+  metrics_ = nullptr;
+  return temp;
+}
+inline ::dmi::MetricsConfig* ListMetricsResponse::mutable_metrics() {
+  
+  if (metrics_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::MetricsConfig>(GetArenaNoVirtual());
+    metrics_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ListMetricsResponse.metrics)
+  return metrics_;
+}
+inline void ListMetricsResponse::set_allocated_metrics(::dmi::MetricsConfig* metrics) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete metrics_;
+  }
+  if (metrics) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      metrics = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, metrics, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  metrics_ = metrics;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ListMetricsResponse.metrics)
+}
+
+// string reason_detail = 4;
+inline void ListMetricsResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ListMetricsResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.ListMetricsResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void ListMetricsResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ListMetricsResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void ListMetricsResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ListMetricsResponse.reason_detail)
+}
+#endif
+inline void ListMetricsResponse::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.ListMetricsResponse.reason_detail)
+}
+inline void ListMetricsResponse::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.ListMetricsResponse.reason_detail)
+}
+inline ::std::string* ListMetricsResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ListMetricsResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ListMetricsResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.ListMetricsResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ListMetricsResponse::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.ListMetricsResponse.reason_detail)
+}
+
+// -------------------------------------------------------------------
+
+// MetricsConfigurationRequest
+
+// .dmi.Uuid device_uuid = 1;
+inline bool MetricsConfigurationRequest::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& MetricsConfigurationRequest::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.MetricsConfigurationRequest.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* MetricsConfigurationRequest::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.MetricsConfigurationRequest.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* MetricsConfigurationRequest::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.MetricsConfigurationRequest.device_uuid)
+  return device_uuid_;
+}
+inline void MetricsConfigurationRequest::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.MetricsConfigurationRequest.device_uuid)
+}
+
+// .dmi.MetricsConfig changes = 2;
+inline bool MetricsConfigurationRequest::has_changes() const {
+  return operation_case() == kChanges;
+}
+inline void MetricsConfigurationRequest::set_has_changes() {
+  _oneof_case_[0] = kChanges;
+}
+inline void MetricsConfigurationRequest::clear_changes() {
+  if (has_changes()) {
+    delete operation_.changes_;
+    clear_has_operation();
+  }
+}
+inline ::dmi::MetricsConfig* MetricsConfigurationRequest::release_changes() {
+  // @@protoc_insertion_point(field_release:dmi.MetricsConfigurationRequest.changes)
+  if (has_changes()) {
+    clear_has_operation();
+      ::dmi::MetricsConfig* temp = operation_.changes_;
+    operation_.changes_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::MetricsConfig& MetricsConfigurationRequest::changes() const {
+  // @@protoc_insertion_point(field_get:dmi.MetricsConfigurationRequest.changes)
+  return has_changes()
+      ? *operation_.changes_
+      : *reinterpret_cast< ::dmi::MetricsConfig*>(&::dmi::_MetricsConfig_default_instance_);
+}
+inline ::dmi::MetricsConfig* MetricsConfigurationRequest::mutable_changes() {
+  if (!has_changes()) {
+    clear_operation();
+    set_has_changes();
+    operation_.changes_ = CreateMaybeMessage< ::dmi::MetricsConfig >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.MetricsConfigurationRequest.changes)
+  return operation_.changes_;
+}
+
+// bool reset_to_default = 3;
+inline bool MetricsConfigurationRequest::has_reset_to_default() const {
+  return operation_case() == kResetToDefault;
+}
+inline void MetricsConfigurationRequest::set_has_reset_to_default() {
+  _oneof_case_[0] = kResetToDefault;
+}
+inline void MetricsConfigurationRequest::clear_reset_to_default() {
+  if (has_reset_to_default()) {
+    operation_.reset_to_default_ = false;
+    clear_has_operation();
+  }
+}
+inline bool MetricsConfigurationRequest::reset_to_default() const {
+  // @@protoc_insertion_point(field_get:dmi.MetricsConfigurationRequest.reset_to_default)
+  if (has_reset_to_default()) {
+    return operation_.reset_to_default_;
+  }
+  return false;
+}
+inline void MetricsConfigurationRequest::set_reset_to_default(bool value) {
+  if (!has_reset_to_default()) {
+    clear_operation();
+    set_has_reset_to_default();
+  }
+  operation_.reset_to_default_ = value;
+  // @@protoc_insertion_point(field_set:dmi.MetricsConfigurationRequest.reset_to_default)
+}
+
+inline bool MetricsConfigurationRequest::has_operation() const {
+  return operation_case() != OPERATION_NOT_SET;
+}
+inline void MetricsConfigurationRequest::clear_has_operation() {
+  _oneof_case_[0] = OPERATION_NOT_SET;
+}
+inline MetricsConfigurationRequest::OperationCase MetricsConfigurationRequest::operation_case() const {
+  return MetricsConfigurationRequest::OperationCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// MetricsConfigurationResponse
+
+// .dmi.Status status = 1;
+inline void MetricsConfigurationResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status MetricsConfigurationResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.MetricsConfigurationResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void MetricsConfigurationResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.MetricsConfigurationResponse.status)
+}
+
+// .dmi.MetricsConfigurationResponse.Reason reason = 2;
+inline void MetricsConfigurationResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::MetricsConfigurationResponse_Reason MetricsConfigurationResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.MetricsConfigurationResponse.reason)
+  return static_cast< ::dmi::MetricsConfigurationResponse_Reason >(reason_);
+}
+inline void MetricsConfigurationResponse::set_reason(::dmi::MetricsConfigurationResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.MetricsConfigurationResponse.reason)
+}
+
+// string reason_detail = 3;
+inline void MetricsConfigurationResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& MetricsConfigurationResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.MetricsConfigurationResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void MetricsConfigurationResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.MetricsConfigurationResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void MetricsConfigurationResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.MetricsConfigurationResponse.reason_detail)
+}
+#endif
+inline void MetricsConfigurationResponse::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.MetricsConfigurationResponse.reason_detail)
+}
+inline void MetricsConfigurationResponse::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.MetricsConfigurationResponse.reason_detail)
+}
+inline ::std::string* MetricsConfigurationResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.MetricsConfigurationResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* MetricsConfigurationResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.MetricsConfigurationResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void MetricsConfigurationResponse::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.MetricsConfigurationResponse.reason_detail)
+}
+
+// -------------------------------------------------------------------
+
+// MetricMetaData
+
+// .dmi.Uuid device_uuid = 1;
+inline bool MetricMetaData::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& MetricMetaData::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.MetricMetaData.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* MetricMetaData::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.MetricMetaData.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* MetricMetaData::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.MetricMetaData.device_uuid)
+  return device_uuid_;
+}
+inline void MetricMetaData::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.MetricMetaData.device_uuid)
+}
+
+// .dmi.Uuid component_uuid = 2;
+inline bool MetricMetaData::has_component_uuid() const {
+  return this != internal_default_instance() && component_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& MetricMetaData::component_uuid() const {
+  const ::dmi::Uuid* p = component_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.MetricMetaData.component_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* MetricMetaData::release_component_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.MetricMetaData.component_uuid)
+  
+  ::dmi::Uuid* temp = component_uuid_;
+  component_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* MetricMetaData::mutable_component_uuid() {
+  
+  if (component_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    component_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.MetricMetaData.component_uuid)
+  return component_uuid_;
+}
+inline void MetricMetaData::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.MetricMetaData.component_uuid)
+}
+
+// string component_name = 3;
+inline void MetricMetaData::clear_component_name() {
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& MetricMetaData::component_name() const {
+  // @@protoc_insertion_point(field_get:dmi.MetricMetaData.component_name)
+  return component_name_.GetNoArena();
+}
+inline void MetricMetaData::set_component_name(const ::std::string& value) {
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.MetricMetaData.component_name)
+}
+#if LANG_CXX11
+inline void MetricMetaData::set_component_name(::std::string&& value) {
+  
+  component_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.MetricMetaData.component_name)
+}
+#endif
+inline void MetricMetaData::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.MetricMetaData.component_name)
+}
+inline void MetricMetaData::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.MetricMetaData.component_name)
+}
+inline ::std::string* MetricMetaData::mutable_component_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.MetricMetaData.component_name)
+  return component_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* MetricMetaData::release_component_name() {
+  // @@protoc_insertion_point(field_release:dmi.MetricMetaData.component_name)
+  
+  return component_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void MetricMetaData::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.MetricMetaData.component_name)
+}
+
+// -------------------------------------------------------------------
+
+// Metric
+
+// .dmi.MetricNames metric_id = 1;
+inline void Metric::clear_metric_id() {
+  metric_id_ = 0;
+}
+inline ::dmi::MetricNames Metric::metric_id() const {
+  // @@protoc_insertion_point(field_get:dmi.Metric.metric_id)
+  return static_cast< ::dmi::MetricNames >(metric_id_);
+}
+inline void Metric::set_metric_id(::dmi::MetricNames value) {
+  
+  metric_id_ = value;
+  // @@protoc_insertion_point(field_set:dmi.Metric.metric_id)
+}
+
+// .dmi.MetricMetaData metric_metadata = 2;
+inline bool Metric::has_metric_metadata() const {
+  return this != internal_default_instance() && metric_metadata_ != nullptr;
+}
+inline void Metric::clear_metric_metadata() {
+  if (GetArenaNoVirtual() == nullptr && metric_metadata_ != nullptr) {
+    delete metric_metadata_;
+  }
+  metric_metadata_ = nullptr;
+}
+inline const ::dmi::MetricMetaData& Metric::metric_metadata() const {
+  const ::dmi::MetricMetaData* p = metric_metadata_;
+  // @@protoc_insertion_point(field_get:dmi.Metric.metric_metadata)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::MetricMetaData*>(
+      &::dmi::_MetricMetaData_default_instance_);
+}
+inline ::dmi::MetricMetaData* Metric::release_metric_metadata() {
+  // @@protoc_insertion_point(field_release:dmi.Metric.metric_metadata)
+  
+  ::dmi::MetricMetaData* temp = metric_metadata_;
+  metric_metadata_ = nullptr;
+  return temp;
+}
+inline ::dmi::MetricMetaData* Metric::mutable_metric_metadata() {
+  
+  if (metric_metadata_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::MetricMetaData>(GetArenaNoVirtual());
+    metric_metadata_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Metric.metric_metadata)
+  return metric_metadata_;
+}
+inline void Metric::set_allocated_metric_metadata(::dmi::MetricMetaData* metric_metadata) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete metric_metadata_;
+  }
+  if (metric_metadata) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      metric_metadata = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, metric_metadata, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  metric_metadata_ = metric_metadata;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Metric.metric_metadata)
+}
+
+// .dmi.ComponentSensorData value = 3;
+inline bool Metric::has_value() const {
+  return this != internal_default_instance() && value_ != nullptr;
+}
+inline const ::dmi::ComponentSensorData& Metric::value() const {
+  const ::dmi::ComponentSensorData* p = value_;
+  // @@protoc_insertion_point(field_get:dmi.Metric.value)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ComponentSensorData*>(
+      &::dmi::_ComponentSensorData_default_instance_);
+}
+inline ::dmi::ComponentSensorData* Metric::release_value() {
+  // @@protoc_insertion_point(field_release:dmi.Metric.value)
+  
+  ::dmi::ComponentSensorData* temp = value_;
+  value_ = nullptr;
+  return temp;
+}
+inline ::dmi::ComponentSensorData* Metric::mutable_value() {
+  
+  if (value_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::ComponentSensorData>(GetArenaNoVirtual());
+    value_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Metric.value)
+  return value_;
+}
+inline void Metric::set_allocated_value(::dmi::ComponentSensorData* value) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(value_);
+  }
+  if (value) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      value = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, value, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  value_ = value;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Metric.value)
+}
+
+// -------------------------------------------------------------------
+
+// GetMetricRequest
+
+// .dmi.MetricMetaData meta_data = 1;
+inline bool GetMetricRequest::has_meta_data() const {
+  return this != internal_default_instance() && meta_data_ != nullptr;
+}
+inline void GetMetricRequest::clear_meta_data() {
+  if (GetArenaNoVirtual() == nullptr && meta_data_ != nullptr) {
+    delete meta_data_;
+  }
+  meta_data_ = nullptr;
+}
+inline const ::dmi::MetricMetaData& GetMetricRequest::meta_data() const {
+  const ::dmi::MetricMetaData* p = meta_data_;
+  // @@protoc_insertion_point(field_get:dmi.GetMetricRequest.meta_data)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::MetricMetaData*>(
+      &::dmi::_MetricMetaData_default_instance_);
+}
+inline ::dmi::MetricMetaData* GetMetricRequest::release_meta_data() {
+  // @@protoc_insertion_point(field_release:dmi.GetMetricRequest.meta_data)
+  
+  ::dmi::MetricMetaData* temp = meta_data_;
+  meta_data_ = nullptr;
+  return temp;
+}
+inline ::dmi::MetricMetaData* GetMetricRequest::mutable_meta_data() {
+  
+  if (meta_data_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::MetricMetaData>(GetArenaNoVirtual());
+    meta_data_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.GetMetricRequest.meta_data)
+  return meta_data_;
+}
+inline void GetMetricRequest::set_allocated_meta_data(::dmi::MetricMetaData* meta_data) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete meta_data_;
+  }
+  if (meta_data) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      meta_data = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, meta_data, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  meta_data_ = meta_data;
+  // @@protoc_insertion_point(field_set_allocated:dmi.GetMetricRequest.meta_data)
+}
+
+// .dmi.MetricNames metric_id = 2;
+inline void GetMetricRequest::clear_metric_id() {
+  metric_id_ = 0;
+}
+inline ::dmi::MetricNames GetMetricRequest::metric_id() const {
+  // @@protoc_insertion_point(field_get:dmi.GetMetricRequest.metric_id)
+  return static_cast< ::dmi::MetricNames >(metric_id_);
+}
+inline void GetMetricRequest::set_metric_id(::dmi::MetricNames value) {
+  
+  metric_id_ = value;
+  // @@protoc_insertion_point(field_set:dmi.GetMetricRequest.metric_id)
+}
+
+// -------------------------------------------------------------------
+
+// GetMetricResponse
+
+// .dmi.Status status = 1;
+inline void GetMetricResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status GetMetricResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.GetMetricResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void GetMetricResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.GetMetricResponse.status)
+}
+
+// .dmi.GetMetricResponse.Reason reason = 2;
+inline void GetMetricResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::GetMetricResponse_Reason GetMetricResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.GetMetricResponse.reason)
+  return static_cast< ::dmi::GetMetricResponse_Reason >(reason_);
+}
+inline void GetMetricResponse::set_reason(::dmi::GetMetricResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.GetMetricResponse.reason)
+}
+
+// .dmi.Metric metric = 3;
+inline bool GetMetricResponse::has_metric() const {
+  return this != internal_default_instance() && metric_ != nullptr;
+}
+inline void GetMetricResponse::clear_metric() {
+  if (GetArenaNoVirtual() == nullptr && metric_ != nullptr) {
+    delete metric_;
+  }
+  metric_ = nullptr;
+}
+inline const ::dmi::Metric& GetMetricResponse::metric() const {
+  const ::dmi::Metric* p = metric_;
+  // @@protoc_insertion_point(field_get:dmi.GetMetricResponse.metric)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Metric*>(
+      &::dmi::_Metric_default_instance_);
+}
+inline ::dmi::Metric* GetMetricResponse::release_metric() {
+  // @@protoc_insertion_point(field_release:dmi.GetMetricResponse.metric)
+  
+  ::dmi::Metric* temp = metric_;
+  metric_ = nullptr;
+  return temp;
+}
+inline ::dmi::Metric* GetMetricResponse::mutable_metric() {
+  
+  if (metric_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Metric>(GetArenaNoVirtual());
+    metric_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.GetMetricResponse.metric)
+  return metric_;
+}
+inline void GetMetricResponse::set_allocated_metric(::dmi::Metric* metric) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete metric_;
+  }
+  if (metric) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      metric = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, metric, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  metric_ = metric;
+  // @@protoc_insertion_point(field_set_allocated:dmi.GetMetricResponse.metric)
+}
+
+// string reason_detail = 4;
+inline void GetMetricResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& GetMetricResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.GetMetricResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void GetMetricResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.GetMetricResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void GetMetricResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.GetMetricResponse.reason_detail)
+}
+#endif
+inline void GetMetricResponse::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.GetMetricResponse.reason_detail)
+}
+inline void GetMetricResponse::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.GetMetricResponse.reason_detail)
+}
+inline ::std::string* GetMetricResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.GetMetricResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* GetMetricResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.GetMetricResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void GetMetricResponse::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.GetMetricResponse.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::ListMetricsResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ListMetricsResponse_Reason>() {
+  return ::dmi::ListMetricsResponse_Reason_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::MetricsConfigurationResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::MetricsConfigurationResponse_Reason>() {
+  return ::dmi::MetricsConfigurationResponse_Reason_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::GetMetricResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::GetMetricResponse_Reason>() {
+  return ::dmi::GetMetricResponse_Reason_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::MetricNames> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::MetricNames>() {
+  return ::dmi::MetricNames_descriptor();
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#include <google/protobuf/port_undef.inc>
+#endif  // PROTOBUF_INCLUDED_dmi_2fhw_5fmetrics_5fmgmt_5fservice_2eproto
diff --git a/cpp/dmi/sw_image.pb.cc b/cpp/dmi/sw_image.pb.cc
new file mode 100644
index 0000000..b96d874
--- /dev/null
+++ b/cpp/dmi/sw_image.pb.cc
@@ -0,0 +1,1657 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/sw_image.proto
+
+#include "dmi/sw_image.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fsw_5fimage_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ImageVersion_dmi_2fsw_5fimage_2eproto;
+namespace dmi {
+class ImageVersionDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ImageVersion> _instance;
+} _ImageVersion_default_instance_;
+class ImageInformationDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ImageInformation> _instance;
+} _ImageInformation_default_instance_;
+class ImageStatusDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ImageStatus> _instance;
+} _ImageStatus_default_instance_;
+}  // namespace dmi
+static void InitDefaultsImageVersion_dmi_2fsw_5fimage_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ImageVersion_default_instance_;
+    new (ptr) ::dmi::ImageVersion();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ImageVersion::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_ImageVersion_dmi_2fsw_5fimage_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsImageVersion_dmi_2fsw_5fimage_2eproto}, {}};
+
+static void InitDefaultsImageInformation_dmi_2fsw_5fimage_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ImageInformation_default_instance_;
+    new (ptr) ::dmi::ImageInformation();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ImageInformation::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ImageInformation_dmi_2fsw_5fimage_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsImageInformation_dmi_2fsw_5fimage_2eproto}, {
+      &scc_info_ImageVersion_dmi_2fsw_5fimage_2eproto.base,}};
+
+static void InitDefaultsImageStatus_dmi_2fsw_5fimage_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ImageStatus_default_instance_;
+    new (ptr) ::dmi::ImageStatus();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ImageStatus::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_ImageStatus_dmi_2fsw_5fimage_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsImageStatus_dmi_2fsw_5fimage_2eproto}, {}};
+
+void InitDefaults_dmi_2fsw_5fimage_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_ImageVersion_dmi_2fsw_5fimage_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ImageInformation_dmi_2fsw_5fimage_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ImageStatus_dmi_2fsw_5fimage_2eproto.base);
+}
+
+::google::protobuf::Metadata file_level_metadata_dmi_2fsw_5fimage_2eproto[3];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fsw_5fimage_2eproto[2];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fsw_5fimage_2eproto = nullptr;
+
+const ::google::protobuf::uint32 TableStruct_dmi_2fsw_5fimage_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageVersion, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageVersion, image_name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageVersion, version_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageInformation, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageInformation, image_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageInformation, image_install_script_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageInformation, image_url_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageInformation, sha256sum_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageStatus, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageStatus, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageStatus, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageStatus, state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageStatus, description_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ImageStatus, reason_detail_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  { 0, -1, sizeof(::dmi::ImageVersion)},
+  { 7, -1, sizeof(::dmi::ImageInformation)},
+  { 16, -1, sizeof(::dmi::ImageStatus)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ImageVersion_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ImageInformation_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ImageStatus_default_instance_),
+};
+
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fsw_5fimage_2eproto = {
+  {}, AddDescriptors_dmi_2fsw_5fimage_2eproto, "dmi/sw_image.proto", schemas,
+  file_default_instances, TableStruct_dmi_2fsw_5fimage_2eproto::offsets,
+  file_level_metadata_dmi_2fsw_5fimage_2eproto, 3, file_level_enum_descriptors_dmi_2fsw_5fimage_2eproto, file_level_service_descriptors_dmi_2fsw_5fimage_2eproto,
+};
+
+const char descriptor_table_protodef_dmi_2fsw_5fimage_2eproto[] =
+  "\n\022dmi/sw_image.proto\022\003dmi\032\021dmi/commons.p"
+  "roto\"3\n\014ImageVersion\022\022\n\nimage_name\030\001 \001(\t"
+  "\022\017\n\007version\030\002 \001(\t\"x\n\020ImageInformation\022 \n"
+  "\005image\030\001 \001(\0132\021.dmi.ImageVersion\022\034\n\024image"
+  "_install_script\030\002 \001(\t\022\021\n\timage_url\030\003 \001(\t"
+  "\022\021\n\tsha256sum\030\005 \001(\t\"\342\004\n\013ImageStatus\022\033\n\006s"
+  "tatus\030\001 \001(\0162\013.dmi.Status\022\'\n\006reason\030\002 \001(\016"
+  "2\027.dmi.ImageStatus.Reason\022*\n\005state\030\003 \001(\016"
+  "2\033.dmi.ImageStatus.ImageState\022\023\n\013descrip"
+  "tion\030\004 \001(\t\022\025\n\rreason_detail\030\005 \001(\t\"\320\001\n\nIm"
+  "ageState\022\023\n\017UNDEFINED_STATE\020\000\022\021\n\rCOPYING"
+  "_IMAGE\020\001\022\024\n\020INSTALLING_IMAGE\020\002\022\024\n\020COMMIT"
+  "TING_IMAGE\020\003\022\024\n\020REBOOTING_DEVICE\020\004\022\024\n\020UP"
+  "GRADE_COMPLETE\020\005\022\022\n\016UPGRADE_FAILED\020\006\022\027\n\023"
+  "ACTIVATION_COMPLETE\020\007\022\025\n\021ACTIVATION_FAIL"
+  "ED\020\010\"\341\001\n\006Reason\022\024\n\020UNDEFINED_REASON\020\000\022\024\n"
+  "\020ERROR_IN_REQUEST\020\001\022\022\n\016INTERNAL_ERROR\020\002\022"
+  "\031\n\025DEVICE_IN_WRONG_STATE\020\003\022\021\n\rINVALID_IM"
+  "AGE\020\004\022\030\n\024WRONG_IMAGE_CHECKSUM\020\005\022!\n\035OPERA"
+  "TION_ALREADY_IN_PROGRESS\020\006\022\022\n\016UNKNOWN_DE"
+  "VICE\020\007\022\030\n\024DEVICE_NOT_REACHABLE\020\010B;Z9gith"
+  "ub.com/opencord/device-management-interf"
+  "ace/v3/go/dmib\006proto3"
+  ;
+::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fsw_5fimage_2eproto = {
+  false, InitDefaults_dmi_2fsw_5fimage_2eproto, 
+  descriptor_table_protodef_dmi_2fsw_5fimage_2eproto,
+  "dmi/sw_image.proto", &assign_descriptors_table_dmi_2fsw_5fimage_2eproto, 901,
+};
+
+void AddDescriptors_dmi_2fsw_5fimage_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
+    ::AddDescriptors_dmi_2fcommons_2eproto,
+  };
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_dmi_2fsw_5fimage_2eproto, deps, 1);
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_dmi_2fsw_5fimage_2eproto = []() { AddDescriptors_dmi_2fsw_5fimage_2eproto(); return true; }();
+namespace dmi {
+const ::google::protobuf::EnumDescriptor* ImageStatus_ImageState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fsw_5fimage_2eproto);
+  return file_level_enum_descriptors_dmi_2fsw_5fimage_2eproto[0];
+}
+bool ImageStatus_ImageState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const ImageStatus_ImageState ImageStatus::UNDEFINED_STATE;
+const ImageStatus_ImageState ImageStatus::COPYING_IMAGE;
+const ImageStatus_ImageState ImageStatus::INSTALLING_IMAGE;
+const ImageStatus_ImageState ImageStatus::COMMITTING_IMAGE;
+const ImageStatus_ImageState ImageStatus::REBOOTING_DEVICE;
+const ImageStatus_ImageState ImageStatus::UPGRADE_COMPLETE;
+const ImageStatus_ImageState ImageStatus::UPGRADE_FAILED;
+const ImageStatus_ImageState ImageStatus::ACTIVATION_COMPLETE;
+const ImageStatus_ImageState ImageStatus::ACTIVATION_FAILED;
+const ImageStatus_ImageState ImageStatus::ImageState_MIN;
+const ImageStatus_ImageState ImageStatus::ImageState_MAX;
+const int ImageStatus::ImageState_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* ImageStatus_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fsw_5fimage_2eproto);
+  return file_level_enum_descriptors_dmi_2fsw_5fimage_2eproto[1];
+}
+bool ImageStatus_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const ImageStatus_Reason ImageStatus::UNDEFINED_REASON;
+const ImageStatus_Reason ImageStatus::ERROR_IN_REQUEST;
+const ImageStatus_Reason ImageStatus::INTERNAL_ERROR;
+const ImageStatus_Reason ImageStatus::DEVICE_IN_WRONG_STATE;
+const ImageStatus_Reason ImageStatus::INVALID_IMAGE;
+const ImageStatus_Reason ImageStatus::WRONG_IMAGE_CHECKSUM;
+const ImageStatus_Reason ImageStatus::OPERATION_ALREADY_IN_PROGRESS;
+const ImageStatus_Reason ImageStatus::UNKNOWN_DEVICE;
+const ImageStatus_Reason ImageStatus::DEVICE_NOT_REACHABLE;
+const ImageStatus_Reason ImageStatus::Reason_MIN;
+const ImageStatus_Reason ImageStatus::Reason_MAX;
+const int ImageStatus::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+// ===================================================================
+
+void ImageVersion::InitAsDefaultInstance() {
+}
+class ImageVersion::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ImageVersion::kImageNameFieldNumber;
+const int ImageVersion::kVersionFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ImageVersion::ImageVersion()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ImageVersion)
+}
+ImageVersion::ImageVersion(const ImageVersion& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  image_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.image_name().size() > 0) {
+    image_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.image_name_);
+  }
+  version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.version().size() > 0) {
+    version_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.version_);
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.ImageVersion)
+}
+
+void ImageVersion::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ImageVersion_dmi_2fsw_5fimage_2eproto.base);
+  image_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+ImageVersion::~ImageVersion() {
+  // @@protoc_insertion_point(destructor:dmi.ImageVersion)
+  SharedDtor();
+}
+
+void ImageVersion::SharedDtor() {
+  image_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  version_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void ImageVersion::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ImageVersion& ImageVersion::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ImageVersion_dmi_2fsw_5fimage_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ImageVersion::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ImageVersion)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  image_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ImageVersion::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ImageVersion*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string image_name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ImageVersion.image_name");
+        object = msg->mutable_image_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string version = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ImageVersion.version");
+        object = msg->mutable_version();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ImageVersion::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ImageVersion)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string image_name = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_image_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->image_name().data(), static_cast<int>(this->image_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ImageVersion.image_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string version = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_version()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->version().data(), static_cast<int>(this->version().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ImageVersion.version"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ImageVersion)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ImageVersion)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ImageVersion::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ImageVersion)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string image_name = 1;
+  if (this->image_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->image_name().data(), static_cast<int>(this->image_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageVersion.image_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->image_name(), output);
+  }
+
+  // string version = 2;
+  if (this->version().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->version().data(), static_cast<int>(this->version().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageVersion.version");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->version(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ImageVersion)
+}
+
+::google::protobuf::uint8* ImageVersion::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ImageVersion)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string image_name = 1;
+  if (this->image_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->image_name().data(), static_cast<int>(this->image_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageVersion.image_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->image_name(), target);
+  }
+
+  // string version = 2;
+  if (this->version().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->version().data(), static_cast<int>(this->version().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageVersion.version");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->version(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ImageVersion)
+  return target;
+}
+
+size_t ImageVersion::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ImageVersion)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string image_name = 1;
+  if (this->image_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->image_name());
+  }
+
+  // string version = 2;
+  if (this->version().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->version());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ImageVersion::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ImageVersion)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ImageVersion* source =
+      ::google::protobuf::DynamicCastToGenerated<ImageVersion>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ImageVersion)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ImageVersion)
+    MergeFrom(*source);
+  }
+}
+
+void ImageVersion::MergeFrom(const ImageVersion& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ImageVersion)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.image_name().size() > 0) {
+
+    image_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.image_name_);
+  }
+  if (from.version().size() > 0) {
+
+    version_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.version_);
+  }
+}
+
+void ImageVersion::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ImageVersion)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ImageVersion::CopyFrom(const ImageVersion& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ImageVersion)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ImageVersion::IsInitialized() const {
+  return true;
+}
+
+void ImageVersion::Swap(ImageVersion* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ImageVersion::InternalSwap(ImageVersion* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  image_name_.Swap(&other->image_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  version_.Swap(&other->version_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+}
+
+::google::protobuf::Metadata ImageVersion::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fimage_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fimage_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ImageInformation::InitAsDefaultInstance() {
+  ::dmi::_ImageInformation_default_instance_._instance.get_mutable()->image_ = const_cast< ::dmi::ImageVersion*>(
+      ::dmi::ImageVersion::internal_default_instance());
+}
+class ImageInformation::HasBitSetters {
+ public:
+  static const ::dmi::ImageVersion& image(const ImageInformation* msg);
+};
+
+const ::dmi::ImageVersion&
+ImageInformation::HasBitSetters::image(const ImageInformation* msg) {
+  return *msg->image_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ImageInformation::kImageFieldNumber;
+const int ImageInformation::kImageInstallScriptFieldNumber;
+const int ImageInformation::kImageUrlFieldNumber;
+const int ImageInformation::kSha256SumFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ImageInformation::ImageInformation()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ImageInformation)
+}
+ImageInformation::ImageInformation(const ImageInformation& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  image_install_script_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.image_install_script().size() > 0) {
+    image_install_script_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.image_install_script_);
+  }
+  image_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.image_url().size() > 0) {
+    image_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.image_url_);
+  }
+  sha256sum_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.sha256sum().size() > 0) {
+    sha256sum_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.sha256sum_);
+  }
+  if (from.has_image()) {
+    image_ = new ::dmi::ImageVersion(*from.image_);
+  } else {
+    image_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.ImageInformation)
+}
+
+void ImageInformation::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ImageInformation_dmi_2fsw_5fimage_2eproto.base);
+  image_install_script_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  image_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  sha256sum_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  image_ = nullptr;
+}
+
+ImageInformation::~ImageInformation() {
+  // @@protoc_insertion_point(destructor:dmi.ImageInformation)
+  SharedDtor();
+}
+
+void ImageInformation::SharedDtor() {
+  image_install_script_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  image_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  sha256sum_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete image_;
+}
+
+void ImageInformation::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ImageInformation& ImageInformation::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ImageInformation_dmi_2fsw_5fimage_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ImageInformation::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ImageInformation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  image_install_script_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  image_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  sha256sum_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && image_ != nullptr) {
+    delete image_;
+  }
+  image_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ImageInformation::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ImageInformation*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.ImageVersion image = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ImageVersion::_InternalParse;
+        object = msg->mutable_image();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string image_install_script = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ImageInformation.image_install_script");
+        object = msg->mutable_image_install_script();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string image_url = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ImageInformation.image_url");
+        object = msg->mutable_image_url();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string sha256sum = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ImageInformation.sha256sum");
+        object = msg->mutable_sha256sum();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ImageInformation::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ImageInformation)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.ImageVersion image = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_image()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string image_install_script = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_image_install_script()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->image_install_script().data(), static_cast<int>(this->image_install_script().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ImageInformation.image_install_script"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string image_url = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_image_url()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->image_url().data(), static_cast<int>(this->image_url().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ImageInformation.image_url"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string sha256sum = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_sha256sum()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->sha256sum().data(), static_cast<int>(this->sha256sum().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ImageInformation.sha256sum"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ImageInformation)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ImageInformation)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ImageInformation::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ImageInformation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ImageVersion image = 1;
+  if (this->has_image()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::image(this), output);
+  }
+
+  // string image_install_script = 2;
+  if (this->image_install_script().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->image_install_script().data(), static_cast<int>(this->image_install_script().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageInformation.image_install_script");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->image_install_script(), output);
+  }
+
+  // string image_url = 3;
+  if (this->image_url().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->image_url().data(), static_cast<int>(this->image_url().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageInformation.image_url");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->image_url(), output);
+  }
+
+  // string sha256sum = 5;
+  if (this->sha256sum().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->sha256sum().data(), static_cast<int>(this->sha256sum().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageInformation.sha256sum");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      5, this->sha256sum(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ImageInformation)
+}
+
+::google::protobuf::uint8* ImageInformation::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ImageInformation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ImageVersion image = 1;
+  if (this->has_image()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::image(this), target);
+  }
+
+  // string image_install_script = 2;
+  if (this->image_install_script().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->image_install_script().data(), static_cast<int>(this->image_install_script().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageInformation.image_install_script");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->image_install_script(), target);
+  }
+
+  // string image_url = 3;
+  if (this->image_url().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->image_url().data(), static_cast<int>(this->image_url().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageInformation.image_url");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->image_url(), target);
+  }
+
+  // string sha256sum = 5;
+  if (this->sha256sum().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->sha256sum().data(), static_cast<int>(this->sha256sum().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageInformation.sha256sum");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        5, this->sha256sum(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ImageInformation)
+  return target;
+}
+
+size_t ImageInformation::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ImageInformation)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string image_install_script = 2;
+  if (this->image_install_script().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->image_install_script());
+  }
+
+  // string image_url = 3;
+  if (this->image_url().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->image_url());
+  }
+
+  // string sha256sum = 5;
+  if (this->sha256sum().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->sha256sum());
+  }
+
+  // .dmi.ImageVersion image = 1;
+  if (this->has_image()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *image_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ImageInformation::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ImageInformation)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ImageInformation* source =
+      ::google::protobuf::DynamicCastToGenerated<ImageInformation>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ImageInformation)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ImageInformation)
+    MergeFrom(*source);
+  }
+}
+
+void ImageInformation::MergeFrom(const ImageInformation& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ImageInformation)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.image_install_script().size() > 0) {
+
+    image_install_script_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.image_install_script_);
+  }
+  if (from.image_url().size() > 0) {
+
+    image_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.image_url_);
+  }
+  if (from.sha256sum().size() > 0) {
+
+    sha256sum_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.sha256sum_);
+  }
+  if (from.has_image()) {
+    mutable_image()->::dmi::ImageVersion::MergeFrom(from.image());
+  }
+}
+
+void ImageInformation::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ImageInformation)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ImageInformation::CopyFrom(const ImageInformation& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ImageInformation)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ImageInformation::IsInitialized() const {
+  return true;
+}
+
+void ImageInformation::Swap(ImageInformation* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ImageInformation::InternalSwap(ImageInformation* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  image_install_script_.Swap(&other->image_install_script_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  image_url_.Swap(&other->image_url_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  sha256sum_.Swap(&other->sha256sum_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(image_, other->image_);
+}
+
+::google::protobuf::Metadata ImageInformation::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fimage_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fimage_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ImageStatus::InitAsDefaultInstance() {
+}
+class ImageStatus::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ImageStatus::kStatusFieldNumber;
+const int ImageStatus::kReasonFieldNumber;
+const int ImageStatus::kStateFieldNumber;
+const int ImageStatus::kDescriptionFieldNumber;
+const int ImageStatus::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ImageStatus::ImageStatus()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ImageStatus)
+}
+ImageStatus::ImageStatus(const ImageStatus& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  description_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.description().size() > 0) {
+    description_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.description_);
+  }
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&state_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(state_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ImageStatus)
+}
+
+void ImageStatus::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ImageStatus_dmi_2fsw_5fimage_2eproto.base);
+  description_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&state_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(state_));
+}
+
+ImageStatus::~ImageStatus() {
+  // @@protoc_insertion_point(destructor:dmi.ImageStatus)
+  SharedDtor();
+}
+
+void ImageStatus::SharedDtor() {
+  description_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void ImageStatus::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ImageStatus& ImageStatus::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ImageStatus_dmi_2fsw_5fimage_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ImageStatus::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ImageStatus)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  description_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&state_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(state_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ImageStatus::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ImageStatus*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ImageStatus.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::ImageStatus_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ImageStatus.ImageState state = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_state(static_cast<::dmi::ImageStatus_ImageState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string description = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ImageStatus.description");
+        object = msg->mutable_description();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string reason_detail = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ImageStatus.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ImageStatus::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ImageStatus)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ImageStatus.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::ImageStatus_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ImageStatus.ImageState state = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_state(static_cast< ::dmi::ImageStatus_ImageState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string description = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_description()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->description().data(), static_cast<int>(this->description().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ImageStatus.description"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ImageStatus.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ImageStatus)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ImageStatus)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ImageStatus::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ImageStatus)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.ImageStatus.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // .dmi.ImageStatus.ImageState state = 3;
+  if (this->state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      3, this->state(), output);
+  }
+
+  // string description = 4;
+  if (this->description().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->description().data(), static_cast<int>(this->description().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageStatus.description");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->description(), output);
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageStatus.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      5, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ImageStatus)
+}
+
+::google::protobuf::uint8* ImageStatus::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ImageStatus)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.ImageStatus.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // .dmi.ImageStatus.ImageState state = 3;
+  if (this->state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      3, this->state(), target);
+  }
+
+  // string description = 4;
+  if (this->description().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->description().data(), static_cast<int>(this->description().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageStatus.description");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->description(), target);
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ImageStatus.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        5, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ImageStatus)
+  return target;
+}
+
+size_t ImageStatus::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ImageStatus)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string description = 4;
+  if (this->description().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->description());
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.ImageStatus.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  // .dmi.ImageStatus.ImageState state = 3;
+  if (this->state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->state());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ImageStatus::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ImageStatus)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ImageStatus* source =
+      ::google::protobuf::DynamicCastToGenerated<ImageStatus>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ImageStatus)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ImageStatus)
+    MergeFrom(*source);
+  }
+}
+
+void ImageStatus::MergeFrom(const ImageStatus& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ImageStatus)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.description().size() > 0) {
+
+    description_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.description_);
+  }
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+  if (from.state() != 0) {
+    set_state(from.state());
+  }
+}
+
+void ImageStatus::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ImageStatus)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ImageStatus::CopyFrom(const ImageStatus& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ImageStatus)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ImageStatus::IsInitialized() const {
+  return true;
+}
+
+void ImageStatus::Swap(ImageStatus* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ImageStatus::InternalSwap(ImageStatus* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  description_.Swap(&other->description_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+  swap(state_, other->state_);
+}
+
+::google::protobuf::Metadata ImageStatus::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fimage_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fimage_2eproto[kIndexInFileMessages];
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> PROTOBUF_NOINLINE ::dmi::ImageVersion* Arena::CreateMaybeMessage< ::dmi::ImageVersion >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ImageVersion >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ImageInformation* Arena::CreateMaybeMessage< ::dmi::ImageInformation >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ImageInformation >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ImageStatus* Arena::CreateMaybeMessage< ::dmi::ImageStatus >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ImageStatus >(arena);
+}
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+#include <google/protobuf/port_undef.inc>
diff --git a/cpp/dmi/sw_image.pb.h b/cpp/dmi/sw_image.pb.h
new file mode 100644
index 0000000..8803132
--- /dev/null
+++ b/cpp/dmi/sw_image.pb.h
@@ -0,0 +1,1175 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/sw_image.proto
+
+#ifndef PROTOBUF_INCLUDED_dmi_2fsw_5fimage_2eproto
+#define PROTOBUF_INCLUDED_dmi_2fsw_5fimage_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"
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_dmi_2fsw_5fimage_2eproto
+
+// Internal implementation detail -- do not use these members.
+struct TableStruct_dmi_2fsw_5fimage_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[3]
+    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_2fsw_5fimage_2eproto();
+namespace dmi {
+class ImageInformation;
+class ImageInformationDefaultTypeInternal;
+extern ImageInformationDefaultTypeInternal _ImageInformation_default_instance_;
+class ImageStatus;
+class ImageStatusDefaultTypeInternal;
+extern ImageStatusDefaultTypeInternal _ImageStatus_default_instance_;
+class ImageVersion;
+class ImageVersionDefaultTypeInternal;
+extern ImageVersionDefaultTypeInternal _ImageVersion_default_instance_;
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> ::dmi::ImageInformation* Arena::CreateMaybeMessage<::dmi::ImageInformation>(Arena*);
+template<> ::dmi::ImageStatus* Arena::CreateMaybeMessage<::dmi::ImageStatus>(Arena*);
+template<> ::dmi::ImageVersion* Arena::CreateMaybeMessage<::dmi::ImageVersion>(Arena*);
+}  // namespace protobuf
+}  // namespace google
+namespace dmi {
+
+enum ImageStatus_ImageState {
+  ImageStatus_ImageState_UNDEFINED_STATE = 0,
+  ImageStatus_ImageState_COPYING_IMAGE = 1,
+  ImageStatus_ImageState_INSTALLING_IMAGE = 2,
+  ImageStatus_ImageState_COMMITTING_IMAGE = 3,
+  ImageStatus_ImageState_REBOOTING_DEVICE = 4,
+  ImageStatus_ImageState_UPGRADE_COMPLETE = 5,
+  ImageStatus_ImageState_UPGRADE_FAILED = 6,
+  ImageStatus_ImageState_ACTIVATION_COMPLETE = 7,
+  ImageStatus_ImageState_ACTIVATION_FAILED = 8,
+  ImageStatus_ImageState_ImageStatus_ImageState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ImageStatus_ImageState_ImageStatus_ImageState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ImageStatus_ImageState_IsValid(int value);
+const ImageStatus_ImageState ImageStatus_ImageState_ImageState_MIN = ImageStatus_ImageState_UNDEFINED_STATE;
+const ImageStatus_ImageState ImageStatus_ImageState_ImageState_MAX = ImageStatus_ImageState_ACTIVATION_FAILED;
+const int ImageStatus_ImageState_ImageState_ARRAYSIZE = ImageStatus_ImageState_ImageState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ImageStatus_ImageState_descriptor();
+inline const ::std::string& ImageStatus_ImageState_Name(ImageStatus_ImageState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ImageStatus_ImageState_descriptor(), value);
+}
+inline bool ImageStatus_ImageState_Parse(
+    const ::std::string& name, ImageStatus_ImageState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ImageStatus_ImageState>(
+    ImageStatus_ImageState_descriptor(), name, value);
+}
+enum ImageStatus_Reason {
+  ImageStatus_Reason_UNDEFINED_REASON = 0,
+  ImageStatus_Reason_ERROR_IN_REQUEST = 1,
+  ImageStatus_Reason_INTERNAL_ERROR = 2,
+  ImageStatus_Reason_DEVICE_IN_WRONG_STATE = 3,
+  ImageStatus_Reason_INVALID_IMAGE = 4,
+  ImageStatus_Reason_WRONG_IMAGE_CHECKSUM = 5,
+  ImageStatus_Reason_OPERATION_ALREADY_IN_PROGRESS = 6,
+  ImageStatus_Reason_UNKNOWN_DEVICE = 7,
+  ImageStatus_Reason_DEVICE_NOT_REACHABLE = 8,
+  ImageStatus_Reason_ImageStatus_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ImageStatus_Reason_ImageStatus_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ImageStatus_Reason_IsValid(int value);
+const ImageStatus_Reason ImageStatus_Reason_Reason_MIN = ImageStatus_Reason_UNDEFINED_REASON;
+const ImageStatus_Reason ImageStatus_Reason_Reason_MAX = ImageStatus_Reason_DEVICE_NOT_REACHABLE;
+const int ImageStatus_Reason_Reason_ARRAYSIZE = ImageStatus_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ImageStatus_Reason_descriptor();
+inline const ::std::string& ImageStatus_Reason_Name(ImageStatus_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ImageStatus_Reason_descriptor(), value);
+}
+inline bool ImageStatus_Reason_Parse(
+    const ::std::string& name, ImageStatus_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ImageStatus_Reason>(
+    ImageStatus_Reason_descriptor(), name, value);
+}
+// ===================================================================
+
+class ImageVersion final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ImageVersion) */ {
+ public:
+  ImageVersion();
+  virtual ~ImageVersion();
+
+  ImageVersion(const ImageVersion& from);
+
+  inline ImageVersion& operator=(const ImageVersion& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ImageVersion(ImageVersion&& from) noexcept
+    : ImageVersion() {
+    *this = ::std::move(from);
+  }
+
+  inline ImageVersion& operator=(ImageVersion&& 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 ImageVersion& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ImageVersion* internal_default_instance() {
+    return reinterpret_cast<const ImageVersion*>(
+               &_ImageVersion_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    0;
+
+  void Swap(ImageVersion* other);
+  friend void swap(ImageVersion& a, ImageVersion& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ImageVersion* New() const final {
+    return CreateMaybeMessage<ImageVersion>(nullptr);
+  }
+
+  ImageVersion* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ImageVersion>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ImageVersion& from);
+  void MergeFrom(const ImageVersion& 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(ImageVersion* 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 image_name = 1;
+  void clear_image_name();
+  static const int kImageNameFieldNumber = 1;
+  const ::std::string& image_name() const;
+  void set_image_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_image_name(::std::string&& value);
+  #endif
+  void set_image_name(const char* value);
+  void set_image_name(const char* value, size_t size);
+  ::std::string* mutable_image_name();
+  ::std::string* release_image_name();
+  void set_allocated_image_name(::std::string* image_name);
+
+  // string version = 2;
+  void clear_version();
+  static const int kVersionFieldNumber = 2;
+  const ::std::string& version() const;
+  void set_version(const ::std::string& value);
+  #if LANG_CXX11
+  void set_version(::std::string&& value);
+  #endif
+  void set_version(const char* value);
+  void set_version(const char* value, size_t size);
+  ::std::string* mutable_version();
+  ::std::string* release_version();
+  void set_allocated_version(::std::string* version);
+
+  // @@protoc_insertion_point(class_scope:dmi.ImageVersion)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr image_name_;
+  ::google::protobuf::internal::ArenaStringPtr version_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fsw_5fimage_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ImageInformation final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ImageInformation) */ {
+ public:
+  ImageInformation();
+  virtual ~ImageInformation();
+
+  ImageInformation(const ImageInformation& from);
+
+  inline ImageInformation& operator=(const ImageInformation& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ImageInformation(ImageInformation&& from) noexcept
+    : ImageInformation() {
+    *this = ::std::move(from);
+  }
+
+  inline ImageInformation& operator=(ImageInformation&& 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 ImageInformation& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ImageInformation* internal_default_instance() {
+    return reinterpret_cast<const ImageInformation*>(
+               &_ImageInformation_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    1;
+
+  void Swap(ImageInformation* other);
+  friend void swap(ImageInformation& a, ImageInformation& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ImageInformation* New() const final {
+    return CreateMaybeMessage<ImageInformation>(nullptr);
+  }
+
+  ImageInformation* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ImageInformation>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ImageInformation& from);
+  void MergeFrom(const ImageInformation& 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(ImageInformation* 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 image_install_script = 2;
+  void clear_image_install_script();
+  static const int kImageInstallScriptFieldNumber = 2;
+  const ::std::string& image_install_script() const;
+  void set_image_install_script(const ::std::string& value);
+  #if LANG_CXX11
+  void set_image_install_script(::std::string&& value);
+  #endif
+  void set_image_install_script(const char* value);
+  void set_image_install_script(const char* value, size_t size);
+  ::std::string* mutable_image_install_script();
+  ::std::string* release_image_install_script();
+  void set_allocated_image_install_script(::std::string* image_install_script);
+
+  // string image_url = 3;
+  void clear_image_url();
+  static const int kImageUrlFieldNumber = 3;
+  const ::std::string& image_url() const;
+  void set_image_url(const ::std::string& value);
+  #if LANG_CXX11
+  void set_image_url(::std::string&& value);
+  #endif
+  void set_image_url(const char* value);
+  void set_image_url(const char* value, size_t size);
+  ::std::string* mutable_image_url();
+  ::std::string* release_image_url();
+  void set_allocated_image_url(::std::string* image_url);
+
+  // string sha256sum = 5;
+  void clear_sha256sum();
+  static const int kSha256SumFieldNumber = 5;
+  const ::std::string& sha256sum() const;
+  void set_sha256sum(const ::std::string& value);
+  #if LANG_CXX11
+  void set_sha256sum(::std::string&& value);
+  #endif
+  void set_sha256sum(const char* value);
+  void set_sha256sum(const char* value, size_t size);
+  ::std::string* mutable_sha256sum();
+  ::std::string* release_sha256sum();
+  void set_allocated_sha256sum(::std::string* sha256sum);
+
+  // .dmi.ImageVersion image = 1;
+  bool has_image() const;
+  void clear_image();
+  static const int kImageFieldNumber = 1;
+  const ::dmi::ImageVersion& image() const;
+  ::dmi::ImageVersion* release_image();
+  ::dmi::ImageVersion* mutable_image();
+  void set_allocated_image(::dmi::ImageVersion* image);
+
+  // @@protoc_insertion_point(class_scope:dmi.ImageInformation)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr image_install_script_;
+  ::google::protobuf::internal::ArenaStringPtr image_url_;
+  ::google::protobuf::internal::ArenaStringPtr sha256sum_;
+  ::dmi::ImageVersion* image_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fsw_5fimage_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ImageStatus final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ImageStatus) */ {
+ public:
+  ImageStatus();
+  virtual ~ImageStatus();
+
+  ImageStatus(const ImageStatus& from);
+
+  inline ImageStatus& operator=(const ImageStatus& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ImageStatus(ImageStatus&& from) noexcept
+    : ImageStatus() {
+    *this = ::std::move(from);
+  }
+
+  inline ImageStatus& operator=(ImageStatus&& 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 ImageStatus& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ImageStatus* internal_default_instance() {
+    return reinterpret_cast<const ImageStatus*>(
+               &_ImageStatus_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    2;
+
+  void Swap(ImageStatus* other);
+  friend void swap(ImageStatus& a, ImageStatus& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ImageStatus* New() const final {
+    return CreateMaybeMessage<ImageStatus>(nullptr);
+  }
+
+  ImageStatus* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ImageStatus>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ImageStatus& from);
+  void MergeFrom(const ImageStatus& 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(ImageStatus* 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 ImageStatus_ImageState ImageState;
+  static const ImageState UNDEFINED_STATE =
+    ImageStatus_ImageState_UNDEFINED_STATE;
+  static const ImageState COPYING_IMAGE =
+    ImageStatus_ImageState_COPYING_IMAGE;
+  static const ImageState INSTALLING_IMAGE =
+    ImageStatus_ImageState_INSTALLING_IMAGE;
+  static const ImageState COMMITTING_IMAGE =
+    ImageStatus_ImageState_COMMITTING_IMAGE;
+  static const ImageState REBOOTING_DEVICE =
+    ImageStatus_ImageState_REBOOTING_DEVICE;
+  static const ImageState UPGRADE_COMPLETE =
+    ImageStatus_ImageState_UPGRADE_COMPLETE;
+  static const ImageState UPGRADE_FAILED =
+    ImageStatus_ImageState_UPGRADE_FAILED;
+  static const ImageState ACTIVATION_COMPLETE =
+    ImageStatus_ImageState_ACTIVATION_COMPLETE;
+  static const ImageState ACTIVATION_FAILED =
+    ImageStatus_ImageState_ACTIVATION_FAILED;
+  static inline bool ImageState_IsValid(int value) {
+    return ImageStatus_ImageState_IsValid(value);
+  }
+  static const ImageState ImageState_MIN =
+    ImageStatus_ImageState_ImageState_MIN;
+  static const ImageState ImageState_MAX =
+    ImageStatus_ImageState_ImageState_MAX;
+  static const int ImageState_ARRAYSIZE =
+    ImageStatus_ImageState_ImageState_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  ImageState_descriptor() {
+    return ImageStatus_ImageState_descriptor();
+  }
+  static inline const ::std::string& ImageState_Name(ImageState value) {
+    return ImageStatus_ImageState_Name(value);
+  }
+  static inline bool ImageState_Parse(const ::std::string& name,
+      ImageState* value) {
+    return ImageStatus_ImageState_Parse(name, value);
+  }
+
+  typedef ImageStatus_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    ImageStatus_Reason_UNDEFINED_REASON;
+  static const Reason ERROR_IN_REQUEST =
+    ImageStatus_Reason_ERROR_IN_REQUEST;
+  static const Reason INTERNAL_ERROR =
+    ImageStatus_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_IN_WRONG_STATE =
+    ImageStatus_Reason_DEVICE_IN_WRONG_STATE;
+  static const Reason INVALID_IMAGE =
+    ImageStatus_Reason_INVALID_IMAGE;
+  static const Reason WRONG_IMAGE_CHECKSUM =
+    ImageStatus_Reason_WRONG_IMAGE_CHECKSUM;
+  static const Reason OPERATION_ALREADY_IN_PROGRESS =
+    ImageStatus_Reason_OPERATION_ALREADY_IN_PROGRESS;
+  static const Reason UNKNOWN_DEVICE =
+    ImageStatus_Reason_UNKNOWN_DEVICE;
+  static const Reason DEVICE_NOT_REACHABLE =
+    ImageStatus_Reason_DEVICE_NOT_REACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return ImageStatus_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    ImageStatus_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    ImageStatus_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    ImageStatus_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return ImageStatus_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return ImageStatus_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return ImageStatus_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string description = 4;
+  void clear_description();
+  static const int kDescriptionFieldNumber = 4;
+  const ::std::string& description() const;
+  void set_description(const ::std::string& value);
+  #if LANG_CXX11
+  void set_description(::std::string&& value);
+  #endif
+  void set_description(const char* value);
+  void set_description(const char* value, size_t size);
+  ::std::string* mutable_description();
+  ::std::string* release_description();
+  void set_allocated_description(::std::string* description);
+
+  // 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.ImageStatus.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::ImageStatus_Reason reason() const;
+  void set_reason(::dmi::ImageStatus_Reason value);
+
+  // .dmi.ImageStatus.ImageState state = 3;
+  void clear_state();
+  static const int kStateFieldNumber = 3;
+  ::dmi::ImageStatus_ImageState state() const;
+  void set_state(::dmi::ImageStatus_ImageState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ImageStatus)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr description_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  int state_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fsw_5fimage_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif  // __GNUC__
+// ImageVersion
+
+// string image_name = 1;
+inline void ImageVersion::clear_image_name() {
+  image_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ImageVersion::image_name() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageVersion.image_name)
+  return image_name_.GetNoArena();
+}
+inline void ImageVersion::set_image_name(const ::std::string& value) {
+  
+  image_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ImageVersion.image_name)
+}
+#if LANG_CXX11
+inline void ImageVersion::set_image_name(::std::string&& value) {
+  
+  image_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageVersion.image_name)
+}
+#endif
+inline void ImageVersion::set_image_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  image_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ImageVersion.image_name)
+}
+inline void ImageVersion::set_image_name(const char* value, size_t size) {
+  
+  image_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ImageVersion.image_name)
+}
+inline ::std::string* ImageVersion::mutable_image_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ImageVersion.image_name)
+  return image_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ImageVersion::release_image_name() {
+  // @@protoc_insertion_point(field_release:dmi.ImageVersion.image_name)
+  
+  return image_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ImageVersion::set_allocated_image_name(::std::string* image_name) {
+  if (image_name != nullptr) {
+    
+  } else {
+    
+  }
+  image_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), image_name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ImageVersion.image_name)
+}
+
+// string version = 2;
+inline void ImageVersion::clear_version() {
+  version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ImageVersion::version() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageVersion.version)
+  return version_.GetNoArena();
+}
+inline void ImageVersion::set_version(const ::std::string& value) {
+  
+  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ImageVersion.version)
+}
+#if LANG_CXX11
+inline void ImageVersion::set_version(::std::string&& value) {
+  
+  version_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageVersion.version)
+}
+#endif
+inline void ImageVersion::set_version(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ImageVersion.version)
+}
+inline void ImageVersion::set_version(const char* value, size_t size) {
+  
+  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ImageVersion.version)
+}
+inline ::std::string* ImageVersion::mutable_version() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ImageVersion.version)
+  return version_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ImageVersion::release_version() {
+  // @@protoc_insertion_point(field_release:dmi.ImageVersion.version)
+  
+  return version_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ImageVersion::set_allocated_version(::std::string* version) {
+  if (version != nullptr) {
+    
+  } else {
+    
+  }
+  version_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), version);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ImageVersion.version)
+}
+
+// -------------------------------------------------------------------
+
+// ImageInformation
+
+// .dmi.ImageVersion image = 1;
+inline bool ImageInformation::has_image() const {
+  return this != internal_default_instance() && image_ != nullptr;
+}
+inline void ImageInformation::clear_image() {
+  if (GetArenaNoVirtual() == nullptr && image_ != nullptr) {
+    delete image_;
+  }
+  image_ = nullptr;
+}
+inline const ::dmi::ImageVersion& ImageInformation::image() const {
+  const ::dmi::ImageVersion* p = image_;
+  // @@protoc_insertion_point(field_get:dmi.ImageInformation.image)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ImageVersion*>(
+      &::dmi::_ImageVersion_default_instance_);
+}
+inline ::dmi::ImageVersion* ImageInformation::release_image() {
+  // @@protoc_insertion_point(field_release:dmi.ImageInformation.image)
+  
+  ::dmi::ImageVersion* temp = image_;
+  image_ = nullptr;
+  return temp;
+}
+inline ::dmi::ImageVersion* ImageInformation::mutable_image() {
+  
+  if (image_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::ImageVersion>(GetArenaNoVirtual());
+    image_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ImageInformation.image)
+  return image_;
+}
+inline void ImageInformation::set_allocated_image(::dmi::ImageVersion* image) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete image_;
+  }
+  if (image) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      image = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, image, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  image_ = image;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ImageInformation.image)
+}
+
+// string image_install_script = 2;
+inline void ImageInformation::clear_image_install_script() {
+  image_install_script_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ImageInformation::image_install_script() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageInformation.image_install_script)
+  return image_install_script_.GetNoArena();
+}
+inline void ImageInformation::set_image_install_script(const ::std::string& value) {
+  
+  image_install_script_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ImageInformation.image_install_script)
+}
+#if LANG_CXX11
+inline void ImageInformation::set_image_install_script(::std::string&& value) {
+  
+  image_install_script_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageInformation.image_install_script)
+}
+#endif
+inline void ImageInformation::set_image_install_script(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  image_install_script_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ImageInformation.image_install_script)
+}
+inline void ImageInformation::set_image_install_script(const char* value, size_t size) {
+  
+  image_install_script_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ImageInformation.image_install_script)
+}
+inline ::std::string* ImageInformation::mutable_image_install_script() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ImageInformation.image_install_script)
+  return image_install_script_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ImageInformation::release_image_install_script() {
+  // @@protoc_insertion_point(field_release:dmi.ImageInformation.image_install_script)
+  
+  return image_install_script_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ImageInformation::set_allocated_image_install_script(::std::string* image_install_script) {
+  if (image_install_script != nullptr) {
+    
+  } else {
+    
+  }
+  image_install_script_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), image_install_script);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ImageInformation.image_install_script)
+}
+
+// string image_url = 3;
+inline void ImageInformation::clear_image_url() {
+  image_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ImageInformation::image_url() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageInformation.image_url)
+  return image_url_.GetNoArena();
+}
+inline void ImageInformation::set_image_url(const ::std::string& value) {
+  
+  image_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ImageInformation.image_url)
+}
+#if LANG_CXX11
+inline void ImageInformation::set_image_url(::std::string&& value) {
+  
+  image_url_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageInformation.image_url)
+}
+#endif
+inline void ImageInformation::set_image_url(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  image_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ImageInformation.image_url)
+}
+inline void ImageInformation::set_image_url(const char* value, size_t size) {
+  
+  image_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ImageInformation.image_url)
+}
+inline ::std::string* ImageInformation::mutable_image_url() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ImageInformation.image_url)
+  return image_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ImageInformation::release_image_url() {
+  // @@protoc_insertion_point(field_release:dmi.ImageInformation.image_url)
+  
+  return image_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ImageInformation::set_allocated_image_url(::std::string* image_url) {
+  if (image_url != nullptr) {
+    
+  } else {
+    
+  }
+  image_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), image_url);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ImageInformation.image_url)
+}
+
+// string sha256sum = 5;
+inline void ImageInformation::clear_sha256sum() {
+  sha256sum_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ImageInformation::sha256sum() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageInformation.sha256sum)
+  return sha256sum_.GetNoArena();
+}
+inline void ImageInformation::set_sha256sum(const ::std::string& value) {
+  
+  sha256sum_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ImageInformation.sha256sum)
+}
+#if LANG_CXX11
+inline void ImageInformation::set_sha256sum(::std::string&& value) {
+  
+  sha256sum_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageInformation.sha256sum)
+}
+#endif
+inline void ImageInformation::set_sha256sum(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  sha256sum_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ImageInformation.sha256sum)
+}
+inline void ImageInformation::set_sha256sum(const char* value, size_t size) {
+  
+  sha256sum_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ImageInformation.sha256sum)
+}
+inline ::std::string* ImageInformation::mutable_sha256sum() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ImageInformation.sha256sum)
+  return sha256sum_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ImageInformation::release_sha256sum() {
+  // @@protoc_insertion_point(field_release:dmi.ImageInformation.sha256sum)
+  
+  return sha256sum_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ImageInformation::set_allocated_sha256sum(::std::string* sha256sum) {
+  if (sha256sum != nullptr) {
+    
+  } else {
+    
+  }
+  sha256sum_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), sha256sum);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ImageInformation.sha256sum)
+}
+
+// -------------------------------------------------------------------
+
+// ImageStatus
+
+// .dmi.Status status = 1;
+inline void ImageStatus::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status ImageStatus::status() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageStatus.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void ImageStatus::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ImageStatus.status)
+}
+
+// .dmi.ImageStatus.Reason reason = 2;
+inline void ImageStatus::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::ImageStatus_Reason ImageStatus::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageStatus.reason)
+  return static_cast< ::dmi::ImageStatus_Reason >(reason_);
+}
+inline void ImageStatus::set_reason(::dmi::ImageStatus_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ImageStatus.reason)
+}
+
+// .dmi.ImageStatus.ImageState state = 3;
+inline void ImageStatus::clear_state() {
+  state_ = 0;
+}
+inline ::dmi::ImageStatus_ImageState ImageStatus::state() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageStatus.state)
+  return static_cast< ::dmi::ImageStatus_ImageState >(state_);
+}
+inline void ImageStatus::set_state(::dmi::ImageStatus_ImageState value) {
+  
+  state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ImageStatus.state)
+}
+
+// string description = 4;
+inline void ImageStatus::clear_description() {
+  description_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ImageStatus::description() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageStatus.description)
+  return description_.GetNoArena();
+}
+inline void ImageStatus::set_description(const ::std::string& value) {
+  
+  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ImageStatus.description)
+}
+#if LANG_CXX11
+inline void ImageStatus::set_description(::std::string&& value) {
+  
+  description_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageStatus.description)
+}
+#endif
+inline void ImageStatus::set_description(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ImageStatus.description)
+}
+inline void ImageStatus::set_description(const char* value, size_t size) {
+  
+  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ImageStatus.description)
+}
+inline ::std::string* ImageStatus::mutable_description() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ImageStatus.description)
+  return description_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ImageStatus::release_description() {
+  // @@protoc_insertion_point(field_release:dmi.ImageStatus.description)
+  
+  return description_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ImageStatus::set_allocated_description(::std::string* description) {
+  if (description != nullptr) {
+    
+  } else {
+    
+  }
+  description_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), description);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ImageStatus.description)
+}
+
+// string reason_detail = 5;
+inline void ImageStatus::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ImageStatus::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.ImageStatus.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void ImageStatus::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ImageStatus.reason_detail)
+}
+#if LANG_CXX11
+inline void ImageStatus::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageStatus.reason_detail)
+}
+#endif
+inline void ImageStatus::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.ImageStatus.reason_detail)
+}
+inline void ImageStatus::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.ImageStatus.reason_detail)
+}
+inline ::std::string* ImageStatus::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ImageStatus.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ImageStatus::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.ImageStatus.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ImageStatus::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.ImageStatus.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::ImageStatus_ImageState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ImageStatus_ImageState>() {
+  return ::dmi::ImageStatus_ImageState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ImageStatus_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ImageStatus_Reason>() {
+  return ::dmi::ImageStatus_Reason_descriptor();
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#include <google/protobuf/port_undef.inc>
+#endif  // PROTOBUF_INCLUDED_dmi_2fsw_5fimage_2eproto
diff --git a/cpp/dmi/sw_management_service.pb.cc b/cpp/dmi/sw_management_service.pb.cc
new file mode 100644
index 0000000..508dd63
--- /dev/null
+++ b/cpp/dmi/sw_management_service.pb.cc
@@ -0,0 +1,3207 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/sw_management_service.proto
+
+#include "dmi/sw_management_service.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fsw_5fimage_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ImageVersion_dmi_2fsw_5fimage_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fsw_5fimage_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ImageInformation_dmi_2fsw_5fimage_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fsw_5fmanagement_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_SoftwareVersionInformation_dmi_2fsw_5fmanagement_5fservice_2eproto;
+namespace dmi {
+class SoftwareVersionInformationDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<SoftwareVersionInformation> _instance;
+} _SoftwareVersionInformation_default_instance_;
+class GetSoftwareVersionInformationResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<GetSoftwareVersionInformationResponse> _instance;
+} _GetSoftwareVersionInformationResponse_default_instance_;
+class DownloadImageRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<DownloadImageRequest> _instance;
+} _DownloadImageRequest_default_instance_;
+class ConfigRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ConfigRequest> _instance;
+} _ConfigRequest_default_instance_;
+class ConfigResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ConfigResponse> _instance;
+} _ConfigResponse_default_instance_;
+class StartupConfigInfoRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<StartupConfigInfoRequest> _instance;
+} _StartupConfigInfoRequest_default_instance_;
+class StartupConfigInfoResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<StartupConfigInfoResponse> _instance;
+} _StartupConfigInfoResponse_default_instance_;
+}  // namespace dmi
+static void InitDefaultsSoftwareVersionInformation_dmi_2fsw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_SoftwareVersionInformation_default_instance_;
+    new (ptr) ::dmi::SoftwareVersionInformation();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::SoftwareVersionInformation::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_SoftwareVersionInformation_dmi_2fsw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsSoftwareVersionInformation_dmi_2fsw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_ImageVersion_dmi_2fsw_5fimage_2eproto.base,}};
+
+static void InitDefaultsGetSoftwareVersionInformationResponse_dmi_2fsw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_GetSoftwareVersionInformationResponse_default_instance_;
+    new (ptr) ::dmi::GetSoftwareVersionInformationResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::GetSoftwareVersionInformationResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_GetSoftwareVersionInformationResponse_dmi_2fsw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsGetSoftwareVersionInformationResponse_dmi_2fsw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_SoftwareVersionInformation_dmi_2fsw_5fmanagement_5fservice_2eproto.base,}};
+
+static void InitDefaultsDownloadImageRequest_dmi_2fsw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_DownloadImageRequest_default_instance_;
+    new (ptr) ::dmi::DownloadImageRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::DownloadImageRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_DownloadImageRequest_dmi_2fsw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsDownloadImageRequest_dmi_2fsw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,
+      &scc_info_ImageInformation_dmi_2fsw_5fimage_2eproto.base,}};
+
+static void InitDefaultsConfigRequest_dmi_2fsw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ConfigRequest_default_instance_;
+    new (ptr) ::dmi::ConfigRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ConfigRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ConfigRequest_dmi_2fsw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsConfigRequest_dmi_2fsw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsConfigResponse_dmi_2fsw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ConfigResponse_default_instance_;
+    new (ptr) ::dmi::ConfigResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ConfigResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_ConfigResponse_dmi_2fsw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsConfigResponse_dmi_2fsw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsStartupConfigInfoRequest_dmi_2fsw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_StartupConfigInfoRequest_default_instance_;
+    new (ptr) ::dmi::StartupConfigInfoRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::StartupConfigInfoRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_StartupConfigInfoRequest_dmi_2fsw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsStartupConfigInfoRequest_dmi_2fsw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsStartupConfigInfoResponse_dmi_2fsw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_StartupConfigInfoResponse_default_instance_;
+    new (ptr) ::dmi::StartupConfigInfoResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::StartupConfigInfoResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_StartupConfigInfoResponse_dmi_2fsw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsStartupConfigInfoResponse_dmi_2fsw_5fmanagement_5fservice_2eproto}, {}};
+
+void InitDefaults_dmi_2fsw_5fmanagement_5fservice_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_SoftwareVersionInformation_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_GetSoftwareVersionInformationResponse_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_DownloadImageRequest_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ConfigRequest_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ConfigResponse_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_StartupConfigInfoRequest_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_StartupConfigInfoResponse_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+}
+
+::google::protobuf::Metadata file_level_metadata_dmi_2fsw_5fmanagement_5fservice_2eproto[7];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fsw_5fmanagement_5fservice_2eproto[3];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fsw_5fmanagement_5fservice_2eproto = nullptr;
+
+const ::google::protobuf::uint32 TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::SoftwareVersionInformation, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::SoftwareVersionInformation, active_versions_),
+  PROTOBUF_FIELD_OFFSET(::dmi::SoftwareVersionInformation, standby_versions_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetSoftwareVersionInformationResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::GetSoftwareVersionInformationResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetSoftwareVersionInformationResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetSoftwareVersionInformationResponse, info_),
+  PROTOBUF_FIELD_OFFSET(::dmi::GetSoftwareVersionInformationResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::DownloadImageRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::DownloadImageRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::DownloadImageRequest, image_info_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ConfigRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ConfigRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ConfigRequest, config_url_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ConfigResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ConfigResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ConfigResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ConfigResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::StartupConfigInfoRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::StartupConfigInfoRequest, device_uuid_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::StartupConfigInfoResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::StartupConfigInfoResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StartupConfigInfoResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StartupConfigInfoResponse, config_url_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StartupConfigInfoResponse, version_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StartupConfigInfoResponse, reason_detail_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  { 0, -1, sizeof(::dmi::SoftwareVersionInformation)},
+  { 7, -1, sizeof(::dmi::GetSoftwareVersionInformationResponse)},
+  { 16, -1, sizeof(::dmi::DownloadImageRequest)},
+  { 23, -1, sizeof(::dmi::ConfigRequest)},
+  { 30, -1, sizeof(::dmi::ConfigResponse)},
+  { 38, -1, sizeof(::dmi::StartupConfigInfoRequest)},
+  { 44, -1, sizeof(::dmi::StartupConfigInfoResponse)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_SoftwareVersionInformation_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_GetSoftwareVersionInformationResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_DownloadImageRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ConfigRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ConfigResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_StartupConfigInfoRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_StartupConfigInfoResponse_default_instance_),
+};
+
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto = {
+  {}, AddDescriptors_dmi_2fsw_5fmanagement_5fservice_2eproto, "dmi/sw_management_service.proto", schemas,
+  file_default_instances, TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto::offsets,
+  file_level_metadata_dmi_2fsw_5fmanagement_5fservice_2eproto, 7, file_level_enum_descriptors_dmi_2fsw_5fmanagement_5fservice_2eproto, file_level_service_descriptors_dmi_2fsw_5fmanagement_5fservice_2eproto,
+};
+
+const char descriptor_table_protodef_dmi_2fsw_5fmanagement_5fservice_2eproto[] =
+  "\n\037dmi/sw_management_service.proto\022\003dmi\032\021"
+  "dmi/commons.proto\032\014dmi/hw.proto\032\022dmi/sw_"
+  "image.proto\"u\n\032SoftwareVersionInformatio"
+  "n\022*\n\017active_versions\030\001 \003(\0132\021.dmi.ImageVe"
+  "rsion\022+\n\020standby_versions\030\002 \003(\0132\021.dmi.Im"
+  "ageVersion\"\255\002\n%GetSoftwareVersionInforma"
+  "tionResponse\022\033\n\006status\030\001 \001(\0162\013.dmi.Statu"
+  "s\022A\n\006reason\030\002 \001(\01621.dmi.GetSoftwareVersi"
+  "onInformationResponse.Reason\022-\n\004info\030\003 \001"
+  "(\0132\037.dmi.SoftwareVersionInformation\022\025\n\rr"
+  "eason_detail\030\004 \001(\t\"^\n\006Reason\022\024\n\020UNDEFINE"
+  "D_REASON\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INTERN"
+  "AL_ERROR\020\002\022\026\n\022DEVICE_UNREACHABLE\020\003\"a\n\024Do"
+  "wnloadImageRequest\022\036\n\013device_uuid\030\001 \001(\0132"
+  "\t.dmi.Uuid\022)\n\nimage_info\030\002 \001(\0132\025.dmi.Ima"
+  "geInformation\"C\n\rConfigRequest\022\036\n\013device"
+  "_uuid\030\001 \001(\0132\t.dmi.Uuid\022\022\n\nconfig_url\030\002 \001"
+  "(\t\"\243\002\n\016ConfigResponse\022\033\n\006status\030\001 \001(\0162\013."
+  "dmi.Status\022*\n\006reason\030\002 \001(\0162\032.dmi.ConfigR"
+  "esponse.Reason\022\025\n\rreason_detail\030\003 \001(\t\"\260\001"
+  "\n\006Reason\022\024\n\020UNDEFINED_REASON\020\000\022\022\n\016UNKNOW"
+  "N_DEVICE\020\001\022\022\n\016INTERNAL_ERROR\020\002\022\031\n\025ERROR_"
+  "FETCHING_CONFIG\020\003\022\022\n\016INVALID_CONFIG\020\004\022!\n"
+  "\035OPERATION_ALREADY_IN_PROGRESS\020\005\022\026\n\022DEVI"
+  "CE_UNREACHABLE\020\006\":\n\030StartupConfigInfoReq"
+  "uest\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uuid\"\213\002\n"
+  "\031StartupConfigInfoResponse\022\033\n\006status\030\001 \001"
+  "(\0162\013.dmi.Status\0225\n\006reason\030\002 \001(\0162%.dmi.St"
+  "artupConfigInfoResponse.Reason\022\022\n\nconfig"
+  "_url\030\003 \001(\t\022\017\n\007version\030\004 \001(\t\022\025\n\rreason_de"
+  "tail\030\005 \001(\t\"^\n\006Reason\022\024\n\020UNDEFINED_REASON"
+  "\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INTERNAL_ERROR"
+  "\020\002\022\026\n\022DEVICE_UNREACHABLE\020\0032\316\003\n\037NativeSof"
+  "twareManagementService\022Q\n\022GetSoftwareVer"
+  "sion\022\017.dmi.HardwareID\032*.dmi.GetSoftwareV"
+  "ersionInformationResponse\022>\n\rDownloadIma"
+  "ge\022\031.dmi.DownloadImageRequest\032\020.dmi.Imag"
+  "eStatus0\001\0224\n\rActivateImage\022\017.dmi.Hardwar"
+  "eID\032\020.dmi.ImageStatus0\001\022;\n\024RevertToStand"
+  "byImage\022\017.dmi.HardwareID\032\020.dmi.ImageStat"
+  "us0\001\022G\n\032UpdateStartupConfiguration\022\022.dmi"
+  ".ConfigRequest\032\023.dmi.ConfigResponse0\001\022\\\n"
+  "\033GetStartupConfigurationInfo\022\035.dmi.Start"
+  "upConfigInfoRequest\032\036.dmi.StartupConfigI"
+  "nfoResponseB;Z9github.com/opencord/devic"
+  "e-management-interface/v3/go/dmib\006proto3"
+  ;
+::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fsw_5fmanagement_5fservice_2eproto = {
+  false, InitDefaults_dmi_2fsw_5fmanagement_5fservice_2eproto, 
+  descriptor_table_protodef_dmi_2fsw_5fmanagement_5fservice_2eproto,
+  "dmi/sw_management_service.proto", &assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto, 1840,
+};
+
+void AddDescriptors_dmi_2fsw_5fmanagement_5fservice_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[3] =
+  {
+    ::AddDescriptors_dmi_2fcommons_2eproto,
+    ::AddDescriptors_dmi_2fhw_2eproto,
+    ::AddDescriptors_dmi_2fsw_5fimage_2eproto,
+  };
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_dmi_2fsw_5fmanagement_5fservice_2eproto, deps, 3);
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_dmi_2fsw_5fmanagement_5fservice_2eproto = []() { AddDescriptors_dmi_2fsw_5fmanagement_5fservice_2eproto(); return true; }();
+namespace dmi {
+const ::google::protobuf::EnumDescriptor* GetSoftwareVersionInformationResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fsw_5fmanagement_5fservice_2eproto[0];
+}
+bool GetSoftwareVersionInformationResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse::UNDEFINED_REASON;
+const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse::UNKNOWN_DEVICE;
+const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse::INTERNAL_ERROR;
+const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse::DEVICE_UNREACHABLE;
+const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse::Reason_MIN;
+const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse::Reason_MAX;
+const int GetSoftwareVersionInformationResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* ConfigResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fsw_5fmanagement_5fservice_2eproto[1];
+}
+bool ConfigResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const ConfigResponse_Reason ConfigResponse::UNDEFINED_REASON;
+const ConfigResponse_Reason ConfigResponse::UNKNOWN_DEVICE;
+const ConfigResponse_Reason ConfigResponse::INTERNAL_ERROR;
+const ConfigResponse_Reason ConfigResponse::ERROR_FETCHING_CONFIG;
+const ConfigResponse_Reason ConfigResponse::INVALID_CONFIG;
+const ConfigResponse_Reason ConfigResponse::OPERATION_ALREADY_IN_PROGRESS;
+const ConfigResponse_Reason ConfigResponse::DEVICE_UNREACHABLE;
+const ConfigResponse_Reason ConfigResponse::Reason_MIN;
+const ConfigResponse_Reason ConfigResponse::Reason_MAX;
+const int ConfigResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* StartupConfigInfoResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fsw_5fmanagement_5fservice_2eproto[2];
+}
+bool StartupConfigInfoResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const StartupConfigInfoResponse_Reason StartupConfigInfoResponse::UNDEFINED_REASON;
+const StartupConfigInfoResponse_Reason StartupConfigInfoResponse::UNKNOWN_DEVICE;
+const StartupConfigInfoResponse_Reason StartupConfigInfoResponse::INTERNAL_ERROR;
+const StartupConfigInfoResponse_Reason StartupConfigInfoResponse::DEVICE_UNREACHABLE;
+const StartupConfigInfoResponse_Reason StartupConfigInfoResponse::Reason_MIN;
+const StartupConfigInfoResponse_Reason StartupConfigInfoResponse::Reason_MAX;
+const int StartupConfigInfoResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+// ===================================================================
+
+void SoftwareVersionInformation::InitAsDefaultInstance() {
+}
+class SoftwareVersionInformation::HasBitSetters {
+ public:
+};
+
+void SoftwareVersionInformation::clear_active_versions() {
+  active_versions_.Clear();
+}
+void SoftwareVersionInformation::clear_standby_versions() {
+  standby_versions_.Clear();
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int SoftwareVersionInformation::kActiveVersionsFieldNumber;
+const int SoftwareVersionInformation::kStandbyVersionsFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+SoftwareVersionInformation::SoftwareVersionInformation()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.SoftwareVersionInformation)
+}
+SoftwareVersionInformation::SoftwareVersionInformation(const SoftwareVersionInformation& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      active_versions_(from.active_versions_),
+      standby_versions_(from.standby_versions_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  // @@protoc_insertion_point(copy_constructor:dmi.SoftwareVersionInformation)
+}
+
+void SoftwareVersionInformation::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_SoftwareVersionInformation_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+}
+
+SoftwareVersionInformation::~SoftwareVersionInformation() {
+  // @@protoc_insertion_point(destructor:dmi.SoftwareVersionInformation)
+  SharedDtor();
+}
+
+void SoftwareVersionInformation::SharedDtor() {
+}
+
+void SoftwareVersionInformation::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const SoftwareVersionInformation& SoftwareVersionInformation::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_SoftwareVersionInformation_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void SoftwareVersionInformation::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.SoftwareVersionInformation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  active_versions_.Clear();
+  standby_versions_.Clear();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* SoftwareVersionInformation::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<SoftwareVersionInformation*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // repeated .dmi.ImageVersion active_versions = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::ImageVersion::_InternalParse;
+          object = msg->add_active_versions();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
+        break;
+      }
+      // repeated .dmi.ImageVersion standby_versions = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::ImageVersion::_InternalParse;
+          object = msg->add_standby_versions();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool SoftwareVersionInformation::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.SoftwareVersionInformation)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated .dmi.ImageVersion active_versions = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_active_versions()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated .dmi.ImageVersion standby_versions = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_standby_versions()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.SoftwareVersionInformation)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.SoftwareVersionInformation)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void SoftwareVersionInformation::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.SoftwareVersionInformation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // repeated .dmi.ImageVersion active_versions = 1;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->active_versions_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1,
+      this->active_versions(static_cast<int>(i)),
+      output);
+  }
+
+  // repeated .dmi.ImageVersion standby_versions = 2;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->standby_versions_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2,
+      this->standby_versions(static_cast<int>(i)),
+      output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.SoftwareVersionInformation)
+}
+
+::google::protobuf::uint8* SoftwareVersionInformation::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.SoftwareVersionInformation)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // repeated .dmi.ImageVersion active_versions = 1;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->active_versions_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, this->active_versions(static_cast<int>(i)), target);
+  }
+
+  // repeated .dmi.ImageVersion standby_versions = 2;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->standby_versions_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, this->standby_versions(static_cast<int>(i)), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.SoftwareVersionInformation)
+  return target;
+}
+
+size_t SoftwareVersionInformation::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.SoftwareVersionInformation)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated .dmi.ImageVersion active_versions = 1;
+  {
+    unsigned int count = static_cast<unsigned int>(this->active_versions_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->active_versions(static_cast<int>(i)));
+    }
+  }
+
+  // repeated .dmi.ImageVersion standby_versions = 2;
+  {
+    unsigned int count = static_cast<unsigned int>(this->standby_versions_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->standby_versions(static_cast<int>(i)));
+    }
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void SoftwareVersionInformation::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.SoftwareVersionInformation)
+  GOOGLE_DCHECK_NE(&from, this);
+  const SoftwareVersionInformation* source =
+      ::google::protobuf::DynamicCastToGenerated<SoftwareVersionInformation>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.SoftwareVersionInformation)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.SoftwareVersionInformation)
+    MergeFrom(*source);
+  }
+}
+
+void SoftwareVersionInformation::MergeFrom(const SoftwareVersionInformation& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.SoftwareVersionInformation)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  active_versions_.MergeFrom(from.active_versions_);
+  standby_versions_.MergeFrom(from.standby_versions_);
+}
+
+void SoftwareVersionInformation::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.SoftwareVersionInformation)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void SoftwareVersionInformation::CopyFrom(const SoftwareVersionInformation& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.SoftwareVersionInformation)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool SoftwareVersionInformation::IsInitialized() const {
+  return true;
+}
+
+void SoftwareVersionInformation::Swap(SoftwareVersionInformation* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void SoftwareVersionInformation::InternalSwap(SoftwareVersionInformation* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  CastToBase(&active_versions_)->InternalSwap(CastToBase(&other->active_versions_));
+  CastToBase(&standby_versions_)->InternalSwap(CastToBase(&other->standby_versions_));
+}
+
+::google::protobuf::Metadata SoftwareVersionInformation::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void GetSoftwareVersionInformationResponse::InitAsDefaultInstance() {
+  ::dmi::_GetSoftwareVersionInformationResponse_default_instance_._instance.get_mutable()->info_ = const_cast< ::dmi::SoftwareVersionInformation*>(
+      ::dmi::SoftwareVersionInformation::internal_default_instance());
+}
+class GetSoftwareVersionInformationResponse::HasBitSetters {
+ public:
+  static const ::dmi::SoftwareVersionInformation& info(const GetSoftwareVersionInformationResponse* msg);
+};
+
+const ::dmi::SoftwareVersionInformation&
+GetSoftwareVersionInformationResponse::HasBitSetters::info(const GetSoftwareVersionInformationResponse* msg) {
+  return *msg->info_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GetSoftwareVersionInformationResponse::kStatusFieldNumber;
+const int GetSoftwareVersionInformationResponse::kReasonFieldNumber;
+const int GetSoftwareVersionInformationResponse::kInfoFieldNumber;
+const int GetSoftwareVersionInformationResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GetSoftwareVersionInformationResponse::GetSoftwareVersionInformationResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.GetSoftwareVersionInformationResponse)
+}
+GetSoftwareVersionInformationResponse::GetSoftwareVersionInformationResponse(const GetSoftwareVersionInformationResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_info()) {
+    info_ = new ::dmi::SoftwareVersionInformation(*from.info_);
+  } else {
+    info_ = nullptr;
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.GetSoftwareVersionInformationResponse)
+}
+
+void GetSoftwareVersionInformationResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_GetSoftwareVersionInformationResponse_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&info_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&info_)) + sizeof(reason_));
+}
+
+GetSoftwareVersionInformationResponse::~GetSoftwareVersionInformationResponse() {
+  // @@protoc_insertion_point(destructor:dmi.GetSoftwareVersionInformationResponse)
+  SharedDtor();
+}
+
+void GetSoftwareVersionInformationResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete info_;
+}
+
+void GetSoftwareVersionInformationResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const GetSoftwareVersionInformationResponse& GetSoftwareVersionInformationResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_GetSoftwareVersionInformationResponse_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void GetSoftwareVersionInformationResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.GetSoftwareVersionInformationResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && info_ != nullptr) {
+    delete info_;
+  }
+  info_ = nullptr;
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* GetSoftwareVersionInformationResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<GetSoftwareVersionInformationResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.GetSoftwareVersionInformationResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::GetSoftwareVersionInformationResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.SoftwareVersionInformation info = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::SoftwareVersionInformation::_InternalParse;
+        object = msg->mutable_info();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.GetSoftwareVersionInformationResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool GetSoftwareVersionInformationResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.GetSoftwareVersionInformationResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.GetSoftwareVersionInformationResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::GetSoftwareVersionInformationResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.SoftwareVersionInformation info = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_info()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.GetSoftwareVersionInformationResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.GetSoftwareVersionInformationResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.GetSoftwareVersionInformationResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void GetSoftwareVersionInformationResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.GetSoftwareVersionInformationResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.GetSoftwareVersionInformationResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // .dmi.SoftwareVersionInformation info = 3;
+  if (this->has_info()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::info(this), output);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetSoftwareVersionInformationResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.GetSoftwareVersionInformationResponse)
+}
+
+::google::protobuf::uint8* GetSoftwareVersionInformationResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.GetSoftwareVersionInformationResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.GetSoftwareVersionInformationResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // .dmi.SoftwareVersionInformation info = 3;
+  if (this->has_info()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::info(this), target);
+  }
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.GetSoftwareVersionInformationResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.GetSoftwareVersionInformationResponse)
+  return target;
+}
+
+size_t GetSoftwareVersionInformationResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.GetSoftwareVersionInformationResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 4;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.SoftwareVersionInformation info = 3;
+  if (this->has_info()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *info_);
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.GetSoftwareVersionInformationResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void GetSoftwareVersionInformationResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.GetSoftwareVersionInformationResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const GetSoftwareVersionInformationResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<GetSoftwareVersionInformationResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.GetSoftwareVersionInformationResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.GetSoftwareVersionInformationResponse)
+    MergeFrom(*source);
+  }
+}
+
+void GetSoftwareVersionInformationResponse::MergeFrom(const GetSoftwareVersionInformationResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.GetSoftwareVersionInformationResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.has_info()) {
+    mutable_info()->::dmi::SoftwareVersionInformation::MergeFrom(from.info());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void GetSoftwareVersionInformationResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.GetSoftwareVersionInformationResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void GetSoftwareVersionInformationResponse::CopyFrom(const GetSoftwareVersionInformationResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.GetSoftwareVersionInformationResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GetSoftwareVersionInformationResponse::IsInitialized() const {
+  return true;
+}
+
+void GetSoftwareVersionInformationResponse::Swap(GetSoftwareVersionInformationResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void GetSoftwareVersionInformationResponse::InternalSwap(GetSoftwareVersionInformationResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(info_, other->info_);
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata GetSoftwareVersionInformationResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void DownloadImageRequest::InitAsDefaultInstance() {
+  ::dmi::_DownloadImageRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_DownloadImageRequest_default_instance_._instance.get_mutable()->image_info_ = const_cast< ::dmi::ImageInformation*>(
+      ::dmi::ImageInformation::internal_default_instance());
+}
+class DownloadImageRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const DownloadImageRequest* msg);
+  static const ::dmi::ImageInformation& image_info(const DownloadImageRequest* msg);
+};
+
+const ::dmi::Uuid&
+DownloadImageRequest::HasBitSetters::device_uuid(const DownloadImageRequest* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::ImageInformation&
+DownloadImageRequest::HasBitSetters::image_info(const DownloadImageRequest* msg) {
+  return *msg->image_info_;
+}
+void DownloadImageRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void DownloadImageRequest::clear_image_info() {
+  if (GetArenaNoVirtual() == nullptr && image_info_ != nullptr) {
+    delete image_info_;
+  }
+  image_info_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int DownloadImageRequest::kDeviceUuidFieldNumber;
+const int DownloadImageRequest::kImageInfoFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+DownloadImageRequest::DownloadImageRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.DownloadImageRequest)
+}
+DownloadImageRequest::DownloadImageRequest(const DownloadImageRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  if (from.has_image_info()) {
+    image_info_ = new ::dmi::ImageInformation(*from.image_info_);
+  } else {
+    image_info_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.DownloadImageRequest)
+}
+
+void DownloadImageRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_DownloadImageRequest_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&image_info_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(image_info_));
+}
+
+DownloadImageRequest::~DownloadImageRequest() {
+  // @@protoc_insertion_point(destructor:dmi.DownloadImageRequest)
+  SharedDtor();
+}
+
+void DownloadImageRequest::SharedDtor() {
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (this != internal_default_instance()) delete image_info_;
+}
+
+void DownloadImageRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const DownloadImageRequest& DownloadImageRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_DownloadImageRequest_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void DownloadImageRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.DownloadImageRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && image_info_ != nullptr) {
+    delete image_info_;
+  }
+  image_info_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* DownloadImageRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<DownloadImageRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ImageInformation image_info = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ImageInformation::_InternalParse;
+        object = msg->mutable_image_info();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool DownloadImageRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.DownloadImageRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ImageInformation image_info = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_image_info()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.DownloadImageRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.DownloadImageRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void DownloadImageRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.DownloadImageRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.ImageInformation image_info = 2;
+  if (this->has_image_info()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::image_info(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.DownloadImageRequest)
+}
+
+::google::protobuf::uint8* DownloadImageRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.DownloadImageRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.ImageInformation image_info = 2;
+  if (this->has_image_info()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::image_info(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.DownloadImageRequest)
+  return target;
+}
+
+size_t DownloadImageRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.DownloadImageRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.ImageInformation image_info = 2;
+  if (this->has_image_info()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *image_info_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void DownloadImageRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.DownloadImageRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const DownloadImageRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<DownloadImageRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.DownloadImageRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.DownloadImageRequest)
+    MergeFrom(*source);
+  }
+}
+
+void DownloadImageRequest::MergeFrom(const DownloadImageRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.DownloadImageRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.has_image_info()) {
+    mutable_image_info()->::dmi::ImageInformation::MergeFrom(from.image_info());
+  }
+}
+
+void DownloadImageRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.DownloadImageRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void DownloadImageRequest::CopyFrom(const DownloadImageRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.DownloadImageRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool DownloadImageRequest::IsInitialized() const {
+  return true;
+}
+
+void DownloadImageRequest::Swap(DownloadImageRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void DownloadImageRequest::InternalSwap(DownloadImageRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(device_uuid_, other->device_uuid_);
+  swap(image_info_, other->image_info_);
+}
+
+::google::protobuf::Metadata DownloadImageRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ConfigRequest::InitAsDefaultInstance() {
+  ::dmi::_ConfigRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class ConfigRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const ConfigRequest* msg);
+};
+
+const ::dmi::Uuid&
+ConfigRequest::HasBitSetters::device_uuid(const ConfigRequest* msg) {
+  return *msg->device_uuid_;
+}
+void ConfigRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ConfigRequest::kDeviceUuidFieldNumber;
+const int ConfigRequest::kConfigUrlFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ConfigRequest::ConfigRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ConfigRequest)
+}
+ConfigRequest::ConfigRequest(const ConfigRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  config_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.config_url().size() > 0) {
+    config_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.config_url_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.ConfigRequest)
+}
+
+void ConfigRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ConfigRequest_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  config_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  device_uuid_ = nullptr;
+}
+
+ConfigRequest::~ConfigRequest() {
+  // @@protoc_insertion_point(destructor:dmi.ConfigRequest)
+  SharedDtor();
+}
+
+void ConfigRequest::SharedDtor() {
+  config_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void ConfigRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ConfigRequest& ConfigRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ConfigRequest_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ConfigRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ConfigRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  config_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ConfigRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ConfigRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string config_url = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ConfigRequest.config_url");
+        object = msg->mutable_config_url();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ConfigRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ConfigRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string config_url = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_config_url()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->config_url().data(), static_cast<int>(this->config_url().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ConfigRequest.config_url"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ConfigRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ConfigRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ConfigRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ConfigRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // string config_url = 2;
+  if (this->config_url().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->config_url().data(), static_cast<int>(this->config_url().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ConfigRequest.config_url");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->config_url(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ConfigRequest)
+}
+
+::google::protobuf::uint8* ConfigRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ConfigRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // string config_url = 2;
+  if (this->config_url().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->config_url().data(), static_cast<int>(this->config_url().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ConfigRequest.config_url");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->config_url(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ConfigRequest)
+  return target;
+}
+
+size_t ConfigRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ConfigRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string config_url = 2;
+  if (this->config_url().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->config_url());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ConfigRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ConfigRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ConfigRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<ConfigRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ConfigRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ConfigRequest)
+    MergeFrom(*source);
+  }
+}
+
+void ConfigRequest::MergeFrom(const ConfigRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ConfigRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.config_url().size() > 0) {
+
+    config_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.config_url_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+}
+
+void ConfigRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ConfigRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ConfigRequest::CopyFrom(const ConfigRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ConfigRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ConfigRequest::IsInitialized() const {
+  return true;
+}
+
+void ConfigRequest::Swap(ConfigRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ConfigRequest::InternalSwap(ConfigRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  config_url_.Swap(&other->config_url_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+}
+
+::google::protobuf::Metadata ConfigRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ConfigResponse::InitAsDefaultInstance() {
+}
+class ConfigResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ConfigResponse::kStatusFieldNumber;
+const int ConfigResponse::kReasonFieldNumber;
+const int ConfigResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ConfigResponse::ConfigResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ConfigResponse)
+}
+ConfigResponse::ConfigResponse(const ConfigResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ConfigResponse)
+}
+
+void ConfigResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ConfigResponse_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+ConfigResponse::~ConfigResponse() {
+  // @@protoc_insertion_point(destructor:dmi.ConfigResponse)
+  SharedDtor();
+}
+
+void ConfigResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void ConfigResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ConfigResponse& ConfigResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ConfigResponse_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ConfigResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ConfigResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ConfigResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ConfigResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ConfigResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::ConfigResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ConfigResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ConfigResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ConfigResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ConfigResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::ConfigResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ConfigResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ConfigResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ConfigResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ConfigResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ConfigResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.ConfigResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ConfigResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ConfigResponse)
+}
+
+::google::protobuf::uint8* ConfigResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ConfigResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.ConfigResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ConfigResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ConfigResponse)
+  return target;
+}
+
+size_t ConfigResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ConfigResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.ConfigResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ConfigResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ConfigResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ConfigResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<ConfigResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ConfigResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ConfigResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ConfigResponse::MergeFrom(const ConfigResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ConfigResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void ConfigResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ConfigResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ConfigResponse::CopyFrom(const ConfigResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ConfigResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ConfigResponse::IsInitialized() const {
+  return true;
+}
+
+void ConfigResponse::Swap(ConfigResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ConfigResponse::InternalSwap(ConfigResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata ConfigResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void StartupConfigInfoRequest::InitAsDefaultInstance() {
+  ::dmi::_StartupConfigInfoRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class StartupConfigInfoRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const StartupConfigInfoRequest* msg);
+};
+
+const ::dmi::Uuid&
+StartupConfigInfoRequest::HasBitSetters::device_uuid(const StartupConfigInfoRequest* msg) {
+  return *msg->device_uuid_;
+}
+void StartupConfigInfoRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int StartupConfigInfoRequest::kDeviceUuidFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+StartupConfigInfoRequest::StartupConfigInfoRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.StartupConfigInfoRequest)
+}
+StartupConfigInfoRequest::StartupConfigInfoRequest(const StartupConfigInfoRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.StartupConfigInfoRequest)
+}
+
+void StartupConfigInfoRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_StartupConfigInfoRequest_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  device_uuid_ = nullptr;
+}
+
+StartupConfigInfoRequest::~StartupConfigInfoRequest() {
+  // @@protoc_insertion_point(destructor:dmi.StartupConfigInfoRequest)
+  SharedDtor();
+}
+
+void StartupConfigInfoRequest::SharedDtor() {
+  if (this != internal_default_instance()) delete device_uuid_;
+}
+
+void StartupConfigInfoRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const StartupConfigInfoRequest& StartupConfigInfoRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_StartupConfigInfoRequest_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void StartupConfigInfoRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.StartupConfigInfoRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* StartupConfigInfoRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<StartupConfigInfoRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool StartupConfigInfoRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.StartupConfigInfoRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.StartupConfigInfoRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.StartupConfigInfoRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void StartupConfigInfoRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.StartupConfigInfoRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.StartupConfigInfoRequest)
+}
+
+::google::protobuf::uint8* StartupConfigInfoRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.StartupConfigInfoRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.StartupConfigInfoRequest)
+  return target;
+}
+
+size_t StartupConfigInfoRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.StartupConfigInfoRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void StartupConfigInfoRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.StartupConfigInfoRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const StartupConfigInfoRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<StartupConfigInfoRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.StartupConfigInfoRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.StartupConfigInfoRequest)
+    MergeFrom(*source);
+  }
+}
+
+void StartupConfigInfoRequest::MergeFrom(const StartupConfigInfoRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.StartupConfigInfoRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+}
+
+void StartupConfigInfoRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.StartupConfigInfoRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void StartupConfigInfoRequest::CopyFrom(const StartupConfigInfoRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.StartupConfigInfoRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool StartupConfigInfoRequest::IsInitialized() const {
+  return true;
+}
+
+void StartupConfigInfoRequest::Swap(StartupConfigInfoRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void StartupConfigInfoRequest::InternalSwap(StartupConfigInfoRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(device_uuid_, other->device_uuid_);
+}
+
+::google::protobuf::Metadata StartupConfigInfoRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void StartupConfigInfoResponse::InitAsDefaultInstance() {
+}
+class StartupConfigInfoResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int StartupConfigInfoResponse::kStatusFieldNumber;
+const int StartupConfigInfoResponse::kReasonFieldNumber;
+const int StartupConfigInfoResponse::kConfigUrlFieldNumber;
+const int StartupConfigInfoResponse::kVersionFieldNumber;
+const int StartupConfigInfoResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+StartupConfigInfoResponse::StartupConfigInfoResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.StartupConfigInfoResponse)
+}
+StartupConfigInfoResponse::StartupConfigInfoResponse(const StartupConfigInfoResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  config_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.config_url().size() > 0) {
+    config_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.config_url_);
+  }
+  version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.version().size() > 0) {
+    version_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.version_);
+  }
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.StartupConfigInfoResponse)
+}
+
+void StartupConfigInfoResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_StartupConfigInfoResponse_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  config_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+StartupConfigInfoResponse::~StartupConfigInfoResponse() {
+  // @@protoc_insertion_point(destructor:dmi.StartupConfigInfoResponse)
+  SharedDtor();
+}
+
+void StartupConfigInfoResponse::SharedDtor() {
+  config_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  version_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void StartupConfigInfoResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const StartupConfigInfoResponse& StartupConfigInfoResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_StartupConfigInfoResponse_dmi_2fsw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void StartupConfigInfoResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.StartupConfigInfoResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  config_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* StartupConfigInfoResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<StartupConfigInfoResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.StartupConfigInfoResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::StartupConfigInfoResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string config_url = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.StartupConfigInfoResponse.config_url");
+        object = msg->mutable_config_url();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string version = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.StartupConfigInfoResponse.version");
+        object = msg->mutable_version();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string reason_detail = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.StartupConfigInfoResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool StartupConfigInfoResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.StartupConfigInfoResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.StartupConfigInfoResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::StartupConfigInfoResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string config_url = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_config_url()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->config_url().data(), static_cast<int>(this->config_url().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.StartupConfigInfoResponse.config_url"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string version = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_version()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->version().data(), static_cast<int>(this->version().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.StartupConfigInfoResponse.version"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.StartupConfigInfoResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.StartupConfigInfoResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.StartupConfigInfoResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void StartupConfigInfoResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.StartupConfigInfoResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.StartupConfigInfoResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string config_url = 3;
+  if (this->config_url().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->config_url().data(), static_cast<int>(this->config_url().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StartupConfigInfoResponse.config_url");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->config_url(), output);
+  }
+
+  // string version = 4;
+  if (this->version().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->version().data(), static_cast<int>(this->version().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StartupConfigInfoResponse.version");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->version(), output);
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StartupConfigInfoResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      5, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.StartupConfigInfoResponse)
+}
+
+::google::protobuf::uint8* StartupConfigInfoResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.StartupConfigInfoResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.StartupConfigInfoResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string config_url = 3;
+  if (this->config_url().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->config_url().data(), static_cast<int>(this->config_url().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StartupConfigInfoResponse.config_url");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->config_url(), target);
+  }
+
+  // string version = 4;
+  if (this->version().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->version().data(), static_cast<int>(this->version().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StartupConfigInfoResponse.version");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->version(), target);
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.StartupConfigInfoResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        5, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.StartupConfigInfoResponse)
+  return target;
+}
+
+size_t StartupConfigInfoResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.StartupConfigInfoResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string config_url = 3;
+  if (this->config_url().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->config_url());
+  }
+
+  // string version = 4;
+  if (this->version().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->version());
+  }
+
+  // string reason_detail = 5;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.StartupConfigInfoResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void StartupConfigInfoResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.StartupConfigInfoResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const StartupConfigInfoResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<StartupConfigInfoResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.StartupConfigInfoResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.StartupConfigInfoResponse)
+    MergeFrom(*source);
+  }
+}
+
+void StartupConfigInfoResponse::MergeFrom(const StartupConfigInfoResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.StartupConfigInfoResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.config_url().size() > 0) {
+
+    config_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.config_url_);
+  }
+  if (from.version().size() > 0) {
+
+    version_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.version_);
+  }
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void StartupConfigInfoResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.StartupConfigInfoResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void StartupConfigInfoResponse::CopyFrom(const StartupConfigInfoResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.StartupConfigInfoResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool StartupConfigInfoResponse::IsInitialized() const {
+  return true;
+}
+
+void StartupConfigInfoResponse::Swap(StartupConfigInfoResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void StartupConfigInfoResponse::InternalSwap(StartupConfigInfoResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  config_url_.Swap(&other->config_url_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  version_.Swap(&other->version_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata StartupConfigInfoResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fsw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fsw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> PROTOBUF_NOINLINE ::dmi::SoftwareVersionInformation* Arena::CreateMaybeMessage< ::dmi::SoftwareVersionInformation >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::SoftwareVersionInformation >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::GetSoftwareVersionInformationResponse* Arena::CreateMaybeMessage< ::dmi::GetSoftwareVersionInformationResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::GetSoftwareVersionInformationResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::DownloadImageRequest* Arena::CreateMaybeMessage< ::dmi::DownloadImageRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::DownloadImageRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ConfigRequest* Arena::CreateMaybeMessage< ::dmi::ConfigRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ConfigRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ConfigResponse* Arena::CreateMaybeMessage< ::dmi::ConfigResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ConfigResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::StartupConfigInfoRequest* Arena::CreateMaybeMessage< ::dmi::StartupConfigInfoRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::StartupConfigInfoRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::StartupConfigInfoResponse* Arena::CreateMaybeMessage< ::dmi::StartupConfigInfoResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::StartupConfigInfoResponse >(arena);
+}
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+#include <google/protobuf/port_undef.inc>
diff --git a/cpp/dmi/sw_management_service.pb.h b/cpp/dmi/sw_management_service.pb.h
new file mode 100644
index 0000000..2610c1a
--- /dev/null
+++ b/cpp/dmi/sw_management_service.pb.h
@@ -0,0 +1,1969 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/sw_management_service.proto
+
+#ifndef PROTOBUF_INCLUDED_dmi_2fsw_5fmanagement_5fservice_2eproto
+#define PROTOBUF_INCLUDED_dmi_2fsw_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 "dmi/sw_image.pb.h"
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_dmi_2fsw_5fmanagement_5fservice_2eproto
+
+// Internal implementation detail -- do not use these members.
+struct TableStruct_dmi_2fsw_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[7]
+    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_2fsw_5fmanagement_5fservice_2eproto();
+namespace dmi {
+class ConfigRequest;
+class ConfigRequestDefaultTypeInternal;
+extern ConfigRequestDefaultTypeInternal _ConfigRequest_default_instance_;
+class ConfigResponse;
+class ConfigResponseDefaultTypeInternal;
+extern ConfigResponseDefaultTypeInternal _ConfigResponse_default_instance_;
+class DownloadImageRequest;
+class DownloadImageRequestDefaultTypeInternal;
+extern DownloadImageRequestDefaultTypeInternal _DownloadImageRequest_default_instance_;
+class GetSoftwareVersionInformationResponse;
+class GetSoftwareVersionInformationResponseDefaultTypeInternal;
+extern GetSoftwareVersionInformationResponseDefaultTypeInternal _GetSoftwareVersionInformationResponse_default_instance_;
+class SoftwareVersionInformation;
+class SoftwareVersionInformationDefaultTypeInternal;
+extern SoftwareVersionInformationDefaultTypeInternal _SoftwareVersionInformation_default_instance_;
+class StartupConfigInfoRequest;
+class StartupConfigInfoRequestDefaultTypeInternal;
+extern StartupConfigInfoRequestDefaultTypeInternal _StartupConfigInfoRequest_default_instance_;
+class StartupConfigInfoResponse;
+class StartupConfigInfoResponseDefaultTypeInternal;
+extern StartupConfigInfoResponseDefaultTypeInternal _StartupConfigInfoResponse_default_instance_;
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> ::dmi::ConfigRequest* Arena::CreateMaybeMessage<::dmi::ConfigRequest>(Arena*);
+template<> ::dmi::ConfigResponse* Arena::CreateMaybeMessage<::dmi::ConfigResponse>(Arena*);
+template<> ::dmi::DownloadImageRequest* Arena::CreateMaybeMessage<::dmi::DownloadImageRequest>(Arena*);
+template<> ::dmi::GetSoftwareVersionInformationResponse* Arena::CreateMaybeMessage<::dmi::GetSoftwareVersionInformationResponse>(Arena*);
+template<> ::dmi::SoftwareVersionInformation* Arena::CreateMaybeMessage<::dmi::SoftwareVersionInformation>(Arena*);
+template<> ::dmi::StartupConfigInfoRequest* Arena::CreateMaybeMessage<::dmi::StartupConfigInfoRequest>(Arena*);
+template<> ::dmi::StartupConfigInfoResponse* Arena::CreateMaybeMessage<::dmi::StartupConfigInfoResponse>(Arena*);
+}  // namespace protobuf
+}  // namespace google
+namespace dmi {
+
+enum GetSoftwareVersionInformationResponse_Reason {
+  GetSoftwareVersionInformationResponse_Reason_UNDEFINED_REASON = 0,
+  GetSoftwareVersionInformationResponse_Reason_UNKNOWN_DEVICE = 1,
+  GetSoftwareVersionInformationResponse_Reason_INTERNAL_ERROR = 2,
+  GetSoftwareVersionInformationResponse_Reason_DEVICE_UNREACHABLE = 3,
+  GetSoftwareVersionInformationResponse_Reason_GetSoftwareVersionInformationResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  GetSoftwareVersionInformationResponse_Reason_GetSoftwareVersionInformationResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool GetSoftwareVersionInformationResponse_Reason_IsValid(int value);
+const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse_Reason_Reason_MIN = GetSoftwareVersionInformationResponse_Reason_UNDEFINED_REASON;
+const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse_Reason_Reason_MAX = GetSoftwareVersionInformationResponse_Reason_DEVICE_UNREACHABLE;
+const int GetSoftwareVersionInformationResponse_Reason_Reason_ARRAYSIZE = GetSoftwareVersionInformationResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* GetSoftwareVersionInformationResponse_Reason_descriptor();
+inline const ::std::string& GetSoftwareVersionInformationResponse_Reason_Name(GetSoftwareVersionInformationResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    GetSoftwareVersionInformationResponse_Reason_descriptor(), value);
+}
+inline bool GetSoftwareVersionInformationResponse_Reason_Parse(
+    const ::std::string& name, GetSoftwareVersionInformationResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<GetSoftwareVersionInformationResponse_Reason>(
+    GetSoftwareVersionInformationResponse_Reason_descriptor(), name, value);
+}
+enum ConfigResponse_Reason {
+  ConfigResponse_Reason_UNDEFINED_REASON = 0,
+  ConfigResponse_Reason_UNKNOWN_DEVICE = 1,
+  ConfigResponse_Reason_INTERNAL_ERROR = 2,
+  ConfigResponse_Reason_ERROR_FETCHING_CONFIG = 3,
+  ConfigResponse_Reason_INVALID_CONFIG = 4,
+  ConfigResponse_Reason_OPERATION_ALREADY_IN_PROGRESS = 5,
+  ConfigResponse_Reason_DEVICE_UNREACHABLE = 6,
+  ConfigResponse_Reason_ConfigResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ConfigResponse_Reason_ConfigResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ConfigResponse_Reason_IsValid(int value);
+const ConfigResponse_Reason ConfigResponse_Reason_Reason_MIN = ConfigResponse_Reason_UNDEFINED_REASON;
+const ConfigResponse_Reason ConfigResponse_Reason_Reason_MAX = ConfigResponse_Reason_DEVICE_UNREACHABLE;
+const int ConfigResponse_Reason_Reason_ARRAYSIZE = ConfigResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ConfigResponse_Reason_descriptor();
+inline const ::std::string& ConfigResponse_Reason_Name(ConfigResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ConfigResponse_Reason_descriptor(), value);
+}
+inline bool ConfigResponse_Reason_Parse(
+    const ::std::string& name, ConfigResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ConfigResponse_Reason>(
+    ConfigResponse_Reason_descriptor(), name, value);
+}
+enum StartupConfigInfoResponse_Reason {
+  StartupConfigInfoResponse_Reason_UNDEFINED_REASON = 0,
+  StartupConfigInfoResponse_Reason_UNKNOWN_DEVICE = 1,
+  StartupConfigInfoResponse_Reason_INTERNAL_ERROR = 2,
+  StartupConfigInfoResponse_Reason_DEVICE_UNREACHABLE = 3,
+  StartupConfigInfoResponse_Reason_StartupConfigInfoResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  StartupConfigInfoResponse_Reason_StartupConfigInfoResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool StartupConfigInfoResponse_Reason_IsValid(int value);
+const StartupConfigInfoResponse_Reason StartupConfigInfoResponse_Reason_Reason_MIN = StartupConfigInfoResponse_Reason_UNDEFINED_REASON;
+const StartupConfigInfoResponse_Reason StartupConfigInfoResponse_Reason_Reason_MAX = StartupConfigInfoResponse_Reason_DEVICE_UNREACHABLE;
+const int StartupConfigInfoResponse_Reason_Reason_ARRAYSIZE = StartupConfigInfoResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* StartupConfigInfoResponse_Reason_descriptor();
+inline const ::std::string& StartupConfigInfoResponse_Reason_Name(StartupConfigInfoResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    StartupConfigInfoResponse_Reason_descriptor(), value);
+}
+inline bool StartupConfigInfoResponse_Reason_Parse(
+    const ::std::string& name, StartupConfigInfoResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<StartupConfigInfoResponse_Reason>(
+    StartupConfigInfoResponse_Reason_descriptor(), name, value);
+}
+// ===================================================================
+
+class SoftwareVersionInformation final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.SoftwareVersionInformation) */ {
+ public:
+  SoftwareVersionInformation();
+  virtual ~SoftwareVersionInformation();
+
+  SoftwareVersionInformation(const SoftwareVersionInformation& from);
+
+  inline SoftwareVersionInformation& operator=(const SoftwareVersionInformation& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  SoftwareVersionInformation(SoftwareVersionInformation&& from) noexcept
+    : SoftwareVersionInformation() {
+    *this = ::std::move(from);
+  }
+
+  inline SoftwareVersionInformation& operator=(SoftwareVersionInformation&& 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 SoftwareVersionInformation& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const SoftwareVersionInformation* internal_default_instance() {
+    return reinterpret_cast<const SoftwareVersionInformation*>(
+               &_SoftwareVersionInformation_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    0;
+
+  void Swap(SoftwareVersionInformation* other);
+  friend void swap(SoftwareVersionInformation& a, SoftwareVersionInformation& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline SoftwareVersionInformation* New() const final {
+    return CreateMaybeMessage<SoftwareVersionInformation>(nullptr);
+  }
+
+  SoftwareVersionInformation* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<SoftwareVersionInformation>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const SoftwareVersionInformation& from);
+  void MergeFrom(const SoftwareVersionInformation& 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(SoftwareVersionInformation* 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.ImageVersion active_versions = 1;
+  int active_versions_size() const;
+  void clear_active_versions();
+  static const int kActiveVersionsFieldNumber = 1;
+  ::dmi::ImageVersion* mutable_active_versions(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >*
+      mutable_active_versions();
+  const ::dmi::ImageVersion& active_versions(int index) const;
+  ::dmi::ImageVersion* add_active_versions();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >&
+      active_versions() const;
+
+  // repeated .dmi.ImageVersion standby_versions = 2;
+  int standby_versions_size() const;
+  void clear_standby_versions();
+  static const int kStandbyVersionsFieldNumber = 2;
+  ::dmi::ImageVersion* mutable_standby_versions(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >*
+      mutable_standby_versions();
+  const ::dmi::ImageVersion& standby_versions(int index) const;
+  ::dmi::ImageVersion* add_standby_versions();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >&
+      standby_versions() const;
+
+  // @@protoc_insertion_point(class_scope:dmi.SoftwareVersionInformation)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion > active_versions_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion > standby_versions_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class GetSoftwareVersionInformationResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.GetSoftwareVersionInformationResponse) */ {
+ public:
+  GetSoftwareVersionInformationResponse();
+  virtual ~GetSoftwareVersionInformationResponse();
+
+  GetSoftwareVersionInformationResponse(const GetSoftwareVersionInformationResponse& from);
+
+  inline GetSoftwareVersionInformationResponse& operator=(const GetSoftwareVersionInformationResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  GetSoftwareVersionInformationResponse(GetSoftwareVersionInformationResponse&& from) noexcept
+    : GetSoftwareVersionInformationResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline GetSoftwareVersionInformationResponse& operator=(GetSoftwareVersionInformationResponse&& 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 GetSoftwareVersionInformationResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const GetSoftwareVersionInformationResponse* internal_default_instance() {
+    return reinterpret_cast<const GetSoftwareVersionInformationResponse*>(
+               &_GetSoftwareVersionInformationResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    1;
+
+  void Swap(GetSoftwareVersionInformationResponse* other);
+  friend void swap(GetSoftwareVersionInformationResponse& a, GetSoftwareVersionInformationResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline GetSoftwareVersionInformationResponse* New() const final {
+    return CreateMaybeMessage<GetSoftwareVersionInformationResponse>(nullptr);
+  }
+
+  GetSoftwareVersionInformationResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<GetSoftwareVersionInformationResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const GetSoftwareVersionInformationResponse& from);
+  void MergeFrom(const GetSoftwareVersionInformationResponse& 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(GetSoftwareVersionInformationResponse* 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 GetSoftwareVersionInformationResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    GetSoftwareVersionInformationResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    GetSoftwareVersionInformationResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    GetSoftwareVersionInformationResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    GetSoftwareVersionInformationResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return GetSoftwareVersionInformationResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    GetSoftwareVersionInformationResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    GetSoftwareVersionInformationResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    GetSoftwareVersionInformationResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return GetSoftwareVersionInformationResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return GetSoftwareVersionInformationResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return GetSoftwareVersionInformationResponse_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.SoftwareVersionInformation info = 3;
+  bool has_info() const;
+  void clear_info();
+  static const int kInfoFieldNumber = 3;
+  const ::dmi::SoftwareVersionInformation& info() const;
+  ::dmi::SoftwareVersionInformation* release_info();
+  ::dmi::SoftwareVersionInformation* mutable_info();
+  void set_allocated_info(::dmi::SoftwareVersionInformation* info);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.GetSoftwareVersionInformationResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::GetSoftwareVersionInformationResponse_Reason reason() const;
+  void set_reason(::dmi::GetSoftwareVersionInformationResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.GetSoftwareVersionInformationResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  ::dmi::SoftwareVersionInformation* info_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class DownloadImageRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.DownloadImageRequest) */ {
+ public:
+  DownloadImageRequest();
+  virtual ~DownloadImageRequest();
+
+  DownloadImageRequest(const DownloadImageRequest& from);
+
+  inline DownloadImageRequest& operator=(const DownloadImageRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  DownloadImageRequest(DownloadImageRequest&& from) noexcept
+    : DownloadImageRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline DownloadImageRequest& operator=(DownloadImageRequest&& 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 DownloadImageRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const DownloadImageRequest* internal_default_instance() {
+    return reinterpret_cast<const DownloadImageRequest*>(
+               &_DownloadImageRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    2;
+
+  void Swap(DownloadImageRequest* other);
+  friend void swap(DownloadImageRequest& a, DownloadImageRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline DownloadImageRequest* New() const final {
+    return CreateMaybeMessage<DownloadImageRequest>(nullptr);
+  }
+
+  DownloadImageRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<DownloadImageRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const DownloadImageRequest& from);
+  void MergeFrom(const DownloadImageRequest& 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(DownloadImageRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.ImageInformation image_info = 2;
+  bool has_image_info() const;
+  void clear_image_info();
+  static const int kImageInfoFieldNumber = 2;
+  const ::dmi::ImageInformation& image_info() const;
+  ::dmi::ImageInformation* release_image_info();
+  ::dmi::ImageInformation* mutable_image_info();
+  void set_allocated_image_info(::dmi::ImageInformation* image_info);
+
+  // @@protoc_insertion_point(class_scope:dmi.DownloadImageRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::Uuid* device_uuid_;
+  ::dmi::ImageInformation* image_info_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ConfigRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ConfigRequest) */ {
+ public:
+  ConfigRequest();
+  virtual ~ConfigRequest();
+
+  ConfigRequest(const ConfigRequest& from);
+
+  inline ConfigRequest& operator=(const ConfigRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ConfigRequest(ConfigRequest&& from) noexcept
+    : ConfigRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline ConfigRequest& operator=(ConfigRequest&& 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 ConfigRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ConfigRequest* internal_default_instance() {
+    return reinterpret_cast<const ConfigRequest*>(
+               &_ConfigRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    3;
+
+  void Swap(ConfigRequest* other);
+  friend void swap(ConfigRequest& a, ConfigRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ConfigRequest* New() const final {
+    return CreateMaybeMessage<ConfigRequest>(nullptr);
+  }
+
+  ConfigRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ConfigRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ConfigRequest& from);
+  void MergeFrom(const ConfigRequest& 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(ConfigRequest* 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 config_url = 2;
+  void clear_config_url();
+  static const int kConfigUrlFieldNumber = 2;
+  const ::std::string& config_url() const;
+  void set_config_url(const ::std::string& value);
+  #if LANG_CXX11
+  void set_config_url(::std::string&& value);
+  #endif
+  void set_config_url(const char* value);
+  void set_config_url(const char* value, size_t size);
+  ::std::string* mutable_config_url();
+  ::std::string* release_config_url();
+  void set_allocated_config_url(::std::string* config_url);
+
+  // .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.ConfigRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr config_url_;
+  ::dmi::Uuid* device_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ConfigResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ConfigResponse) */ {
+ public:
+  ConfigResponse();
+  virtual ~ConfigResponse();
+
+  ConfigResponse(const ConfigResponse& from);
+
+  inline ConfigResponse& operator=(const ConfigResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ConfigResponse(ConfigResponse&& from) noexcept
+    : ConfigResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline ConfigResponse& operator=(ConfigResponse&& 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 ConfigResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ConfigResponse* internal_default_instance() {
+    return reinterpret_cast<const ConfigResponse*>(
+               &_ConfigResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    4;
+
+  void Swap(ConfigResponse* other);
+  friend void swap(ConfigResponse& a, ConfigResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ConfigResponse* New() const final {
+    return CreateMaybeMessage<ConfigResponse>(nullptr);
+  }
+
+  ConfigResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ConfigResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ConfigResponse& from);
+  void MergeFrom(const ConfigResponse& 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(ConfigResponse* 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 ConfigResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    ConfigResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    ConfigResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    ConfigResponse_Reason_INTERNAL_ERROR;
+  static const Reason ERROR_FETCHING_CONFIG =
+    ConfigResponse_Reason_ERROR_FETCHING_CONFIG;
+  static const Reason INVALID_CONFIG =
+    ConfigResponse_Reason_INVALID_CONFIG;
+  static const Reason OPERATION_ALREADY_IN_PROGRESS =
+    ConfigResponse_Reason_OPERATION_ALREADY_IN_PROGRESS;
+  static const Reason DEVICE_UNREACHABLE =
+    ConfigResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return ConfigResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    ConfigResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    ConfigResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    ConfigResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return ConfigResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return ConfigResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return ConfigResponse_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.ConfigResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::ConfigResponse_Reason reason() const;
+  void set_reason(::dmi::ConfigResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ConfigResponse)
+ 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_2fsw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class StartupConfigInfoRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.StartupConfigInfoRequest) */ {
+ public:
+  StartupConfigInfoRequest();
+  virtual ~StartupConfigInfoRequest();
+
+  StartupConfigInfoRequest(const StartupConfigInfoRequest& from);
+
+  inline StartupConfigInfoRequest& operator=(const StartupConfigInfoRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  StartupConfigInfoRequest(StartupConfigInfoRequest&& from) noexcept
+    : StartupConfigInfoRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline StartupConfigInfoRequest& operator=(StartupConfigInfoRequest&& 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 StartupConfigInfoRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const StartupConfigInfoRequest* internal_default_instance() {
+    return reinterpret_cast<const StartupConfigInfoRequest*>(
+               &_StartupConfigInfoRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    5;
+
+  void Swap(StartupConfigInfoRequest* other);
+  friend void swap(StartupConfigInfoRequest& a, StartupConfigInfoRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline StartupConfigInfoRequest* New() const final {
+    return CreateMaybeMessage<StartupConfigInfoRequest>(nullptr);
+  }
+
+  StartupConfigInfoRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<StartupConfigInfoRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const StartupConfigInfoRequest& from);
+  void MergeFrom(const StartupConfigInfoRequest& 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(StartupConfigInfoRequest* 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.StartupConfigInfoRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::Uuid* device_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class StartupConfigInfoResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.StartupConfigInfoResponse) */ {
+ public:
+  StartupConfigInfoResponse();
+  virtual ~StartupConfigInfoResponse();
+
+  StartupConfigInfoResponse(const StartupConfigInfoResponse& from);
+
+  inline StartupConfigInfoResponse& operator=(const StartupConfigInfoResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  StartupConfigInfoResponse(StartupConfigInfoResponse&& from) noexcept
+    : StartupConfigInfoResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline StartupConfigInfoResponse& operator=(StartupConfigInfoResponse&& 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 StartupConfigInfoResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const StartupConfigInfoResponse* internal_default_instance() {
+    return reinterpret_cast<const StartupConfigInfoResponse*>(
+               &_StartupConfigInfoResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    6;
+
+  void Swap(StartupConfigInfoResponse* other);
+  friend void swap(StartupConfigInfoResponse& a, StartupConfigInfoResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline StartupConfigInfoResponse* New() const final {
+    return CreateMaybeMessage<StartupConfigInfoResponse>(nullptr);
+  }
+
+  StartupConfigInfoResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<StartupConfigInfoResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const StartupConfigInfoResponse& from);
+  void MergeFrom(const StartupConfigInfoResponse& 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(StartupConfigInfoResponse* 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 StartupConfigInfoResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    StartupConfigInfoResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    StartupConfigInfoResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason INTERNAL_ERROR =
+    StartupConfigInfoResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    StartupConfigInfoResponse_Reason_DEVICE_UNREACHABLE;
+  static inline bool Reason_IsValid(int value) {
+    return StartupConfigInfoResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    StartupConfigInfoResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    StartupConfigInfoResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    StartupConfigInfoResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return StartupConfigInfoResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return StartupConfigInfoResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return StartupConfigInfoResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string config_url = 3;
+  void clear_config_url();
+  static const int kConfigUrlFieldNumber = 3;
+  const ::std::string& config_url() const;
+  void set_config_url(const ::std::string& value);
+  #if LANG_CXX11
+  void set_config_url(::std::string&& value);
+  #endif
+  void set_config_url(const char* value);
+  void set_config_url(const char* value, size_t size);
+  ::std::string* mutable_config_url();
+  ::std::string* release_config_url();
+  void set_allocated_config_url(::std::string* config_url);
+
+  // string version = 4;
+  void clear_version();
+  static const int kVersionFieldNumber = 4;
+  const ::std::string& version() const;
+  void set_version(const ::std::string& value);
+  #if LANG_CXX11
+  void set_version(::std::string&& value);
+  #endif
+  void set_version(const char* value);
+  void set_version(const char* value, size_t size);
+  ::std::string* mutable_version();
+  ::std::string* release_version();
+  void set_allocated_version(::std::string* version);
+
+  // 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.StartupConfigInfoResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::StartupConfigInfoResponse_Reason reason() const;
+  void set_reason(::dmi::StartupConfigInfoResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.StartupConfigInfoResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr config_url_;
+  ::google::protobuf::internal::ArenaStringPtr version_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif  // __GNUC__
+// SoftwareVersionInformation
+
+// repeated .dmi.ImageVersion active_versions = 1;
+inline int SoftwareVersionInformation::active_versions_size() const {
+  return active_versions_.size();
+}
+inline ::dmi::ImageVersion* SoftwareVersionInformation::mutable_active_versions(int index) {
+  // @@protoc_insertion_point(field_mutable:dmi.SoftwareVersionInformation.active_versions)
+  return active_versions_.Mutable(index);
+}
+inline ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >*
+SoftwareVersionInformation::mutable_active_versions() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.SoftwareVersionInformation.active_versions)
+  return &active_versions_;
+}
+inline const ::dmi::ImageVersion& SoftwareVersionInformation::active_versions(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.SoftwareVersionInformation.active_versions)
+  return active_versions_.Get(index);
+}
+inline ::dmi::ImageVersion* SoftwareVersionInformation::add_active_versions() {
+  // @@protoc_insertion_point(field_add:dmi.SoftwareVersionInformation.active_versions)
+  return active_versions_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >&
+SoftwareVersionInformation::active_versions() const {
+  // @@protoc_insertion_point(field_list:dmi.SoftwareVersionInformation.active_versions)
+  return active_versions_;
+}
+
+// repeated .dmi.ImageVersion standby_versions = 2;
+inline int SoftwareVersionInformation::standby_versions_size() const {
+  return standby_versions_.size();
+}
+inline ::dmi::ImageVersion* SoftwareVersionInformation::mutable_standby_versions(int index) {
+  // @@protoc_insertion_point(field_mutable:dmi.SoftwareVersionInformation.standby_versions)
+  return standby_versions_.Mutable(index);
+}
+inline ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >*
+SoftwareVersionInformation::mutable_standby_versions() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.SoftwareVersionInformation.standby_versions)
+  return &standby_versions_;
+}
+inline const ::dmi::ImageVersion& SoftwareVersionInformation::standby_versions(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.SoftwareVersionInformation.standby_versions)
+  return standby_versions_.Get(index);
+}
+inline ::dmi::ImageVersion* SoftwareVersionInformation::add_standby_versions() {
+  // @@protoc_insertion_point(field_add:dmi.SoftwareVersionInformation.standby_versions)
+  return standby_versions_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >&
+SoftwareVersionInformation::standby_versions() const {
+  // @@protoc_insertion_point(field_list:dmi.SoftwareVersionInformation.standby_versions)
+  return standby_versions_;
+}
+
+// -------------------------------------------------------------------
+
+// GetSoftwareVersionInformationResponse
+
+// .dmi.Status status = 1;
+inline void GetSoftwareVersionInformationResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status GetSoftwareVersionInformationResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.GetSoftwareVersionInformationResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void GetSoftwareVersionInformationResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.GetSoftwareVersionInformationResponse.status)
+}
+
+// .dmi.GetSoftwareVersionInformationResponse.Reason reason = 2;
+inline void GetSoftwareVersionInformationResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.GetSoftwareVersionInformationResponse.reason)
+  return static_cast< ::dmi::GetSoftwareVersionInformationResponse_Reason >(reason_);
+}
+inline void GetSoftwareVersionInformationResponse::set_reason(::dmi::GetSoftwareVersionInformationResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.GetSoftwareVersionInformationResponse.reason)
+}
+
+// .dmi.SoftwareVersionInformation info = 3;
+inline bool GetSoftwareVersionInformationResponse::has_info() const {
+  return this != internal_default_instance() && info_ != nullptr;
+}
+inline void GetSoftwareVersionInformationResponse::clear_info() {
+  if (GetArenaNoVirtual() == nullptr && info_ != nullptr) {
+    delete info_;
+  }
+  info_ = nullptr;
+}
+inline const ::dmi::SoftwareVersionInformation& GetSoftwareVersionInformationResponse::info() const {
+  const ::dmi::SoftwareVersionInformation* p = info_;
+  // @@protoc_insertion_point(field_get:dmi.GetSoftwareVersionInformationResponse.info)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::SoftwareVersionInformation*>(
+      &::dmi::_SoftwareVersionInformation_default_instance_);
+}
+inline ::dmi::SoftwareVersionInformation* GetSoftwareVersionInformationResponse::release_info() {
+  // @@protoc_insertion_point(field_release:dmi.GetSoftwareVersionInformationResponse.info)
+  
+  ::dmi::SoftwareVersionInformation* temp = info_;
+  info_ = nullptr;
+  return temp;
+}
+inline ::dmi::SoftwareVersionInformation* GetSoftwareVersionInformationResponse::mutable_info() {
+  
+  if (info_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::SoftwareVersionInformation>(GetArenaNoVirtual());
+    info_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.GetSoftwareVersionInformationResponse.info)
+  return info_;
+}
+inline void GetSoftwareVersionInformationResponse::set_allocated_info(::dmi::SoftwareVersionInformation* info) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete 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.GetSoftwareVersionInformationResponse.info)
+}
+
+// string reason_detail = 4;
+inline void GetSoftwareVersionInformationResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& GetSoftwareVersionInformationResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.GetSoftwareVersionInformationResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void GetSoftwareVersionInformationResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.GetSoftwareVersionInformationResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void GetSoftwareVersionInformationResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.GetSoftwareVersionInformationResponse.reason_detail)
+}
+#endif
+inline void GetSoftwareVersionInformationResponse::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.GetSoftwareVersionInformationResponse.reason_detail)
+}
+inline void GetSoftwareVersionInformationResponse::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.GetSoftwareVersionInformationResponse.reason_detail)
+}
+inline ::std::string* GetSoftwareVersionInformationResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.GetSoftwareVersionInformationResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* GetSoftwareVersionInformationResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.GetSoftwareVersionInformationResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void GetSoftwareVersionInformationResponse::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.GetSoftwareVersionInformationResponse.reason_detail)
+}
+
+// -------------------------------------------------------------------
+
+// DownloadImageRequest
+
+// .dmi.Uuid device_uuid = 1;
+inline bool DownloadImageRequest::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& DownloadImageRequest::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.DownloadImageRequest.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* DownloadImageRequest::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.DownloadImageRequest.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* DownloadImageRequest::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.DownloadImageRequest.device_uuid)
+  return device_uuid_;
+}
+inline void DownloadImageRequest::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.DownloadImageRequest.device_uuid)
+}
+
+// .dmi.ImageInformation image_info = 2;
+inline bool DownloadImageRequest::has_image_info() const {
+  return this != internal_default_instance() && image_info_ != nullptr;
+}
+inline const ::dmi::ImageInformation& DownloadImageRequest::image_info() const {
+  const ::dmi::ImageInformation* p = image_info_;
+  // @@protoc_insertion_point(field_get:dmi.DownloadImageRequest.image_info)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ImageInformation*>(
+      &::dmi::_ImageInformation_default_instance_);
+}
+inline ::dmi::ImageInformation* DownloadImageRequest::release_image_info() {
+  // @@protoc_insertion_point(field_release:dmi.DownloadImageRequest.image_info)
+  
+  ::dmi::ImageInformation* temp = image_info_;
+  image_info_ = nullptr;
+  return temp;
+}
+inline ::dmi::ImageInformation* DownloadImageRequest::mutable_image_info() {
+  
+  if (image_info_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::ImageInformation>(GetArenaNoVirtual());
+    image_info_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.DownloadImageRequest.image_info)
+  return image_info_;
+}
+inline void DownloadImageRequest::set_allocated_image_info(::dmi::ImageInformation* image_info) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(image_info_);
+  }
+  if (image_info) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      image_info = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, image_info, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  image_info_ = image_info;
+  // @@protoc_insertion_point(field_set_allocated:dmi.DownloadImageRequest.image_info)
+}
+
+// -------------------------------------------------------------------
+
+// ConfigRequest
+
+// .dmi.Uuid device_uuid = 1;
+inline bool ConfigRequest::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& ConfigRequest::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.ConfigRequest.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* ConfigRequest::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.ConfigRequest.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* ConfigRequest::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ConfigRequest.device_uuid)
+  return device_uuid_;
+}
+inline void ConfigRequest::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.ConfigRequest.device_uuid)
+}
+
+// string config_url = 2;
+inline void ConfigRequest::clear_config_url() {
+  config_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ConfigRequest::config_url() const {
+  // @@protoc_insertion_point(field_get:dmi.ConfigRequest.config_url)
+  return config_url_.GetNoArena();
+}
+inline void ConfigRequest::set_config_url(const ::std::string& value) {
+  
+  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ConfigRequest.config_url)
+}
+#if LANG_CXX11
+inline void ConfigRequest::set_config_url(::std::string&& value) {
+  
+  config_url_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ConfigRequest.config_url)
+}
+#endif
+inline void ConfigRequest::set_config_url(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ConfigRequest.config_url)
+}
+inline void ConfigRequest::set_config_url(const char* value, size_t size) {
+  
+  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ConfigRequest.config_url)
+}
+inline ::std::string* ConfigRequest::mutable_config_url() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ConfigRequest.config_url)
+  return config_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ConfigRequest::release_config_url() {
+  // @@protoc_insertion_point(field_release:dmi.ConfigRequest.config_url)
+  
+  return config_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ConfigRequest::set_allocated_config_url(::std::string* config_url) {
+  if (config_url != nullptr) {
+    
+  } else {
+    
+  }
+  config_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), config_url);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ConfigRequest.config_url)
+}
+
+// -------------------------------------------------------------------
+
+// ConfigResponse
+
+// .dmi.Status status = 1;
+inline void ConfigResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status ConfigResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.ConfigResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void ConfigResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ConfigResponse.status)
+}
+
+// .dmi.ConfigResponse.Reason reason = 2;
+inline void ConfigResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::ConfigResponse_Reason ConfigResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.ConfigResponse.reason)
+  return static_cast< ::dmi::ConfigResponse_Reason >(reason_);
+}
+inline void ConfigResponse::set_reason(::dmi::ConfigResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ConfigResponse.reason)
+}
+
+// string reason_detail = 3;
+inline void ConfigResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ConfigResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.ConfigResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void ConfigResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ConfigResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void ConfigResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ConfigResponse.reason_detail)
+}
+#endif
+inline void ConfigResponse::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.ConfigResponse.reason_detail)
+}
+inline void ConfigResponse::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.ConfigResponse.reason_detail)
+}
+inline ::std::string* ConfigResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ConfigResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ConfigResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.ConfigResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ConfigResponse::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.ConfigResponse.reason_detail)
+}
+
+// -------------------------------------------------------------------
+
+// StartupConfigInfoRequest
+
+// .dmi.Uuid device_uuid = 1;
+inline bool StartupConfigInfoRequest::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& StartupConfigInfoRequest::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoRequest.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* StartupConfigInfoRequest::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.StartupConfigInfoRequest.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* StartupConfigInfoRequest::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.StartupConfigInfoRequest.device_uuid)
+  return device_uuid_;
+}
+inline void StartupConfigInfoRequest::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.StartupConfigInfoRequest.device_uuid)
+}
+
+// -------------------------------------------------------------------
+
+// StartupConfigInfoResponse
+
+// .dmi.Status status = 1;
+inline void StartupConfigInfoResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status StartupConfigInfoResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void StartupConfigInfoResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.StartupConfigInfoResponse.status)
+}
+
+// .dmi.StartupConfigInfoResponse.Reason reason = 2;
+inline void StartupConfigInfoResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::StartupConfigInfoResponse_Reason StartupConfigInfoResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoResponse.reason)
+  return static_cast< ::dmi::StartupConfigInfoResponse_Reason >(reason_);
+}
+inline void StartupConfigInfoResponse::set_reason(::dmi::StartupConfigInfoResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.StartupConfigInfoResponse.reason)
+}
+
+// string config_url = 3;
+inline void StartupConfigInfoResponse::clear_config_url() {
+  config_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& StartupConfigInfoResponse::config_url() const {
+  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoResponse.config_url)
+  return config_url_.GetNoArena();
+}
+inline void StartupConfigInfoResponse::set_config_url(const ::std::string& value) {
+  
+  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.StartupConfigInfoResponse.config_url)
+}
+#if LANG_CXX11
+inline void StartupConfigInfoResponse::set_config_url(::std::string&& value) {
+  
+  config_url_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.StartupConfigInfoResponse.config_url)
+}
+#endif
+inline void StartupConfigInfoResponse::set_config_url(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.StartupConfigInfoResponse.config_url)
+}
+inline void StartupConfigInfoResponse::set_config_url(const char* value, size_t size) {
+  
+  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.StartupConfigInfoResponse.config_url)
+}
+inline ::std::string* StartupConfigInfoResponse::mutable_config_url() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.StartupConfigInfoResponse.config_url)
+  return config_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* StartupConfigInfoResponse::release_config_url() {
+  // @@protoc_insertion_point(field_release:dmi.StartupConfigInfoResponse.config_url)
+  
+  return config_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void StartupConfigInfoResponse::set_allocated_config_url(::std::string* config_url) {
+  if (config_url != nullptr) {
+    
+  } else {
+    
+  }
+  config_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), config_url);
+  // @@protoc_insertion_point(field_set_allocated:dmi.StartupConfigInfoResponse.config_url)
+}
+
+// string version = 4;
+inline void StartupConfigInfoResponse::clear_version() {
+  version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& StartupConfigInfoResponse::version() const {
+  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoResponse.version)
+  return version_.GetNoArena();
+}
+inline void StartupConfigInfoResponse::set_version(const ::std::string& value) {
+  
+  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.StartupConfigInfoResponse.version)
+}
+#if LANG_CXX11
+inline void StartupConfigInfoResponse::set_version(::std::string&& value) {
+  
+  version_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.StartupConfigInfoResponse.version)
+}
+#endif
+inline void StartupConfigInfoResponse::set_version(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.StartupConfigInfoResponse.version)
+}
+inline void StartupConfigInfoResponse::set_version(const char* value, size_t size) {
+  
+  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.StartupConfigInfoResponse.version)
+}
+inline ::std::string* StartupConfigInfoResponse::mutable_version() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.StartupConfigInfoResponse.version)
+  return version_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* StartupConfigInfoResponse::release_version() {
+  // @@protoc_insertion_point(field_release:dmi.StartupConfigInfoResponse.version)
+  
+  return version_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void StartupConfigInfoResponse::set_allocated_version(::std::string* version) {
+  if (version != nullptr) {
+    
+  } else {
+    
+  }
+  version_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), version);
+  // @@protoc_insertion_point(field_set_allocated:dmi.StartupConfigInfoResponse.version)
+}
+
+// string reason_detail = 5;
+inline void StartupConfigInfoResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& StartupConfigInfoResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void StartupConfigInfoResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.StartupConfigInfoResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void StartupConfigInfoResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.StartupConfigInfoResponse.reason_detail)
+}
+#endif
+inline void StartupConfigInfoResponse::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.StartupConfigInfoResponse.reason_detail)
+}
+inline void StartupConfigInfoResponse::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.StartupConfigInfoResponse.reason_detail)
+}
+inline ::std::string* StartupConfigInfoResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.StartupConfigInfoResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* StartupConfigInfoResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.StartupConfigInfoResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void StartupConfigInfoResponse::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.StartupConfigInfoResponse.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::GetSoftwareVersionInformationResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::GetSoftwareVersionInformationResponse_Reason>() {
+  return ::dmi::GetSoftwareVersionInformationResponse_Reason_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ConfigResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ConfigResponse_Reason>() {
+  return ::dmi::ConfigResponse_Reason_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::StartupConfigInfoResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::StartupConfigInfoResponse_Reason>() {
+  return ::dmi::StartupConfigInfoResponse_Reason_descriptor();
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#include <google/protobuf/port_undef.inc>
+#endif  // PROTOBUF_INCLUDED_dmi_2fsw_5fmanagement_5fservice_2eproto
diff --git a/test/test-cpp-proto-consistency.sh b/test/test-cpp-proto-consistency.sh
new file mode 100755
index 0000000..04ae53b
--- /dev/null
+++ b/test/test-cpp-proto-consistency.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+# Copyright 2020-present Open Networking Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# test-go-proto-consistency.sh
+#
+# This test validates that go proto outputs are committed to git.  It does this
+# by regenerating them and validating whether git thinks they are the same. If
+# they become out of sync, there can be problems for consumers of the protos.
+
+set -eu -o pipefail
+
+git status > /dev/null
+STAGED="$(git diff-index --quiet HEAD -- || echo 'staged')"
+UNTRACKED="$(git ls-files --exclude-standard --others)"
+
+if [ "$STAGED" == "staged" ] || [ "$UNTRACKED" != "" ]; then
+    echo "Please commit or ignore local changes before executing this test"
+    git status
+    exit 1
+fi
+
+# delete and regenerate go protos
+rm -rf cpp/dmi
+make cpp-protos
+
+# Running git status ensures correct git diff-index picks up changes
+git status > /dev/null
+STAGED_POST="$(git diff-index --quiet HEAD -- || echo "staged")"
+UNTRACKED_POST="$(git ls-files --exclude-standard --others)"
+
+if [ "$STAGED_POST" == "staged" ] || [ "$UNTRACKED_POST" != "" ] ; then
+    echo "You have cpp proto build outputs that are not committed."
+    echo "Check git status and commit updated files."
+    git status
+    exit 1
+else
+    echo "Test successful. All cpp proto build outputs are committed"
+    exit 0
+fi
