diff --git a/cpp/dmi/hw.pb.h b/cpp/dmi/hw.pb.h
new file mode 100644
index 0000000..f4b9c89
--- /dev/null
+++ b/cpp/dmi/hw.pb.h
@@ -0,0 +1,5215 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/hw.proto
+
+#ifndef PROTOBUF_INCLUDED_dmi_2fhw_2eproto
+#define PROTOBUF_INCLUDED_dmi_2fhw_2eproto
+
+#include <limits>
+#include <string>
+
+#include <google/protobuf/port_def.inc>
+#if PROTOBUF_VERSION < 3007000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 3007000 < PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/port_undef.inc>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_table_driven.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/inlined_string_field.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
+#include <google/protobuf/extension_set.h>  // IWYU pragma: export
+#include <google/protobuf/generated_enum_reflection.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/timestamp.pb.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+#define PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto
+
+// Internal implementation detail -- do not use these members.
+struct TableStruct_dmi_2fhw_2eproto {
+  static const ::google::protobuf::internal::ParseTableField entries[]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::ParseTable schema[12]
+    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
+  static const ::google::protobuf::internal::FieldMetadata field_metadata[];
+  static const ::google::protobuf::internal::SerializationTable serialization_table[];
+  static const ::google::protobuf::uint32 offsets[];
+};
+void AddDescriptors_dmi_2fhw_2eproto();
+namespace dmi {
+class Component;
+class ComponentDefaultTypeInternal;
+extern ComponentDefaultTypeInternal _Component_default_instance_;
+class ComponentSensorData;
+class ComponentSensorDataDefaultTypeInternal;
+extern ComponentSensorDataDefaultTypeInternal _ComponentSensorData_default_instance_;
+class ComponentState;
+class ComponentStateDefaultTypeInternal;
+extern ComponentStateDefaultTypeInternal _ComponentState_default_instance_;
+class ContainerComponentAttributes;
+class ContainerComponentAttributesDefaultTypeInternal;
+extern ContainerComponentAttributesDefaultTypeInternal _ContainerComponentAttributes_default_instance_;
+class Hardware;
+class HardwareDefaultTypeInternal;
+extern HardwareDefaultTypeInternal _Hardware_default_instance_;
+class HardwareID;
+class HardwareIDDefaultTypeInternal;
+extern HardwareIDDefaultTypeInternal _HardwareID_default_instance_;
+class ModifiableComponent;
+class ModifiableComponentDefaultTypeInternal;
+extern ModifiableComponentDefaultTypeInternal _ModifiableComponent_default_instance_;
+class PortComponentAttributes;
+class PortComponentAttributesDefaultTypeInternal;
+extern PortComponentAttributesDefaultTypeInternal _PortComponentAttributes_default_instance_;
+class PsuComponentAttributes;
+class PsuComponentAttributesDefaultTypeInternal;
+extern PsuComponentAttributesDefaultTypeInternal _PsuComponentAttributes_default_instance_;
+class TransceiverComponentsAttributes;
+class TransceiverComponentsAttributesDefaultTypeInternal;
+extern TransceiverComponentsAttributesDefaultTypeInternal _TransceiverComponentsAttributes_default_instance_;
+class Uri;
+class UriDefaultTypeInternal;
+extern UriDefaultTypeInternal _Uri_default_instance_;
+class Uuid;
+class UuidDefaultTypeInternal;
+extern UuidDefaultTypeInternal _Uuid_default_instance_;
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> ::dmi::Component* Arena::CreateMaybeMessage<::dmi::Component>(Arena*);
+template<> ::dmi::ComponentSensorData* Arena::CreateMaybeMessage<::dmi::ComponentSensorData>(Arena*);
+template<> ::dmi::ComponentState* Arena::CreateMaybeMessage<::dmi::ComponentState>(Arena*);
+template<> ::dmi::ContainerComponentAttributes* Arena::CreateMaybeMessage<::dmi::ContainerComponentAttributes>(Arena*);
+template<> ::dmi::Hardware* Arena::CreateMaybeMessage<::dmi::Hardware>(Arena*);
+template<> ::dmi::HardwareID* Arena::CreateMaybeMessage<::dmi::HardwareID>(Arena*);
+template<> ::dmi::ModifiableComponent* Arena::CreateMaybeMessage<::dmi::ModifiableComponent>(Arena*);
+template<> ::dmi::PortComponentAttributes* Arena::CreateMaybeMessage<::dmi::PortComponentAttributes>(Arena*);
+template<> ::dmi::PsuComponentAttributes* Arena::CreateMaybeMessage<::dmi::PsuComponentAttributes>(Arena*);
+template<> ::dmi::TransceiverComponentsAttributes* Arena::CreateMaybeMessage<::dmi::TransceiverComponentsAttributes>(Arena*);
+template<> ::dmi::Uri* Arena::CreateMaybeMessage<::dmi::Uri>(Arena*);
+template<> ::dmi::Uuid* Arena::CreateMaybeMessage<::dmi::Uuid>(Arena*);
+}  // namespace protobuf
+}  // namespace google
+namespace dmi {
+
+enum PortComponentAttributes_ConnectorType {
+  PortComponentAttributes_ConnectorType_CONNECTOR_TYPE_UNDEFINED = 0,
+  PortComponentAttributes_ConnectorType_RJ45 = 1,
+  PortComponentAttributes_ConnectorType_FIBER_LC = 2,
+  PortComponentAttributes_ConnectorType_FIBER_SC_PC = 3,
+  PortComponentAttributes_ConnectorType_FIBER_MPO = 4,
+  PortComponentAttributes_ConnectorType_RS232 = 5,
+  PortComponentAttributes_ConnectorType_PortComponentAttributes_ConnectorType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  PortComponentAttributes_ConnectorType_PortComponentAttributes_ConnectorType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool PortComponentAttributes_ConnectorType_IsValid(int value);
+const PortComponentAttributes_ConnectorType PortComponentAttributes_ConnectorType_ConnectorType_MIN = PortComponentAttributes_ConnectorType_CONNECTOR_TYPE_UNDEFINED;
+const PortComponentAttributes_ConnectorType PortComponentAttributes_ConnectorType_ConnectorType_MAX = PortComponentAttributes_ConnectorType_RS232;
+const int PortComponentAttributes_ConnectorType_ConnectorType_ARRAYSIZE = PortComponentAttributes_ConnectorType_ConnectorType_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_ConnectorType_descriptor();
+inline const ::std::string& PortComponentAttributes_ConnectorType_Name(PortComponentAttributes_ConnectorType value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    PortComponentAttributes_ConnectorType_descriptor(), value);
+}
+inline bool PortComponentAttributes_ConnectorType_Parse(
+    const ::std::string& name, PortComponentAttributes_ConnectorType* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<PortComponentAttributes_ConnectorType>(
+    PortComponentAttributes_ConnectorType_descriptor(), name, value);
+}
+enum PortComponentAttributes_Speed {
+  PortComponentAttributes_Speed_SPEED_UNDEFINED = 0,
+  PortComponentAttributes_Speed_DYNAMIC = 1,
+  PortComponentAttributes_Speed_GIGABIT_1 = 2,
+  PortComponentAttributes_Speed_GIGABIT_10 = 3,
+  PortComponentAttributes_Speed_GIGABIT_25 = 4,
+  PortComponentAttributes_Speed_GIGABIT_40 = 5,
+  PortComponentAttributes_Speed_GIGABIT_100 = 6,
+  PortComponentAttributes_Speed_GIGABIT_400 = 7,
+  PortComponentAttributes_Speed_MEGABIT_2500 = 8,
+  PortComponentAttributes_Speed_MEGABIT_1250 = 9,
+  PortComponentAttributes_Speed_PortComponentAttributes_Speed_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  PortComponentAttributes_Speed_PortComponentAttributes_Speed_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool PortComponentAttributes_Speed_IsValid(int value);
+const PortComponentAttributes_Speed PortComponentAttributes_Speed_Speed_MIN = PortComponentAttributes_Speed_SPEED_UNDEFINED;
+const PortComponentAttributes_Speed PortComponentAttributes_Speed_Speed_MAX = PortComponentAttributes_Speed_MEGABIT_1250;
+const int PortComponentAttributes_Speed_Speed_ARRAYSIZE = PortComponentAttributes_Speed_Speed_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Speed_descriptor();
+inline const ::std::string& PortComponentAttributes_Speed_Name(PortComponentAttributes_Speed value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    PortComponentAttributes_Speed_descriptor(), value);
+}
+inline bool PortComponentAttributes_Speed_Parse(
+    const ::std::string& name, PortComponentAttributes_Speed* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<PortComponentAttributes_Speed>(
+    PortComponentAttributes_Speed_descriptor(), name, value);
+}
+enum PortComponentAttributes_Protocol {
+  PortComponentAttributes_Protocol_PROTOCOL_UNDEFINED = 0,
+  PortComponentAttributes_Protocol_ETHERNET = 1,
+  PortComponentAttributes_Protocol_GPON = 2,
+  PortComponentAttributes_Protocol_XGPON = 3,
+  PortComponentAttributes_Protocol_XGSPON = 4,
+  PortComponentAttributes_Protocol_GFAST = 5,
+  PortComponentAttributes_Protocol_SERIAL = 6,
+  PortComponentAttributes_Protocol_EPON = 7,
+  PortComponentAttributes_Protocol_BITS = 8,
+  PortComponentAttributes_Protocol_PortComponentAttributes_Protocol_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  PortComponentAttributes_Protocol_PortComponentAttributes_Protocol_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool PortComponentAttributes_Protocol_IsValid(int value);
+const PortComponentAttributes_Protocol PortComponentAttributes_Protocol_Protocol_MIN = PortComponentAttributes_Protocol_PROTOCOL_UNDEFINED;
+const PortComponentAttributes_Protocol PortComponentAttributes_Protocol_Protocol_MAX = PortComponentAttributes_Protocol_BITS;
+const int PortComponentAttributes_Protocol_Protocol_ARRAYSIZE = PortComponentAttributes_Protocol_Protocol_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Protocol_descriptor();
+inline const ::std::string& PortComponentAttributes_Protocol_Name(PortComponentAttributes_Protocol value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    PortComponentAttributes_Protocol_descriptor(), value);
+}
+inline bool PortComponentAttributes_Protocol_Parse(
+    const ::std::string& name, PortComponentAttributes_Protocol* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<PortComponentAttributes_Protocol>(
+    PortComponentAttributes_Protocol_descriptor(), name, value);
+}
+enum PsuComponentAttributes_SupportedVoltage {
+  PsuComponentAttributes_SupportedVoltage_SUPPORTED_VOLTAGE_UNDEFINED = 0,
+  PsuComponentAttributes_SupportedVoltage_V48 = 1,
+  PsuComponentAttributes_SupportedVoltage_V230 = 2,
+  PsuComponentAttributes_SupportedVoltage_V115 = 3,
+  PsuComponentAttributes_SupportedVoltage_PsuComponentAttributes_SupportedVoltage_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  PsuComponentAttributes_SupportedVoltage_PsuComponentAttributes_SupportedVoltage_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool PsuComponentAttributes_SupportedVoltage_IsValid(int value);
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MIN = PsuComponentAttributes_SupportedVoltage_SUPPORTED_VOLTAGE_UNDEFINED;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MAX = PsuComponentAttributes_SupportedVoltage_V115;
+const int PsuComponentAttributes_SupportedVoltage_SupportedVoltage_ARRAYSIZE = PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* PsuComponentAttributes_SupportedVoltage_descriptor();
+inline const ::std::string& PsuComponentAttributes_SupportedVoltage_Name(PsuComponentAttributes_SupportedVoltage value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    PsuComponentAttributes_SupportedVoltage_descriptor(), value);
+}
+inline bool PsuComponentAttributes_SupportedVoltage_Parse(
+    const ::std::string& name, PsuComponentAttributes_SupportedVoltage* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<PsuComponentAttributes_SupportedVoltage>(
+    PsuComponentAttributes_SupportedVoltage_descriptor(), name, value);
+}
+enum TransceiverComponentsAttributes_FormFactor {
+  TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN = 0,
+  TransceiverComponentsAttributes_FormFactor_QSFP = 1,
+  TransceiverComponentsAttributes_FormFactor_QSFP_PLUS = 2,
+  TransceiverComponentsAttributes_FormFactor_QSFP28 = 3,
+  TransceiverComponentsAttributes_FormFactor_SFP = 4,
+  TransceiverComponentsAttributes_FormFactor_SFP_PLUS = 5,
+  TransceiverComponentsAttributes_FormFactor_XFP = 6,
+  TransceiverComponentsAttributes_FormFactor_CFP4 = 7,
+  TransceiverComponentsAttributes_FormFactor_CFP2 = 8,
+  TransceiverComponentsAttributes_FormFactor_CPAK = 9,
+  TransceiverComponentsAttributes_FormFactor_X2 = 10,
+  TransceiverComponentsAttributes_FormFactor_OTHER = 11,
+  TransceiverComponentsAttributes_FormFactor_CFP = 12,
+  TransceiverComponentsAttributes_FormFactor_CFP2_ACO = 13,
+  TransceiverComponentsAttributes_FormFactor_CFP2_DCO = 14,
+  TransceiverComponentsAttributes_FormFactor_TransceiverComponentsAttributes_FormFactor_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  TransceiverComponentsAttributes_FormFactor_TransceiverComponentsAttributes_FormFactor_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool TransceiverComponentsAttributes_FormFactor_IsValid(int value);
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes_FormFactor_FormFactor_MIN = TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes_FormFactor_FormFactor_MAX = TransceiverComponentsAttributes_FormFactor_CFP2_DCO;
+const int TransceiverComponentsAttributes_FormFactor_FormFactor_ARRAYSIZE = TransceiverComponentsAttributes_FormFactor_FormFactor_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_FormFactor_descriptor();
+inline const ::std::string& TransceiverComponentsAttributes_FormFactor_Name(TransceiverComponentsAttributes_FormFactor value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    TransceiverComponentsAttributes_FormFactor_descriptor(), value);
+}
+inline bool TransceiverComponentsAttributes_FormFactor_Parse(
+    const ::std::string& name, TransceiverComponentsAttributes_FormFactor* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<TransceiverComponentsAttributes_FormFactor>(
+    TransceiverComponentsAttributes_FormFactor_descriptor(), name, value);
+}
+enum TransceiverComponentsAttributes_Type {
+  TransceiverComponentsAttributes_Type_TYPE_UNKNOWN = 0,
+  TransceiverComponentsAttributes_Type_ETHERNET = 1,
+  TransceiverComponentsAttributes_Type_GPON = 2,
+  TransceiverComponentsAttributes_Type_XGPON = 3,
+  TransceiverComponentsAttributes_Type_XGSPON = 4,
+  TransceiverComponentsAttributes_Type_CPON = 5,
+  TransceiverComponentsAttributes_Type_NG_PON2 = 6,
+  TransceiverComponentsAttributes_Type_EPON = 7,
+  TransceiverComponentsAttributes_Type_TransceiverComponentsAttributes_Type_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  TransceiverComponentsAttributes_Type_TransceiverComponentsAttributes_Type_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool TransceiverComponentsAttributes_Type_IsValid(int value);
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes_Type_Type_MIN = TransceiverComponentsAttributes_Type_TYPE_UNKNOWN;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes_Type_Type_MAX = TransceiverComponentsAttributes_Type_EPON;
+const int TransceiverComponentsAttributes_Type_Type_ARRAYSIZE = TransceiverComponentsAttributes_Type_Type_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_Type_descriptor();
+inline const ::std::string& TransceiverComponentsAttributes_Type_Name(TransceiverComponentsAttributes_Type value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    TransceiverComponentsAttributes_Type_descriptor(), value);
+}
+inline bool TransceiverComponentsAttributes_Type_Parse(
+    const ::std::string& name, TransceiverComponentsAttributes_Type* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<TransceiverComponentsAttributes_Type>(
+    TransceiverComponentsAttributes_Type_descriptor(), name, value);
+}
+enum ComponentType {
+  COMPONENT_TYPE_UNDEFINED = 0,
+  COMPONENT_TYPE_UNKNOWN = 1,
+  COMPONENT_TYPE_CHASSIS = 2,
+  COMPONENT_TYPE_BACKPLANE = 3,
+  COMPONENT_TYPE_CONTAINER = 4,
+  COMPONENT_TYPE_POWER_SUPPLY = 5,
+  COMPONENT_TYPE_FAN = 6,
+  COMPONENT_TYPE_SENSOR = 7,
+  COMPONENT_TYPE_MODULE = 8,
+  COMPONENT_TYPE_PORT = 9,
+  COMPONENT_TYPE_CPU = 10,
+  COMPONENT_TYPE_BATTERY = 11,
+  COMPONENT_TYPE_STORAGE = 12,
+  COMPONENT_TYPE_MEMORY = 13,
+  COMPONENT_TYPE_TRANSCEIVER = 14,
+  ComponentType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentType_IsValid(int value);
+const ComponentType ComponentType_MIN = COMPONENT_TYPE_UNDEFINED;
+const ComponentType ComponentType_MAX = COMPONENT_TYPE_TRANSCEIVER;
+const int ComponentType_ARRAYSIZE = ComponentType_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentType_descriptor();
+inline const ::std::string& ComponentType_Name(ComponentType value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentType_descriptor(), value);
+}
+inline bool ComponentType_Parse(
+    const ::std::string& name, ComponentType* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentType>(
+    ComponentType_descriptor(), name, value);
+}
+enum ComponentAdminState {
+  COMP_ADMIN_STATE_UNDEFINED = 0,
+  COMP_ADMIN_STATE_UNKNOWN = 1,
+  COMP_ADMIN_STATE_LOCKED = 2,
+  COMP_ADMIN_STATE_SHUTTING_DOWN = 3,
+  COMP_ADMIN_STATE_UNLOCKED = 4,
+  ComponentAdminState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentAdminState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentAdminState_IsValid(int value);
+const ComponentAdminState ComponentAdminState_MIN = COMP_ADMIN_STATE_UNDEFINED;
+const ComponentAdminState ComponentAdminState_MAX = COMP_ADMIN_STATE_UNLOCKED;
+const int ComponentAdminState_ARRAYSIZE = ComponentAdminState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentAdminState_descriptor();
+inline const ::std::string& ComponentAdminState_Name(ComponentAdminState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentAdminState_descriptor(), value);
+}
+inline bool ComponentAdminState_Parse(
+    const ::std::string& name, ComponentAdminState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentAdminState>(
+    ComponentAdminState_descriptor(), name, value);
+}
+enum ComponentOperState {
+  COMP_OPER_STATE_UNDEFINED = 0,
+  COMP_OPER_STATE_UNKNOWN = 1,
+  COMP_OPER_STATE_DISABLED = 2,
+  COMP_OPER_STATE_ENABLED = 3,
+  COMP_OPER_STATE_TESTING = 4,
+  ComponentOperState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentOperState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentOperState_IsValid(int value);
+const ComponentOperState ComponentOperState_MIN = COMP_OPER_STATE_UNDEFINED;
+const ComponentOperState ComponentOperState_MAX = COMP_OPER_STATE_TESTING;
+const int ComponentOperState_ARRAYSIZE = ComponentOperState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentOperState_descriptor();
+inline const ::std::string& ComponentOperState_Name(ComponentOperState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentOperState_descriptor(), value);
+}
+inline bool ComponentOperState_Parse(
+    const ::std::string& name, ComponentOperState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentOperState>(
+    ComponentOperState_descriptor(), name, value);
+}
+enum ComponentUsageState {
+  COMP_USAGE_STATE_UNDEFINED = 0,
+  COMP_USAGE_STATE_UNKNOWN = 1,
+  COMP_USAGE_STATE_IDLE = 2,
+  COMP_USAGE_STATE_ACTIVE = 3,
+  COMP_USAGE_STATE_BUSY = 4,
+  ComponentUsageState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentUsageState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentUsageState_IsValid(int value);
+const ComponentUsageState ComponentUsageState_MIN = COMP_USAGE_STATE_UNDEFINED;
+const ComponentUsageState ComponentUsageState_MAX = COMP_USAGE_STATE_BUSY;
+const int ComponentUsageState_ARRAYSIZE = ComponentUsageState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentUsageState_descriptor();
+inline const ::std::string& ComponentUsageState_Name(ComponentUsageState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentUsageState_descriptor(), value);
+}
+inline bool ComponentUsageState_Parse(
+    const ::std::string& name, ComponentUsageState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentUsageState>(
+    ComponentUsageState_descriptor(), name, value);
+}
+enum ComponentAlarmState {
+  COMP_ALARM_STATE_UNDEFINED = 0,
+  COMP_ALARM_STATE_UNKNOWN = 1,
+  COMP_ALARM_STATE_UNDER_REPAIR = 2,
+  COMP_ALARM_STATE_CRITICAL = 3,
+  COMP_ALARM_STATE_MAJOR = 4,
+  COMP_ALARM_STATE_MINOR = 5,
+  COMP_ALARM_STATE_WARNING = 6,
+  COMP_ALARM_STATE_INDETERMINATE = 7,
+  ComponentAlarmState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentAlarmState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentAlarmState_IsValid(int value);
+const ComponentAlarmState ComponentAlarmState_MIN = COMP_ALARM_STATE_UNDEFINED;
+const ComponentAlarmState ComponentAlarmState_MAX = COMP_ALARM_STATE_INDETERMINATE;
+const int ComponentAlarmState_ARRAYSIZE = ComponentAlarmState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentAlarmState_descriptor();
+inline const ::std::string& ComponentAlarmState_Name(ComponentAlarmState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentAlarmState_descriptor(), value);
+}
+inline bool ComponentAlarmState_Parse(
+    const ::std::string& name, ComponentAlarmState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentAlarmState>(
+    ComponentAlarmState_descriptor(), name, value);
+}
+enum ComponentStandbyState {
+  COMP_STANDBY_STATE_UNDEFINED = 0,
+  COMP_STANDBY_STATE_UNKNOWN = 1,
+  COMP_STANDBY_STATE_HOT = 2,
+  COMP_STANDBY_STATE_COLD = 3,
+  COMP_STANDBY_STATE_PROVIDING_SERVICE = 4,
+  ComponentStandbyState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ComponentStandbyState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ComponentStandbyState_IsValid(int value);
+const ComponentStandbyState ComponentStandbyState_MIN = COMP_STANDBY_STATE_UNDEFINED;
+const ComponentStandbyState ComponentStandbyState_MAX = COMP_STANDBY_STATE_PROVIDING_SERVICE;
+const int ComponentStandbyState_ARRAYSIZE = ComponentStandbyState_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ComponentStandbyState_descriptor();
+inline const ::std::string& ComponentStandbyState_Name(ComponentStandbyState value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ComponentStandbyState_descriptor(), value);
+}
+inline bool ComponentStandbyState_Parse(
+    const ::std::string& name, ComponentStandbyState* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ComponentStandbyState>(
+    ComponentStandbyState_descriptor(), name, value);
+}
+enum DataValueType {
+  VALUE_TYPE_UNDEFINED = 0,
+  VALUE_TYPE_OTHER = 1,
+  VALUE_TYPE_UNKNOWN = 2,
+  VALUE_TYPE_VOLTS_AC = 3,
+  VALUE_TYPE_VOLTS_DC = 4,
+  VALUE_TYPE_AMPERES = 5,
+  VALUE_TYPE_WATTS = 6,
+  VALUE_TYPE_HERTZ = 7,
+  VALUE_TYPE_CELSIUS = 8,
+  VALUE_TYPE_PERCENT_RH = 9,
+  VALUE_TYPE_RPM = 10,
+  VALUE_TYPE_CMM = 11,
+  VALUE_TYPE_TRUTH_VALUE = 12,
+  VALUE_TYPE_PERCENT = 13,
+  VALUE_TYPE_METERS = 14,
+  VALUE_TYPE_BYTES = 15,
+  DataValueType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  DataValueType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool DataValueType_IsValid(int value);
+const DataValueType DataValueType_MIN = VALUE_TYPE_UNDEFINED;
+const DataValueType DataValueType_MAX = VALUE_TYPE_BYTES;
+const int DataValueType_ARRAYSIZE = DataValueType_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* DataValueType_descriptor();
+inline const ::std::string& DataValueType_Name(DataValueType value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    DataValueType_descriptor(), value);
+}
+inline bool DataValueType_Parse(
+    const ::std::string& name, DataValueType* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<DataValueType>(
+    DataValueType_descriptor(), name, value);
+}
+enum ValueScale {
+  VALUE_SCALE_UNDEFINED = 0,
+  VALUE_SCALE_YOCTO = 1,
+  VALUE_SCALE_ZEPTO = 2,
+  VALUE_SCALE_ATTO = 3,
+  VALUE_SCALE_FEMTO = 4,
+  VALUE_SCALE_PICO = 5,
+  VALUE_SCALE_NANO = 6,
+  VALUE_SCALE_MICRO = 7,
+  VALUE_SCALE_MILLI = 8,
+  VALUE_SCALE_UNITS = 9,
+  VALUE_SCALE_KILO = 10,
+  VALUE_SCALE_MEGA = 11,
+  VALUE_SCALE_GIGA = 12,
+  VALUE_SCALE_TERA = 13,
+  VALUE_SCALE_PETA = 14,
+  VALUE_SCALE_EXA = 15,
+  VALUE_SCALE_ZETTA = 16,
+  VALUE_SCALE_YOTTA = 17,
+  ValueScale_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ValueScale_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ValueScale_IsValid(int value);
+const ValueScale ValueScale_MIN = VALUE_SCALE_UNDEFINED;
+const ValueScale ValueScale_MAX = VALUE_SCALE_YOTTA;
+const int ValueScale_ARRAYSIZE = ValueScale_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ValueScale_descriptor();
+inline const ::std::string& ValueScale_Name(ValueScale value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ValueScale_descriptor(), value);
+}
+inline bool ValueScale_Parse(
+    const ::std::string& name, ValueScale* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ValueScale>(
+    ValueScale_descriptor(), name, value);
+}
+enum SensorStatus {
+  SENSOR_STATUS_UNDEFINED = 0,
+  SENSOR_STATUS_OK = 1,
+  SENSOR_STATUS_UNAVAILABLE = 2,
+  SENSOR_STATUS_NONOPERATIONAL = 3,
+  SensorStatus_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  SensorStatus_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool SensorStatus_IsValid(int value);
+const SensorStatus SensorStatus_MIN = SENSOR_STATUS_UNDEFINED;
+const SensorStatus SensorStatus_MAX = SENSOR_STATUS_NONOPERATIONAL;
+const int SensorStatus_ARRAYSIZE = SensorStatus_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* SensorStatus_descriptor();
+inline const ::std::string& SensorStatus_Name(SensorStatus value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    SensorStatus_descriptor(), value);
+}
+inline bool SensorStatus_Parse(
+    const ::std::string& name, SensorStatus* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<SensorStatus>(
+    SensorStatus_descriptor(), name, value);
+}
+// ===================================================================
+
+class Uuid final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Uuid) */ {
+ public:
+  Uuid();
+  virtual ~Uuid();
+
+  Uuid(const Uuid& from);
+
+  inline Uuid& operator=(const Uuid& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Uuid(Uuid&& from) noexcept
+    : Uuid() {
+    *this = ::std::move(from);
+  }
+
+  inline Uuid& operator=(Uuid&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const Uuid& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Uuid* internal_default_instance() {
+    return reinterpret_cast<const Uuid*>(
+               &_Uuid_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    0;
+
+  void Swap(Uuid* other);
+  friend void swap(Uuid& a, Uuid& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Uuid* New() const final {
+    return CreateMaybeMessage<Uuid>(nullptr);
+  }
+
+  Uuid* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Uuid>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Uuid& from);
+  void MergeFrom(const Uuid& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(Uuid* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string uuid = 1;
+  void clear_uuid();
+  static const int kUuidFieldNumber = 1;
+  const ::std::string& uuid() const;
+  void set_uuid(const ::std::string& value);
+  #if LANG_CXX11
+  void set_uuid(::std::string&& value);
+  #endif
+  void set_uuid(const char* value);
+  void set_uuid(const char* value, size_t size);
+  ::std::string* mutable_uuid();
+  ::std::string* release_uuid();
+  void set_allocated_uuid(::std::string* uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.Uuid)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class HardwareID final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.HardwareID) */ {
+ public:
+  HardwareID();
+  virtual ~HardwareID();
+
+  HardwareID(const HardwareID& from);
+
+  inline HardwareID& operator=(const HardwareID& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  HardwareID(HardwareID&& from) noexcept
+    : HardwareID() {
+    *this = ::std::move(from);
+  }
+
+  inline HardwareID& operator=(HardwareID&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const HardwareID& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const HardwareID* internal_default_instance() {
+    return reinterpret_cast<const HardwareID*>(
+               &_HardwareID_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    1;
+
+  void Swap(HardwareID* other);
+  friend void swap(HardwareID& a, HardwareID& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline HardwareID* New() const final {
+    return CreateMaybeMessage<HardwareID>(nullptr);
+  }
+
+  HardwareID* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<HardwareID>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const HardwareID& from);
+  void MergeFrom(const HardwareID& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(HardwareID* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.Uuid uuid = 1;
+  bool has_uuid() const;
+  void clear_uuid();
+  static const int kUuidFieldNumber = 1;
+  const ::dmi::Uuid& uuid() const;
+  ::dmi::Uuid* release_uuid();
+  ::dmi::Uuid* mutable_uuid();
+  void set_allocated_uuid(::dmi::Uuid* uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.HardwareID)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::dmi::Uuid* uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Uri final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Uri) */ {
+ public:
+  Uri();
+  virtual ~Uri();
+
+  Uri(const Uri& from);
+
+  inline Uri& operator=(const Uri& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Uri(Uri&& from) noexcept
+    : Uri() {
+    *this = ::std::move(from);
+  }
+
+  inline Uri& operator=(Uri&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const Uri& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Uri* internal_default_instance() {
+    return reinterpret_cast<const Uri*>(
+               &_Uri_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    2;
+
+  void Swap(Uri* other);
+  friend void swap(Uri& a, Uri& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Uri* New() const final {
+    return CreateMaybeMessage<Uri>(nullptr);
+  }
+
+  Uri* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Uri>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Uri& from);
+  void MergeFrom(const Uri& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(Uri* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string uri = 1;
+  void clear_uri();
+  static const int kUriFieldNumber = 1;
+  const ::std::string& uri() const;
+  void set_uri(const ::std::string& value);
+  #if LANG_CXX11
+  void set_uri(::std::string&& value);
+  #endif
+  void set_uri(const char* value);
+  void set_uri(const char* value, size_t size);
+  ::std::string* mutable_uri();
+  ::std::string* release_uri();
+  void set_allocated_uri(::std::string* uri);
+
+  // @@protoc_insertion_point(class_scope:dmi.Uri)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr uri_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ComponentState final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ComponentState) */ {
+ public:
+  ComponentState();
+  virtual ~ComponentState();
+
+  ComponentState(const ComponentState& from);
+
+  inline ComponentState& operator=(const ComponentState& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ComponentState(ComponentState&& from) noexcept
+    : ComponentState() {
+    *this = ::std::move(from);
+  }
+
+  inline ComponentState& operator=(ComponentState&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ComponentState& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ComponentState* internal_default_instance() {
+    return reinterpret_cast<const ComponentState*>(
+               &_ComponentState_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    3;
+
+  void Swap(ComponentState* other);
+  friend void swap(ComponentState& a, ComponentState& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ComponentState* New() const final {
+    return CreateMaybeMessage<ComponentState>(nullptr);
+  }
+
+  ComponentState* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ComponentState>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ComponentState& from);
+  void MergeFrom(const ComponentState& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ComponentState* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .google.protobuf.Timestamp state_last_changed = 1;
+  bool has_state_last_changed() const;
+  void clear_state_last_changed();
+  static const int kStateLastChangedFieldNumber = 1;
+  const ::google::protobuf::Timestamp& state_last_changed() const;
+  ::google::protobuf::Timestamp* release_state_last_changed();
+  ::google::protobuf::Timestamp* mutable_state_last_changed();
+  void set_allocated_state_last_changed(::google::protobuf::Timestamp* state_last_changed);
+
+  // .dmi.ComponentAdminState admin_state = 2;
+  void clear_admin_state();
+  static const int kAdminStateFieldNumber = 2;
+  ::dmi::ComponentAdminState admin_state() const;
+  void set_admin_state(::dmi::ComponentAdminState value);
+
+  // .dmi.ComponentOperState oper_state = 3;
+  void clear_oper_state();
+  static const int kOperStateFieldNumber = 3;
+  ::dmi::ComponentOperState oper_state() const;
+  void set_oper_state(::dmi::ComponentOperState value);
+
+  // .dmi.ComponentUsageState usage_state = 4;
+  void clear_usage_state();
+  static const int kUsageStateFieldNumber = 4;
+  ::dmi::ComponentUsageState usage_state() const;
+  void set_usage_state(::dmi::ComponentUsageState value);
+
+  // .dmi.ComponentAlarmState alarm_state = 5;
+  void clear_alarm_state();
+  static const int kAlarmStateFieldNumber = 5;
+  ::dmi::ComponentAlarmState alarm_state() const;
+  void set_alarm_state(::dmi::ComponentAlarmState value);
+
+  // .dmi.ComponentStandbyState standby_state = 6;
+  void clear_standby_state();
+  static const int kStandbyStateFieldNumber = 6;
+  ::dmi::ComponentStandbyState standby_state() const;
+  void set_standby_state(::dmi::ComponentStandbyState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ComponentState)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::Timestamp* state_last_changed_;
+  int admin_state_;
+  int oper_state_;
+  int usage_state_;
+  int alarm_state_;
+  int standby_state_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ComponentSensorData final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ComponentSensorData) */ {
+ public:
+  ComponentSensorData();
+  virtual ~ComponentSensorData();
+
+  ComponentSensorData(const ComponentSensorData& from);
+
+  inline ComponentSensorData& operator=(const ComponentSensorData& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ComponentSensorData(ComponentSensorData&& from) noexcept
+    : ComponentSensorData() {
+    *this = ::std::move(from);
+  }
+
+  inline ComponentSensorData& operator=(ComponentSensorData&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ComponentSensorData& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ComponentSensorData* internal_default_instance() {
+    return reinterpret_cast<const ComponentSensorData*>(
+               &_ComponentSensorData_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    4;
+
+  void Swap(ComponentSensorData* other);
+  friend void swap(ComponentSensorData& a, ComponentSensorData& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ComponentSensorData* New() const final {
+    return CreateMaybeMessage<ComponentSensorData>(nullptr);
+  }
+
+  ComponentSensorData* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ComponentSensorData>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ComponentSensorData& from);
+  void MergeFrom(const ComponentSensorData& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ComponentSensorData* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string units_display = 6;
+  void clear_units_display();
+  static const int kUnitsDisplayFieldNumber = 6;
+  const ::std::string& units_display() const;
+  void set_units_display(const ::std::string& value);
+  #if LANG_CXX11
+  void set_units_display(::std::string&& value);
+  #endif
+  void set_units_display(const char* value);
+  void set_units_display(const char* value, size_t size);
+  ::std::string* mutable_units_display();
+  ::std::string* release_units_display();
+  void set_allocated_units_display(::std::string* units_display);
+
+  // string data_type = 9;
+  void clear_data_type();
+  static const int kDataTypeFieldNumber = 9;
+  const ::std::string& data_type() const;
+  void set_data_type(const ::std::string& value);
+  #if LANG_CXX11
+  void set_data_type(::std::string&& value);
+  #endif
+  void set_data_type(const char* value);
+  void set_data_type(const char* value, size_t size);
+  ::std::string* mutable_data_type();
+  ::std::string* release_data_type();
+  void set_allocated_data_type(::std::string* data_type);
+
+  // .google.protobuf.Timestamp timestamp = 7;
+  bool has_timestamp() const;
+  void clear_timestamp();
+  static const int kTimestampFieldNumber = 7;
+  const ::google::protobuf::Timestamp& timestamp() const;
+  ::google::protobuf::Timestamp* release_timestamp();
+  ::google::protobuf::Timestamp* mutable_timestamp();
+  void set_allocated_timestamp(::google::protobuf::Timestamp* timestamp);
+
+  // int32 value = 1;
+  void clear_value();
+  static const int kValueFieldNumber = 1;
+  ::google::protobuf::int32 value() const;
+  void set_value(::google::protobuf::int32 value);
+
+  // .dmi.DataValueType type = 2;
+  void clear_type();
+  static const int kTypeFieldNumber = 2;
+  ::dmi::DataValueType type() const;
+  void set_type(::dmi::DataValueType value);
+
+  // .dmi.ValueScale scale = 3;
+  void clear_scale();
+  static const int kScaleFieldNumber = 3;
+  ::dmi::ValueScale scale() const;
+  void set_scale(::dmi::ValueScale value);
+
+  // int32 precision = 4;
+  void clear_precision();
+  static const int kPrecisionFieldNumber = 4;
+  ::google::protobuf::int32 precision() const;
+  void set_precision(::google::protobuf::int32 value);
+
+  // .dmi.SensorStatus status = 5;
+  void clear_status();
+  static const int kStatusFieldNumber = 5;
+  ::dmi::SensorStatus status() const;
+  void set_status(::dmi::SensorStatus value);
+
+  // uint32 value_update_rate = 8;
+  void clear_value_update_rate();
+  static const int kValueUpdateRateFieldNumber = 8;
+  ::google::protobuf::uint32 value_update_rate() const;
+  void set_value_update_rate(::google::protobuf::uint32 value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ComponentSensorData)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr units_display_;
+  ::google::protobuf::internal::ArenaStringPtr data_type_;
+  ::google::protobuf::Timestamp* timestamp_;
+  ::google::protobuf::int32 value_;
+  int type_;
+  int scale_;
+  ::google::protobuf::int32 precision_;
+  int status_;
+  ::google::protobuf::uint32 value_update_rate_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PortComponentAttributes final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.PortComponentAttributes) */ {
+ public:
+  PortComponentAttributes();
+  virtual ~PortComponentAttributes();
+
+  PortComponentAttributes(const PortComponentAttributes& from);
+
+  inline PortComponentAttributes& operator=(const PortComponentAttributes& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  PortComponentAttributes(PortComponentAttributes&& from) noexcept
+    : PortComponentAttributes() {
+    *this = ::std::move(from);
+  }
+
+  inline PortComponentAttributes& operator=(PortComponentAttributes&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const PortComponentAttributes& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const PortComponentAttributes* internal_default_instance() {
+    return reinterpret_cast<const PortComponentAttributes*>(
+               &_PortComponentAttributes_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    5;
+
+  void Swap(PortComponentAttributes* other);
+  friend void swap(PortComponentAttributes& a, PortComponentAttributes& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline PortComponentAttributes* New() const final {
+    return CreateMaybeMessage<PortComponentAttributes>(nullptr);
+  }
+
+  PortComponentAttributes* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<PortComponentAttributes>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const PortComponentAttributes& from);
+  void MergeFrom(const PortComponentAttributes& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(PortComponentAttributes* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef PortComponentAttributes_ConnectorType ConnectorType;
+  static const ConnectorType CONNECTOR_TYPE_UNDEFINED =
+    PortComponentAttributes_ConnectorType_CONNECTOR_TYPE_UNDEFINED;
+  static const ConnectorType RJ45 =
+    PortComponentAttributes_ConnectorType_RJ45;
+  static const ConnectorType FIBER_LC =
+    PortComponentAttributes_ConnectorType_FIBER_LC;
+  static const ConnectorType FIBER_SC_PC =
+    PortComponentAttributes_ConnectorType_FIBER_SC_PC;
+  static const ConnectorType FIBER_MPO =
+    PortComponentAttributes_ConnectorType_FIBER_MPO;
+  static const ConnectorType RS232 =
+    PortComponentAttributes_ConnectorType_RS232;
+  static inline bool ConnectorType_IsValid(int value) {
+    return PortComponentAttributes_ConnectorType_IsValid(value);
+  }
+  static const ConnectorType ConnectorType_MIN =
+    PortComponentAttributes_ConnectorType_ConnectorType_MIN;
+  static const ConnectorType ConnectorType_MAX =
+    PortComponentAttributes_ConnectorType_ConnectorType_MAX;
+  static const int ConnectorType_ARRAYSIZE =
+    PortComponentAttributes_ConnectorType_ConnectorType_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  ConnectorType_descriptor() {
+    return PortComponentAttributes_ConnectorType_descriptor();
+  }
+  static inline const ::std::string& ConnectorType_Name(ConnectorType value) {
+    return PortComponentAttributes_ConnectorType_Name(value);
+  }
+  static inline bool ConnectorType_Parse(const ::std::string& name,
+      ConnectorType* value) {
+    return PortComponentAttributes_ConnectorType_Parse(name, value);
+  }
+
+  typedef PortComponentAttributes_Speed Speed;
+  static const Speed SPEED_UNDEFINED =
+    PortComponentAttributes_Speed_SPEED_UNDEFINED;
+  static const Speed DYNAMIC =
+    PortComponentAttributes_Speed_DYNAMIC;
+  static const Speed GIGABIT_1 =
+    PortComponentAttributes_Speed_GIGABIT_1;
+  static const Speed GIGABIT_10 =
+    PortComponentAttributes_Speed_GIGABIT_10;
+  static const Speed GIGABIT_25 =
+    PortComponentAttributes_Speed_GIGABIT_25;
+  static const Speed GIGABIT_40 =
+    PortComponentAttributes_Speed_GIGABIT_40;
+  static const Speed GIGABIT_100 =
+    PortComponentAttributes_Speed_GIGABIT_100;
+  static const Speed GIGABIT_400 =
+    PortComponentAttributes_Speed_GIGABIT_400;
+  static const Speed MEGABIT_2500 =
+    PortComponentAttributes_Speed_MEGABIT_2500;
+  static const Speed MEGABIT_1250 =
+    PortComponentAttributes_Speed_MEGABIT_1250;
+  static inline bool Speed_IsValid(int value) {
+    return PortComponentAttributes_Speed_IsValid(value);
+  }
+  static const Speed Speed_MIN =
+    PortComponentAttributes_Speed_Speed_MIN;
+  static const Speed Speed_MAX =
+    PortComponentAttributes_Speed_Speed_MAX;
+  static const int Speed_ARRAYSIZE =
+    PortComponentAttributes_Speed_Speed_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Speed_descriptor() {
+    return PortComponentAttributes_Speed_descriptor();
+  }
+  static inline const ::std::string& Speed_Name(Speed value) {
+    return PortComponentAttributes_Speed_Name(value);
+  }
+  static inline bool Speed_Parse(const ::std::string& name,
+      Speed* value) {
+    return PortComponentAttributes_Speed_Parse(name, value);
+  }
+
+  typedef PortComponentAttributes_Protocol Protocol;
+  static const Protocol PROTOCOL_UNDEFINED =
+    PortComponentAttributes_Protocol_PROTOCOL_UNDEFINED;
+  static const Protocol ETHERNET =
+    PortComponentAttributes_Protocol_ETHERNET;
+  static const Protocol GPON =
+    PortComponentAttributes_Protocol_GPON;
+  static const Protocol XGPON =
+    PortComponentAttributes_Protocol_XGPON;
+  static const Protocol XGSPON =
+    PortComponentAttributes_Protocol_XGSPON;
+  static const Protocol GFAST =
+    PortComponentAttributes_Protocol_GFAST;
+  static const Protocol SERIAL =
+    PortComponentAttributes_Protocol_SERIAL;
+  static const Protocol EPON =
+    PortComponentAttributes_Protocol_EPON;
+  static const Protocol BITS =
+    PortComponentAttributes_Protocol_BITS;
+  static inline bool Protocol_IsValid(int value) {
+    return PortComponentAttributes_Protocol_IsValid(value);
+  }
+  static const Protocol Protocol_MIN =
+    PortComponentAttributes_Protocol_Protocol_MIN;
+  static const Protocol Protocol_MAX =
+    PortComponentAttributes_Protocol_Protocol_MAX;
+  static const int Protocol_ARRAYSIZE =
+    PortComponentAttributes_Protocol_Protocol_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Protocol_descriptor() {
+    return PortComponentAttributes_Protocol_descriptor();
+  }
+  static inline const ::std::string& Protocol_Name(Protocol value) {
+    return PortComponentAttributes_Protocol_Name(value);
+  }
+  static inline bool Protocol_Parse(const ::std::string& name,
+      Protocol* value) {
+    return PortComponentAttributes_Protocol_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string physical_label = 4;
+  void clear_physical_label();
+  static const int kPhysicalLabelFieldNumber = 4;
+  const ::std::string& physical_label() const;
+  void set_physical_label(const ::std::string& value);
+  #if LANG_CXX11
+  void set_physical_label(::std::string&& value);
+  #endif
+  void set_physical_label(const char* value);
+  void set_physical_label(const char* value, size_t size);
+  ::std::string* mutable_physical_label();
+  ::std::string* release_physical_label();
+  void set_allocated_physical_label(::std::string* physical_label);
+
+  // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+  void clear_connector_type();
+  static const int kConnectorTypeFieldNumber = 1;
+  ::dmi::PortComponentAttributes_ConnectorType connector_type() const;
+  void set_connector_type(::dmi::PortComponentAttributes_ConnectorType value);
+
+  // .dmi.PortComponentAttributes.Speed speed = 2;
+  void clear_speed();
+  static const int kSpeedFieldNumber = 2;
+  ::dmi::PortComponentAttributes_Speed speed() const;
+  void set_speed(::dmi::PortComponentAttributes_Speed value);
+
+  // .dmi.PortComponentAttributes.Protocol protocol = 3;
+  void clear_protocol();
+  static const int kProtocolFieldNumber = 3;
+  ::dmi::PortComponentAttributes_Protocol protocol() const;
+  void set_protocol(::dmi::PortComponentAttributes_Protocol value);
+
+  // @@protoc_insertion_point(class_scope:dmi.PortComponentAttributes)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr physical_label_;
+  int connector_type_;
+  int speed_;
+  int protocol_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ContainerComponentAttributes final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ContainerComponentAttributes) */ {
+ public:
+  ContainerComponentAttributes();
+  virtual ~ContainerComponentAttributes();
+
+  ContainerComponentAttributes(const ContainerComponentAttributes& from);
+
+  inline ContainerComponentAttributes& operator=(const ContainerComponentAttributes& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ContainerComponentAttributes(ContainerComponentAttributes&& from) noexcept
+    : ContainerComponentAttributes() {
+    *this = ::std::move(from);
+  }
+
+  inline ContainerComponentAttributes& operator=(ContainerComponentAttributes&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ContainerComponentAttributes& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ContainerComponentAttributes* internal_default_instance() {
+    return reinterpret_cast<const ContainerComponentAttributes*>(
+               &_ContainerComponentAttributes_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    6;
+
+  void Swap(ContainerComponentAttributes* other);
+  friend void swap(ContainerComponentAttributes& a, ContainerComponentAttributes& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ContainerComponentAttributes* New() const final {
+    return CreateMaybeMessage<ContainerComponentAttributes>(nullptr);
+  }
+
+  ContainerComponentAttributes* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ContainerComponentAttributes>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ContainerComponentAttributes& from);
+  void MergeFrom(const ContainerComponentAttributes& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ContainerComponentAttributes* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string physical_label = 1;
+  void clear_physical_label();
+  static const int kPhysicalLabelFieldNumber = 1;
+  const ::std::string& physical_label() const;
+  void set_physical_label(const ::std::string& value);
+  #if LANG_CXX11
+  void set_physical_label(::std::string&& value);
+  #endif
+  void set_physical_label(const char* value);
+  void set_physical_label(const char* value, size_t size);
+  ::std::string* mutable_physical_label();
+  ::std::string* release_physical_label();
+  void set_allocated_physical_label(::std::string* physical_label);
+
+  // @@protoc_insertion_point(class_scope:dmi.ContainerComponentAttributes)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr physical_label_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class PsuComponentAttributes final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.PsuComponentAttributes) */ {
+ public:
+  PsuComponentAttributes();
+  virtual ~PsuComponentAttributes();
+
+  PsuComponentAttributes(const PsuComponentAttributes& from);
+
+  inline PsuComponentAttributes& operator=(const PsuComponentAttributes& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  PsuComponentAttributes(PsuComponentAttributes&& from) noexcept
+    : PsuComponentAttributes() {
+    *this = ::std::move(from);
+  }
+
+  inline PsuComponentAttributes& operator=(PsuComponentAttributes&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const PsuComponentAttributes& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const PsuComponentAttributes* internal_default_instance() {
+    return reinterpret_cast<const PsuComponentAttributes*>(
+               &_PsuComponentAttributes_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    7;
+
+  void Swap(PsuComponentAttributes* other);
+  friend void swap(PsuComponentAttributes& a, PsuComponentAttributes& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline PsuComponentAttributes* New() const final {
+    return CreateMaybeMessage<PsuComponentAttributes>(nullptr);
+  }
+
+  PsuComponentAttributes* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<PsuComponentAttributes>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const PsuComponentAttributes& from);
+  void MergeFrom(const PsuComponentAttributes& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(PsuComponentAttributes* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef PsuComponentAttributes_SupportedVoltage SupportedVoltage;
+  static const SupportedVoltage SUPPORTED_VOLTAGE_UNDEFINED =
+    PsuComponentAttributes_SupportedVoltage_SUPPORTED_VOLTAGE_UNDEFINED;
+  static const SupportedVoltage V48 =
+    PsuComponentAttributes_SupportedVoltage_V48;
+  static const SupportedVoltage V230 =
+    PsuComponentAttributes_SupportedVoltage_V230;
+  static const SupportedVoltage V115 =
+    PsuComponentAttributes_SupportedVoltage_V115;
+  static inline bool SupportedVoltage_IsValid(int value) {
+    return PsuComponentAttributes_SupportedVoltage_IsValid(value);
+  }
+  static const SupportedVoltage SupportedVoltage_MIN =
+    PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MIN;
+  static const SupportedVoltage SupportedVoltage_MAX =
+    PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MAX;
+  static const int SupportedVoltage_ARRAYSIZE =
+    PsuComponentAttributes_SupportedVoltage_SupportedVoltage_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  SupportedVoltage_descriptor() {
+    return PsuComponentAttributes_SupportedVoltage_descriptor();
+  }
+  static inline const ::std::string& SupportedVoltage_Name(SupportedVoltage value) {
+    return PsuComponentAttributes_SupportedVoltage_Name(value);
+  }
+  static inline bool SupportedVoltage_Parse(const ::std::string& name,
+      SupportedVoltage* value) {
+    return PsuComponentAttributes_SupportedVoltage_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+  void clear_supported_voltage();
+  static const int kSupportedVoltageFieldNumber = 1;
+  ::dmi::PsuComponentAttributes_SupportedVoltage supported_voltage() const;
+  void set_supported_voltage(::dmi::PsuComponentAttributes_SupportedVoltage value);
+
+  // @@protoc_insertion_point(class_scope:dmi.PsuComponentAttributes)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  int supported_voltage_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class TransceiverComponentsAttributes final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.TransceiverComponentsAttributes) */ {
+ public:
+  TransceiverComponentsAttributes();
+  virtual ~TransceiverComponentsAttributes();
+
+  TransceiverComponentsAttributes(const TransceiverComponentsAttributes& from);
+
+  inline TransceiverComponentsAttributes& operator=(const TransceiverComponentsAttributes& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  TransceiverComponentsAttributes(TransceiverComponentsAttributes&& from) noexcept
+    : TransceiverComponentsAttributes() {
+    *this = ::std::move(from);
+  }
+
+  inline TransceiverComponentsAttributes& operator=(TransceiverComponentsAttributes&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const TransceiverComponentsAttributes& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const TransceiverComponentsAttributes* internal_default_instance() {
+    return reinterpret_cast<const TransceiverComponentsAttributes*>(
+               &_TransceiverComponentsAttributes_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    8;
+
+  void Swap(TransceiverComponentsAttributes* other);
+  friend void swap(TransceiverComponentsAttributes& a, TransceiverComponentsAttributes& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline TransceiverComponentsAttributes* New() const final {
+    return CreateMaybeMessage<TransceiverComponentsAttributes>(nullptr);
+  }
+
+  TransceiverComponentsAttributes* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<TransceiverComponentsAttributes>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const TransceiverComponentsAttributes& from);
+  void MergeFrom(const TransceiverComponentsAttributes& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(TransceiverComponentsAttributes* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef TransceiverComponentsAttributes_FormFactor FormFactor;
+  static const FormFactor FORM_FACTOR_UNKNOWN =
+    TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN;
+  static const FormFactor QSFP =
+    TransceiverComponentsAttributes_FormFactor_QSFP;
+  static const FormFactor QSFP_PLUS =
+    TransceiverComponentsAttributes_FormFactor_QSFP_PLUS;
+  static const FormFactor QSFP28 =
+    TransceiverComponentsAttributes_FormFactor_QSFP28;
+  static const FormFactor SFP =
+    TransceiverComponentsAttributes_FormFactor_SFP;
+  static const FormFactor SFP_PLUS =
+    TransceiverComponentsAttributes_FormFactor_SFP_PLUS;
+  static const FormFactor XFP =
+    TransceiverComponentsAttributes_FormFactor_XFP;
+  static const FormFactor CFP4 =
+    TransceiverComponentsAttributes_FormFactor_CFP4;
+  static const FormFactor CFP2 =
+    TransceiverComponentsAttributes_FormFactor_CFP2;
+  static const FormFactor CPAK =
+    TransceiverComponentsAttributes_FormFactor_CPAK;
+  static const FormFactor X2 =
+    TransceiverComponentsAttributes_FormFactor_X2;
+  static const FormFactor OTHER =
+    TransceiverComponentsAttributes_FormFactor_OTHER;
+  static const FormFactor CFP =
+    TransceiverComponentsAttributes_FormFactor_CFP;
+  static const FormFactor CFP2_ACO =
+    TransceiverComponentsAttributes_FormFactor_CFP2_ACO;
+  static const FormFactor CFP2_DCO =
+    TransceiverComponentsAttributes_FormFactor_CFP2_DCO;
+  static inline bool FormFactor_IsValid(int value) {
+    return TransceiverComponentsAttributes_FormFactor_IsValid(value);
+  }
+  static const FormFactor FormFactor_MIN =
+    TransceiverComponentsAttributes_FormFactor_FormFactor_MIN;
+  static const FormFactor FormFactor_MAX =
+    TransceiverComponentsAttributes_FormFactor_FormFactor_MAX;
+  static const int FormFactor_ARRAYSIZE =
+    TransceiverComponentsAttributes_FormFactor_FormFactor_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  FormFactor_descriptor() {
+    return TransceiverComponentsAttributes_FormFactor_descriptor();
+  }
+  static inline const ::std::string& FormFactor_Name(FormFactor value) {
+    return TransceiverComponentsAttributes_FormFactor_Name(value);
+  }
+  static inline bool FormFactor_Parse(const ::std::string& name,
+      FormFactor* value) {
+    return TransceiverComponentsAttributes_FormFactor_Parse(name, value);
+  }
+
+  typedef TransceiverComponentsAttributes_Type Type;
+  static const Type TYPE_UNKNOWN =
+    TransceiverComponentsAttributes_Type_TYPE_UNKNOWN;
+  static const Type ETHERNET =
+    TransceiverComponentsAttributes_Type_ETHERNET;
+  static const Type GPON =
+    TransceiverComponentsAttributes_Type_GPON;
+  static const Type XGPON =
+    TransceiverComponentsAttributes_Type_XGPON;
+  static const Type XGSPON =
+    TransceiverComponentsAttributes_Type_XGSPON;
+  static const Type CPON =
+    TransceiverComponentsAttributes_Type_CPON;
+  static const Type NG_PON2 =
+    TransceiverComponentsAttributes_Type_NG_PON2;
+  static const Type EPON =
+    TransceiverComponentsAttributes_Type_EPON;
+  static inline bool Type_IsValid(int value) {
+    return TransceiverComponentsAttributes_Type_IsValid(value);
+  }
+  static const Type Type_MIN =
+    TransceiverComponentsAttributes_Type_Type_MIN;
+  static const Type Type_MAX =
+    TransceiverComponentsAttributes_Type_Type_MAX;
+  static const int Type_ARRAYSIZE =
+    TransceiverComponentsAttributes_Type_Type_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Type_descriptor() {
+    return TransceiverComponentsAttributes_Type_descriptor();
+  }
+  static inline const ::std::string& Type_Name(Type value) {
+    return TransceiverComponentsAttributes_Type_Name(value);
+  }
+  static inline bool Type_Parse(const ::std::string& name,
+      Type* value) {
+    return TransceiverComponentsAttributes_Type_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // repeated uint32 rx_wavelength = 5;
+  int rx_wavelength_size() const;
+  void clear_rx_wavelength();
+  static const int kRxWavelengthFieldNumber = 5;
+  ::google::protobuf::uint32 rx_wavelength(int index) const;
+  void set_rx_wavelength(int index, ::google::protobuf::uint32 value);
+  void add_rx_wavelength(::google::protobuf::uint32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+      rx_wavelength() const;
+  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+      mutable_rx_wavelength();
+
+  // repeated uint32 tx_wavelength = 6;
+  int tx_wavelength_size() const;
+  void clear_tx_wavelength();
+  static const int kTxWavelengthFieldNumber = 6;
+  ::google::protobuf::uint32 tx_wavelength(int index) const;
+  void set_tx_wavelength(int index, ::google::protobuf::uint32 value);
+  void add_tx_wavelength(::google::protobuf::uint32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+      tx_wavelength() const;
+  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+      mutable_tx_wavelength();
+
+  // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+  void clear_form_factor();
+  static const int kFormFactorFieldNumber = 1;
+  ::dmi::TransceiverComponentsAttributes_FormFactor form_factor() const;
+  void set_form_factor(::dmi::TransceiverComponentsAttributes_FormFactor value);
+
+  // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+  void clear_trans_type();
+  static const int kTransTypeFieldNumber = 2;
+  ::dmi::TransceiverComponentsAttributes_Type trans_type() const;
+  void set_trans_type(::dmi::TransceiverComponentsAttributes_Type value);
+
+  // uint32 max_distance = 3;
+  void clear_max_distance();
+  static const int kMaxDistanceFieldNumber = 3;
+  ::google::protobuf::uint32 max_distance() const;
+  void set_max_distance(::google::protobuf::uint32 value);
+
+  // .dmi.ValueScale max_distance_scale = 4;
+  void clear_max_distance_scale();
+  static const int kMaxDistanceScaleFieldNumber = 4;
+  ::dmi::ValueScale max_distance_scale() const;
+  void set_max_distance_scale(::dmi::ValueScale value);
+
+  // .dmi.ValueScale wavelength_scale = 7;
+  void clear_wavelength_scale();
+  static const int kWavelengthScaleFieldNumber = 7;
+  ::dmi::ValueScale wavelength_scale() const;
+  void set_wavelength_scale(::dmi::ValueScale value);
+
+  // @@protoc_insertion_point(class_scope:dmi.TransceiverComponentsAttributes)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > rx_wavelength_;
+  mutable std::atomic<int> _rx_wavelength_cached_byte_size_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > tx_wavelength_;
+  mutable std::atomic<int> _tx_wavelength_cached_byte_size_;
+  int form_factor_;
+  int trans_type_;
+  ::google::protobuf::uint32 max_distance_;
+  int max_distance_scale_;
+  int wavelength_scale_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Component final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Component) */ {
+ public:
+  Component();
+  virtual ~Component();
+
+  Component(const Component& from);
+
+  inline Component& operator=(const Component& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Component(Component&& from) noexcept
+    : Component() {
+    *this = ::std::move(from);
+  }
+
+  inline Component& operator=(Component&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const Component& default_instance();
+
+  enum SpecificCase {
+    kPortAttr = 50,
+    kContainerAttr = 51,
+    kPsuAttr = 52,
+    kTransceiverAttr = 53,
+    SPECIFIC_NOT_SET = 0,
+  };
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Component* internal_default_instance() {
+    return reinterpret_cast<const Component*>(
+               &_Component_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    9;
+
+  void Swap(Component* other);
+  friend void swap(Component& a, Component& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Component* New() const final {
+    return CreateMaybeMessage<Component>(nullptr);
+  }
+
+  Component* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Component>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Component& from);
+  void MergeFrom(const Component& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(Component* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated .dmi.Component children = 6;
+  int children_size() const;
+  void clear_children();
+  static const int kChildrenFieldNumber = 6;
+  ::dmi::Component* mutable_children(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::Component >*
+      mutable_children();
+  const ::dmi::Component& children(int index) const;
+  ::dmi::Component* add_children();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::Component >&
+      children() const;
+
+  // repeated .dmi.ComponentSensorData sensor_data = 20;
+  int sensor_data_size() const;
+  void clear_sensor_data();
+  static const int kSensorDataFieldNumber = 20;
+  ::dmi::ComponentSensorData* mutable_sensor_data(int index);
+  ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >*
+      mutable_sensor_data();
+  const ::dmi::ComponentSensorData& sensor_data(int index) const;
+  ::dmi::ComponentSensorData* add_sensor_data();
+  const ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >&
+      sensor_data() const;
+
+  // string name = 1;
+  void clear_name();
+  static const int kNameFieldNumber = 1;
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_name(::std::string&& value);
+  #endif
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
+
+  // string description = 3;
+  void clear_description();
+  static const int kDescriptionFieldNumber = 3;
+  const ::std::string& description() const;
+  void set_description(const ::std::string& value);
+  #if LANG_CXX11
+  void set_description(::std::string&& value);
+  #endif
+  void set_description(const char* value);
+  void set_description(const char* value, size_t size);
+  ::std::string* mutable_description();
+  ::std::string* release_description();
+  void set_allocated_description(::std::string* description);
+
+  // string parent = 4;
+  void clear_parent();
+  static const int kParentFieldNumber = 4;
+  const ::std::string& parent() const;
+  void set_parent(const ::std::string& value);
+  #if LANG_CXX11
+  void set_parent(::std::string&& value);
+  #endif
+  void set_parent(const char* value);
+  void set_parent(const char* value, size_t size);
+  ::std::string* mutable_parent();
+  ::std::string* release_parent();
+  void set_allocated_parent(::std::string* parent);
+
+  // string hardware_rev = 7;
+  void clear_hardware_rev();
+  static const int kHardwareRevFieldNumber = 7;
+  const ::std::string& hardware_rev() const;
+  void set_hardware_rev(const ::std::string& value);
+  #if LANG_CXX11
+  void set_hardware_rev(::std::string&& value);
+  #endif
+  void set_hardware_rev(const char* value);
+  void set_hardware_rev(const char* value, size_t size);
+  ::std::string* mutable_hardware_rev();
+  ::std::string* release_hardware_rev();
+  void set_allocated_hardware_rev(::std::string* hardware_rev);
+
+  // string firmware_rev = 8;
+  void clear_firmware_rev();
+  static const int kFirmwareRevFieldNumber = 8;
+  const ::std::string& firmware_rev() const;
+  void set_firmware_rev(const ::std::string& value);
+  #if LANG_CXX11
+  void set_firmware_rev(::std::string&& value);
+  #endif
+  void set_firmware_rev(const char* value);
+  void set_firmware_rev(const char* value, size_t size);
+  ::std::string* mutable_firmware_rev();
+  ::std::string* release_firmware_rev();
+  void set_allocated_firmware_rev(::std::string* firmware_rev);
+
+  // string software_rev = 9;
+  void clear_software_rev();
+  static const int kSoftwareRevFieldNumber = 9;
+  const ::std::string& software_rev() const;
+  void set_software_rev(const ::std::string& value);
+  #if LANG_CXX11
+  void set_software_rev(::std::string&& value);
+  #endif
+  void set_software_rev(const char* value);
+  void set_software_rev(const char* value, size_t size);
+  ::std::string* mutable_software_rev();
+  ::std::string* release_software_rev();
+  void set_allocated_software_rev(::std::string* software_rev);
+
+  // string serial_num = 10;
+  void clear_serial_num();
+  static const int kSerialNumFieldNumber = 10;
+  const ::std::string& serial_num() const;
+  void set_serial_num(const ::std::string& value);
+  #if LANG_CXX11
+  void set_serial_num(::std::string&& value);
+  #endif
+  void set_serial_num(const char* value);
+  void set_serial_num(const char* value, size_t size);
+  ::std::string* mutable_serial_num();
+  ::std::string* release_serial_num();
+  void set_allocated_serial_num(::std::string* serial_num);
+
+  // string mfg_name = 11;
+  void clear_mfg_name();
+  static const int kMfgNameFieldNumber = 11;
+  const ::std::string& mfg_name() const;
+  void set_mfg_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_mfg_name(::std::string&& value);
+  #endif
+  void set_mfg_name(const char* value);
+  void set_mfg_name(const char* value, size_t size);
+  ::std::string* mutable_mfg_name();
+  ::std::string* release_mfg_name();
+  void set_allocated_mfg_name(::std::string* mfg_name);
+
+  // string model_name = 12;
+  void clear_model_name();
+  static const int kModelNameFieldNumber = 12;
+  const ::std::string& model_name() const;
+  void set_model_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_model_name(::std::string&& value);
+  #endif
+  void set_model_name(const char* value);
+  void set_model_name(const char* value, size_t size);
+  ::std::string* mutable_model_name();
+  ::std::string* release_model_name();
+  void set_allocated_model_name(::std::string* model_name);
+
+  // string alias = 13;
+  void clear_alias();
+  static const int kAliasFieldNumber = 13;
+  const ::std::string& alias() const;
+  void set_alias(const ::std::string& value);
+  #if LANG_CXX11
+  void set_alias(::std::string&& value);
+  #endif
+  void set_alias(const char* value);
+  void set_alias(const char* value, size_t size);
+  ::std::string* mutable_alias();
+  ::std::string* release_alias();
+  void set_allocated_alias(::std::string* alias);
+
+  // string asset_id = 14;
+  void clear_asset_id();
+  static const int kAssetIdFieldNumber = 14;
+  const ::std::string& asset_id() const;
+  void set_asset_id(const ::std::string& value);
+  #if LANG_CXX11
+  void set_asset_id(::std::string&& value);
+  #endif
+  void set_asset_id(const char* value);
+  void set_asset_id(const char* value, size_t size);
+  ::std::string* mutable_asset_id();
+  ::std::string* release_asset_id();
+  void set_allocated_asset_id(::std::string* asset_id);
+
+  // .google.protobuf.Timestamp mfg_date = 16;
+  bool has_mfg_date() const;
+  void clear_mfg_date();
+  static const int kMfgDateFieldNumber = 16;
+  const ::google::protobuf::Timestamp& mfg_date() const;
+  ::google::protobuf::Timestamp* release_mfg_date();
+  ::google::protobuf::Timestamp* mutable_mfg_date();
+  void set_allocated_mfg_date(::google::protobuf::Timestamp* mfg_date);
+
+  // .dmi.Uri uri = 17;
+  bool has_uri() const;
+  void clear_uri();
+  static const int kUriFieldNumber = 17;
+  const ::dmi::Uri& uri() const;
+  ::dmi::Uri* release_uri();
+  ::dmi::Uri* mutable_uri();
+  void set_allocated_uri(::dmi::Uri* uri);
+
+  // .dmi.Uuid uuid = 18;
+  bool has_uuid() const;
+  void clear_uuid();
+  static const int kUuidFieldNumber = 18;
+  const ::dmi::Uuid& uuid() const;
+  ::dmi::Uuid* release_uuid();
+  ::dmi::Uuid* mutable_uuid();
+  void set_allocated_uuid(::dmi::Uuid* uuid);
+
+  // .dmi.ComponentState state = 19;
+  bool has_state() const;
+  void clear_state();
+  static const int kStateFieldNumber = 19;
+  const ::dmi::ComponentState& state() const;
+  ::dmi::ComponentState* release_state();
+  ::dmi::ComponentState* mutable_state();
+  void set_allocated_state(::dmi::ComponentState* state);
+
+  // .dmi.ComponentType class = 2;
+  void clear_class_();
+  static const int kClassFieldNumber = 2;
+  ::dmi::ComponentType class_() const;
+  void set_class_(::dmi::ComponentType value);
+
+  // int32 parent_rel_pos = 5;
+  void clear_parent_rel_pos();
+  static const int kParentRelPosFieldNumber = 5;
+  ::google::protobuf::int32 parent_rel_pos() const;
+  void set_parent_rel_pos(::google::protobuf::int32 value);
+
+  // bool is_fru = 15;
+  void clear_is_fru();
+  static const int kIsFruFieldNumber = 15;
+  bool is_fru() const;
+  void set_is_fru(bool value);
+
+  // .dmi.PortComponentAttributes port_attr = 50;
+  bool has_port_attr() const;
+  void clear_port_attr();
+  static const int kPortAttrFieldNumber = 50;
+  const ::dmi::PortComponentAttributes& port_attr() const;
+  ::dmi::PortComponentAttributes* release_port_attr();
+  ::dmi::PortComponentAttributes* mutable_port_attr();
+  void set_allocated_port_attr(::dmi::PortComponentAttributes* port_attr);
+
+  // .dmi.ContainerComponentAttributes container_attr = 51;
+  bool has_container_attr() const;
+  void clear_container_attr();
+  static const int kContainerAttrFieldNumber = 51;
+  const ::dmi::ContainerComponentAttributes& container_attr() const;
+  ::dmi::ContainerComponentAttributes* release_container_attr();
+  ::dmi::ContainerComponentAttributes* mutable_container_attr();
+  void set_allocated_container_attr(::dmi::ContainerComponentAttributes* container_attr);
+
+  // .dmi.PsuComponentAttributes psu_attr = 52;
+  bool has_psu_attr() const;
+  void clear_psu_attr();
+  static const int kPsuAttrFieldNumber = 52;
+  const ::dmi::PsuComponentAttributes& psu_attr() const;
+  ::dmi::PsuComponentAttributes* release_psu_attr();
+  ::dmi::PsuComponentAttributes* mutable_psu_attr();
+  void set_allocated_psu_attr(::dmi::PsuComponentAttributes* psu_attr);
+
+  // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+  bool has_transceiver_attr() const;
+  void clear_transceiver_attr();
+  static const int kTransceiverAttrFieldNumber = 53;
+  const ::dmi::TransceiverComponentsAttributes& transceiver_attr() const;
+  ::dmi::TransceiverComponentsAttributes* release_transceiver_attr();
+  ::dmi::TransceiverComponentsAttributes* mutable_transceiver_attr();
+  void set_allocated_transceiver_attr(::dmi::TransceiverComponentsAttributes* transceiver_attr);
+
+  void clear_specific();
+  SpecificCase specific_case() const;
+  // @@protoc_insertion_point(class_scope:dmi.Component)
+ private:
+  class HasBitSetters;
+  void set_has_port_attr();
+  void set_has_container_attr();
+  void set_has_psu_attr();
+  void set_has_transceiver_attr();
+
+  inline bool has_specific() const;
+  inline void clear_has_specific();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::Component > children_;
+  ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData > sensor_data_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  ::google::protobuf::internal::ArenaStringPtr description_;
+  ::google::protobuf::internal::ArenaStringPtr parent_;
+  ::google::protobuf::internal::ArenaStringPtr hardware_rev_;
+  ::google::protobuf::internal::ArenaStringPtr firmware_rev_;
+  ::google::protobuf::internal::ArenaStringPtr software_rev_;
+  ::google::protobuf::internal::ArenaStringPtr serial_num_;
+  ::google::protobuf::internal::ArenaStringPtr mfg_name_;
+  ::google::protobuf::internal::ArenaStringPtr model_name_;
+  ::google::protobuf::internal::ArenaStringPtr alias_;
+  ::google::protobuf::internal::ArenaStringPtr asset_id_;
+  ::google::protobuf::Timestamp* mfg_date_;
+  ::dmi::Uri* uri_;
+  ::dmi::Uuid* uuid_;
+  ::dmi::ComponentState* state_;
+  int class__;
+  ::google::protobuf::int32 parent_rel_pos_;
+  bool is_fru_;
+  union SpecificUnion {
+    SpecificUnion() {}
+    ::dmi::PortComponentAttributes* port_attr_;
+    ::dmi::ContainerComponentAttributes* container_attr_;
+    ::dmi::PsuComponentAttributes* psu_attr_;
+    ::dmi::TransceiverComponentsAttributes* transceiver_attr_;
+  } specific_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class Hardware final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Hardware) */ {
+ public:
+  Hardware();
+  virtual ~Hardware();
+
+  Hardware(const Hardware& from);
+
+  inline Hardware& operator=(const Hardware& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  Hardware(Hardware&& from) noexcept
+    : Hardware() {
+    *this = ::std::move(from);
+  }
+
+  inline Hardware& operator=(Hardware&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const Hardware& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const Hardware* internal_default_instance() {
+    return reinterpret_cast<const Hardware*>(
+               &_Hardware_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    10;
+
+  void Swap(Hardware* other);
+  friend void swap(Hardware& a, Hardware& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline Hardware* New() const final {
+    return CreateMaybeMessage<Hardware>(nullptr);
+  }
+
+  Hardware* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<Hardware>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const Hardware& from);
+  void MergeFrom(const Hardware& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(Hardware* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .google.protobuf.Timestamp last_change = 1;
+  bool has_last_change() const;
+  void clear_last_change();
+  static const int kLastChangeFieldNumber = 1;
+  const ::google::protobuf::Timestamp& last_change() const;
+  ::google::protobuf::Timestamp* release_last_change();
+  ::google::protobuf::Timestamp* mutable_last_change();
+  void set_allocated_last_change(::google::protobuf::Timestamp* last_change);
+
+  // .dmi.Component root = 2;
+  bool has_root() const;
+  void clear_root();
+  static const int kRootFieldNumber = 2;
+  const ::dmi::Component& root() const;
+  ::dmi::Component* release_root();
+  ::dmi::Component* mutable_root();
+  void set_allocated_root(::dmi::Component* root);
+
+  // .google.protobuf.Timestamp last_booted = 3;
+  bool has_last_booted() const;
+  void clear_last_booted();
+  static const int kLastBootedFieldNumber = 3;
+  const ::google::protobuf::Timestamp& last_booted() const;
+  ::google::protobuf::Timestamp* release_last_booted();
+  ::google::protobuf::Timestamp* mutable_last_booted();
+  void set_allocated_last_booted(::google::protobuf::Timestamp* last_booted);
+
+  // @@protoc_insertion_point(class_scope:dmi.Hardware)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::Timestamp* last_change_;
+  ::dmi::Component* root_;
+  ::google::protobuf::Timestamp* last_booted_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ModifiableComponent final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ModifiableComponent) */ {
+ public:
+  ModifiableComponent();
+  virtual ~ModifiableComponent();
+
+  ModifiableComponent(const ModifiableComponent& from);
+
+  inline ModifiableComponent& operator=(const ModifiableComponent& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ModifiableComponent(ModifiableComponent&& from) noexcept
+    : ModifiableComponent() {
+    *this = ::std::move(from);
+  }
+
+  inline ModifiableComponent& operator=(ModifiableComponent&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ModifiableComponent& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ModifiableComponent* internal_default_instance() {
+    return reinterpret_cast<const ModifiableComponent*>(
+               &_ModifiableComponent_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    11;
+
+  void Swap(ModifiableComponent* other);
+  friend void swap(ModifiableComponent& a, ModifiableComponent& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ModifiableComponent* New() const final {
+    return CreateMaybeMessage<ModifiableComponent>(nullptr);
+  }
+
+  ModifiableComponent* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ModifiableComponent>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ModifiableComponent& from);
+  void MergeFrom(const ModifiableComponent& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ModifiableComponent* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string name = 1;
+  void clear_name();
+  static const int kNameFieldNumber = 1;
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_name(::std::string&& value);
+  #endif
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
+
+  // string alias = 5;
+  void clear_alias();
+  static const int kAliasFieldNumber = 5;
+  const ::std::string& alias() const;
+  void set_alias(const ::std::string& value);
+  #if LANG_CXX11
+  void set_alias(::std::string&& value);
+  #endif
+  void set_alias(const char* value);
+  void set_alias(const char* value, size_t size);
+  ::std::string* mutable_alias();
+  ::std::string* release_alias();
+  void set_allocated_alias(::std::string* alias);
+
+  // string asset_id = 6;
+  void clear_asset_id();
+  static const int kAssetIdFieldNumber = 6;
+  const ::std::string& asset_id() const;
+  void set_asset_id(const ::std::string& value);
+  #if LANG_CXX11
+  void set_asset_id(::std::string&& value);
+  #endif
+  void set_asset_id(const char* value);
+  void set_asset_id(const char* value, size_t size);
+  ::std::string* mutable_asset_id();
+  ::std::string* release_asset_id();
+  void set_allocated_asset_id(::std::string* asset_id);
+
+  // .dmi.Component parent = 3;
+  bool has_parent() const;
+  void clear_parent();
+  static const int kParentFieldNumber = 3;
+  const ::dmi::Component& parent() const;
+  ::dmi::Component* release_parent();
+  ::dmi::Component* mutable_parent();
+  void set_allocated_parent(::dmi::Component* parent);
+
+  // .dmi.Uri uri = 7;
+  bool has_uri() const;
+  void clear_uri();
+  static const int kUriFieldNumber = 7;
+  const ::dmi::Uri& uri() const;
+  ::dmi::Uri* release_uri();
+  ::dmi::Uri* mutable_uri();
+  void set_allocated_uri(::dmi::Uri* uri);
+
+  // .dmi.ComponentType class = 2;
+  void clear_class_();
+  static const int kClassFieldNumber = 2;
+  ::dmi::ComponentType class_() const;
+  void set_class_(::dmi::ComponentType value);
+
+  // int32 parent_rel_pos = 4;
+  void clear_parent_rel_pos();
+  static const int kParentRelPosFieldNumber = 4;
+  ::google::protobuf::int32 parent_rel_pos() const;
+  void set_parent_rel_pos(::google::protobuf::int32 value);
+
+  // .dmi.ComponentAdminState admin_state = 8;
+  void clear_admin_state();
+  static const int kAdminStateFieldNumber = 8;
+  ::dmi::ComponentAdminState admin_state() const;
+  void set_admin_state(::dmi::ComponentAdminState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ModifiableComponent)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  ::google::protobuf::internal::ArenaStringPtr alias_;
+  ::google::protobuf::internal::ArenaStringPtr asset_id_;
+  ::dmi::Component* parent_;
+  ::dmi::Uri* uri_;
+  int class__;
+  ::google::protobuf::int32 parent_rel_pos_;
+  int admin_state_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_2eproto;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic push
+  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif  // __GNUC__
+// Uuid
+
+// string uuid = 1;
+inline void Uuid::clear_uuid() {
+  uuid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Uuid::uuid() const {
+  // @@protoc_insertion_point(field_get:dmi.Uuid.uuid)
+  return uuid_.GetNoArena();
+}
+inline void Uuid::set_uuid(const ::std::string& value) {
+  
+  uuid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Uuid.uuid)
+}
+#if LANG_CXX11
+inline void Uuid::set_uuid(::std::string&& value) {
+  
+  uuid_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Uuid.uuid)
+}
+#endif
+inline void Uuid::set_uuid(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  uuid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Uuid.uuid)
+}
+inline void Uuid::set_uuid(const char* value, size_t size) {
+  
+  uuid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Uuid.uuid)
+}
+inline ::std::string* Uuid::mutable_uuid() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Uuid.uuid)
+  return uuid_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Uuid::release_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.Uuid.uuid)
+  
+  return uuid_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Uuid::set_allocated_uuid(::std::string* uuid) {
+  if (uuid != nullptr) {
+    
+  } else {
+    
+  }
+  uuid_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), uuid);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Uuid.uuid)
+}
+
+// -------------------------------------------------------------------
+
+// HardwareID
+
+// .dmi.Uuid uuid = 1;
+inline bool HardwareID::has_uuid() const {
+  return this != internal_default_instance() && uuid_ != nullptr;
+}
+inline void HardwareID::clear_uuid() {
+  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
+    delete uuid_;
+  }
+  uuid_ = nullptr;
+}
+inline const ::dmi::Uuid& HardwareID::uuid() const {
+  const ::dmi::Uuid* p = uuid_;
+  // @@protoc_insertion_point(field_get:dmi.HardwareID.uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* HardwareID::release_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.HardwareID.uuid)
+  
+  ::dmi::Uuid* temp = uuid_;
+  uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* HardwareID::mutable_uuid() {
+  
+  if (uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.HardwareID.uuid)
+  return uuid_;
+}
+inline void HardwareID::set_allocated_uuid(::dmi::Uuid* uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete uuid_;
+  }
+  if (uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  uuid_ = uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.HardwareID.uuid)
+}
+
+// -------------------------------------------------------------------
+
+// Uri
+
+// string uri = 1;
+inline void Uri::clear_uri() {
+  uri_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Uri::uri() const {
+  // @@protoc_insertion_point(field_get:dmi.Uri.uri)
+  return uri_.GetNoArena();
+}
+inline void Uri::set_uri(const ::std::string& value) {
+  
+  uri_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Uri.uri)
+}
+#if LANG_CXX11
+inline void Uri::set_uri(::std::string&& value) {
+  
+  uri_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Uri.uri)
+}
+#endif
+inline void Uri::set_uri(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  uri_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Uri.uri)
+}
+inline void Uri::set_uri(const char* value, size_t size) {
+  
+  uri_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Uri.uri)
+}
+inline ::std::string* Uri::mutable_uri() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Uri.uri)
+  return uri_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Uri::release_uri() {
+  // @@protoc_insertion_point(field_release:dmi.Uri.uri)
+  
+  return uri_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Uri::set_allocated_uri(::std::string* uri) {
+  if (uri != nullptr) {
+    
+  } else {
+    
+  }
+  uri_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), uri);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Uri.uri)
+}
+
+// -------------------------------------------------------------------
+
+// ComponentState
+
+// .google.protobuf.Timestamp state_last_changed = 1;
+inline bool ComponentState::has_state_last_changed() const {
+  return this != internal_default_instance() && state_last_changed_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& ComponentState::state_last_changed() const {
+  const ::google::protobuf::Timestamp* p = state_last_changed_;
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.state_last_changed)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* ComponentState::release_state_last_changed() {
+  // @@protoc_insertion_point(field_release:dmi.ComponentState.state_last_changed)
+  
+  ::google::protobuf::Timestamp* temp = state_last_changed_;
+  state_last_changed_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* ComponentState::mutable_state_last_changed() {
+  
+  if (state_last_changed_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    state_last_changed_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ComponentState.state_last_changed)
+  return state_last_changed_;
+}
+inline void ComponentState::set_allocated_state_last_changed(::google::protobuf::Timestamp* state_last_changed) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(state_last_changed_);
+  }
+  if (state_last_changed) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(state_last_changed)->GetArena();
+    if (message_arena != submessage_arena) {
+      state_last_changed = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, state_last_changed, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  state_last_changed_ = state_last_changed;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentState.state_last_changed)
+}
+
+// .dmi.ComponentAdminState admin_state = 2;
+inline void ComponentState::clear_admin_state() {
+  admin_state_ = 0;
+}
+inline ::dmi::ComponentAdminState ComponentState::admin_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.admin_state)
+  return static_cast< ::dmi::ComponentAdminState >(admin_state_);
+}
+inline void ComponentState::set_admin_state(::dmi::ComponentAdminState value) {
+  
+  admin_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.admin_state)
+}
+
+// .dmi.ComponentOperState oper_state = 3;
+inline void ComponentState::clear_oper_state() {
+  oper_state_ = 0;
+}
+inline ::dmi::ComponentOperState ComponentState::oper_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.oper_state)
+  return static_cast< ::dmi::ComponentOperState >(oper_state_);
+}
+inline void ComponentState::set_oper_state(::dmi::ComponentOperState value) {
+  
+  oper_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.oper_state)
+}
+
+// .dmi.ComponentUsageState usage_state = 4;
+inline void ComponentState::clear_usage_state() {
+  usage_state_ = 0;
+}
+inline ::dmi::ComponentUsageState ComponentState::usage_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.usage_state)
+  return static_cast< ::dmi::ComponentUsageState >(usage_state_);
+}
+inline void ComponentState::set_usage_state(::dmi::ComponentUsageState value) {
+  
+  usage_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.usage_state)
+}
+
+// .dmi.ComponentAlarmState alarm_state = 5;
+inline void ComponentState::clear_alarm_state() {
+  alarm_state_ = 0;
+}
+inline ::dmi::ComponentAlarmState ComponentState::alarm_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.alarm_state)
+  return static_cast< ::dmi::ComponentAlarmState >(alarm_state_);
+}
+inline void ComponentState::set_alarm_state(::dmi::ComponentAlarmState value) {
+  
+  alarm_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.alarm_state)
+}
+
+// .dmi.ComponentStandbyState standby_state = 6;
+inline void ComponentState::clear_standby_state() {
+  standby_state_ = 0;
+}
+inline ::dmi::ComponentStandbyState ComponentState::standby_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentState.standby_state)
+  return static_cast< ::dmi::ComponentStandbyState >(standby_state_);
+}
+inline void ComponentState::set_standby_state(::dmi::ComponentStandbyState value) {
+  
+  standby_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentState.standby_state)
+}
+
+// -------------------------------------------------------------------
+
+// ComponentSensorData
+
+// int32 value = 1;
+inline void ComponentSensorData::clear_value() {
+  value_ = 0;
+}
+inline ::google::protobuf::int32 ComponentSensorData::value() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.value)
+  return value_;
+}
+inline void ComponentSensorData::set_value(::google::protobuf::int32 value) {
+  
+  value_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.value)
+}
+
+// .dmi.DataValueType type = 2;
+inline void ComponentSensorData::clear_type() {
+  type_ = 0;
+}
+inline ::dmi::DataValueType ComponentSensorData::type() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.type)
+  return static_cast< ::dmi::DataValueType >(type_);
+}
+inline void ComponentSensorData::set_type(::dmi::DataValueType value) {
+  
+  type_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.type)
+}
+
+// .dmi.ValueScale scale = 3;
+inline void ComponentSensorData::clear_scale() {
+  scale_ = 0;
+}
+inline ::dmi::ValueScale ComponentSensorData::scale() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.scale)
+  return static_cast< ::dmi::ValueScale >(scale_);
+}
+inline void ComponentSensorData::set_scale(::dmi::ValueScale value) {
+  
+  scale_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.scale)
+}
+
+// int32 precision = 4;
+inline void ComponentSensorData::clear_precision() {
+  precision_ = 0;
+}
+inline ::google::protobuf::int32 ComponentSensorData::precision() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.precision)
+  return precision_;
+}
+inline void ComponentSensorData::set_precision(::google::protobuf::int32 value) {
+  
+  precision_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.precision)
+}
+
+// .dmi.SensorStatus status = 5;
+inline void ComponentSensorData::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::SensorStatus ComponentSensorData::status() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.status)
+  return static_cast< ::dmi::SensorStatus >(status_);
+}
+inline void ComponentSensorData::set_status(::dmi::SensorStatus value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.status)
+}
+
+// string units_display = 6;
+inline void ComponentSensorData::clear_units_display() {
+  units_display_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ComponentSensorData::units_display() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.units_display)
+  return units_display_.GetNoArena();
+}
+inline void ComponentSensorData::set_units_display(const ::std::string& value) {
+  
+  units_display_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.units_display)
+}
+#if LANG_CXX11
+inline void ComponentSensorData::set_units_display(::std::string&& value) {
+  
+  units_display_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ComponentSensorData.units_display)
+}
+#endif
+inline void ComponentSensorData::set_units_display(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  units_display_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ComponentSensorData.units_display)
+}
+inline void ComponentSensorData::set_units_display(const char* value, size_t size) {
+  
+  units_display_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ComponentSensorData.units_display)
+}
+inline ::std::string* ComponentSensorData::mutable_units_display() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ComponentSensorData.units_display)
+  return units_display_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ComponentSensorData::release_units_display() {
+  // @@protoc_insertion_point(field_release:dmi.ComponentSensorData.units_display)
+  
+  return units_display_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ComponentSensorData::set_allocated_units_display(::std::string* units_display) {
+  if (units_display != nullptr) {
+    
+  } else {
+    
+  }
+  units_display_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), units_display);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentSensorData.units_display)
+}
+
+// .google.protobuf.Timestamp timestamp = 7;
+inline bool ComponentSensorData::has_timestamp() const {
+  return this != internal_default_instance() && timestamp_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& ComponentSensorData::timestamp() const {
+  const ::google::protobuf::Timestamp* p = timestamp_;
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.timestamp)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* ComponentSensorData::release_timestamp() {
+  // @@protoc_insertion_point(field_release:dmi.ComponentSensorData.timestamp)
+  
+  ::google::protobuf::Timestamp* temp = timestamp_;
+  timestamp_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* ComponentSensorData::mutable_timestamp() {
+  
+  if (timestamp_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    timestamp_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ComponentSensorData.timestamp)
+  return timestamp_;
+}
+inline void ComponentSensorData::set_allocated_timestamp(::google::protobuf::Timestamp* timestamp) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(timestamp_);
+  }
+  if (timestamp) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(timestamp)->GetArena();
+    if (message_arena != submessage_arena) {
+      timestamp = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, timestamp, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  timestamp_ = timestamp;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentSensorData.timestamp)
+}
+
+// uint32 value_update_rate = 8;
+inline void ComponentSensorData::clear_value_update_rate() {
+  value_update_rate_ = 0u;
+}
+inline ::google::protobuf::uint32 ComponentSensorData::value_update_rate() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.value_update_rate)
+  return value_update_rate_;
+}
+inline void ComponentSensorData::set_value_update_rate(::google::protobuf::uint32 value) {
+  
+  value_update_rate_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.value_update_rate)
+}
+
+// string data_type = 9;
+inline void ComponentSensorData::clear_data_type() {
+  data_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ComponentSensorData::data_type() const {
+  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.data_type)
+  return data_type_.GetNoArena();
+}
+inline void ComponentSensorData::set_data_type(const ::std::string& value) {
+  
+  data_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.data_type)
+}
+#if LANG_CXX11
+inline void ComponentSensorData::set_data_type(::std::string&& value) {
+  
+  data_type_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ComponentSensorData.data_type)
+}
+#endif
+inline void ComponentSensorData::set_data_type(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  data_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ComponentSensorData.data_type)
+}
+inline void ComponentSensorData::set_data_type(const char* value, size_t size) {
+  
+  data_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ComponentSensorData.data_type)
+}
+inline ::std::string* ComponentSensorData::mutable_data_type() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ComponentSensorData.data_type)
+  return data_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ComponentSensorData::release_data_type() {
+  // @@protoc_insertion_point(field_release:dmi.ComponentSensorData.data_type)
+  
+  return data_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ComponentSensorData::set_allocated_data_type(::std::string* data_type) {
+  if (data_type != nullptr) {
+    
+  } else {
+    
+  }
+  data_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), data_type);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentSensorData.data_type)
+}
+
+// -------------------------------------------------------------------
+
+// PortComponentAttributes
+
+// .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+inline void PortComponentAttributes::clear_connector_type() {
+  connector_type_ = 0;
+}
+inline ::dmi::PortComponentAttributes_ConnectorType PortComponentAttributes::connector_type() const {
+  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.connector_type)
+  return static_cast< ::dmi::PortComponentAttributes_ConnectorType >(connector_type_);
+}
+inline void PortComponentAttributes::set_connector_type(::dmi::PortComponentAttributes_ConnectorType value) {
+  
+  connector_type_ = value;
+  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.connector_type)
+}
+
+// .dmi.PortComponentAttributes.Speed speed = 2;
+inline void PortComponentAttributes::clear_speed() {
+  speed_ = 0;
+}
+inline ::dmi::PortComponentAttributes_Speed PortComponentAttributes::speed() const {
+  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.speed)
+  return static_cast< ::dmi::PortComponentAttributes_Speed >(speed_);
+}
+inline void PortComponentAttributes::set_speed(::dmi::PortComponentAttributes_Speed value) {
+  
+  speed_ = value;
+  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.speed)
+}
+
+// .dmi.PortComponentAttributes.Protocol protocol = 3;
+inline void PortComponentAttributes::clear_protocol() {
+  protocol_ = 0;
+}
+inline ::dmi::PortComponentAttributes_Protocol PortComponentAttributes::protocol() const {
+  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.protocol)
+  return static_cast< ::dmi::PortComponentAttributes_Protocol >(protocol_);
+}
+inline void PortComponentAttributes::set_protocol(::dmi::PortComponentAttributes_Protocol value) {
+  
+  protocol_ = value;
+  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.protocol)
+}
+
+// string physical_label = 4;
+inline void PortComponentAttributes::clear_physical_label() {
+  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& PortComponentAttributes::physical_label() const {
+  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.physical_label)
+  return physical_label_.GetNoArena();
+}
+inline void PortComponentAttributes::set_physical_label(const ::std::string& value) {
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.physical_label)
+}
+#if LANG_CXX11
+inline void PortComponentAttributes::set_physical_label(::std::string&& value) {
+  
+  physical_label_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.PortComponentAttributes.physical_label)
+}
+#endif
+inline void PortComponentAttributes::set_physical_label(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.PortComponentAttributes.physical_label)
+}
+inline void PortComponentAttributes::set_physical_label(const char* value, size_t size) {
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.PortComponentAttributes.physical_label)
+}
+inline ::std::string* PortComponentAttributes::mutable_physical_label() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.PortComponentAttributes.physical_label)
+  return physical_label_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* PortComponentAttributes::release_physical_label() {
+  // @@protoc_insertion_point(field_release:dmi.PortComponentAttributes.physical_label)
+  
+  return physical_label_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void PortComponentAttributes::set_allocated_physical_label(::std::string* physical_label) {
+  if (physical_label != nullptr) {
+    
+  } else {
+    
+  }
+  physical_label_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), physical_label);
+  // @@protoc_insertion_point(field_set_allocated:dmi.PortComponentAttributes.physical_label)
+}
+
+// -------------------------------------------------------------------
+
+// ContainerComponentAttributes
+
+// string physical_label = 1;
+inline void ContainerComponentAttributes::clear_physical_label() {
+  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ContainerComponentAttributes::physical_label() const {
+  // @@protoc_insertion_point(field_get:dmi.ContainerComponentAttributes.physical_label)
+  return physical_label_.GetNoArena();
+}
+inline void ContainerComponentAttributes::set_physical_label(const ::std::string& value) {
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ContainerComponentAttributes.physical_label)
+}
+#if LANG_CXX11
+inline void ContainerComponentAttributes::set_physical_label(::std::string&& value) {
+  
+  physical_label_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ContainerComponentAttributes.physical_label)
+}
+#endif
+inline void ContainerComponentAttributes::set_physical_label(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ContainerComponentAttributes.physical_label)
+}
+inline void ContainerComponentAttributes::set_physical_label(const char* value, size_t size) {
+  
+  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ContainerComponentAttributes.physical_label)
+}
+inline ::std::string* ContainerComponentAttributes::mutable_physical_label() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ContainerComponentAttributes.physical_label)
+  return physical_label_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ContainerComponentAttributes::release_physical_label() {
+  // @@protoc_insertion_point(field_release:dmi.ContainerComponentAttributes.physical_label)
+  
+  return physical_label_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ContainerComponentAttributes::set_allocated_physical_label(::std::string* physical_label) {
+  if (physical_label != nullptr) {
+    
+  } else {
+    
+  }
+  physical_label_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), physical_label);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ContainerComponentAttributes.physical_label)
+}
+
+// -------------------------------------------------------------------
+
+// PsuComponentAttributes
+
+// .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+inline void PsuComponentAttributes::clear_supported_voltage() {
+  supported_voltage_ = 0;
+}
+inline ::dmi::PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::supported_voltage() const {
+  // @@protoc_insertion_point(field_get:dmi.PsuComponentAttributes.supported_voltage)
+  return static_cast< ::dmi::PsuComponentAttributes_SupportedVoltage >(supported_voltage_);
+}
+inline void PsuComponentAttributes::set_supported_voltage(::dmi::PsuComponentAttributes_SupportedVoltage value) {
+  
+  supported_voltage_ = value;
+  // @@protoc_insertion_point(field_set:dmi.PsuComponentAttributes.supported_voltage)
+}
+
+// -------------------------------------------------------------------
+
+// TransceiverComponentsAttributes
+
+// .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+inline void TransceiverComponentsAttributes::clear_form_factor() {
+  form_factor_ = 0;
+}
+inline ::dmi::TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::form_factor() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.form_factor)
+  return static_cast< ::dmi::TransceiverComponentsAttributes_FormFactor >(form_factor_);
+}
+inline void TransceiverComponentsAttributes::set_form_factor(::dmi::TransceiverComponentsAttributes_FormFactor value) {
+  
+  form_factor_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.form_factor)
+}
+
+// .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+inline void TransceiverComponentsAttributes::clear_trans_type() {
+  trans_type_ = 0;
+}
+inline ::dmi::TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::trans_type() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.trans_type)
+  return static_cast< ::dmi::TransceiverComponentsAttributes_Type >(trans_type_);
+}
+inline void TransceiverComponentsAttributes::set_trans_type(::dmi::TransceiverComponentsAttributes_Type value) {
+  
+  trans_type_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.trans_type)
+}
+
+// uint32 max_distance = 3;
+inline void TransceiverComponentsAttributes::clear_max_distance() {
+  max_distance_ = 0u;
+}
+inline ::google::protobuf::uint32 TransceiverComponentsAttributes::max_distance() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.max_distance)
+  return max_distance_;
+}
+inline void TransceiverComponentsAttributes::set_max_distance(::google::protobuf::uint32 value) {
+  
+  max_distance_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.max_distance)
+}
+
+// .dmi.ValueScale max_distance_scale = 4;
+inline void TransceiverComponentsAttributes::clear_max_distance_scale() {
+  max_distance_scale_ = 0;
+}
+inline ::dmi::ValueScale TransceiverComponentsAttributes::max_distance_scale() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.max_distance_scale)
+  return static_cast< ::dmi::ValueScale >(max_distance_scale_);
+}
+inline void TransceiverComponentsAttributes::set_max_distance_scale(::dmi::ValueScale value) {
+  
+  max_distance_scale_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.max_distance_scale)
+}
+
+// repeated uint32 rx_wavelength = 5;
+inline int TransceiverComponentsAttributes::rx_wavelength_size() const {
+  return rx_wavelength_.size();
+}
+inline void TransceiverComponentsAttributes::clear_rx_wavelength() {
+  rx_wavelength_.Clear();
+}
+inline ::google::protobuf::uint32 TransceiverComponentsAttributes::rx_wavelength(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.rx_wavelength)
+  return rx_wavelength_.Get(index);
+}
+inline void TransceiverComponentsAttributes::set_rx_wavelength(int index, ::google::protobuf::uint32 value) {
+  rx_wavelength_.Set(index, value);
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.rx_wavelength)
+}
+inline void TransceiverComponentsAttributes::add_rx_wavelength(::google::protobuf::uint32 value) {
+  rx_wavelength_.Add(value);
+  // @@protoc_insertion_point(field_add:dmi.TransceiverComponentsAttributes.rx_wavelength)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+TransceiverComponentsAttributes::rx_wavelength() const {
+  // @@protoc_insertion_point(field_list:dmi.TransceiverComponentsAttributes.rx_wavelength)
+  return rx_wavelength_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+TransceiverComponentsAttributes::mutable_rx_wavelength() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.TransceiverComponentsAttributes.rx_wavelength)
+  return &rx_wavelength_;
+}
+
+// repeated uint32 tx_wavelength = 6;
+inline int TransceiverComponentsAttributes::tx_wavelength_size() const {
+  return tx_wavelength_.size();
+}
+inline void TransceiverComponentsAttributes::clear_tx_wavelength() {
+  tx_wavelength_.Clear();
+}
+inline ::google::protobuf::uint32 TransceiverComponentsAttributes::tx_wavelength(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.tx_wavelength)
+  return tx_wavelength_.Get(index);
+}
+inline void TransceiverComponentsAttributes::set_tx_wavelength(int index, ::google::protobuf::uint32 value) {
+  tx_wavelength_.Set(index, value);
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.tx_wavelength)
+}
+inline void TransceiverComponentsAttributes::add_tx_wavelength(::google::protobuf::uint32 value) {
+  tx_wavelength_.Add(value);
+  // @@protoc_insertion_point(field_add:dmi.TransceiverComponentsAttributes.tx_wavelength)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
+TransceiverComponentsAttributes::tx_wavelength() const {
+  // @@protoc_insertion_point(field_list:dmi.TransceiverComponentsAttributes.tx_wavelength)
+  return tx_wavelength_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
+TransceiverComponentsAttributes::mutable_tx_wavelength() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.TransceiverComponentsAttributes.tx_wavelength)
+  return &tx_wavelength_;
+}
+
+// .dmi.ValueScale wavelength_scale = 7;
+inline void TransceiverComponentsAttributes::clear_wavelength_scale() {
+  wavelength_scale_ = 0;
+}
+inline ::dmi::ValueScale TransceiverComponentsAttributes::wavelength_scale() const {
+  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.wavelength_scale)
+  return static_cast< ::dmi::ValueScale >(wavelength_scale_);
+}
+inline void TransceiverComponentsAttributes::set_wavelength_scale(::dmi::ValueScale value) {
+  
+  wavelength_scale_ = value;
+  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.wavelength_scale)
+}
+
+// -------------------------------------------------------------------
+
+// Component
+
+// string name = 1;
+inline void Component::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::name() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.name)
+  return name_.GetNoArena();
+}
+inline void Component::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.name)
+}
+#if LANG_CXX11
+inline void Component::set_name(::std::string&& value) {
+  
+  name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.name)
+}
+#endif
+inline void Component::set_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.name)
+}
+inline void Component::set_name(const char* value, size_t size) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.name)
+}
+inline ::std::string* Component::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_name() {
+  // @@protoc_insertion_point(field_release:dmi.Component.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_name(::std::string* name) {
+  if (name != nullptr) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.name)
+}
+
+// .dmi.ComponentType class = 2;
+inline void Component::clear_class_() {
+  class__ = 0;
+}
+inline ::dmi::ComponentType Component::class_() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.class)
+  return static_cast< ::dmi::ComponentType >(class__);
+}
+inline void Component::set_class_(::dmi::ComponentType value) {
+  
+  class__ = value;
+  // @@protoc_insertion_point(field_set:dmi.Component.class)
+}
+
+// string description = 3;
+inline void Component::clear_description() {
+  description_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::description() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.description)
+  return description_.GetNoArena();
+}
+inline void Component::set_description(const ::std::string& value) {
+  
+  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.description)
+}
+#if LANG_CXX11
+inline void Component::set_description(::std::string&& value) {
+  
+  description_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.description)
+}
+#endif
+inline void Component::set_description(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.description)
+}
+inline void Component::set_description(const char* value, size_t size) {
+  
+  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.description)
+}
+inline ::std::string* Component::mutable_description() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.description)
+  return description_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_description() {
+  // @@protoc_insertion_point(field_release:dmi.Component.description)
+  
+  return description_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_description(::std::string* description) {
+  if (description != nullptr) {
+    
+  } else {
+    
+  }
+  description_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), description);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.description)
+}
+
+// string parent = 4;
+inline void Component::clear_parent() {
+  parent_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::parent() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.parent)
+  return parent_.GetNoArena();
+}
+inline void Component::set_parent(const ::std::string& value) {
+  
+  parent_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.parent)
+}
+#if LANG_CXX11
+inline void Component::set_parent(::std::string&& value) {
+  
+  parent_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.parent)
+}
+#endif
+inline void Component::set_parent(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  parent_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.parent)
+}
+inline void Component::set_parent(const char* value, size_t size) {
+  
+  parent_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.parent)
+}
+inline ::std::string* Component::mutable_parent() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.parent)
+  return parent_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_parent() {
+  // @@protoc_insertion_point(field_release:dmi.Component.parent)
+  
+  return parent_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_parent(::std::string* parent) {
+  if (parent != nullptr) {
+    
+  } else {
+    
+  }
+  parent_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), parent);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.parent)
+}
+
+// int32 parent_rel_pos = 5;
+inline void Component::clear_parent_rel_pos() {
+  parent_rel_pos_ = 0;
+}
+inline ::google::protobuf::int32 Component::parent_rel_pos() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.parent_rel_pos)
+  return parent_rel_pos_;
+}
+inline void Component::set_parent_rel_pos(::google::protobuf::int32 value) {
+  
+  parent_rel_pos_ = value;
+  // @@protoc_insertion_point(field_set:dmi.Component.parent_rel_pos)
+}
+
+// repeated .dmi.Component children = 6;
+inline int Component::children_size() const {
+  return children_.size();
+}
+inline void Component::clear_children() {
+  children_.Clear();
+}
+inline ::dmi::Component* Component::mutable_children(int index) {
+  // @@protoc_insertion_point(field_mutable:dmi.Component.children)
+  return children_.Mutable(index);
+}
+inline ::google::protobuf::RepeatedPtrField< ::dmi::Component >*
+Component::mutable_children() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.Component.children)
+  return &children_;
+}
+inline const ::dmi::Component& Component::children(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.Component.children)
+  return children_.Get(index);
+}
+inline ::dmi::Component* Component::add_children() {
+  // @@protoc_insertion_point(field_add:dmi.Component.children)
+  return children_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::dmi::Component >&
+Component::children() const {
+  // @@protoc_insertion_point(field_list:dmi.Component.children)
+  return children_;
+}
+
+// string hardware_rev = 7;
+inline void Component::clear_hardware_rev() {
+  hardware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::hardware_rev() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.hardware_rev)
+  return hardware_rev_.GetNoArena();
+}
+inline void Component::set_hardware_rev(const ::std::string& value) {
+  
+  hardware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.hardware_rev)
+}
+#if LANG_CXX11
+inline void Component::set_hardware_rev(::std::string&& value) {
+  
+  hardware_rev_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.hardware_rev)
+}
+#endif
+inline void Component::set_hardware_rev(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  hardware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.hardware_rev)
+}
+inline void Component::set_hardware_rev(const char* value, size_t size) {
+  
+  hardware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.hardware_rev)
+}
+inline ::std::string* Component::mutable_hardware_rev() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.hardware_rev)
+  return hardware_rev_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_hardware_rev() {
+  // @@protoc_insertion_point(field_release:dmi.Component.hardware_rev)
+  
+  return hardware_rev_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_hardware_rev(::std::string* hardware_rev) {
+  if (hardware_rev != nullptr) {
+    
+  } else {
+    
+  }
+  hardware_rev_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), hardware_rev);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.hardware_rev)
+}
+
+// string firmware_rev = 8;
+inline void Component::clear_firmware_rev() {
+  firmware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::firmware_rev() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.firmware_rev)
+  return firmware_rev_.GetNoArena();
+}
+inline void Component::set_firmware_rev(const ::std::string& value) {
+  
+  firmware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.firmware_rev)
+}
+#if LANG_CXX11
+inline void Component::set_firmware_rev(::std::string&& value) {
+  
+  firmware_rev_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.firmware_rev)
+}
+#endif
+inline void Component::set_firmware_rev(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  firmware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.firmware_rev)
+}
+inline void Component::set_firmware_rev(const char* value, size_t size) {
+  
+  firmware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.firmware_rev)
+}
+inline ::std::string* Component::mutable_firmware_rev() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.firmware_rev)
+  return firmware_rev_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_firmware_rev() {
+  // @@protoc_insertion_point(field_release:dmi.Component.firmware_rev)
+  
+  return firmware_rev_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_firmware_rev(::std::string* firmware_rev) {
+  if (firmware_rev != nullptr) {
+    
+  } else {
+    
+  }
+  firmware_rev_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), firmware_rev);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.firmware_rev)
+}
+
+// string software_rev = 9;
+inline void Component::clear_software_rev() {
+  software_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::software_rev() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.software_rev)
+  return software_rev_.GetNoArena();
+}
+inline void Component::set_software_rev(const ::std::string& value) {
+  
+  software_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.software_rev)
+}
+#if LANG_CXX11
+inline void Component::set_software_rev(::std::string&& value) {
+  
+  software_rev_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.software_rev)
+}
+#endif
+inline void Component::set_software_rev(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  software_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.software_rev)
+}
+inline void Component::set_software_rev(const char* value, size_t size) {
+  
+  software_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.software_rev)
+}
+inline ::std::string* Component::mutable_software_rev() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.software_rev)
+  return software_rev_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_software_rev() {
+  // @@protoc_insertion_point(field_release:dmi.Component.software_rev)
+  
+  return software_rev_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_software_rev(::std::string* software_rev) {
+  if (software_rev != nullptr) {
+    
+  } else {
+    
+  }
+  software_rev_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), software_rev);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.software_rev)
+}
+
+// string serial_num = 10;
+inline void Component::clear_serial_num() {
+  serial_num_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::serial_num() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.serial_num)
+  return serial_num_.GetNoArena();
+}
+inline void Component::set_serial_num(const ::std::string& value) {
+  
+  serial_num_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.serial_num)
+}
+#if LANG_CXX11
+inline void Component::set_serial_num(::std::string&& value) {
+  
+  serial_num_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.serial_num)
+}
+#endif
+inline void Component::set_serial_num(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  serial_num_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.serial_num)
+}
+inline void Component::set_serial_num(const char* value, size_t size) {
+  
+  serial_num_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.serial_num)
+}
+inline ::std::string* Component::mutable_serial_num() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.serial_num)
+  return serial_num_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_serial_num() {
+  // @@protoc_insertion_point(field_release:dmi.Component.serial_num)
+  
+  return serial_num_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_serial_num(::std::string* serial_num) {
+  if (serial_num != nullptr) {
+    
+  } else {
+    
+  }
+  serial_num_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), serial_num);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.serial_num)
+}
+
+// string mfg_name = 11;
+inline void Component::clear_mfg_name() {
+  mfg_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::mfg_name() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.mfg_name)
+  return mfg_name_.GetNoArena();
+}
+inline void Component::set_mfg_name(const ::std::string& value) {
+  
+  mfg_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.mfg_name)
+}
+#if LANG_CXX11
+inline void Component::set_mfg_name(::std::string&& value) {
+  
+  mfg_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.mfg_name)
+}
+#endif
+inline void Component::set_mfg_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  mfg_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.mfg_name)
+}
+inline void Component::set_mfg_name(const char* value, size_t size) {
+  
+  mfg_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.mfg_name)
+}
+inline ::std::string* Component::mutable_mfg_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.mfg_name)
+  return mfg_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_mfg_name() {
+  // @@protoc_insertion_point(field_release:dmi.Component.mfg_name)
+  
+  return mfg_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_mfg_name(::std::string* mfg_name) {
+  if (mfg_name != nullptr) {
+    
+  } else {
+    
+  }
+  mfg_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), mfg_name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.mfg_name)
+}
+
+// string model_name = 12;
+inline void Component::clear_model_name() {
+  model_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::model_name() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.model_name)
+  return model_name_.GetNoArena();
+}
+inline void Component::set_model_name(const ::std::string& value) {
+  
+  model_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.model_name)
+}
+#if LANG_CXX11
+inline void Component::set_model_name(::std::string&& value) {
+  
+  model_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.model_name)
+}
+#endif
+inline void Component::set_model_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  model_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.model_name)
+}
+inline void Component::set_model_name(const char* value, size_t size) {
+  
+  model_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.model_name)
+}
+inline ::std::string* Component::mutable_model_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.model_name)
+  return model_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_model_name() {
+  // @@protoc_insertion_point(field_release:dmi.Component.model_name)
+  
+  return model_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_model_name(::std::string* model_name) {
+  if (model_name != nullptr) {
+    
+  } else {
+    
+  }
+  model_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), model_name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.model_name)
+}
+
+// string alias = 13;
+inline void Component::clear_alias() {
+  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::alias() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.alias)
+  return alias_.GetNoArena();
+}
+inline void Component::set_alias(const ::std::string& value) {
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.alias)
+}
+#if LANG_CXX11
+inline void Component::set_alias(::std::string&& value) {
+  
+  alias_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.alias)
+}
+#endif
+inline void Component::set_alias(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.alias)
+}
+inline void Component::set_alias(const char* value, size_t size) {
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.alias)
+}
+inline ::std::string* Component::mutable_alias() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.alias)
+  return alias_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_alias() {
+  // @@protoc_insertion_point(field_release:dmi.Component.alias)
+  
+  return alias_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_alias(::std::string* alias) {
+  if (alias != nullptr) {
+    
+  } else {
+    
+  }
+  alias_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), alias);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.alias)
+}
+
+// string asset_id = 14;
+inline void Component::clear_asset_id() {
+  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Component::asset_id() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.asset_id)
+  return asset_id_.GetNoArena();
+}
+inline void Component::set_asset_id(const ::std::string& value) {
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.Component.asset_id)
+}
+#if LANG_CXX11
+inline void Component::set_asset_id(::std::string&& value) {
+  
+  asset_id_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.asset_id)
+}
+#endif
+inline void Component::set_asset_id(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.Component.asset_id)
+}
+inline void Component::set_asset_id(const char* value, size_t size) {
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.Component.asset_id)
+}
+inline ::std::string* Component::mutable_asset_id() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.Component.asset_id)
+  return asset_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Component::release_asset_id() {
+  // @@protoc_insertion_point(field_release:dmi.Component.asset_id)
+  
+  return asset_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Component::set_allocated_asset_id(::std::string* asset_id) {
+  if (asset_id != nullptr) {
+    
+  } else {
+    
+  }
+  asset_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), asset_id);
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.asset_id)
+}
+
+// bool is_fru = 15;
+inline void Component::clear_is_fru() {
+  is_fru_ = false;
+}
+inline bool Component::is_fru() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.is_fru)
+  return is_fru_;
+}
+inline void Component::set_is_fru(bool value) {
+  
+  is_fru_ = value;
+  // @@protoc_insertion_point(field_set:dmi.Component.is_fru)
+}
+
+// .google.protobuf.Timestamp mfg_date = 16;
+inline bool Component::has_mfg_date() const {
+  return this != internal_default_instance() && mfg_date_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& Component::mfg_date() const {
+  const ::google::protobuf::Timestamp* p = mfg_date_;
+  // @@protoc_insertion_point(field_get:dmi.Component.mfg_date)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* Component::release_mfg_date() {
+  // @@protoc_insertion_point(field_release:dmi.Component.mfg_date)
+  
+  ::google::protobuf::Timestamp* temp = mfg_date_;
+  mfg_date_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* Component::mutable_mfg_date() {
+  
+  if (mfg_date_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    mfg_date_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.mfg_date)
+  return mfg_date_;
+}
+inline void Component::set_allocated_mfg_date(::google::protobuf::Timestamp* mfg_date) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(mfg_date_);
+  }
+  if (mfg_date) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(mfg_date)->GetArena();
+    if (message_arena != submessage_arena) {
+      mfg_date = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, mfg_date, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  mfg_date_ = mfg_date;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.mfg_date)
+}
+
+// .dmi.Uri uri = 17;
+inline bool Component::has_uri() const {
+  return this != internal_default_instance() && uri_ != nullptr;
+}
+inline void Component::clear_uri() {
+  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
+    delete uri_;
+  }
+  uri_ = nullptr;
+}
+inline const ::dmi::Uri& Component::uri() const {
+  const ::dmi::Uri* p = uri_;
+  // @@protoc_insertion_point(field_get:dmi.Component.uri)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uri*>(
+      &::dmi::_Uri_default_instance_);
+}
+inline ::dmi::Uri* Component::release_uri() {
+  // @@protoc_insertion_point(field_release:dmi.Component.uri)
+  
+  ::dmi::Uri* temp = uri_;
+  uri_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uri* Component::mutable_uri() {
+  
+  if (uri_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uri>(GetArenaNoVirtual());
+    uri_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.uri)
+  return uri_;
+}
+inline void Component::set_allocated_uri(::dmi::Uri* uri) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete uri_;
+  }
+  if (uri) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      uri = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, uri, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  uri_ = uri;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.uri)
+}
+
+// .dmi.Uuid uuid = 18;
+inline bool Component::has_uuid() const {
+  return this != internal_default_instance() && uuid_ != nullptr;
+}
+inline void Component::clear_uuid() {
+  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
+    delete uuid_;
+  }
+  uuid_ = nullptr;
+}
+inline const ::dmi::Uuid& Component::uuid() const {
+  const ::dmi::Uuid* p = uuid_;
+  // @@protoc_insertion_point(field_get:dmi.Component.uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* Component::release_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.Component.uuid)
+  
+  ::dmi::Uuid* temp = uuid_;
+  uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* Component::mutable_uuid() {
+  
+  if (uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.uuid)
+  return uuid_;
+}
+inline void Component::set_allocated_uuid(::dmi::Uuid* uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete uuid_;
+  }
+  if (uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  uuid_ = uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.uuid)
+}
+
+// .dmi.ComponentState state = 19;
+inline bool Component::has_state() const {
+  return this != internal_default_instance() && state_ != nullptr;
+}
+inline void Component::clear_state() {
+  if (GetArenaNoVirtual() == nullptr && state_ != nullptr) {
+    delete state_;
+  }
+  state_ = nullptr;
+}
+inline const ::dmi::ComponentState& Component::state() const {
+  const ::dmi::ComponentState* p = state_;
+  // @@protoc_insertion_point(field_get:dmi.Component.state)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ComponentState*>(
+      &::dmi::_ComponentState_default_instance_);
+}
+inline ::dmi::ComponentState* Component::release_state() {
+  // @@protoc_insertion_point(field_release:dmi.Component.state)
+  
+  ::dmi::ComponentState* temp = state_;
+  state_ = nullptr;
+  return temp;
+}
+inline ::dmi::ComponentState* Component::mutable_state() {
+  
+  if (state_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::ComponentState>(GetArenaNoVirtual());
+    state_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.state)
+  return state_;
+}
+inline void Component::set_allocated_state(::dmi::ComponentState* state) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete state_;
+  }
+  if (state) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      state = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, state, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  state_ = state;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.state)
+}
+
+// repeated .dmi.ComponentSensorData sensor_data = 20;
+inline int Component::sensor_data_size() const {
+  return sensor_data_.size();
+}
+inline void Component::clear_sensor_data() {
+  sensor_data_.Clear();
+}
+inline ::dmi::ComponentSensorData* Component::mutable_sensor_data(int index) {
+  // @@protoc_insertion_point(field_mutable:dmi.Component.sensor_data)
+  return sensor_data_.Mutable(index);
+}
+inline ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >*
+Component::mutable_sensor_data() {
+  // @@protoc_insertion_point(field_mutable_list:dmi.Component.sensor_data)
+  return &sensor_data_;
+}
+inline const ::dmi::ComponentSensorData& Component::sensor_data(int index) const {
+  // @@protoc_insertion_point(field_get:dmi.Component.sensor_data)
+  return sensor_data_.Get(index);
+}
+inline ::dmi::ComponentSensorData* Component::add_sensor_data() {
+  // @@protoc_insertion_point(field_add:dmi.Component.sensor_data)
+  return sensor_data_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >&
+Component::sensor_data() const {
+  // @@protoc_insertion_point(field_list:dmi.Component.sensor_data)
+  return sensor_data_;
+}
+
+// .dmi.PortComponentAttributes port_attr = 50;
+inline bool Component::has_port_attr() const {
+  return specific_case() == kPortAttr;
+}
+inline void Component::set_has_port_attr() {
+  _oneof_case_[0] = kPortAttr;
+}
+inline void Component::clear_port_attr() {
+  if (has_port_attr()) {
+    delete specific_.port_attr_;
+    clear_has_specific();
+  }
+}
+inline ::dmi::PortComponentAttributes* Component::release_port_attr() {
+  // @@protoc_insertion_point(field_release:dmi.Component.port_attr)
+  if (has_port_attr()) {
+    clear_has_specific();
+      ::dmi::PortComponentAttributes* temp = specific_.port_attr_;
+    specific_.port_attr_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::PortComponentAttributes& Component::port_attr() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.port_attr)
+  return has_port_attr()
+      ? *specific_.port_attr_
+      : *reinterpret_cast< ::dmi::PortComponentAttributes*>(&::dmi::_PortComponentAttributes_default_instance_);
+}
+inline ::dmi::PortComponentAttributes* Component::mutable_port_attr() {
+  if (!has_port_attr()) {
+    clear_specific();
+    set_has_port_attr();
+    specific_.port_attr_ = CreateMaybeMessage< ::dmi::PortComponentAttributes >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.port_attr)
+  return specific_.port_attr_;
+}
+
+// .dmi.ContainerComponentAttributes container_attr = 51;
+inline bool Component::has_container_attr() const {
+  return specific_case() == kContainerAttr;
+}
+inline void Component::set_has_container_attr() {
+  _oneof_case_[0] = kContainerAttr;
+}
+inline void Component::clear_container_attr() {
+  if (has_container_attr()) {
+    delete specific_.container_attr_;
+    clear_has_specific();
+  }
+}
+inline ::dmi::ContainerComponentAttributes* Component::release_container_attr() {
+  // @@protoc_insertion_point(field_release:dmi.Component.container_attr)
+  if (has_container_attr()) {
+    clear_has_specific();
+      ::dmi::ContainerComponentAttributes* temp = specific_.container_attr_;
+    specific_.container_attr_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::ContainerComponentAttributes& Component::container_attr() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.container_attr)
+  return has_container_attr()
+      ? *specific_.container_attr_
+      : *reinterpret_cast< ::dmi::ContainerComponentAttributes*>(&::dmi::_ContainerComponentAttributes_default_instance_);
+}
+inline ::dmi::ContainerComponentAttributes* Component::mutable_container_attr() {
+  if (!has_container_attr()) {
+    clear_specific();
+    set_has_container_attr();
+    specific_.container_attr_ = CreateMaybeMessage< ::dmi::ContainerComponentAttributes >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.container_attr)
+  return specific_.container_attr_;
+}
+
+// .dmi.PsuComponentAttributes psu_attr = 52;
+inline bool Component::has_psu_attr() const {
+  return specific_case() == kPsuAttr;
+}
+inline void Component::set_has_psu_attr() {
+  _oneof_case_[0] = kPsuAttr;
+}
+inline void Component::clear_psu_attr() {
+  if (has_psu_attr()) {
+    delete specific_.psu_attr_;
+    clear_has_specific();
+  }
+}
+inline ::dmi::PsuComponentAttributes* Component::release_psu_attr() {
+  // @@protoc_insertion_point(field_release:dmi.Component.psu_attr)
+  if (has_psu_attr()) {
+    clear_has_specific();
+      ::dmi::PsuComponentAttributes* temp = specific_.psu_attr_;
+    specific_.psu_attr_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::PsuComponentAttributes& Component::psu_attr() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.psu_attr)
+  return has_psu_attr()
+      ? *specific_.psu_attr_
+      : *reinterpret_cast< ::dmi::PsuComponentAttributes*>(&::dmi::_PsuComponentAttributes_default_instance_);
+}
+inline ::dmi::PsuComponentAttributes* Component::mutable_psu_attr() {
+  if (!has_psu_attr()) {
+    clear_specific();
+    set_has_psu_attr();
+    specific_.psu_attr_ = CreateMaybeMessage< ::dmi::PsuComponentAttributes >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.psu_attr)
+  return specific_.psu_attr_;
+}
+
+// .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+inline bool Component::has_transceiver_attr() const {
+  return specific_case() == kTransceiverAttr;
+}
+inline void Component::set_has_transceiver_attr() {
+  _oneof_case_[0] = kTransceiverAttr;
+}
+inline void Component::clear_transceiver_attr() {
+  if (has_transceiver_attr()) {
+    delete specific_.transceiver_attr_;
+    clear_has_specific();
+  }
+}
+inline ::dmi::TransceiverComponentsAttributes* Component::release_transceiver_attr() {
+  // @@protoc_insertion_point(field_release:dmi.Component.transceiver_attr)
+  if (has_transceiver_attr()) {
+    clear_has_specific();
+      ::dmi::TransceiverComponentsAttributes* temp = specific_.transceiver_attr_;
+    specific_.transceiver_attr_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::TransceiverComponentsAttributes& Component::transceiver_attr() const {
+  // @@protoc_insertion_point(field_get:dmi.Component.transceiver_attr)
+  return has_transceiver_attr()
+      ? *specific_.transceiver_attr_
+      : *reinterpret_cast< ::dmi::TransceiverComponentsAttributes*>(&::dmi::_TransceiverComponentsAttributes_default_instance_);
+}
+inline ::dmi::TransceiverComponentsAttributes* Component::mutable_transceiver_attr() {
+  if (!has_transceiver_attr()) {
+    clear_specific();
+    set_has_transceiver_attr();
+    specific_.transceiver_attr_ = CreateMaybeMessage< ::dmi::TransceiverComponentsAttributes >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Component.transceiver_attr)
+  return specific_.transceiver_attr_;
+}
+
+inline bool Component::has_specific() const {
+  return specific_case() != SPECIFIC_NOT_SET;
+}
+inline void Component::clear_has_specific() {
+  _oneof_case_[0] = SPECIFIC_NOT_SET;
+}
+inline Component::SpecificCase Component::specific_case() const {
+  return Component::SpecificCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// Hardware
+
+// .google.protobuf.Timestamp last_change = 1;
+inline bool Hardware::has_last_change() const {
+  return this != internal_default_instance() && last_change_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& Hardware::last_change() const {
+  const ::google::protobuf::Timestamp* p = last_change_;
+  // @@protoc_insertion_point(field_get:dmi.Hardware.last_change)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* Hardware::release_last_change() {
+  // @@protoc_insertion_point(field_release:dmi.Hardware.last_change)
+  
+  ::google::protobuf::Timestamp* temp = last_change_;
+  last_change_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* Hardware::mutable_last_change() {
+  
+  if (last_change_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    last_change_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Hardware.last_change)
+  return last_change_;
+}
+inline void Hardware::set_allocated_last_change(::google::protobuf::Timestamp* last_change) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(last_change_);
+  }
+  if (last_change) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(last_change)->GetArena();
+    if (message_arena != submessage_arena) {
+      last_change = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, last_change, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  last_change_ = last_change;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Hardware.last_change)
+}
+
+// .dmi.Component root = 2;
+inline bool Hardware::has_root() const {
+  return this != internal_default_instance() && root_ != nullptr;
+}
+inline void Hardware::clear_root() {
+  if (GetArenaNoVirtual() == nullptr && root_ != nullptr) {
+    delete root_;
+  }
+  root_ = nullptr;
+}
+inline const ::dmi::Component& Hardware::root() const {
+  const ::dmi::Component* p = root_;
+  // @@protoc_insertion_point(field_get:dmi.Hardware.root)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Component*>(
+      &::dmi::_Component_default_instance_);
+}
+inline ::dmi::Component* Hardware::release_root() {
+  // @@protoc_insertion_point(field_release:dmi.Hardware.root)
+  
+  ::dmi::Component* temp = root_;
+  root_ = nullptr;
+  return temp;
+}
+inline ::dmi::Component* Hardware::mutable_root() {
+  
+  if (root_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Component>(GetArenaNoVirtual());
+    root_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Hardware.root)
+  return root_;
+}
+inline void Hardware::set_allocated_root(::dmi::Component* root) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete root_;
+  }
+  if (root) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      root = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, root, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  root_ = root;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Hardware.root)
+}
+
+// .google.protobuf.Timestamp last_booted = 3;
+inline bool Hardware::has_last_booted() const {
+  return this != internal_default_instance() && last_booted_ != nullptr;
+}
+inline const ::google::protobuf::Timestamp& Hardware::last_booted() const {
+  const ::google::protobuf::Timestamp* p = last_booted_;
+  // @@protoc_insertion_point(field_get:dmi.Hardware.last_booted)
+  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
+      &::google::protobuf::_Timestamp_default_instance_);
+}
+inline ::google::protobuf::Timestamp* Hardware::release_last_booted() {
+  // @@protoc_insertion_point(field_release:dmi.Hardware.last_booted)
+  
+  ::google::protobuf::Timestamp* temp = last_booted_;
+  last_booted_ = nullptr;
+  return temp;
+}
+inline ::google::protobuf::Timestamp* Hardware::mutable_last_booted() {
+  
+  if (last_booted_ == nullptr) {
+    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
+    last_booted_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Hardware.last_booted)
+  return last_booted_;
+}
+inline void Hardware::set_allocated_last_booted(::google::protobuf::Timestamp* last_booted) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(last_booted_);
+  }
+  if (last_booted) {
+    ::google::protobuf::Arena* submessage_arena =
+      reinterpret_cast<::google::protobuf::MessageLite*>(last_booted)->GetArena();
+    if (message_arena != submessage_arena) {
+      last_booted = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, last_booted, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  last_booted_ = last_booted;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Hardware.last_booted)
+}
+
+// -------------------------------------------------------------------
+
+// ModifiableComponent
+
+// string name = 1;
+inline void ModifiableComponent::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ModifiableComponent::name() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.name)
+  return name_.GetNoArena();
+}
+inline void ModifiableComponent::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.name)
+}
+#if LANG_CXX11
+inline void ModifiableComponent::set_name(::std::string&& value) {
+  
+  name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ModifiableComponent.name)
+}
+#endif
+inline void ModifiableComponent::set_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ModifiableComponent.name)
+}
+inline void ModifiableComponent::set_name(const char* value, size_t size) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ModifiableComponent.name)
+}
+inline ::std::string* ModifiableComponent::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ModifiableComponent::release_name() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ModifiableComponent::set_allocated_name(::std::string* name) {
+  if (name != nullptr) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.name)
+}
+
+// .dmi.ComponentType class = 2;
+inline void ModifiableComponent::clear_class_() {
+  class__ = 0;
+}
+inline ::dmi::ComponentType ModifiableComponent::class_() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.class)
+  return static_cast< ::dmi::ComponentType >(class__);
+}
+inline void ModifiableComponent::set_class_(::dmi::ComponentType value) {
+  
+  class__ = value;
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.class)
+}
+
+// .dmi.Component parent = 3;
+inline bool ModifiableComponent::has_parent() const {
+  return this != internal_default_instance() && parent_ != nullptr;
+}
+inline void ModifiableComponent::clear_parent() {
+  if (GetArenaNoVirtual() == nullptr && parent_ != nullptr) {
+    delete parent_;
+  }
+  parent_ = nullptr;
+}
+inline const ::dmi::Component& ModifiableComponent::parent() const {
+  const ::dmi::Component* p = parent_;
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.parent)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Component*>(
+      &::dmi::_Component_default_instance_);
+}
+inline ::dmi::Component* ModifiableComponent::release_parent() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.parent)
+  
+  ::dmi::Component* temp = parent_;
+  parent_ = nullptr;
+  return temp;
+}
+inline ::dmi::Component* ModifiableComponent::mutable_parent() {
+  
+  if (parent_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Component>(GetArenaNoVirtual());
+    parent_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.parent)
+  return parent_;
+}
+inline void ModifiableComponent::set_allocated_parent(::dmi::Component* parent) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete parent_;
+  }
+  if (parent) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      parent = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, parent, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  parent_ = parent;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.parent)
+}
+
+// int32 parent_rel_pos = 4;
+inline void ModifiableComponent::clear_parent_rel_pos() {
+  parent_rel_pos_ = 0;
+}
+inline ::google::protobuf::int32 ModifiableComponent::parent_rel_pos() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.parent_rel_pos)
+  return parent_rel_pos_;
+}
+inline void ModifiableComponent::set_parent_rel_pos(::google::protobuf::int32 value) {
+  
+  parent_rel_pos_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.parent_rel_pos)
+}
+
+// string alias = 5;
+inline void ModifiableComponent::clear_alias() {
+  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ModifiableComponent::alias() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.alias)
+  return alias_.GetNoArena();
+}
+inline void ModifiableComponent::set_alias(const ::std::string& value) {
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.alias)
+}
+#if LANG_CXX11
+inline void ModifiableComponent::set_alias(::std::string&& value) {
+  
+  alias_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ModifiableComponent.alias)
+}
+#endif
+inline void ModifiableComponent::set_alias(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ModifiableComponent.alias)
+}
+inline void ModifiableComponent::set_alias(const char* value, size_t size) {
+  
+  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ModifiableComponent.alias)
+}
+inline ::std::string* ModifiableComponent::mutable_alias() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.alias)
+  return alias_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ModifiableComponent::release_alias() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.alias)
+  
+  return alias_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ModifiableComponent::set_allocated_alias(::std::string* alias) {
+  if (alias != nullptr) {
+    
+  } else {
+    
+  }
+  alias_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), alias);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.alias)
+}
+
+// string asset_id = 6;
+inline void ModifiableComponent::clear_asset_id() {
+  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ModifiableComponent::asset_id() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.asset_id)
+  return asset_id_.GetNoArena();
+}
+inline void ModifiableComponent::set_asset_id(const ::std::string& value) {
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.asset_id)
+}
+#if LANG_CXX11
+inline void ModifiableComponent::set_asset_id(::std::string&& value) {
+  
+  asset_id_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ModifiableComponent.asset_id)
+}
+#endif
+inline void ModifiableComponent::set_asset_id(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ModifiableComponent.asset_id)
+}
+inline void ModifiableComponent::set_asset_id(const char* value, size_t size) {
+  
+  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ModifiableComponent.asset_id)
+}
+inline ::std::string* ModifiableComponent::mutable_asset_id() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.asset_id)
+  return asset_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ModifiableComponent::release_asset_id() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.asset_id)
+  
+  return asset_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ModifiableComponent::set_allocated_asset_id(::std::string* asset_id) {
+  if (asset_id != nullptr) {
+    
+  } else {
+    
+  }
+  asset_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), asset_id);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.asset_id)
+}
+
+// .dmi.Uri uri = 7;
+inline bool ModifiableComponent::has_uri() const {
+  return this != internal_default_instance() && uri_ != nullptr;
+}
+inline void ModifiableComponent::clear_uri() {
+  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
+    delete uri_;
+  }
+  uri_ = nullptr;
+}
+inline const ::dmi::Uri& ModifiableComponent::uri() const {
+  const ::dmi::Uri* p = uri_;
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.uri)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uri*>(
+      &::dmi::_Uri_default_instance_);
+}
+inline ::dmi::Uri* ModifiableComponent::release_uri() {
+  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.uri)
+  
+  ::dmi::Uri* temp = uri_;
+  uri_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uri* ModifiableComponent::mutable_uri() {
+  
+  if (uri_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uri>(GetArenaNoVirtual());
+    uri_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.uri)
+  return uri_;
+}
+inline void ModifiableComponent::set_allocated_uri(::dmi::Uri* uri) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete uri_;
+  }
+  if (uri) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      uri = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, uri, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  uri_ = uri;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.uri)
+}
+
+// .dmi.ComponentAdminState admin_state = 8;
+inline void ModifiableComponent::clear_admin_state() {
+  admin_state_ = 0;
+}
+inline ::dmi::ComponentAdminState ModifiableComponent::admin_state() const {
+  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.admin_state)
+  return static_cast< ::dmi::ComponentAdminState >(admin_state_);
+}
+inline void ModifiableComponent::set_admin_state(::dmi::ComponentAdminState value) {
+  
+  admin_state_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.admin_state)
+}
+
+#ifdef __GNUC__
+  #pragma GCC diagnostic pop
+#endif  // __GNUC__
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace dmi
+
+namespace google {
+namespace protobuf {
+
+template <> struct is_proto_enum< ::dmi::PortComponentAttributes_ConnectorType> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PortComponentAttributes_ConnectorType>() {
+  return ::dmi::PortComponentAttributes_ConnectorType_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::PortComponentAttributes_Speed> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PortComponentAttributes_Speed>() {
+  return ::dmi::PortComponentAttributes_Speed_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::PortComponentAttributes_Protocol> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PortComponentAttributes_Protocol>() {
+  return ::dmi::PortComponentAttributes_Protocol_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::PsuComponentAttributes_SupportedVoltage> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PsuComponentAttributes_SupportedVoltage>() {
+  return ::dmi::PsuComponentAttributes_SupportedVoltage_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::TransceiverComponentsAttributes_FormFactor> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::TransceiverComponentsAttributes_FormFactor>() {
+  return ::dmi::TransceiverComponentsAttributes_FormFactor_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::TransceiverComponentsAttributes_Type> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::TransceiverComponentsAttributes_Type>() {
+  return ::dmi::TransceiverComponentsAttributes_Type_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentType> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentType>() {
+  return ::dmi::ComponentType_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentAdminState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentAdminState>() {
+  return ::dmi::ComponentAdminState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentOperState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentOperState>() {
+  return ::dmi::ComponentOperState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentUsageState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentUsageState>() {
+  return ::dmi::ComponentUsageState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentAlarmState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentAlarmState>() {
+  return ::dmi::ComponentAlarmState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ComponentStandbyState> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentStandbyState>() {
+  return ::dmi::ComponentStandbyState_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::DataValueType> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::DataValueType>() {
+  return ::dmi::DataValueType_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ValueScale> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ValueScale>() {
+  return ::dmi::ValueScale_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::SensorStatus> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::SensorStatus>() {
+  return ::dmi::SensorStatus_descriptor();
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+
+#include <google/protobuf/port_undef.inc>
+#endif  // PROTOBUF_INCLUDED_dmi_2fhw_2eproto
