// 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"
#include <google/protobuf/empty.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_TRANSCEIVER_XGSPON_TX_POWER = 206,
  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
