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
