diff --git a/cpp/dmi/hw.pb.cc b/cpp/dmi/hw.pb.cc
new file mode 100644
index 0000000..1b32844
--- /dev/null
+++ b/cpp/dmi/hw.pb.cc
@@ -0,0 +1,7832 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: dmi/hw.proto
+
+#include "dmi/hw.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+#include <google/protobuf/port_def.inc>
+
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_PortComponentAttributes_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_PsuComponentAttributes_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uri_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ComponentSensorData_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_ComponentState_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<9> scc_info_Component_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto;
+namespace dmi {
+class UuidDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Uuid> _instance;
+} _Uuid_default_instance_;
+class HardwareIDDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<HardwareID> _instance;
+} _HardwareID_default_instance_;
+class UriDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Uri> _instance;
+} _Uri_default_instance_;
+class ComponentStateDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ComponentState> _instance;
+} _ComponentState_default_instance_;
+class ComponentSensorDataDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ComponentSensorData> _instance;
+} _ComponentSensorData_default_instance_;
+class PortComponentAttributesDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<PortComponentAttributes> _instance;
+} _PortComponentAttributes_default_instance_;
+class ContainerComponentAttributesDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ContainerComponentAttributes> _instance;
+} _ContainerComponentAttributes_default_instance_;
+class PsuComponentAttributesDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<PsuComponentAttributes> _instance;
+} _PsuComponentAttributes_default_instance_;
+class TransceiverComponentsAttributesDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<TransceiverComponentsAttributes> _instance;
+} _TransceiverComponentsAttributes_default_instance_;
+class ComponentDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Component> _instance;
+  const ::dmi::PortComponentAttributes* port_attr_;
+  const ::dmi::ContainerComponentAttributes* container_attr_;
+  const ::dmi::PsuComponentAttributes* psu_attr_;
+  const ::dmi::TransceiverComponentsAttributes* transceiver_attr_;
+} _Component_default_instance_;
+class HardwareDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<Hardware> _instance;
+} _Hardware_default_instance_;
+class ModifiableComponentDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ModifiableComponent> _instance;
+} _ModifiableComponent_default_instance_;
+}  // namespace dmi
+static void InitDefaultsUuid_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Uuid_default_instance_;
+    new (ptr) ::dmi::Uuid();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Uuid::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUuid_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsHardwareID_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_HardwareID_default_instance_;
+    new (ptr) ::dmi::HardwareID();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::HardwareID::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_HardwareID_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsHardwareID_dmi_2fhw_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsUri_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Uri_default_instance_;
+    new (ptr) ::dmi::Uri();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Uri::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_Uri_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUri_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsComponentState_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ComponentState_default_instance_;
+    new (ptr) ::dmi::ComponentState();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ComponentState::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ComponentState_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsComponentState_dmi_2fhw_2eproto}, {
+      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,}};
+
+static void InitDefaultsComponentSensorData_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ComponentSensorData_default_instance_;
+    new (ptr) ::dmi::ComponentSensorData();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ComponentSensorData::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ComponentSensorData_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsComponentSensorData_dmi_2fhw_2eproto}, {
+      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,}};
+
+static void InitDefaultsPortComponentAttributes_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_PortComponentAttributes_default_instance_;
+    new (ptr) ::dmi::PortComponentAttributes();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::PortComponentAttributes::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_PortComponentAttributes_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsPortComponentAttributes_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsContainerComponentAttributes_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ContainerComponentAttributes_default_instance_;
+    new (ptr) ::dmi::ContainerComponentAttributes();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ContainerComponentAttributes::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsContainerComponentAttributes_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsPsuComponentAttributes_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_PsuComponentAttributes_default_instance_;
+    new (ptr) ::dmi::PsuComponentAttributes();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::PsuComponentAttributes::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_PsuComponentAttributes_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsPsuComponentAttributes_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsTransceiverComponentsAttributes_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_TransceiverComponentsAttributes_default_instance_;
+    new (ptr) ::dmi::TransceiverComponentsAttributes();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::TransceiverComponentsAttributes::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsTransceiverComponentsAttributes_dmi_2fhw_2eproto}, {}};
+
+static void InitDefaultsComponent_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Component_default_instance_;
+    new (ptr) ::dmi::Component();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Component::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<9> scc_info_Component_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 9, InitDefaultsComponent_dmi_2fhw_2eproto}, {
+      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,
+      &scc_info_Uri_dmi_2fhw_2eproto.base,
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,
+      &scc_info_ComponentState_dmi_2fhw_2eproto.base,
+      &scc_info_ComponentSensorData_dmi_2fhw_2eproto.base,
+      &scc_info_PortComponentAttributes_dmi_2fhw_2eproto.base,
+      &scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto.base,
+      &scc_info_PsuComponentAttributes_dmi_2fhw_2eproto.base,
+      &scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsHardware_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_Hardware_default_instance_;
+    new (ptr) ::dmi::Hardware();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::Hardware::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_Hardware_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsHardware_dmi_2fhw_2eproto}, {
+      &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,
+      &scc_info_Component_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsModifiableComponent_dmi_2fhw_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ModifiableComponent_default_instance_;
+    new (ptr) ::dmi::ModifiableComponent();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ModifiableComponent::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<2> scc_info_ModifiableComponent_dmi_2fhw_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsModifiableComponent_dmi_2fhw_2eproto}, {
+      &scc_info_Component_dmi_2fhw_2eproto.base,
+      &scc_info_Uri_dmi_2fhw_2eproto.base,}};
+
+void InitDefaults_dmi_2fhw_2eproto() {
+  ::google::protobuf::internal::InitSCC(&scc_info_Uuid_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_HardwareID_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Uri_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ComponentState_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ComponentSensorData_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_PortComponentAttributes_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_PsuComponentAttributes_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Component_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_Hardware_dmi_2fhw_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ModifiableComponent_dmi_2fhw_2eproto.base);
+}
+
+::google::protobuf::Metadata file_level_metadata_dmi_2fhw_2eproto[12];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fhw_2eproto[15];
+constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fhw_2eproto = nullptr;
+
+const ::google::protobuf::uint32 TableStruct_dmi_2fhw_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Uuid, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Uuid, uuid_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::HardwareID, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::HardwareID, uuid_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Uri, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Uri, uri_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, state_last_changed_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, admin_state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, oper_state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, usage_state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, alarm_state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentState, standby_state_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, value_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, type_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, scale_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, precision_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, units_display_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, timestamp_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, value_update_rate_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ComponentSensorData, data_type_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, connector_type_),
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, speed_),
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, protocol_),
+  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, physical_label_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ContainerComponentAttributes, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ContainerComponentAttributes, physical_label_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::PsuComponentAttributes, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::PsuComponentAttributes, supported_voltage_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, form_factor_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, trans_type_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, max_distance_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, max_distance_scale_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, rx_wavelength_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, tx_wavelength_),
+  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, wavelength_scale_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, _internal_metadata_),
+  ~0u,  // no _extensions_
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, _oneof_case_[0]),
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, class__),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, description_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, parent_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, parent_rel_pos_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, children_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, hardware_rev_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, firmware_rev_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, software_rev_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, serial_num_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, mfg_name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, model_name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, alias_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, asset_id_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, is_fru_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, mfg_date_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, uri_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, state_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, sensor_data_),
+  offsetof(::dmi::ComponentDefaultTypeInternal, port_attr_),
+  offsetof(::dmi::ComponentDefaultTypeInternal, container_attr_),
+  offsetof(::dmi::ComponentDefaultTypeInternal, psu_attr_),
+  offsetof(::dmi::ComponentDefaultTypeInternal, transceiver_attr_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Component, specific_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::Hardware, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::Hardware, last_change_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Hardware, root_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Hardware, last_booted_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, name_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, class__),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, parent_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, parent_rel_pos_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, alias_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, asset_id_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, uri_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, admin_state_),
+};
+static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
+  { 0, -1, sizeof(::dmi::Uuid)},
+  { 6, -1, sizeof(::dmi::HardwareID)},
+  { 12, -1, sizeof(::dmi::Uri)},
+  { 18, -1, sizeof(::dmi::ComponentState)},
+  { 29, -1, sizeof(::dmi::ComponentSensorData)},
+  { 43, -1, sizeof(::dmi::PortComponentAttributes)},
+  { 52, -1, sizeof(::dmi::ContainerComponentAttributes)},
+  { 58, -1, sizeof(::dmi::PsuComponentAttributes)},
+  { 64, -1, sizeof(::dmi::TransceiverComponentsAttributes)},
+  { 76, -1, sizeof(::dmi::Component)},
+  { 106, -1, sizeof(::dmi::Hardware)},
+  { 114, -1, sizeof(::dmi::ModifiableComponent)},
+};
+
+static ::google::protobuf::Message const * const file_default_instances[] = {
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Uuid_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_HardwareID_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Uri_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ComponentState_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ComponentSensorData_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_PortComponentAttributes_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ContainerComponentAttributes_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_PsuComponentAttributes_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_TransceiverComponentsAttributes_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Component_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Hardware_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ModifiableComponent_default_instance_),
+};
+
+::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fhw_2eproto = {
+  {}, AddDescriptors_dmi_2fhw_2eproto, "dmi/hw.proto", schemas,
+  file_default_instances, TableStruct_dmi_2fhw_2eproto::offsets,
+  file_level_metadata_dmi_2fhw_2eproto, 12, file_level_enum_descriptors_dmi_2fhw_2eproto, file_level_service_descriptors_dmi_2fhw_2eproto,
+};
+
+const char descriptor_table_protodef_dmi_2fhw_2eproto[] =
+  "\n\014dmi/hw.proto\022\003dmi\032\037google/protobuf/tim"
+  "estamp.proto\"\024\n\004Uuid\022\014\n\004uuid\030\001 \001(\t\"%\n\nHa"
+  "rdwareID\022\027\n\004uuid\030\001 \001(\0132\t.dmi.Uuid\"\022\n\003Uri"
+  "\022\013\n\003uri\030\001 \001(\t\"\265\002\n\016ComponentState\0226\n\022stat"
+  "e_last_changed\030\001 \001(\0132\032.google.protobuf.T"
+  "imestamp\022-\n\013admin_state\030\002 \001(\0162\030.dmi.Comp"
+  "onentAdminState\022+\n\noper_state\030\003 \001(\0162\027.dm"
+  "i.ComponentOperState\022-\n\013usage_state\030\004 \001("
+  "\0162\030.dmi.ComponentUsageState\022-\n\013alarm_sta"
+  "te\030\005 \001(\0162\030.dmi.ComponentAlarmState\0221\n\rst"
+  "andby_state\030\006 \001(\0162\032.dmi.ComponentStandby"
+  "State\"\220\002\n\023ComponentSensorData\022\r\n\005value\030\001"
+  " \001(\005\022 \n\004type\030\002 \001(\0162\022.dmi.DataValueType\022\036"
+  "\n\005scale\030\003 \001(\0162\017.dmi.ValueScale\022\021\n\tprecis"
+  "ion\030\004 \001(\005\022!\n\006status\030\005 \001(\0162\021.dmi.SensorSt"
+  "atus\022\025\n\runits_display\030\006 \001(\t\022-\n\ttimestamp"
+  "\030\007 \001(\0132\032.google.protobuf.Timestamp\022\031\n\021va"
+  "lue_update_rate\030\010 \001(\r\022\021\n\tdata_type\030\t \001(\t"
+  "\"\202\005\n\027PortComponentAttributes\022B\n\016connecto"
+  "r_type\030\001 \001(\0162*.dmi.PortComponentAttribut"
+  "es.ConnectorType\0221\n\005speed\030\002 \001(\0162\".dmi.Po"
+  "rtComponentAttributes.Speed\0227\n\010protocol\030"
+  "\003 \001(\0162%.dmi.PortComponentAttributes.Prot"
+  "ocol\022\026\n\016physical_label\030\004 \001(\t\"p\n\rConnecto"
+  "rType\022\034\n\030CONNECTOR_TYPE_UNDEFINED\020\000\022\010\n\004R"
+  "J45\020\001\022\014\n\010FIBER_LC\020\002\022\017\n\013FIBER_SC_PC\020\003\022\r\n\t"
+  "FIBER_MPO\020\004\022\t\n\005RS232\020\005\"\256\001\n\005Speed\022\023\n\017SPEE"
+  "D_UNDEFINED\020\000\022\013\n\007DYNAMIC\020\001\022\r\n\tGIGABIT_1\020"
+  "\002\022\016\n\nGIGABIT_10\020\003\022\016\n\nGIGABIT_25\020\004\022\016\n\nGIG"
+  "ABIT_40\020\005\022\017\n\013GIGABIT_100\020\006\022\017\n\013GIGABIT_40"
+  "0\020\007\022\020\n\014MEGABIT_2500\020\010\022\020\n\014MEGABIT_1250\020\t\""
+  "|\n\010Protocol\022\026\n\022PROTOCOL_UNDEFINED\020\000\022\014\n\010E"
+  "THERNET\020\001\022\010\n\004GPON\020\002\022\t\n\005XGPON\020\003\022\n\n\006XGSPON"
+  "\020\004\022\t\n\005GFAST\020\005\022\n\n\006SERIAL\020\006\022\010\n\004EPON\020\007\022\010\n\004B"
+  "ITS\020\010\"6\n\034ContainerComponentAttributes\022\026\n"
+  "\016physical_label\030\001 \001(\t\"\263\001\n\026PsuComponentAt"
+  "tributes\022G\n\021supported_voltage\030\001 \001(\0162,.dm"
+  "i.PsuComponentAttributes.SupportedVoltag"
+  "e\"P\n\020SupportedVoltage\022\037\n\033SUPPORTED_VOLTA"
+  "GE_UNDEFINED\020\000\022\007\n\003V48\020\001\022\010\n\004V230\020\002\022\010\n\004V11"
+  "5\020\003\"\357\004\n\037TransceiverComponentsAttributes\022"
+  "D\n\013form_factor\030\001 \001(\0162/.dmi.TransceiverCo"
+  "mponentsAttributes.FormFactor\022=\n\ntrans_t"
+  "ype\030\002 \001(\0162).dmi.TransceiverComponentsAtt"
+  "ributes.Type\022\024\n\014max_distance\030\003 \001(\r\022+\n\022ma"
+  "x_distance_scale\030\004 \001(\0162\017.dmi.ValueScale\022"
+  "\025\n\rrx_wavelength\030\005 \003(\r\022\025\n\rtx_wavelength\030"
+  "\006 \003(\r\022)\n\020wavelength_scale\030\007 \001(\0162\017.dmi.Va"
+  "lueScale\"\300\001\n\nFormFactor\022\027\n\023FORM_FACTOR_U"
+  "NKNOWN\020\000\022\010\n\004QSFP\020\001\022\r\n\tQSFP_PLUS\020\002\022\n\n\006QSF"
+  "P28\020\003\022\007\n\003SFP\020\004\022\014\n\010SFP_PLUS\020\005\022\007\n\003XFP\020\006\022\010\n"
+  "\004CFP4\020\007\022\010\n\004CFP2\020\010\022\010\n\004CPAK\020\t\022\006\n\002X2\020\n\022\t\n\005O"
+  "THER\020\013\022\007\n\003CFP\020\014\022\014\n\010CFP2_ACO\020\r\022\014\n\010CFP2_DC"
+  "O\020\016\"h\n\004Type\022\020\n\014TYPE_UNKNOWN\020\000\022\014\n\010ETHERNE"
+  "T\020\001\022\010\n\004GPON\020\002\022\t\n\005XGPON\020\003\022\n\n\006XGSPON\020\004\022\010\n\004"
+  "CPON\020\005\022\013\n\007NG_PON2\020\006\022\010\n\004EPON\020\007\"\350\005\n\tCompon"
+  "ent\022\014\n\004name\030\001 \001(\t\022!\n\005class\030\002 \001(\0162\022.dmi.C"
+  "omponentType\022\023\n\013description\030\003 \001(\t\022\016\n\006par"
+  "ent\030\004 \001(\t\022\026\n\016parent_rel_pos\030\005 \001(\005\022 \n\010chi"
+  "ldren\030\006 \003(\0132\016.dmi.Component\022\024\n\014hardware_"
+  "rev\030\007 \001(\t\022\024\n\014firmware_rev\030\010 \001(\t\022\024\n\014softw"
+  "are_rev\030\t \001(\t\022\022\n\nserial_num\030\n \001(\t\022\020\n\010mfg"
+  "_name\030\013 \001(\t\022\022\n\nmodel_name\030\014 \001(\t\022\r\n\005alias"
+  "\030\r \001(\t\022\020\n\010asset_id\030\016 \001(\t\022\016\n\006is_fru\030\017 \001(\010"
+  "\022,\n\010mfg_date\030\020 \001(\0132\032.google.protobuf.Tim"
+  "estamp\022\025\n\003uri\030\021 \001(\0132\010.dmi.Uri\022\027\n\004uuid\030\022 "
+  "\001(\0132\t.dmi.Uuid\022\"\n\005state\030\023 \001(\0132\023.dmi.Comp"
+  "onentState\022-\n\013sensor_data\030\024 \003(\0132\030.dmi.Co"
+  "mponentSensorData\0221\n\tport_attr\0302 \001(\0132\034.d"
+  "mi.PortComponentAttributesH\000\022;\n\016containe"
+  "r_attr\0303 \001(\0132!.dmi.ContainerComponentAtt"
+  "ributesH\000\022/\n\010psu_attr\0304 \001(\0132\033.dmi.PsuCom"
+  "ponentAttributesH\000\022@\n\020transceiver_attr\0305"
+  " \001(\0132$.dmi.TransceiverComponentsAttribut"
+  "esH\000B\n\n\010specific\"\212\001\n\010Hardware\022/\n\013last_ch"
+  "ange\030\001 \001(\0132\032.google.protobuf.Timestamp\022\034"
+  "\n\004root\030\002 \001(\0132\016.dmi.Component\022/\n\013last_boo"
+  "ted\030\003 \001(\0132\032.google.protobuf.Timestamp\"\345\001"
+  "\n\023ModifiableComponent\022\014\n\004name\030\001 \001(\t\022!\n\005c"
+  "lass\030\002 \001(\0162\022.dmi.ComponentType\022\036\n\006parent"
+  "\030\003 \001(\0132\016.dmi.Component\022\026\n\016parent_rel_pos"
+  "\030\004 \001(\005\022\r\n\005alias\030\005 \001(\t\022\020\n\010asset_id\030\006 \001(\t\022"
+  "\025\n\003uri\030\007 \001(\0132\010.dmi.Uri\022-\n\013admin_state\030\010 "
+  "\001(\0162\030.dmi.ComponentAdminState*\264\003\n\rCompon"
+  "entType\022\034\n\030COMPONENT_TYPE_UNDEFINED\020\000\022\032\n"
+  "\026COMPONENT_TYPE_UNKNOWN\020\001\022\032\n\026COMPONENT_T"
+  "YPE_CHASSIS\020\002\022\034\n\030COMPONENT_TYPE_BACKPLAN"
+  "E\020\003\022\034\n\030COMPONENT_TYPE_CONTAINER\020\004\022\037\n\033COM"
+  "PONENT_TYPE_POWER_SUPPLY\020\005\022\026\n\022COMPONENT_"
+  "TYPE_FAN\020\006\022\031\n\025COMPONENT_TYPE_SENSOR\020\007\022\031\n"
+  "\025COMPONENT_TYPE_MODULE\020\010\022\027\n\023COMPONENT_TY"
+  "PE_PORT\020\t\022\026\n\022COMPONENT_TYPE_CPU\020\n\022\032\n\026COM"
+  "PONENT_TYPE_BATTERY\020\013\022\032\n\026COMPONENT_TYPE_"
+  "STORAGE\020\014\022\031\n\025COMPONENT_TYPE_MEMORY\020\r\022\036\n\032"
+  "COMPONENT_TYPE_TRANSCEIVER\020\016*\263\001\n\023Compone"
+  "ntAdminState\022\036\n\032COMP_ADMIN_STATE_UNDEFIN"
+  "ED\020\000\022\034\n\030COMP_ADMIN_STATE_UNKNOWN\020\001\022\033\n\027CO"
+  "MP_ADMIN_STATE_LOCKED\020\002\022\"\n\036COMP_ADMIN_ST"
+  "ATE_SHUTTING_DOWN\020\003\022\035\n\031COMP_ADMIN_STATE_"
+  "UNLOCKED\020\004*\250\001\n\022ComponentOperState\022\035\n\031COM"
+  "P_OPER_STATE_UNDEFINED\020\000\022\033\n\027COMP_OPER_ST"
+  "ATE_UNKNOWN\020\001\022\034\n\030COMP_OPER_STATE_DISABLE"
+  "D\020\002\022\033\n\027COMP_OPER_STATE_ENABLED\020\003\022\033\n\027COMP"
+  "_OPER_STATE_TESTING\020\004*\246\001\n\023ComponentUsage"
+  "State\022\036\n\032COMP_USAGE_STATE_UNDEFINED\020\000\022\034\n"
+  "\030COMP_USAGE_STATE_UNKNOWN\020\001\022\031\n\025COMP_USAG"
+  "E_STATE_IDLE\020\002\022\033\n\027COMP_USAGE_STATE_ACTIV"
+  "E\020\003\022\031\n\025COMP_USAGE_STATE_BUSY\020\004*\217\002\n\023Compo"
+  "nentAlarmState\022\036\n\032COMP_ALARM_STATE_UNDEF"
+  "INED\020\000\022\034\n\030COMP_ALARM_STATE_UNKNOWN\020\001\022!\n\035"
+  "COMP_ALARM_STATE_UNDER_REPAIR\020\002\022\035\n\031COMP_"
+  "ALARM_STATE_CRITICAL\020\003\022\032\n\026COMP_ALARM_STA"
+  "TE_MAJOR\020\004\022\032\n\026COMP_ALARM_STATE_MINOR\020\005\022\034"
+  "\n\030COMP_ALARM_STATE_WARNING\020\006\022\"\n\036COMP_ALA"
+  "RM_STATE_INDETERMINATE\020\007*\274\001\n\025ComponentSt"
+  "andbyState\022 \n\034COMP_STANDBY_STATE_UNDEFIN"
+  "ED\020\000\022\036\n\032COMP_STANDBY_STATE_UNKNOWN\020\001\022\032\n\026"
+  "COMP_STANDBY_STATE_HOT\020\002\022\033\n\027COMP_STANDBY"
+  "_STATE_COLD\020\003\022(\n$COMP_STANDBY_STATE_PROV"
+  "IDING_SERVICE\020\004*\211\003\n\rDataValueType\022\030\n\024VAL"
+  "UE_TYPE_UNDEFINED\020\000\022\024\n\020VALUE_TYPE_OTHER\020"
+  "\001\022\026\n\022VALUE_TYPE_UNKNOWN\020\002\022\027\n\023VALUE_TYPE_"
+  "VOLTS_AC\020\003\022\027\n\023VALUE_TYPE_VOLTS_DC\020\004\022\026\n\022V"
+  "ALUE_TYPE_AMPERES\020\005\022\024\n\020VALUE_TYPE_WATTS\020"
+  "\006\022\024\n\020VALUE_TYPE_HERTZ\020\007\022\026\n\022VALUE_TYPE_CE"
+  "LSIUS\020\010\022\031\n\025VALUE_TYPE_PERCENT_RH\020\t\022\022\n\016VA"
+  "LUE_TYPE_RPM\020\n\022\022\n\016VALUE_TYPE_CMM\020\013\022\032\n\026VA"
+  "LUE_TYPE_TRUTH_VALUE\020\014\022\026\n\022VALUE_TYPE_PER"
+  "CENT\020\r\022\025\n\021VALUE_TYPE_METERS\020\016\022\024\n\020VALUE_T"
+  "YPE_BYTES\020\017*\244\003\n\nValueScale\022\031\n\025VALUE_SCAL"
+  "E_UNDEFINED\020\000\022\025\n\021VALUE_SCALE_YOCTO\020\001\022\025\n\021"
+  "VALUE_SCALE_ZEPTO\020\002\022\024\n\020VALUE_SCALE_ATTO\020"
+  "\003\022\025\n\021VALUE_SCALE_FEMTO\020\004\022\024\n\020VALUE_SCALE_"
+  "PICO\020\005\022\024\n\020VALUE_SCALE_NANO\020\006\022\025\n\021VALUE_SC"
+  "ALE_MICRO\020\007\022\025\n\021VALUE_SCALE_MILLI\020\010\022\025\n\021VA"
+  "LUE_SCALE_UNITS\020\t\022\024\n\020VALUE_SCALE_KILO\020\n\022"
+  "\024\n\020VALUE_SCALE_MEGA\020\013\022\024\n\020VALUE_SCALE_GIG"
+  "A\020\014\022\024\n\020VALUE_SCALE_TERA\020\r\022\024\n\020VALUE_SCALE"
+  "_PETA\020\016\022\023\n\017VALUE_SCALE_EXA\020\017\022\025\n\021VALUE_SC"
+  "ALE_ZETTA\020\020\022\025\n\021VALUE_SCALE_YOTTA\020\021*\202\001\n\014S"
+  "ensorStatus\022\033\n\027SENSOR_STATUS_UNDEFINED\020\000"
+  "\022\024\n\020SENSOR_STATUS_OK\020\001\022\035\n\031SENSOR_STATUS_"
+  "UNAVAILABLE\020\002\022 \n\034SENSOR_STATUS_NONOPERAT"
+  "IONAL\020\003B;Z9github.com/opencord/device-ma"
+  "nagement-interface/v3/go/dmib\006proto3"
+  ;
+::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fhw_2eproto = {
+  false, InitDefaults_dmi_2fhw_2eproto, 
+  descriptor_table_protodef_dmi_2fhw_2eproto,
+  "dmi/hw.proto", &assign_descriptors_table_dmi_2fhw_2eproto, 5796,
+};
+
+void AddDescriptors_dmi_2fhw_2eproto() {
+  static constexpr ::google::protobuf::internal::InitFunc deps[1] =
+  {
+    ::AddDescriptors_google_2fprotobuf_2ftimestamp_2eproto,
+  };
+ ::google::protobuf::internal::AddDescriptors(&descriptor_table_dmi_2fhw_2eproto, deps, 1);
+}
+
+// Force running AddDescriptors() at dynamic initialization time.
+static bool dynamic_init_dummy_dmi_2fhw_2eproto = []() { AddDescriptors_dmi_2fhw_2eproto(); return true; }();
+namespace dmi {
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_ConnectorType_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[0];
+}
+bool PortComponentAttributes_ConnectorType_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const PortComponentAttributes_ConnectorType PortComponentAttributes::CONNECTOR_TYPE_UNDEFINED;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::RJ45;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::FIBER_LC;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::FIBER_SC_PC;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::FIBER_MPO;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::RS232;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::ConnectorType_MIN;
+const PortComponentAttributes_ConnectorType PortComponentAttributes::ConnectorType_MAX;
+const int PortComponentAttributes::ConnectorType_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Speed_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[1];
+}
+bool PortComponentAttributes_Speed_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const PortComponentAttributes_Speed PortComponentAttributes::SPEED_UNDEFINED;
+const PortComponentAttributes_Speed PortComponentAttributes::DYNAMIC;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_1;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_10;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_25;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_40;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_100;
+const PortComponentAttributes_Speed PortComponentAttributes::GIGABIT_400;
+const PortComponentAttributes_Speed PortComponentAttributes::MEGABIT_2500;
+const PortComponentAttributes_Speed PortComponentAttributes::MEGABIT_1250;
+const PortComponentAttributes_Speed PortComponentAttributes::Speed_MIN;
+const PortComponentAttributes_Speed PortComponentAttributes::Speed_MAX;
+const int PortComponentAttributes::Speed_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Protocol_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[2];
+}
+bool PortComponentAttributes_Protocol_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const PortComponentAttributes_Protocol PortComponentAttributes::PROTOCOL_UNDEFINED;
+const PortComponentAttributes_Protocol PortComponentAttributes::ETHERNET;
+const PortComponentAttributes_Protocol PortComponentAttributes::GPON;
+const PortComponentAttributes_Protocol PortComponentAttributes::XGPON;
+const PortComponentAttributes_Protocol PortComponentAttributes::XGSPON;
+const PortComponentAttributes_Protocol PortComponentAttributes::GFAST;
+const PortComponentAttributes_Protocol PortComponentAttributes::SERIAL;
+const PortComponentAttributes_Protocol PortComponentAttributes::EPON;
+const PortComponentAttributes_Protocol PortComponentAttributes::BITS;
+const PortComponentAttributes_Protocol PortComponentAttributes::Protocol_MIN;
+const PortComponentAttributes_Protocol PortComponentAttributes::Protocol_MAX;
+const int PortComponentAttributes::Protocol_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* PsuComponentAttributes_SupportedVoltage_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[3];
+}
+bool PsuComponentAttributes_SupportedVoltage_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::SUPPORTED_VOLTAGE_UNDEFINED;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::V48;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::V230;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::V115;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::SupportedVoltage_MIN;
+const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::SupportedVoltage_MAX;
+const int PsuComponentAttributes::SupportedVoltage_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_FormFactor_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[4];
+}
+bool TransceiverComponentsAttributes_FormFactor_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::FORM_FACTOR_UNKNOWN;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::QSFP;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::QSFP_PLUS;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::QSFP28;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::SFP;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::SFP_PLUS;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::XFP;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP4;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP2;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CPAK;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::X2;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::OTHER;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP2_ACO;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::CFP2_DCO;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::FormFactor_MIN;
+const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::FormFactor_MAX;
+const int TransceiverComponentsAttributes::FormFactor_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_Type_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[5];
+}
+bool TransceiverComponentsAttributes_Type_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::TYPE_UNKNOWN;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::ETHERNET;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::GPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::XGPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::XGSPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::CPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::NG_PON2;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::EPON;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::Type_MIN;
+const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::Type_MAX;
+const int TransceiverComponentsAttributes::Type_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* ComponentType_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[6];
+}
+bool ComponentType_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentAdminState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[7];
+}
+bool ComponentAdminState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentOperState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[8];
+}
+bool ComponentOperState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentUsageState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[9];
+}
+bool ComponentUsageState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentAlarmState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[10];
+}
+bool ComponentAlarmState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ComponentStandbyState_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[11];
+}
+bool ComponentStandbyState_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* DataValueType_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[12];
+}
+bool DataValueType_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* ValueScale_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[13];
+}
+bool ValueScale_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+    case 16:
+    case 17:
+      return true;
+    default:
+      return false;
+  }
+}
+
+const ::google::protobuf::EnumDescriptor* SensorStatus_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_2eproto[14];
+}
+bool SensorStatus_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+
+// ===================================================================
+
+void Uuid::InitAsDefaultInstance() {
+}
+class Uuid::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Uuid::kUuidFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Uuid::Uuid()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Uuid)
+}
+Uuid::Uuid(const Uuid& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  uuid_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.uuid().size() > 0) {
+    uuid_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.uuid_);
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.Uuid)
+}
+
+void Uuid::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Uuid_dmi_2fhw_2eproto.base);
+  uuid_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+Uuid::~Uuid() {
+  // @@protoc_insertion_point(destructor:dmi.Uuid)
+  SharedDtor();
+}
+
+void Uuid::SharedDtor() {
+  uuid_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void Uuid::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Uuid& Uuid::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Uuid_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Uuid::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Uuid)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  uuid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Uuid::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Uuid*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Uuid.uuid");
+        object = msg->mutable_uuid();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Uuid::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Uuid)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_uuid()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->uuid().data(), static_cast<int>(this->uuid().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Uuid.uuid"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Uuid)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Uuid)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Uuid::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Uuid)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string uuid = 1;
+  if (this->uuid().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->uuid().data(), static_cast<int>(this->uuid().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Uuid.uuid");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->uuid(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Uuid)
+}
+
+::google::protobuf::uint8* Uuid::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Uuid)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string uuid = 1;
+  if (this->uuid().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->uuid().data(), static_cast<int>(this->uuid().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Uuid.uuid");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->uuid(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Uuid)
+  return target;
+}
+
+size_t Uuid::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Uuid)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string uuid = 1;
+  if (this->uuid().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->uuid());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Uuid::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Uuid)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Uuid* source =
+      ::google::protobuf::DynamicCastToGenerated<Uuid>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Uuid)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Uuid)
+    MergeFrom(*source);
+  }
+}
+
+void Uuid::MergeFrom(const Uuid& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Uuid)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.uuid().size() > 0) {
+
+    uuid_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.uuid_);
+  }
+}
+
+void Uuid::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Uuid)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Uuid::CopyFrom(const Uuid& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Uuid)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Uuid::IsInitialized() const {
+  return true;
+}
+
+void Uuid::Swap(Uuid* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Uuid::InternalSwap(Uuid* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  uuid_.Swap(&other->uuid_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+}
+
+::google::protobuf::Metadata Uuid::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void HardwareID::InitAsDefaultInstance() {
+  ::dmi::_HardwareID_default_instance_._instance.get_mutable()->uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class HardwareID::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& uuid(const HardwareID* msg);
+};
+
+const ::dmi::Uuid&
+HardwareID::HasBitSetters::uuid(const HardwareID* msg) {
+  return *msg->uuid_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int HardwareID::kUuidFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+HardwareID::HardwareID()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.HardwareID)
+}
+HardwareID::HardwareID(const HardwareID& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_uuid()) {
+    uuid_ = new ::dmi::Uuid(*from.uuid_);
+  } else {
+    uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.HardwareID)
+}
+
+void HardwareID::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_HardwareID_dmi_2fhw_2eproto.base);
+  uuid_ = nullptr;
+}
+
+HardwareID::~HardwareID() {
+  // @@protoc_insertion_point(destructor:dmi.HardwareID)
+  SharedDtor();
+}
+
+void HardwareID::SharedDtor() {
+  if (this != internal_default_instance()) delete uuid_;
+}
+
+void HardwareID::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const HardwareID& HardwareID::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_HardwareID_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void HardwareID::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.HardwareID)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
+    delete uuid_;
+  }
+  uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* HardwareID::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<HardwareID*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool HardwareID::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.HardwareID)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.HardwareID)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.HardwareID)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void HardwareID::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.HardwareID)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid uuid = 1;
+  if (this->has_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::uuid(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.HardwareID)
+}
+
+::google::protobuf::uint8* HardwareID::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.HardwareID)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid uuid = 1;
+  if (this->has_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::uuid(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.HardwareID)
+  return target;
+}
+
+size_t HardwareID::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.HardwareID)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.Uuid uuid = 1;
+  if (this->has_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void HardwareID::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.HardwareID)
+  GOOGLE_DCHECK_NE(&from, this);
+  const HardwareID* source =
+      ::google::protobuf::DynamicCastToGenerated<HardwareID>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.HardwareID)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.HardwareID)
+    MergeFrom(*source);
+  }
+}
+
+void HardwareID::MergeFrom(const HardwareID& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.HardwareID)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_uuid()) {
+    mutable_uuid()->::dmi::Uuid::MergeFrom(from.uuid());
+  }
+}
+
+void HardwareID::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.HardwareID)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void HardwareID::CopyFrom(const HardwareID& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.HardwareID)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool HardwareID::IsInitialized() const {
+  return true;
+}
+
+void HardwareID::Swap(HardwareID* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void HardwareID::InternalSwap(HardwareID* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(uuid_, other->uuid_);
+}
+
+::google::protobuf::Metadata HardwareID::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void Uri::InitAsDefaultInstance() {
+}
+class Uri::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Uri::kUriFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Uri::Uri()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Uri)
+}
+Uri::Uri(const Uri& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  uri_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.uri().size() > 0) {
+    uri_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.uri_);
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.Uri)
+}
+
+void Uri::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Uri_dmi_2fhw_2eproto.base);
+  uri_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+Uri::~Uri() {
+  // @@protoc_insertion_point(destructor:dmi.Uri)
+  SharedDtor();
+}
+
+void Uri::SharedDtor() {
+  uri_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void Uri::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Uri& Uri::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Uri_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Uri::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Uri)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  uri_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Uri::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Uri*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string uri = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Uri.uri");
+        object = msg->mutable_uri();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Uri::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Uri)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string uri = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_uri()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->uri().data(), static_cast<int>(this->uri().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Uri.uri"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Uri)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Uri)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Uri::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Uri)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string uri = 1;
+  if (this->uri().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->uri().data(), static_cast<int>(this->uri().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Uri.uri");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->uri(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Uri)
+}
+
+::google::protobuf::uint8* Uri::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Uri)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string uri = 1;
+  if (this->uri().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->uri().data(), static_cast<int>(this->uri().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Uri.uri");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->uri(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Uri)
+  return target;
+}
+
+size_t Uri::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Uri)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string uri = 1;
+  if (this->uri().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->uri());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Uri::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Uri)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Uri* source =
+      ::google::protobuf::DynamicCastToGenerated<Uri>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Uri)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Uri)
+    MergeFrom(*source);
+  }
+}
+
+void Uri::MergeFrom(const Uri& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Uri)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.uri().size() > 0) {
+
+    uri_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.uri_);
+  }
+}
+
+void Uri::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Uri)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Uri::CopyFrom(const Uri& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Uri)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Uri::IsInitialized() const {
+  return true;
+}
+
+void Uri::Swap(Uri* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Uri::InternalSwap(Uri* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  uri_.Swap(&other->uri_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+}
+
+::google::protobuf::Metadata Uri::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ComponentState::InitAsDefaultInstance() {
+  ::dmi::_ComponentState_default_instance_._instance.get_mutable()->state_last_changed_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+}
+class ComponentState::HasBitSetters {
+ public:
+  static const ::google::protobuf::Timestamp& state_last_changed(const ComponentState* msg);
+};
+
+const ::google::protobuf::Timestamp&
+ComponentState::HasBitSetters::state_last_changed(const ComponentState* msg) {
+  return *msg->state_last_changed_;
+}
+void ComponentState::clear_state_last_changed() {
+  if (GetArenaNoVirtual() == nullptr && state_last_changed_ != nullptr) {
+    delete state_last_changed_;
+  }
+  state_last_changed_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ComponentState::kStateLastChangedFieldNumber;
+const int ComponentState::kAdminStateFieldNumber;
+const int ComponentState::kOperStateFieldNumber;
+const int ComponentState::kUsageStateFieldNumber;
+const int ComponentState::kAlarmStateFieldNumber;
+const int ComponentState::kStandbyStateFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ComponentState::ComponentState()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ComponentState)
+}
+ComponentState::ComponentState(const ComponentState& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_state_last_changed()) {
+    state_last_changed_ = new ::google::protobuf::Timestamp(*from.state_last_changed_);
+  } else {
+    state_last_changed_ = nullptr;
+  }
+  ::memcpy(&admin_state_, &from.admin_state_,
+    static_cast<size_t>(reinterpret_cast<char*>(&standby_state_) -
+    reinterpret_cast<char*>(&admin_state_)) + sizeof(standby_state_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ComponentState)
+}
+
+void ComponentState::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ComponentState_dmi_2fhw_2eproto.base);
+  ::memset(&state_last_changed_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&standby_state_) -
+      reinterpret_cast<char*>(&state_last_changed_)) + sizeof(standby_state_));
+}
+
+ComponentState::~ComponentState() {
+  // @@protoc_insertion_point(destructor:dmi.ComponentState)
+  SharedDtor();
+}
+
+void ComponentState::SharedDtor() {
+  if (this != internal_default_instance()) delete state_last_changed_;
+}
+
+void ComponentState::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ComponentState& ComponentState::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ComponentState_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ComponentState::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ComponentState)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && state_last_changed_ != nullptr) {
+    delete state_last_changed_;
+  }
+  state_last_changed_ = nullptr;
+  ::memset(&admin_state_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&standby_state_) -
+      reinterpret_cast<char*>(&admin_state_)) + sizeof(standby_state_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ComponentState::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ComponentState*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .google.protobuf.Timestamp state_last_changed = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_state_last_changed();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ComponentAdminState admin_state = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_admin_state(static_cast<::dmi::ComponentAdminState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentOperState oper_state = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_oper_state(static_cast<::dmi::ComponentOperState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentUsageState usage_state = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_usage_state(static_cast<::dmi::ComponentUsageState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentAlarmState alarm_state = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_alarm_state(static_cast<::dmi::ComponentAlarmState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentStandbyState standby_state = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_standby_state(static_cast<::dmi::ComponentStandbyState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ComponentState::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ComponentState)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .google.protobuf.Timestamp state_last_changed = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_state_last_changed()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentAdminState admin_state = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_admin_state(static_cast< ::dmi::ComponentAdminState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentOperState oper_state = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_oper_state(static_cast< ::dmi::ComponentOperState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentUsageState usage_state = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_usage_state(static_cast< ::dmi::ComponentUsageState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentAlarmState alarm_state = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_alarm_state(static_cast< ::dmi::ComponentAlarmState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentStandbyState standby_state = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (48 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_standby_state(static_cast< ::dmi::ComponentStandbyState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ComponentState)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ComponentState)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ComponentState::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ComponentState)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp state_last_changed = 1;
+  if (this->has_state_last_changed()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::state_last_changed(this), output);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 2;
+  if (this->admin_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->admin_state(), output);
+  }
+
+  // .dmi.ComponentOperState oper_state = 3;
+  if (this->oper_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      3, this->oper_state(), output);
+  }
+
+  // .dmi.ComponentUsageState usage_state = 4;
+  if (this->usage_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      4, this->usage_state(), output);
+  }
+
+  // .dmi.ComponentAlarmState alarm_state = 5;
+  if (this->alarm_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      5, this->alarm_state(), output);
+  }
+
+  // .dmi.ComponentStandbyState standby_state = 6;
+  if (this->standby_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      6, this->standby_state(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ComponentState)
+}
+
+::google::protobuf::uint8* ComponentState::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ComponentState)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp state_last_changed = 1;
+  if (this->has_state_last_changed()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::state_last_changed(this), target);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 2;
+  if (this->admin_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->admin_state(), target);
+  }
+
+  // .dmi.ComponentOperState oper_state = 3;
+  if (this->oper_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      3, this->oper_state(), target);
+  }
+
+  // .dmi.ComponentUsageState usage_state = 4;
+  if (this->usage_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      4, this->usage_state(), target);
+  }
+
+  // .dmi.ComponentAlarmState alarm_state = 5;
+  if (this->alarm_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      5, this->alarm_state(), target);
+  }
+
+  // .dmi.ComponentStandbyState standby_state = 6;
+  if (this->standby_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      6, this->standby_state(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ComponentState)
+  return target;
+}
+
+size_t ComponentState::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ComponentState)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp state_last_changed = 1;
+  if (this->has_state_last_changed()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *state_last_changed_);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 2;
+  if (this->admin_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->admin_state());
+  }
+
+  // .dmi.ComponentOperState oper_state = 3;
+  if (this->oper_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->oper_state());
+  }
+
+  // .dmi.ComponentUsageState usage_state = 4;
+  if (this->usage_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->usage_state());
+  }
+
+  // .dmi.ComponentAlarmState alarm_state = 5;
+  if (this->alarm_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->alarm_state());
+  }
+
+  // .dmi.ComponentStandbyState standby_state = 6;
+  if (this->standby_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->standby_state());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ComponentState::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ComponentState)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ComponentState* source =
+      ::google::protobuf::DynamicCastToGenerated<ComponentState>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ComponentState)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ComponentState)
+    MergeFrom(*source);
+  }
+}
+
+void ComponentState::MergeFrom(const ComponentState& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ComponentState)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_state_last_changed()) {
+    mutable_state_last_changed()->::google::protobuf::Timestamp::MergeFrom(from.state_last_changed());
+  }
+  if (from.admin_state() != 0) {
+    set_admin_state(from.admin_state());
+  }
+  if (from.oper_state() != 0) {
+    set_oper_state(from.oper_state());
+  }
+  if (from.usage_state() != 0) {
+    set_usage_state(from.usage_state());
+  }
+  if (from.alarm_state() != 0) {
+    set_alarm_state(from.alarm_state());
+  }
+  if (from.standby_state() != 0) {
+    set_standby_state(from.standby_state());
+  }
+}
+
+void ComponentState::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ComponentState)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ComponentState::CopyFrom(const ComponentState& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ComponentState)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ComponentState::IsInitialized() const {
+  return true;
+}
+
+void ComponentState::Swap(ComponentState* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ComponentState::InternalSwap(ComponentState* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(state_last_changed_, other->state_last_changed_);
+  swap(admin_state_, other->admin_state_);
+  swap(oper_state_, other->oper_state_);
+  swap(usage_state_, other->usage_state_);
+  swap(alarm_state_, other->alarm_state_);
+  swap(standby_state_, other->standby_state_);
+}
+
+::google::protobuf::Metadata ComponentState::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ComponentSensorData::InitAsDefaultInstance() {
+  ::dmi::_ComponentSensorData_default_instance_._instance.get_mutable()->timestamp_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+}
+class ComponentSensorData::HasBitSetters {
+ public:
+  static const ::google::protobuf::Timestamp& timestamp(const ComponentSensorData* msg);
+};
+
+const ::google::protobuf::Timestamp&
+ComponentSensorData::HasBitSetters::timestamp(const ComponentSensorData* msg) {
+  return *msg->timestamp_;
+}
+void ComponentSensorData::clear_timestamp() {
+  if (GetArenaNoVirtual() == nullptr && timestamp_ != nullptr) {
+    delete timestamp_;
+  }
+  timestamp_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ComponentSensorData::kValueFieldNumber;
+const int ComponentSensorData::kTypeFieldNumber;
+const int ComponentSensorData::kScaleFieldNumber;
+const int ComponentSensorData::kPrecisionFieldNumber;
+const int ComponentSensorData::kStatusFieldNumber;
+const int ComponentSensorData::kUnitsDisplayFieldNumber;
+const int ComponentSensorData::kTimestampFieldNumber;
+const int ComponentSensorData::kValueUpdateRateFieldNumber;
+const int ComponentSensorData::kDataTypeFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ComponentSensorData::ComponentSensorData()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ComponentSensorData)
+}
+ComponentSensorData::ComponentSensorData(const ComponentSensorData& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  units_display_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.units_display().size() > 0) {
+    units_display_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.units_display_);
+  }
+  data_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.data_type().size() > 0) {
+    data_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.data_type_);
+  }
+  if (from.has_timestamp()) {
+    timestamp_ = new ::google::protobuf::Timestamp(*from.timestamp_);
+  } else {
+    timestamp_ = nullptr;
+  }
+  ::memcpy(&value_, &from.value_,
+    static_cast<size_t>(reinterpret_cast<char*>(&value_update_rate_) -
+    reinterpret_cast<char*>(&value_)) + sizeof(value_update_rate_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ComponentSensorData)
+}
+
+void ComponentSensorData::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ComponentSensorData_dmi_2fhw_2eproto.base);
+  units_display_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  data_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&timestamp_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&value_update_rate_) -
+      reinterpret_cast<char*>(&timestamp_)) + sizeof(value_update_rate_));
+}
+
+ComponentSensorData::~ComponentSensorData() {
+  // @@protoc_insertion_point(destructor:dmi.ComponentSensorData)
+  SharedDtor();
+}
+
+void ComponentSensorData::SharedDtor() {
+  units_display_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  data_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete timestamp_;
+}
+
+void ComponentSensorData::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ComponentSensorData& ComponentSensorData::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ComponentSensorData_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ComponentSensorData::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ComponentSensorData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  units_display_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  data_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && timestamp_ != nullptr) {
+    delete timestamp_;
+  }
+  timestamp_ = nullptr;
+  ::memset(&value_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&value_update_rate_) -
+      reinterpret_cast<char*>(&value_)) + sizeof(value_update_rate_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ComponentSensorData::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ComponentSensorData*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // int32 value = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.DataValueType type = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_type(static_cast<::dmi::DataValueType>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ValueScale scale = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_scale(static_cast<::dmi::ValueScale>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // int32 precision = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        msg->set_precision(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.SensorStatus status = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::SensorStatus>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string units_display = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ComponentSensorData.units_display");
+        object = msg->mutable_units_display();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // .google.protobuf.Timestamp timestamp = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_timestamp();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // uint32 value_update_rate = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 64) goto handle_unusual;
+        msg->set_value_update_rate(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string data_type = 9;
+      case 9: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ComponentSensorData.data_type");
+        object = msg->mutable_data_type();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ComponentSensorData::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ComponentSensorData)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // int32 value = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &value_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.DataValueType type = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_type(static_cast< ::dmi::DataValueType >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ValueScale scale = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_scale(static_cast< ::dmi::ValueScale >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // int32 precision = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &precision_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.SensorStatus status = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::SensorStatus >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string units_display = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_units_display()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->units_display().data(), static_cast<int>(this->units_display().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ComponentSensorData.units_display"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .google.protobuf.Timestamp timestamp = 7;
+      case 7: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_timestamp()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // uint32 value_update_rate = 8;
+      case 8: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (64 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, &value_update_rate_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string data_type = 9;
+      case 9: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (74 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_data_type()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->data_type().data(), static_cast<int>(this->data_type().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ComponentSensorData.data_type"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ComponentSensorData)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ComponentSensorData)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ComponentSensorData::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ComponentSensorData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // int32 value = 1;
+  if (this->value() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->value(), output);
+  }
+
+  // .dmi.DataValueType type = 2;
+  if (this->type() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->type(), output);
+  }
+
+  // .dmi.ValueScale scale = 3;
+  if (this->scale() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      3, this->scale(), output);
+  }
+
+  // int32 precision = 4;
+  if (this->precision() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->precision(), output);
+  }
+
+  // .dmi.SensorStatus status = 5;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      5, this->status(), output);
+  }
+
+  // string units_display = 6;
+  if (this->units_display().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->units_display().data(), static_cast<int>(this->units_display().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ComponentSensorData.units_display");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      6, this->units_display(), output);
+  }
+
+  // .google.protobuf.Timestamp timestamp = 7;
+  if (this->has_timestamp()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      7, HasBitSetters::timestamp(this), output);
+  }
+
+  // uint32 value_update_rate = 8;
+  if (this->value_update_rate() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32(8, this->value_update_rate(), output);
+  }
+
+  // string data_type = 9;
+  if (this->data_type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->data_type().data(), static_cast<int>(this->data_type().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ComponentSensorData.data_type");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      9, this->data_type(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ComponentSensorData)
+}
+
+::google::protobuf::uint8* ComponentSensorData::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ComponentSensorData)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // int32 value = 1;
+  if (this->value() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->value(), target);
+  }
+
+  // .dmi.DataValueType type = 2;
+  if (this->type() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->type(), target);
+  }
+
+  // .dmi.ValueScale scale = 3;
+  if (this->scale() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      3, this->scale(), target);
+  }
+
+  // int32 precision = 4;
+  if (this->precision() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->precision(), target);
+  }
+
+  // .dmi.SensorStatus status = 5;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      5, this->status(), target);
+  }
+
+  // string units_display = 6;
+  if (this->units_display().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->units_display().data(), static_cast<int>(this->units_display().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ComponentSensorData.units_display");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        6, this->units_display(), target);
+  }
+
+  // .google.protobuf.Timestamp timestamp = 7;
+  if (this->has_timestamp()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        7, HasBitSetters::timestamp(this), target);
+  }
+
+  // uint32 value_update_rate = 8;
+  if (this->value_update_rate() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(8, this->value_update_rate(), target);
+  }
+
+  // string data_type = 9;
+  if (this->data_type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->data_type().data(), static_cast<int>(this->data_type().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ComponentSensorData.data_type");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        9, this->data_type(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ComponentSensorData)
+  return target;
+}
+
+size_t ComponentSensorData::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ComponentSensorData)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string units_display = 6;
+  if (this->units_display().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->units_display());
+  }
+
+  // string data_type = 9;
+  if (this->data_type().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->data_type());
+  }
+
+  // .google.protobuf.Timestamp timestamp = 7;
+  if (this->has_timestamp()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *timestamp_);
+  }
+
+  // int32 value = 1;
+  if (this->value() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->value());
+  }
+
+  // .dmi.DataValueType type = 2;
+  if (this->type() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
+  }
+
+  // .dmi.ValueScale scale = 3;
+  if (this->scale() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->scale());
+  }
+
+  // int32 precision = 4;
+  if (this->precision() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->precision());
+  }
+
+  // .dmi.SensorStatus status = 5;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // uint32 value_update_rate = 8;
+  if (this->value_update_rate() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::UInt32Size(
+        this->value_update_rate());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ComponentSensorData::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ComponentSensorData)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ComponentSensorData* source =
+      ::google::protobuf::DynamicCastToGenerated<ComponentSensorData>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ComponentSensorData)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ComponentSensorData)
+    MergeFrom(*source);
+  }
+}
+
+void ComponentSensorData::MergeFrom(const ComponentSensorData& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ComponentSensorData)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.units_display().size() > 0) {
+
+    units_display_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.units_display_);
+  }
+  if (from.data_type().size() > 0) {
+
+    data_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.data_type_);
+  }
+  if (from.has_timestamp()) {
+    mutable_timestamp()->::google::protobuf::Timestamp::MergeFrom(from.timestamp());
+  }
+  if (from.value() != 0) {
+    set_value(from.value());
+  }
+  if (from.type() != 0) {
+    set_type(from.type());
+  }
+  if (from.scale() != 0) {
+    set_scale(from.scale());
+  }
+  if (from.precision() != 0) {
+    set_precision(from.precision());
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.value_update_rate() != 0) {
+    set_value_update_rate(from.value_update_rate());
+  }
+}
+
+void ComponentSensorData::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ComponentSensorData)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ComponentSensorData::CopyFrom(const ComponentSensorData& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ComponentSensorData)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ComponentSensorData::IsInitialized() const {
+  return true;
+}
+
+void ComponentSensorData::Swap(ComponentSensorData* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ComponentSensorData::InternalSwap(ComponentSensorData* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  units_display_.Swap(&other->units_display_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  data_type_.Swap(&other->data_type_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(timestamp_, other->timestamp_);
+  swap(value_, other->value_);
+  swap(type_, other->type_);
+  swap(scale_, other->scale_);
+  swap(precision_, other->precision_);
+  swap(status_, other->status_);
+  swap(value_update_rate_, other->value_update_rate_);
+}
+
+::google::protobuf::Metadata ComponentSensorData::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void PortComponentAttributes::InitAsDefaultInstance() {
+}
+class PortComponentAttributes::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int PortComponentAttributes::kConnectorTypeFieldNumber;
+const int PortComponentAttributes::kSpeedFieldNumber;
+const int PortComponentAttributes::kProtocolFieldNumber;
+const int PortComponentAttributes::kPhysicalLabelFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+PortComponentAttributes::PortComponentAttributes()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.PortComponentAttributes)
+}
+PortComponentAttributes::PortComponentAttributes(const PortComponentAttributes& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  physical_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.physical_label().size() > 0) {
+    physical_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.physical_label_);
+  }
+  ::memcpy(&connector_type_, &from.connector_type_,
+    static_cast<size_t>(reinterpret_cast<char*>(&protocol_) -
+    reinterpret_cast<char*>(&connector_type_)) + sizeof(protocol_));
+  // @@protoc_insertion_point(copy_constructor:dmi.PortComponentAttributes)
+}
+
+void PortComponentAttributes::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_PortComponentAttributes_dmi_2fhw_2eproto.base);
+  physical_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&connector_type_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&protocol_) -
+      reinterpret_cast<char*>(&connector_type_)) + sizeof(protocol_));
+}
+
+PortComponentAttributes::~PortComponentAttributes() {
+  // @@protoc_insertion_point(destructor:dmi.PortComponentAttributes)
+  SharedDtor();
+}
+
+void PortComponentAttributes::SharedDtor() {
+  physical_label_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void PortComponentAttributes::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const PortComponentAttributes& PortComponentAttributes::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_PortComponentAttributes_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void PortComponentAttributes::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.PortComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&connector_type_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&protocol_) -
+      reinterpret_cast<char*>(&connector_type_)) + sizeof(protocol_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* PortComponentAttributes::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<PortComponentAttributes*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_connector_type(static_cast<::dmi::PortComponentAttributes_ConnectorType>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.PortComponentAttributes.Speed speed = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_speed(static_cast<::dmi::PortComponentAttributes_Speed>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.PortComponentAttributes.Protocol protocol = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_protocol(static_cast<::dmi::PortComponentAttributes_Protocol>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string physical_label = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.PortComponentAttributes.physical_label");
+        object = msg->mutable_physical_label();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool PortComponentAttributes::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.PortComponentAttributes)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_connector_type(static_cast< ::dmi::PortComponentAttributes_ConnectorType >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.PortComponentAttributes.Speed speed = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_speed(static_cast< ::dmi::PortComponentAttributes_Speed >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.PortComponentAttributes.Protocol protocol = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_protocol(static_cast< ::dmi::PortComponentAttributes_Protocol >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string physical_label = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_physical_label()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.PortComponentAttributes.physical_label"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.PortComponentAttributes)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.PortComponentAttributes)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void PortComponentAttributes::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.PortComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+  if (this->connector_type() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->connector_type(), output);
+  }
+
+  // .dmi.PortComponentAttributes.Speed speed = 2;
+  if (this->speed() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->speed(), output);
+  }
+
+  // .dmi.PortComponentAttributes.Protocol protocol = 3;
+  if (this->protocol() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      3, this->protocol(), output);
+  }
+
+  // string physical_label = 4;
+  if (this->physical_label().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.PortComponentAttributes.physical_label");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->physical_label(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.PortComponentAttributes)
+}
+
+::google::protobuf::uint8* PortComponentAttributes::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.PortComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+  if (this->connector_type() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->connector_type(), target);
+  }
+
+  // .dmi.PortComponentAttributes.Speed speed = 2;
+  if (this->speed() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->speed(), target);
+  }
+
+  // .dmi.PortComponentAttributes.Protocol protocol = 3;
+  if (this->protocol() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      3, this->protocol(), target);
+  }
+
+  // string physical_label = 4;
+  if (this->physical_label().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.PortComponentAttributes.physical_label");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->physical_label(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.PortComponentAttributes)
+  return target;
+}
+
+size_t PortComponentAttributes::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.PortComponentAttributes)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string physical_label = 4;
+  if (this->physical_label().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->physical_label());
+  }
+
+  // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
+  if (this->connector_type() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->connector_type());
+  }
+
+  // .dmi.PortComponentAttributes.Speed speed = 2;
+  if (this->speed() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->speed());
+  }
+
+  // .dmi.PortComponentAttributes.Protocol protocol = 3;
+  if (this->protocol() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->protocol());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void PortComponentAttributes::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.PortComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  const PortComponentAttributes* source =
+      ::google::protobuf::DynamicCastToGenerated<PortComponentAttributes>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.PortComponentAttributes)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.PortComponentAttributes)
+    MergeFrom(*source);
+  }
+}
+
+void PortComponentAttributes::MergeFrom(const PortComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.PortComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.physical_label().size() > 0) {
+
+    physical_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.physical_label_);
+  }
+  if (from.connector_type() != 0) {
+    set_connector_type(from.connector_type());
+  }
+  if (from.speed() != 0) {
+    set_speed(from.speed());
+  }
+  if (from.protocol() != 0) {
+    set_protocol(from.protocol());
+  }
+}
+
+void PortComponentAttributes::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.PortComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void PortComponentAttributes::CopyFrom(const PortComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.PortComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool PortComponentAttributes::IsInitialized() const {
+  return true;
+}
+
+void PortComponentAttributes::Swap(PortComponentAttributes* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void PortComponentAttributes::InternalSwap(PortComponentAttributes* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  physical_label_.Swap(&other->physical_label_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(connector_type_, other->connector_type_);
+  swap(speed_, other->speed_);
+  swap(protocol_, other->protocol_);
+}
+
+::google::protobuf::Metadata PortComponentAttributes::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ContainerComponentAttributes::InitAsDefaultInstance() {
+}
+class ContainerComponentAttributes::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ContainerComponentAttributes::kPhysicalLabelFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ContainerComponentAttributes::ContainerComponentAttributes()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ContainerComponentAttributes)
+}
+ContainerComponentAttributes::ContainerComponentAttributes(const ContainerComponentAttributes& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  physical_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.physical_label().size() > 0) {
+    physical_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.physical_label_);
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.ContainerComponentAttributes)
+}
+
+void ContainerComponentAttributes::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto.base);
+  physical_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+ContainerComponentAttributes::~ContainerComponentAttributes() {
+  // @@protoc_insertion_point(destructor:dmi.ContainerComponentAttributes)
+  SharedDtor();
+}
+
+void ContainerComponentAttributes::SharedDtor() {
+  physical_label_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void ContainerComponentAttributes::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ContainerComponentAttributes& ContainerComponentAttributes::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ContainerComponentAttributes_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ContainerComponentAttributes::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ContainerComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ContainerComponentAttributes::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ContainerComponentAttributes*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string physical_label = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ContainerComponentAttributes.physical_label");
+        object = msg->mutable_physical_label();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ContainerComponentAttributes::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ContainerComponentAttributes)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string physical_label = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_physical_label()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ContainerComponentAttributes.physical_label"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ContainerComponentAttributes)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ContainerComponentAttributes)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ContainerComponentAttributes::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ContainerComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string physical_label = 1;
+  if (this->physical_label().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ContainerComponentAttributes.physical_label");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->physical_label(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ContainerComponentAttributes)
+}
+
+::google::protobuf::uint8* ContainerComponentAttributes::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ContainerComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string physical_label = 1;
+  if (this->physical_label().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->physical_label().data(), static_cast<int>(this->physical_label().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ContainerComponentAttributes.physical_label");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->physical_label(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ContainerComponentAttributes)
+  return target;
+}
+
+size_t ContainerComponentAttributes::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ContainerComponentAttributes)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string physical_label = 1;
+  if (this->physical_label().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->physical_label());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ContainerComponentAttributes::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ContainerComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ContainerComponentAttributes* source =
+      ::google::protobuf::DynamicCastToGenerated<ContainerComponentAttributes>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ContainerComponentAttributes)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ContainerComponentAttributes)
+    MergeFrom(*source);
+  }
+}
+
+void ContainerComponentAttributes::MergeFrom(const ContainerComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ContainerComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.physical_label().size() > 0) {
+
+    physical_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.physical_label_);
+  }
+}
+
+void ContainerComponentAttributes::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ContainerComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ContainerComponentAttributes::CopyFrom(const ContainerComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ContainerComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ContainerComponentAttributes::IsInitialized() const {
+  return true;
+}
+
+void ContainerComponentAttributes::Swap(ContainerComponentAttributes* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ContainerComponentAttributes::InternalSwap(ContainerComponentAttributes* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  physical_label_.Swap(&other->physical_label_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+}
+
+::google::protobuf::Metadata ContainerComponentAttributes::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void PsuComponentAttributes::InitAsDefaultInstance() {
+}
+class PsuComponentAttributes::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int PsuComponentAttributes::kSupportedVoltageFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+PsuComponentAttributes::PsuComponentAttributes()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.PsuComponentAttributes)
+}
+PsuComponentAttributes::PsuComponentAttributes(const PsuComponentAttributes& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  supported_voltage_ = from.supported_voltage_;
+  // @@protoc_insertion_point(copy_constructor:dmi.PsuComponentAttributes)
+}
+
+void PsuComponentAttributes::SharedCtor() {
+  supported_voltage_ = 0;
+}
+
+PsuComponentAttributes::~PsuComponentAttributes() {
+  // @@protoc_insertion_point(destructor:dmi.PsuComponentAttributes)
+  SharedDtor();
+}
+
+void PsuComponentAttributes::SharedDtor() {
+}
+
+void PsuComponentAttributes::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const PsuComponentAttributes& PsuComponentAttributes::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_PsuComponentAttributes_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void PsuComponentAttributes::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.PsuComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  supported_voltage_ = 0;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* PsuComponentAttributes::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<PsuComponentAttributes*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_supported_voltage(static_cast<::dmi::PsuComponentAttributes_SupportedVoltage>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool PsuComponentAttributes::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.PsuComponentAttributes)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_supported_voltage(static_cast< ::dmi::PsuComponentAttributes_SupportedVoltage >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.PsuComponentAttributes)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.PsuComponentAttributes)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void PsuComponentAttributes::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.PsuComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+  if (this->supported_voltage() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->supported_voltage(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.PsuComponentAttributes)
+}
+
+::google::protobuf::uint8* PsuComponentAttributes::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.PsuComponentAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+  if (this->supported_voltage() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->supported_voltage(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.PsuComponentAttributes)
+  return target;
+}
+
+size_t PsuComponentAttributes::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.PsuComponentAttributes)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
+  if (this->supported_voltage() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->supported_voltage());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void PsuComponentAttributes::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.PsuComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  const PsuComponentAttributes* source =
+      ::google::protobuf::DynamicCastToGenerated<PsuComponentAttributes>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.PsuComponentAttributes)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.PsuComponentAttributes)
+    MergeFrom(*source);
+  }
+}
+
+void PsuComponentAttributes::MergeFrom(const PsuComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.PsuComponentAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.supported_voltage() != 0) {
+    set_supported_voltage(from.supported_voltage());
+  }
+}
+
+void PsuComponentAttributes::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.PsuComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void PsuComponentAttributes::CopyFrom(const PsuComponentAttributes& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.PsuComponentAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool PsuComponentAttributes::IsInitialized() const {
+  return true;
+}
+
+void PsuComponentAttributes::Swap(PsuComponentAttributes* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void PsuComponentAttributes::InternalSwap(PsuComponentAttributes* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(supported_voltage_, other->supported_voltage_);
+}
+
+::google::protobuf::Metadata PsuComponentAttributes::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void TransceiverComponentsAttributes::InitAsDefaultInstance() {
+}
+class TransceiverComponentsAttributes::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int TransceiverComponentsAttributes::kFormFactorFieldNumber;
+const int TransceiverComponentsAttributes::kTransTypeFieldNumber;
+const int TransceiverComponentsAttributes::kMaxDistanceFieldNumber;
+const int TransceiverComponentsAttributes::kMaxDistanceScaleFieldNumber;
+const int TransceiverComponentsAttributes::kRxWavelengthFieldNumber;
+const int TransceiverComponentsAttributes::kTxWavelengthFieldNumber;
+const int TransceiverComponentsAttributes::kWavelengthScaleFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+TransceiverComponentsAttributes::TransceiverComponentsAttributes()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.TransceiverComponentsAttributes)
+}
+TransceiverComponentsAttributes::TransceiverComponentsAttributes(const TransceiverComponentsAttributes& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      rx_wavelength_(from.rx_wavelength_),
+      tx_wavelength_(from.tx_wavelength_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::memcpy(&form_factor_, &from.form_factor_,
+    static_cast<size_t>(reinterpret_cast<char*>(&wavelength_scale_) -
+    reinterpret_cast<char*>(&form_factor_)) + sizeof(wavelength_scale_));
+  // @@protoc_insertion_point(copy_constructor:dmi.TransceiverComponentsAttributes)
+}
+
+void TransceiverComponentsAttributes::SharedCtor() {
+  ::memset(&form_factor_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&wavelength_scale_) -
+      reinterpret_cast<char*>(&form_factor_)) + sizeof(wavelength_scale_));
+}
+
+TransceiverComponentsAttributes::~TransceiverComponentsAttributes() {
+  // @@protoc_insertion_point(destructor:dmi.TransceiverComponentsAttributes)
+  SharedDtor();
+}
+
+void TransceiverComponentsAttributes::SharedDtor() {
+}
+
+void TransceiverComponentsAttributes::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const TransceiverComponentsAttributes& TransceiverComponentsAttributes::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_TransceiverComponentsAttributes_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void TransceiverComponentsAttributes::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.TransceiverComponentsAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  rx_wavelength_.Clear();
+  tx_wavelength_.Clear();
+  ::memset(&form_factor_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&wavelength_scale_) -
+      reinterpret_cast<char*>(&form_factor_)) + sizeof(wavelength_scale_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* TransceiverComponentsAttributes::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<TransceiverComponentsAttributes*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_form_factor(static_cast<::dmi::TransceiverComponentsAttributes_FormFactor>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_trans_type(static_cast<::dmi::TransceiverComponentsAttributes_Type>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // uint32 max_distance = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
+        msg->set_max_distance(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ValueScale max_distance_scale = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_max_distance_scale(static_cast<::dmi::ValueScale>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // repeated uint32 rx_wavelength = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) == 42) {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::google::protobuf::internal::PackedUInt32Parser;
+          object = msg->mutable_rx_wavelength();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (size) ptr = parser_till_end(ptr, newend, object, ctx);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr == newend);
+          break;
+        } else if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        do {
+          msg->add_rx_wavelength(::google::protobuf::internal::ReadVarint(&ptr));
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 40 && (ptr += 1));
+        break;
+      }
+      // repeated uint32 tx_wavelength = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) == 50) {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::google::protobuf::internal::PackedUInt32Parser;
+          object = msg->mutable_tx_wavelength();
+          if (size > end - ptr) goto len_delim_till_end;
+          auto newend = ptr + size;
+          if (size) ptr = parser_till_end(ptr, newend, object, ctx);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr == newend);
+          break;
+        } else if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
+        do {
+          msg->add_tx_wavelength(::google::protobuf::internal::ReadVarint(&ptr));
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 48 && (ptr += 1));
+        break;
+      }
+      // .dmi.ValueScale wavelength_scale = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_wavelength_scale(static_cast<::dmi::ValueScale>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool TransceiverComponentsAttributes::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.TransceiverComponentsAttributes)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_form_factor(static_cast< ::dmi::TransceiverComponentsAttributes_FormFactor >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_trans_type(static_cast< ::dmi::TransceiverComponentsAttributes_Type >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // uint32 max_distance = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (24 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, &max_distance_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ValueScale max_distance_scale = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_max_distance_scale(static_cast< ::dmi::ValueScale >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated uint32 rx_wavelength = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, this->mutable_rx_wavelength())));
+        } else if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 1, 42u, input, this->mutable_rx_wavelength())));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated uint32 tx_wavelength = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, this->mutable_tx_wavelength())));
+        } else if (static_cast< ::google::protobuf::uint8>(tag) == (48 & 0xFF)) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 1, 50u, input, this->mutable_tx_wavelength())));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ValueScale wavelength_scale = 7;
+      case 7: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (56 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_wavelength_scale(static_cast< ::dmi::ValueScale >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.TransceiverComponentsAttributes)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.TransceiverComponentsAttributes)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void TransceiverComponentsAttributes::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.TransceiverComponentsAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+  if (this->form_factor() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->form_factor(), output);
+  }
+
+  // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+  if (this->trans_type() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->trans_type(), output);
+  }
+
+  // uint32 max_distance = 3;
+  if (this->max_distance() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->max_distance(), output);
+  }
+
+  // .dmi.ValueScale max_distance_scale = 4;
+  if (this->max_distance_scale() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      4, this->max_distance_scale(), output);
+  }
+
+  // repeated uint32 rx_wavelength = 5;
+  if (this->rx_wavelength_size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteTag(5, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+    output->WriteVarint32(_rx_wavelength_cached_byte_size_.load(
+        std::memory_order_relaxed));
+  }
+  for (int i = 0, n = this->rx_wavelength_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
+      this->rx_wavelength(i), output);
+  }
+
+  // repeated uint32 tx_wavelength = 6;
+  if (this->tx_wavelength_size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteTag(6, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+    output->WriteVarint32(_tx_wavelength_cached_byte_size_.load(
+        std::memory_order_relaxed));
+  }
+  for (int i = 0, n = this->tx_wavelength_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32NoTag(
+      this->tx_wavelength(i), output);
+  }
+
+  // .dmi.ValueScale wavelength_scale = 7;
+  if (this->wavelength_scale() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      7, this->wavelength_scale(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.TransceiverComponentsAttributes)
+}
+
+::google::protobuf::uint8* TransceiverComponentsAttributes::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.TransceiverComponentsAttributes)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+  if (this->form_factor() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->form_factor(), target);
+  }
+
+  // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+  if (this->trans_type() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->trans_type(), target);
+  }
+
+  // uint32 max_distance = 3;
+  if (this->max_distance() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->max_distance(), target);
+  }
+
+  // .dmi.ValueScale max_distance_scale = 4;
+  if (this->max_distance_scale() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      4, this->max_distance_scale(), target);
+  }
+
+  // repeated uint32 rx_wavelength = 5;
+  if (this->rx_wavelength_size() > 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+      5,
+      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+      target);
+    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+        _rx_wavelength_cached_byte_size_.load(std::memory_order_relaxed),
+         target);
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteUInt32NoTagToArray(this->rx_wavelength_, target);
+  }
+
+  // repeated uint32 tx_wavelength = 6;
+  if (this->tx_wavelength_size() > 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+      6,
+      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+      target);
+    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+        _tx_wavelength_cached_byte_size_.load(std::memory_order_relaxed),
+         target);
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteUInt32NoTagToArray(this->tx_wavelength_, target);
+  }
+
+  // .dmi.ValueScale wavelength_scale = 7;
+  if (this->wavelength_scale() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      7, this->wavelength_scale(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.TransceiverComponentsAttributes)
+  return target;
+}
+
+size_t TransceiverComponentsAttributes::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.TransceiverComponentsAttributes)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated uint32 rx_wavelength = 5;
+  {
+    size_t data_size = ::google::protobuf::internal::WireFormatLite::
+      UInt32Size(this->rx_wavelength_);
+    if (data_size > 0) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+            static_cast<::google::protobuf::int32>(data_size));
+    }
+    int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
+    _rx_wavelength_cached_byte_size_.store(cached_size,
+                                    std::memory_order_relaxed);
+    total_size += data_size;
+  }
+
+  // repeated uint32 tx_wavelength = 6;
+  {
+    size_t data_size = ::google::protobuf::internal::WireFormatLite::
+      UInt32Size(this->tx_wavelength_);
+    if (data_size > 0) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+            static_cast<::google::protobuf::int32>(data_size));
+    }
+    int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);
+    _tx_wavelength_cached_byte_size_.store(cached_size,
+                                    std::memory_order_relaxed);
+    total_size += data_size;
+  }
+
+  // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
+  if (this->form_factor() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->form_factor());
+  }
+
+  // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
+  if (this->trans_type() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->trans_type());
+  }
+
+  // uint32 max_distance = 3;
+  if (this->max_distance() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::UInt32Size(
+        this->max_distance());
+  }
+
+  // .dmi.ValueScale max_distance_scale = 4;
+  if (this->max_distance_scale() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->max_distance_scale());
+  }
+
+  // .dmi.ValueScale wavelength_scale = 7;
+  if (this->wavelength_scale() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->wavelength_scale());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void TransceiverComponentsAttributes::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.TransceiverComponentsAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  const TransceiverComponentsAttributes* source =
+      ::google::protobuf::DynamicCastToGenerated<TransceiverComponentsAttributes>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.TransceiverComponentsAttributes)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.TransceiverComponentsAttributes)
+    MergeFrom(*source);
+  }
+}
+
+void TransceiverComponentsAttributes::MergeFrom(const TransceiverComponentsAttributes& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.TransceiverComponentsAttributes)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  rx_wavelength_.MergeFrom(from.rx_wavelength_);
+  tx_wavelength_.MergeFrom(from.tx_wavelength_);
+  if (from.form_factor() != 0) {
+    set_form_factor(from.form_factor());
+  }
+  if (from.trans_type() != 0) {
+    set_trans_type(from.trans_type());
+  }
+  if (from.max_distance() != 0) {
+    set_max_distance(from.max_distance());
+  }
+  if (from.max_distance_scale() != 0) {
+    set_max_distance_scale(from.max_distance_scale());
+  }
+  if (from.wavelength_scale() != 0) {
+    set_wavelength_scale(from.wavelength_scale());
+  }
+}
+
+void TransceiverComponentsAttributes::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.TransceiverComponentsAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void TransceiverComponentsAttributes::CopyFrom(const TransceiverComponentsAttributes& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.TransceiverComponentsAttributes)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool TransceiverComponentsAttributes::IsInitialized() const {
+  return true;
+}
+
+void TransceiverComponentsAttributes::Swap(TransceiverComponentsAttributes* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void TransceiverComponentsAttributes::InternalSwap(TransceiverComponentsAttributes* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  rx_wavelength_.InternalSwap(&other->rx_wavelength_);
+  tx_wavelength_.InternalSwap(&other->tx_wavelength_);
+  swap(form_factor_, other->form_factor_);
+  swap(trans_type_, other->trans_type_);
+  swap(max_distance_, other->max_distance_);
+  swap(max_distance_scale_, other->max_distance_scale_);
+  swap(wavelength_scale_, other->wavelength_scale_);
+}
+
+::google::protobuf::Metadata TransceiverComponentsAttributes::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void Component::InitAsDefaultInstance() {
+  ::dmi::_Component_default_instance_._instance.get_mutable()->mfg_date_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+  ::dmi::_Component_default_instance_._instance.get_mutable()->uri_ = const_cast< ::dmi::Uri*>(
+      ::dmi::Uri::internal_default_instance());
+  ::dmi::_Component_default_instance_._instance.get_mutable()->uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_Component_default_instance_._instance.get_mutable()->state_ = const_cast< ::dmi::ComponentState*>(
+      ::dmi::ComponentState::internal_default_instance());
+  ::dmi::_Component_default_instance_.port_attr_ = const_cast< ::dmi::PortComponentAttributes*>(
+      ::dmi::PortComponentAttributes::internal_default_instance());
+  ::dmi::_Component_default_instance_.container_attr_ = const_cast< ::dmi::ContainerComponentAttributes*>(
+      ::dmi::ContainerComponentAttributes::internal_default_instance());
+  ::dmi::_Component_default_instance_.psu_attr_ = const_cast< ::dmi::PsuComponentAttributes*>(
+      ::dmi::PsuComponentAttributes::internal_default_instance());
+  ::dmi::_Component_default_instance_.transceiver_attr_ = const_cast< ::dmi::TransceiverComponentsAttributes*>(
+      ::dmi::TransceiverComponentsAttributes::internal_default_instance());
+}
+class Component::HasBitSetters {
+ public:
+  static const ::google::protobuf::Timestamp& mfg_date(const Component* msg);
+  static const ::dmi::Uri& uri(const Component* msg);
+  static const ::dmi::Uuid& uuid(const Component* msg);
+  static const ::dmi::ComponentState& state(const Component* msg);
+  static const ::dmi::PortComponentAttributes& port_attr(const Component* msg);
+  static const ::dmi::ContainerComponentAttributes& container_attr(const Component* msg);
+  static const ::dmi::PsuComponentAttributes& psu_attr(const Component* msg);
+  static const ::dmi::TransceiverComponentsAttributes& transceiver_attr(const Component* msg);
+};
+
+const ::google::protobuf::Timestamp&
+Component::HasBitSetters::mfg_date(const Component* msg) {
+  return *msg->mfg_date_;
+}
+const ::dmi::Uri&
+Component::HasBitSetters::uri(const Component* msg) {
+  return *msg->uri_;
+}
+const ::dmi::Uuid&
+Component::HasBitSetters::uuid(const Component* msg) {
+  return *msg->uuid_;
+}
+const ::dmi::ComponentState&
+Component::HasBitSetters::state(const Component* msg) {
+  return *msg->state_;
+}
+const ::dmi::PortComponentAttributes&
+Component::HasBitSetters::port_attr(const Component* msg) {
+  return *msg->specific_.port_attr_;
+}
+const ::dmi::ContainerComponentAttributes&
+Component::HasBitSetters::container_attr(const Component* msg) {
+  return *msg->specific_.container_attr_;
+}
+const ::dmi::PsuComponentAttributes&
+Component::HasBitSetters::psu_attr(const Component* msg) {
+  return *msg->specific_.psu_attr_;
+}
+const ::dmi::TransceiverComponentsAttributes&
+Component::HasBitSetters::transceiver_attr(const Component* msg) {
+  return *msg->specific_.transceiver_attr_;
+}
+void Component::clear_mfg_date() {
+  if (GetArenaNoVirtual() == nullptr && mfg_date_ != nullptr) {
+    delete mfg_date_;
+  }
+  mfg_date_ = nullptr;
+}
+void Component::set_allocated_port_attr(::dmi::PortComponentAttributes* port_attr) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_specific();
+  if (port_attr) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      port_attr = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, port_attr, submessage_arena);
+    }
+    set_has_port_attr();
+    specific_.port_attr_ = port_attr;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.port_attr)
+}
+void Component::set_allocated_container_attr(::dmi::ContainerComponentAttributes* container_attr) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_specific();
+  if (container_attr) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      container_attr = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, container_attr, submessage_arena);
+    }
+    set_has_container_attr();
+    specific_.container_attr_ = container_attr;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.container_attr)
+}
+void Component::set_allocated_psu_attr(::dmi::PsuComponentAttributes* psu_attr) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_specific();
+  if (psu_attr) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      psu_attr = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, psu_attr, submessage_arena);
+    }
+    set_has_psu_attr();
+    specific_.psu_attr_ = psu_attr;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.psu_attr)
+}
+void Component::set_allocated_transceiver_attr(::dmi::TransceiverComponentsAttributes* transceiver_attr) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_specific();
+  if (transceiver_attr) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      transceiver_attr = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, transceiver_attr, submessage_arena);
+    }
+    set_has_transceiver_attr();
+    specific_.transceiver_attr_ = transceiver_attr;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.Component.transceiver_attr)
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Component::kNameFieldNumber;
+const int Component::kClassFieldNumber;
+const int Component::kDescriptionFieldNumber;
+const int Component::kParentFieldNumber;
+const int Component::kParentRelPosFieldNumber;
+const int Component::kChildrenFieldNumber;
+const int Component::kHardwareRevFieldNumber;
+const int Component::kFirmwareRevFieldNumber;
+const int Component::kSoftwareRevFieldNumber;
+const int Component::kSerialNumFieldNumber;
+const int Component::kMfgNameFieldNumber;
+const int Component::kModelNameFieldNumber;
+const int Component::kAliasFieldNumber;
+const int Component::kAssetIdFieldNumber;
+const int Component::kIsFruFieldNumber;
+const int Component::kMfgDateFieldNumber;
+const int Component::kUriFieldNumber;
+const int Component::kUuidFieldNumber;
+const int Component::kStateFieldNumber;
+const int Component::kSensorDataFieldNumber;
+const int Component::kPortAttrFieldNumber;
+const int Component::kContainerAttrFieldNumber;
+const int Component::kPsuAttrFieldNumber;
+const int Component::kTransceiverAttrFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Component::Component()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Component)
+}
+Component::Component(const Component& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr),
+      children_(from.children_),
+      sensor_data_(from.sensor_data_) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.name().size() > 0) {
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  description_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.description().size() > 0) {
+    description_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.description_);
+  }
+  parent_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.parent().size() > 0) {
+    parent_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parent_);
+  }
+  hardware_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.hardware_rev().size() > 0) {
+    hardware_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.hardware_rev_);
+  }
+  firmware_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.firmware_rev().size() > 0) {
+    firmware_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.firmware_rev_);
+  }
+  software_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.software_rev().size() > 0) {
+    software_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.software_rev_);
+  }
+  serial_num_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.serial_num().size() > 0) {
+    serial_num_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.serial_num_);
+  }
+  mfg_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.mfg_name().size() > 0) {
+    mfg_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.mfg_name_);
+  }
+  model_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.model_name().size() > 0) {
+    model_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.model_name_);
+  }
+  alias_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.alias().size() > 0) {
+    alias_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.alias_);
+  }
+  asset_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.asset_id().size() > 0) {
+    asset_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.asset_id_);
+  }
+  if (from.has_mfg_date()) {
+    mfg_date_ = new ::google::protobuf::Timestamp(*from.mfg_date_);
+  } else {
+    mfg_date_ = nullptr;
+  }
+  if (from.has_uri()) {
+    uri_ = new ::dmi::Uri(*from.uri_);
+  } else {
+    uri_ = nullptr;
+  }
+  if (from.has_uuid()) {
+    uuid_ = new ::dmi::Uuid(*from.uuid_);
+  } else {
+    uuid_ = nullptr;
+  }
+  if (from.has_state()) {
+    state_ = new ::dmi::ComponentState(*from.state_);
+  } else {
+    state_ = nullptr;
+  }
+  ::memcpy(&class__, &from.class__,
+    static_cast<size_t>(reinterpret_cast<char*>(&is_fru_) -
+    reinterpret_cast<char*>(&class__)) + sizeof(is_fru_));
+  clear_has_specific();
+  switch (from.specific_case()) {
+    case kPortAttr: {
+      mutable_port_attr()->::dmi::PortComponentAttributes::MergeFrom(from.port_attr());
+      break;
+    }
+    case kContainerAttr: {
+      mutable_container_attr()->::dmi::ContainerComponentAttributes::MergeFrom(from.container_attr());
+      break;
+    }
+    case kPsuAttr: {
+      mutable_psu_attr()->::dmi::PsuComponentAttributes::MergeFrom(from.psu_attr());
+      break;
+    }
+    case kTransceiverAttr: {
+      mutable_transceiver_attr()->::dmi::TransceiverComponentsAttributes::MergeFrom(from.transceiver_attr());
+      break;
+    }
+    case SPECIFIC_NOT_SET: {
+      break;
+    }
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.Component)
+}
+
+void Component::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Component_dmi_2fhw_2eproto.base);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  description_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  parent_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  hardware_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  firmware_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  software_rev_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  serial_num_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  mfg_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  model_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&mfg_date_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&is_fru_) -
+      reinterpret_cast<char*>(&mfg_date_)) + sizeof(is_fru_));
+  clear_has_specific();
+}
+
+Component::~Component() {
+  // @@protoc_insertion_point(destructor:dmi.Component)
+  SharedDtor();
+}
+
+void Component::SharedDtor() {
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  description_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  parent_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  hardware_rev_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  firmware_rev_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  software_rev_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  serial_num_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  mfg_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  model_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete mfg_date_;
+  if (this != internal_default_instance()) delete uri_;
+  if (this != internal_default_instance()) delete uuid_;
+  if (this != internal_default_instance()) delete state_;
+  if (has_specific()) {
+    clear_specific();
+  }
+}
+
+void Component::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Component& Component::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Component_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Component::clear_specific() {
+// @@protoc_insertion_point(one_of_clear_start:dmi.Component)
+  switch (specific_case()) {
+    case kPortAttr: {
+      delete specific_.port_attr_;
+      break;
+    }
+    case kContainerAttr: {
+      delete specific_.container_attr_;
+      break;
+    }
+    case kPsuAttr: {
+      delete specific_.psu_attr_;
+      break;
+    }
+    case kTransceiverAttr: {
+      delete specific_.transceiver_attr_;
+      break;
+    }
+    case SPECIFIC_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = SPECIFIC_NOT_SET;
+}
+
+
+void Component::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Component)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  children_.Clear();
+  sensor_data_.Clear();
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  description_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  parent_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  hardware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  firmware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  software_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  serial_num_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  mfg_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  model_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && mfg_date_ != nullptr) {
+    delete mfg_date_;
+  }
+  mfg_date_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
+    delete uri_;
+  }
+  uri_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
+    delete uuid_;
+  }
+  uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && state_ != nullptr) {
+    delete state_;
+  }
+  state_ = nullptr;
+  ::memset(&class__, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&is_fru_) -
+      reinterpret_cast<char*>(&class__)) + sizeof(is_fru_));
+  clear_specific();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Component::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Component*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.name");
+        object = msg->mutable_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // .dmi.ComponentType class = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_class_(static_cast<::dmi::ComponentType>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string description = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.description");
+        object = msg->mutable_description();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string parent = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.parent");
+        object = msg->mutable_parent();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // int32 parent_rel_pos = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
+        msg->set_parent_rel_pos(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // repeated .dmi.Component children = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::Component::_InternalParse;
+          object = msg->add_children();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
+        break;
+      }
+      // string hardware_rev = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.hardware_rev");
+        object = msg->mutable_hardware_rev();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string firmware_rev = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 66) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.firmware_rev");
+        object = msg->mutable_firmware_rev();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string software_rev = 9;
+      case 9: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 74) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.software_rev");
+        object = msg->mutable_software_rev();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string serial_num = 10;
+      case 10: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 82) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.serial_num");
+        object = msg->mutable_serial_num();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string mfg_name = 11;
+      case 11: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 90) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.mfg_name");
+        object = msg->mutable_mfg_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string model_name = 12;
+      case 12: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 98) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.model_name");
+        object = msg->mutable_model_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string alias = 13;
+      case 13: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 106) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.alias");
+        object = msg->mutable_alias();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string asset_id = 14;
+      case 14: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 114) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.Component.asset_id");
+        object = msg->mutable_asset_id();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // bool is_fru = 15;
+      case 15: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 120) goto handle_unusual;
+        msg->set_is_fru(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .google.protobuf.Timestamp mfg_date = 16;
+      case 16: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 130) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_mfg_date();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uri uri = 17;
+      case 17: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 138) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uri::_InternalParse;
+        object = msg->mutable_uri();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid uuid = 18;
+      case 18: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 146) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ComponentState state = 19;
+      case 19: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 154) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ComponentState::_InternalParse;
+        object = msg->mutable_state();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // repeated .dmi.ComponentSensorData sensor_data = 20;
+      case 20: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 162) goto handle_unusual;
+        do {
+          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+          parser_till_end = ::dmi::ComponentSensorData::_InternalParse;
+          object = msg->add_sensor_data();
+          if (size > end - ptr) goto len_delim_till_end;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
+          if (ptr >= end) break;
+        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 65535) == 418 && (ptr += 2));
+        break;
+      }
+      // .dmi.PortComponentAttributes port_attr = 50;
+      case 50: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 146) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::PortComponentAttributes::_InternalParse;
+        object = msg->mutable_port_attr();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ContainerComponentAttributes container_attr = 51;
+      case 51: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 154) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::ContainerComponentAttributes::_InternalParse;
+        object = msg->mutable_container_attr();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.PsuComponentAttributes psu_attr = 52;
+      case 52: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 162) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::PsuComponentAttributes::_InternalParse;
+        object = msg->mutable_psu_attr();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+      case 53: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 170) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::TransceiverComponentsAttributes::_InternalParse;
+        object = msg->mutable_transceiver_attr();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Component::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Component)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(16383u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string name = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->name().data(), static_cast<int>(this->name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentType class = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_class_(static_cast< ::dmi::ComponentType >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string description = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_description()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->description().data(), static_cast<int>(this->description().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.description"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string parent = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_parent()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->parent().data(), static_cast<int>(this->parent().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.parent"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // int32 parent_rel_pos = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (40 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &parent_rel_pos_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated .dmi.Component children = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_children()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string hardware_rev = 7;
+      case 7: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_hardware_rev()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->hardware_rev().data(), static_cast<int>(this->hardware_rev().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.hardware_rev"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string firmware_rev = 8;
+      case 8: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (66 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_firmware_rev()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->firmware_rev().data(), static_cast<int>(this->firmware_rev().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.firmware_rev"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string software_rev = 9;
+      case 9: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (74 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_software_rev()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->software_rev().data(), static_cast<int>(this->software_rev().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.software_rev"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string serial_num = 10;
+      case 10: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (82 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_serial_num()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->serial_num().data(), static_cast<int>(this->serial_num().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.serial_num"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string mfg_name = 11;
+      case 11: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (90 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_mfg_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->mfg_name().data(), static_cast<int>(this->mfg_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.mfg_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string model_name = 12;
+      case 12: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (98 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_model_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->model_name().data(), static_cast<int>(this->model_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.model_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string alias = 13;
+      case 13: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (106 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_alias()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->alias().data(), static_cast<int>(this->alias().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.alias"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string asset_id = 14;
+      case 14: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (114 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_asset_id()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.Component.asset_id"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // bool is_fru = 15;
+      case 15: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (120 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &is_fru_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .google.protobuf.Timestamp mfg_date = 16;
+      case 16: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (130 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_mfg_date()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uri uri = 17;
+      case 17: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (138 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_uri()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid uuid = 18;
+      case 18: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (146 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentState state = 19;
+      case 19: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (154 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_state()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // repeated .dmi.ComponentSensorData sensor_data = 20;
+      case 20: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (162 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+                input, add_sensor_data()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.PortComponentAttributes port_attr = 50;
+      case 50: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (402 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_port_attr()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ContainerComponentAttributes container_attr = 51;
+      case 51: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (410 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_container_attr()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.PsuComponentAttributes psu_attr = 52;
+      case 52: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (418 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_psu_attr()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+      case 53: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (426 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_transceiver_attr()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Component)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Component)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Component::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Component)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->class_(), output);
+  }
+
+  // string description = 3;
+  if (this->description().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->description().data(), static_cast<int>(this->description().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.description");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->description(), output);
+  }
+
+  // string parent = 4;
+  if (this->parent().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->parent().data(), static_cast<int>(this->parent().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.parent");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->parent(), output);
+  }
+
+  // int32 parent_rel_pos = 5;
+  if (this->parent_rel_pos() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->parent_rel_pos(), output);
+  }
+
+  // repeated .dmi.Component children = 6;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->children_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      6,
+      this->children(static_cast<int>(i)),
+      output);
+  }
+
+  // string hardware_rev = 7;
+  if (this->hardware_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->hardware_rev().data(), static_cast<int>(this->hardware_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.hardware_rev");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      7, this->hardware_rev(), output);
+  }
+
+  // string firmware_rev = 8;
+  if (this->firmware_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->firmware_rev().data(), static_cast<int>(this->firmware_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.firmware_rev");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      8, this->firmware_rev(), output);
+  }
+
+  // string software_rev = 9;
+  if (this->software_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->software_rev().data(), static_cast<int>(this->software_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.software_rev");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      9, this->software_rev(), output);
+  }
+
+  // string serial_num = 10;
+  if (this->serial_num().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->serial_num().data(), static_cast<int>(this->serial_num().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.serial_num");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      10, this->serial_num(), output);
+  }
+
+  // string mfg_name = 11;
+  if (this->mfg_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->mfg_name().data(), static_cast<int>(this->mfg_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.mfg_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      11, this->mfg_name(), output);
+  }
+
+  // string model_name = 12;
+  if (this->model_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->model_name().data(), static_cast<int>(this->model_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.model_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      12, this->model_name(), output);
+  }
+
+  // string alias = 13;
+  if (this->alias().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->alias().data(), static_cast<int>(this->alias().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.alias");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      13, this->alias(), output);
+  }
+
+  // string asset_id = 14;
+  if (this->asset_id().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.asset_id");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      14, this->asset_id(), output);
+  }
+
+  // bool is_fru = 15;
+  if (this->is_fru() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(15, this->is_fru(), output);
+  }
+
+  // .google.protobuf.Timestamp mfg_date = 16;
+  if (this->has_mfg_date()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      16, HasBitSetters::mfg_date(this), output);
+  }
+
+  // .dmi.Uri uri = 17;
+  if (this->has_uri()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      17, HasBitSetters::uri(this), output);
+  }
+
+  // .dmi.Uuid uuid = 18;
+  if (this->has_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      18, HasBitSetters::uuid(this), output);
+  }
+
+  // .dmi.ComponentState state = 19;
+  if (this->has_state()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      19, HasBitSetters::state(this), output);
+  }
+
+  // repeated .dmi.ComponentSensorData sensor_data = 20;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->sensor_data_size()); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      20,
+      this->sensor_data(static_cast<int>(i)),
+      output);
+  }
+
+  // .dmi.PortComponentAttributes port_attr = 50;
+  if (has_port_attr()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      50, HasBitSetters::port_attr(this), output);
+  }
+
+  // .dmi.ContainerComponentAttributes container_attr = 51;
+  if (has_container_attr()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      51, HasBitSetters::container_attr(this), output);
+  }
+
+  // .dmi.PsuComponentAttributes psu_attr = 52;
+  if (has_psu_attr()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      52, HasBitSetters::psu_attr(this), output);
+  }
+
+  // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+  if (has_transceiver_attr()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      53, HasBitSetters::transceiver_attr(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Component)
+}
+
+::google::protobuf::uint8* Component::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Component)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->class_(), target);
+  }
+
+  // string description = 3;
+  if (this->description().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->description().data(), static_cast<int>(this->description().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.description");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->description(), target);
+  }
+
+  // string parent = 4;
+  if (this->parent().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->parent().data(), static_cast<int>(this->parent().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.parent");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->parent(), target);
+  }
+
+  // int32 parent_rel_pos = 5;
+  if (this->parent_rel_pos() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(5, this->parent_rel_pos(), target);
+  }
+
+  // repeated .dmi.Component children = 6;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->children_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        6, this->children(static_cast<int>(i)), target);
+  }
+
+  // string hardware_rev = 7;
+  if (this->hardware_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->hardware_rev().data(), static_cast<int>(this->hardware_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.hardware_rev");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        7, this->hardware_rev(), target);
+  }
+
+  // string firmware_rev = 8;
+  if (this->firmware_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->firmware_rev().data(), static_cast<int>(this->firmware_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.firmware_rev");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        8, this->firmware_rev(), target);
+  }
+
+  // string software_rev = 9;
+  if (this->software_rev().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->software_rev().data(), static_cast<int>(this->software_rev().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.software_rev");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        9, this->software_rev(), target);
+  }
+
+  // string serial_num = 10;
+  if (this->serial_num().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->serial_num().data(), static_cast<int>(this->serial_num().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.serial_num");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        10, this->serial_num(), target);
+  }
+
+  // string mfg_name = 11;
+  if (this->mfg_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->mfg_name().data(), static_cast<int>(this->mfg_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.mfg_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        11, this->mfg_name(), target);
+  }
+
+  // string model_name = 12;
+  if (this->model_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->model_name().data(), static_cast<int>(this->model_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.model_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        12, this->model_name(), target);
+  }
+
+  // string alias = 13;
+  if (this->alias().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->alias().data(), static_cast<int>(this->alias().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.alias");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        13, this->alias(), target);
+  }
+
+  // string asset_id = 14;
+  if (this->asset_id().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.Component.asset_id");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        14, this->asset_id(), target);
+  }
+
+  // bool is_fru = 15;
+  if (this->is_fru() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(15, this->is_fru(), target);
+  }
+
+  // .google.protobuf.Timestamp mfg_date = 16;
+  if (this->has_mfg_date()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        16, HasBitSetters::mfg_date(this), target);
+  }
+
+  // .dmi.Uri uri = 17;
+  if (this->has_uri()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        17, HasBitSetters::uri(this), target);
+  }
+
+  // .dmi.Uuid uuid = 18;
+  if (this->has_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        18, HasBitSetters::uuid(this), target);
+  }
+
+  // .dmi.ComponentState state = 19;
+  if (this->has_state()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        19, HasBitSetters::state(this), target);
+  }
+
+  // repeated .dmi.ComponentSensorData sensor_data = 20;
+  for (unsigned int i = 0,
+      n = static_cast<unsigned int>(this->sensor_data_size()); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        20, this->sensor_data(static_cast<int>(i)), target);
+  }
+
+  // .dmi.PortComponentAttributes port_attr = 50;
+  if (has_port_attr()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        50, HasBitSetters::port_attr(this), target);
+  }
+
+  // .dmi.ContainerComponentAttributes container_attr = 51;
+  if (has_container_attr()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        51, HasBitSetters::container_attr(this), target);
+  }
+
+  // .dmi.PsuComponentAttributes psu_attr = 52;
+  if (has_psu_attr()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        52, HasBitSetters::psu_attr(this), target);
+  }
+
+  // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+  if (has_transceiver_attr()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        53, HasBitSetters::transceiver_attr(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Component)
+  return target;
+}
+
+size_t Component::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Component)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // repeated .dmi.Component children = 6;
+  {
+    unsigned int count = static_cast<unsigned int>(this->children_size());
+    total_size += 1UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->children(static_cast<int>(i)));
+    }
+  }
+
+  // repeated .dmi.ComponentSensorData sensor_data = 20;
+  {
+    unsigned int count = static_cast<unsigned int>(this->sensor_data_size());
+    total_size += 2UL * count;
+    for (unsigned int i = 0; i < count; i++) {
+      total_size +=
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          this->sensor_data(static_cast<int>(i)));
+    }
+  }
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->name());
+  }
+
+  // string description = 3;
+  if (this->description().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->description());
+  }
+
+  // string parent = 4;
+  if (this->parent().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->parent());
+  }
+
+  // string hardware_rev = 7;
+  if (this->hardware_rev().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->hardware_rev());
+  }
+
+  // string firmware_rev = 8;
+  if (this->firmware_rev().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->firmware_rev());
+  }
+
+  // string software_rev = 9;
+  if (this->software_rev().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->software_rev());
+  }
+
+  // string serial_num = 10;
+  if (this->serial_num().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->serial_num());
+  }
+
+  // string mfg_name = 11;
+  if (this->mfg_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->mfg_name());
+  }
+
+  // string model_name = 12;
+  if (this->model_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->model_name());
+  }
+
+  // string alias = 13;
+  if (this->alias().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->alias());
+  }
+
+  // string asset_id = 14;
+  if (this->asset_id().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->asset_id());
+  }
+
+  // .google.protobuf.Timestamp mfg_date = 16;
+  if (this->has_mfg_date()) {
+    total_size += 2 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *mfg_date_);
+  }
+
+  // .dmi.Uri uri = 17;
+  if (this->has_uri()) {
+    total_size += 2 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *uri_);
+  }
+
+  // .dmi.Uuid uuid = 18;
+  if (this->has_uuid()) {
+    total_size += 2 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *uuid_);
+  }
+
+  // .dmi.ComponentState state = 19;
+  if (this->has_state()) {
+    total_size += 2 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *state_);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->class_());
+  }
+
+  // int32 parent_rel_pos = 5;
+  if (this->parent_rel_pos() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->parent_rel_pos());
+  }
+
+  // bool is_fru = 15;
+  if (this->is_fru() != 0) {
+    total_size += 1 + 1;
+  }
+
+  switch (specific_case()) {
+    // .dmi.PortComponentAttributes port_attr = 50;
+    case kPortAttr: {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *specific_.port_attr_);
+      break;
+    }
+    // .dmi.ContainerComponentAttributes container_attr = 51;
+    case kContainerAttr: {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *specific_.container_attr_);
+      break;
+    }
+    // .dmi.PsuComponentAttributes psu_attr = 52;
+    case kPsuAttr: {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *specific_.psu_attr_);
+      break;
+    }
+    // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
+    case kTransceiverAttr: {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *specific_.transceiver_attr_);
+      break;
+    }
+    case SPECIFIC_NOT_SET: {
+      break;
+    }
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Component::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Component)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Component* source =
+      ::google::protobuf::DynamicCastToGenerated<Component>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Component)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Component)
+    MergeFrom(*source);
+  }
+}
+
+void Component::MergeFrom(const Component& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Component)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  children_.MergeFrom(from.children_);
+  sensor_data_.MergeFrom(from.sensor_data_);
+  if (from.name().size() > 0) {
+
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  if (from.description().size() > 0) {
+
+    description_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.description_);
+  }
+  if (from.parent().size() > 0) {
+
+    parent_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parent_);
+  }
+  if (from.hardware_rev().size() > 0) {
+
+    hardware_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.hardware_rev_);
+  }
+  if (from.firmware_rev().size() > 0) {
+
+    firmware_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.firmware_rev_);
+  }
+  if (from.software_rev().size() > 0) {
+
+    software_rev_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.software_rev_);
+  }
+  if (from.serial_num().size() > 0) {
+
+    serial_num_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.serial_num_);
+  }
+  if (from.mfg_name().size() > 0) {
+
+    mfg_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.mfg_name_);
+  }
+  if (from.model_name().size() > 0) {
+
+    model_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.model_name_);
+  }
+  if (from.alias().size() > 0) {
+
+    alias_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.alias_);
+  }
+  if (from.asset_id().size() > 0) {
+
+    asset_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.asset_id_);
+  }
+  if (from.has_mfg_date()) {
+    mutable_mfg_date()->::google::protobuf::Timestamp::MergeFrom(from.mfg_date());
+  }
+  if (from.has_uri()) {
+    mutable_uri()->::dmi::Uri::MergeFrom(from.uri());
+  }
+  if (from.has_uuid()) {
+    mutable_uuid()->::dmi::Uuid::MergeFrom(from.uuid());
+  }
+  if (from.has_state()) {
+    mutable_state()->::dmi::ComponentState::MergeFrom(from.state());
+  }
+  if (from.class_() != 0) {
+    set_class_(from.class_());
+  }
+  if (from.parent_rel_pos() != 0) {
+    set_parent_rel_pos(from.parent_rel_pos());
+  }
+  if (from.is_fru() != 0) {
+    set_is_fru(from.is_fru());
+  }
+  switch (from.specific_case()) {
+    case kPortAttr: {
+      mutable_port_attr()->::dmi::PortComponentAttributes::MergeFrom(from.port_attr());
+      break;
+    }
+    case kContainerAttr: {
+      mutable_container_attr()->::dmi::ContainerComponentAttributes::MergeFrom(from.container_attr());
+      break;
+    }
+    case kPsuAttr: {
+      mutable_psu_attr()->::dmi::PsuComponentAttributes::MergeFrom(from.psu_attr());
+      break;
+    }
+    case kTransceiverAttr: {
+      mutable_transceiver_attr()->::dmi::TransceiverComponentsAttributes::MergeFrom(from.transceiver_attr());
+      break;
+    }
+    case SPECIFIC_NOT_SET: {
+      break;
+    }
+  }
+}
+
+void Component::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Component)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Component::CopyFrom(const Component& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Component)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Component::IsInitialized() const {
+  return true;
+}
+
+void Component::Swap(Component* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Component::InternalSwap(Component* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  CastToBase(&children_)->InternalSwap(CastToBase(&other->children_));
+  CastToBase(&sensor_data_)->InternalSwap(CastToBase(&other->sensor_data_));
+  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  description_.Swap(&other->description_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  parent_.Swap(&other->parent_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  hardware_rev_.Swap(&other->hardware_rev_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  firmware_rev_.Swap(&other->firmware_rev_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  software_rev_.Swap(&other->software_rev_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  serial_num_.Swap(&other->serial_num_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  mfg_name_.Swap(&other->mfg_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  model_name_.Swap(&other->model_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  alias_.Swap(&other->alias_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  asset_id_.Swap(&other->asset_id_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(mfg_date_, other->mfg_date_);
+  swap(uri_, other->uri_);
+  swap(uuid_, other->uuid_);
+  swap(state_, other->state_);
+  swap(class__, other->class__);
+  swap(parent_rel_pos_, other->parent_rel_pos_);
+  swap(is_fru_, other->is_fru_);
+  swap(specific_, other->specific_);
+  swap(_oneof_case_[0], other->_oneof_case_[0]);
+}
+
+::google::protobuf::Metadata Component::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void Hardware::InitAsDefaultInstance() {
+  ::dmi::_Hardware_default_instance_._instance.get_mutable()->last_change_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+  ::dmi::_Hardware_default_instance_._instance.get_mutable()->root_ = const_cast< ::dmi::Component*>(
+      ::dmi::Component::internal_default_instance());
+  ::dmi::_Hardware_default_instance_._instance.get_mutable()->last_booted_ = const_cast< ::google::protobuf::Timestamp*>(
+      ::google::protobuf::Timestamp::internal_default_instance());
+}
+class Hardware::HasBitSetters {
+ public:
+  static const ::google::protobuf::Timestamp& last_change(const Hardware* msg);
+  static const ::dmi::Component& root(const Hardware* msg);
+  static const ::google::protobuf::Timestamp& last_booted(const Hardware* msg);
+};
+
+const ::google::protobuf::Timestamp&
+Hardware::HasBitSetters::last_change(const Hardware* msg) {
+  return *msg->last_change_;
+}
+const ::dmi::Component&
+Hardware::HasBitSetters::root(const Hardware* msg) {
+  return *msg->root_;
+}
+const ::google::protobuf::Timestamp&
+Hardware::HasBitSetters::last_booted(const Hardware* msg) {
+  return *msg->last_booted_;
+}
+void Hardware::clear_last_change() {
+  if (GetArenaNoVirtual() == nullptr && last_change_ != nullptr) {
+    delete last_change_;
+  }
+  last_change_ = nullptr;
+}
+void Hardware::clear_last_booted() {
+  if (GetArenaNoVirtual() == nullptr && last_booted_ != nullptr) {
+    delete last_booted_;
+  }
+  last_booted_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Hardware::kLastChangeFieldNumber;
+const int Hardware::kRootFieldNumber;
+const int Hardware::kLastBootedFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Hardware::Hardware()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.Hardware)
+}
+Hardware::Hardware(const Hardware& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from.has_last_change()) {
+    last_change_ = new ::google::protobuf::Timestamp(*from.last_change_);
+  } else {
+    last_change_ = nullptr;
+  }
+  if (from.has_root()) {
+    root_ = new ::dmi::Component(*from.root_);
+  } else {
+    root_ = nullptr;
+  }
+  if (from.has_last_booted()) {
+    last_booted_ = new ::google::protobuf::Timestamp(*from.last_booted_);
+  } else {
+    last_booted_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.Hardware)
+}
+
+void Hardware::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_Hardware_dmi_2fhw_2eproto.base);
+  ::memset(&last_change_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&last_booted_) -
+      reinterpret_cast<char*>(&last_change_)) + sizeof(last_booted_));
+}
+
+Hardware::~Hardware() {
+  // @@protoc_insertion_point(destructor:dmi.Hardware)
+  SharedDtor();
+}
+
+void Hardware::SharedDtor() {
+  if (this != internal_default_instance()) delete last_change_;
+  if (this != internal_default_instance()) delete root_;
+  if (this != internal_default_instance()) delete last_booted_;
+}
+
+void Hardware::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const Hardware& Hardware::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_Hardware_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void Hardware::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.Hardware)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  if (GetArenaNoVirtual() == nullptr && last_change_ != nullptr) {
+    delete last_change_;
+  }
+  last_change_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && root_ != nullptr) {
+    delete root_;
+  }
+  root_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && last_booted_ != nullptr) {
+    delete last_booted_;
+  }
+  last_booted_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* Hardware::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<Hardware*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .google.protobuf.Timestamp last_change = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_last_change();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Component root = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Component::_InternalParse;
+        object = msg->mutable_root();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .google.protobuf.Timestamp last_booted = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::google::protobuf::Timestamp::_InternalParse;
+        object = msg->mutable_last_booted();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool Hardware::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.Hardware)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .google.protobuf.Timestamp last_change = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_last_change()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Component root = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_root()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .google.protobuf.Timestamp last_booted = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_last_booted()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.Hardware)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.Hardware)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void Hardware::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.Hardware)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp last_change = 1;
+  if (this->has_last_change()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::last_change(this), output);
+  }
+
+  // .dmi.Component root = 2;
+  if (this->has_root()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::root(this), output);
+  }
+
+  // .google.protobuf.Timestamp last_booted = 3;
+  if (this->has_last_booted()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::last_booted(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.Hardware)
+}
+
+::google::protobuf::uint8* Hardware::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.Hardware)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp last_change = 1;
+  if (this->has_last_change()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::last_change(this), target);
+  }
+
+  // .dmi.Component root = 2;
+  if (this->has_root()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::root(this), target);
+  }
+
+  // .google.protobuf.Timestamp last_booted = 3;
+  if (this->has_last_booted()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::last_booted(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.Hardware)
+  return target;
+}
+
+size_t Hardware::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.Hardware)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .google.protobuf.Timestamp last_change = 1;
+  if (this->has_last_change()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *last_change_);
+  }
+
+  // .dmi.Component root = 2;
+  if (this->has_root()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *root_);
+  }
+
+  // .google.protobuf.Timestamp last_booted = 3;
+  if (this->has_last_booted()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *last_booted_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void Hardware::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.Hardware)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Hardware* source =
+      ::google::protobuf::DynamicCastToGenerated<Hardware>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.Hardware)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.Hardware)
+    MergeFrom(*source);
+  }
+}
+
+void Hardware::MergeFrom(const Hardware& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.Hardware)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.has_last_change()) {
+    mutable_last_change()->::google::protobuf::Timestamp::MergeFrom(from.last_change());
+  }
+  if (from.has_root()) {
+    mutable_root()->::dmi::Component::MergeFrom(from.root());
+  }
+  if (from.has_last_booted()) {
+    mutable_last_booted()->::google::protobuf::Timestamp::MergeFrom(from.last_booted());
+  }
+}
+
+void Hardware::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.Hardware)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Hardware::CopyFrom(const Hardware& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.Hardware)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Hardware::IsInitialized() const {
+  return true;
+}
+
+void Hardware::Swap(Hardware* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Hardware::InternalSwap(Hardware* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(last_change_, other->last_change_);
+  swap(root_, other->root_);
+  swap(last_booted_, other->last_booted_);
+}
+
+::google::protobuf::Metadata Hardware::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ModifiableComponent::InitAsDefaultInstance() {
+  ::dmi::_ModifiableComponent_default_instance_._instance.get_mutable()->parent_ = const_cast< ::dmi::Component*>(
+      ::dmi::Component::internal_default_instance());
+  ::dmi::_ModifiableComponent_default_instance_._instance.get_mutable()->uri_ = const_cast< ::dmi::Uri*>(
+      ::dmi::Uri::internal_default_instance());
+}
+class ModifiableComponent::HasBitSetters {
+ public:
+  static const ::dmi::Component& parent(const ModifiableComponent* msg);
+  static const ::dmi::Uri& uri(const ModifiableComponent* msg);
+};
+
+const ::dmi::Component&
+ModifiableComponent::HasBitSetters::parent(const ModifiableComponent* msg) {
+  return *msg->parent_;
+}
+const ::dmi::Uri&
+ModifiableComponent::HasBitSetters::uri(const ModifiableComponent* msg) {
+  return *msg->uri_;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ModifiableComponent::kNameFieldNumber;
+const int ModifiableComponent::kClassFieldNumber;
+const int ModifiableComponent::kParentFieldNumber;
+const int ModifiableComponent::kParentRelPosFieldNumber;
+const int ModifiableComponent::kAliasFieldNumber;
+const int ModifiableComponent::kAssetIdFieldNumber;
+const int ModifiableComponent::kUriFieldNumber;
+const int ModifiableComponent::kAdminStateFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ModifiableComponent::ModifiableComponent()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ModifiableComponent)
+}
+ModifiableComponent::ModifiableComponent(const ModifiableComponent& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.name().size() > 0) {
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  alias_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.alias().size() > 0) {
+    alias_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.alias_);
+  }
+  asset_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.asset_id().size() > 0) {
+    asset_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.asset_id_);
+  }
+  if (from.has_parent()) {
+    parent_ = new ::dmi::Component(*from.parent_);
+  } else {
+    parent_ = nullptr;
+  }
+  if (from.has_uri()) {
+    uri_ = new ::dmi::Uri(*from.uri_);
+  } else {
+    uri_ = nullptr;
+  }
+  ::memcpy(&class__, &from.class__,
+    static_cast<size_t>(reinterpret_cast<char*>(&admin_state_) -
+    reinterpret_cast<char*>(&class__)) + sizeof(admin_state_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ModifiableComponent)
+}
+
+void ModifiableComponent::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ModifiableComponent_dmi_2fhw_2eproto.base);
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&parent_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&admin_state_) -
+      reinterpret_cast<char*>(&parent_)) + sizeof(admin_state_));
+}
+
+ModifiableComponent::~ModifiableComponent() {
+  // @@protoc_insertion_point(destructor:dmi.ModifiableComponent)
+  SharedDtor();
+}
+
+void ModifiableComponent::SharedDtor() {
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete parent_;
+  if (this != internal_default_instance()) delete uri_;
+}
+
+void ModifiableComponent::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ModifiableComponent& ModifiableComponent::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ModifiableComponent_dmi_2fhw_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ModifiableComponent::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ModifiableComponent)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && parent_ != nullptr) {
+    delete parent_;
+  }
+  parent_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
+    delete uri_;
+  }
+  uri_ = nullptr;
+  ::memset(&class__, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&admin_state_) -
+      reinterpret_cast<char*>(&class__)) + sizeof(admin_state_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ModifiableComponent::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ModifiableComponent*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // string name = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ModifiableComponent.name");
+        object = msg->mutable_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // .dmi.ComponentType class = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_class_(static_cast<::dmi::ComponentType>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.Component parent = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Component::_InternalParse;
+        object = msg->mutable_parent();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // int32 parent_rel_pos = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
+        msg->set_parent_rel_pos(::google::protobuf::internal::ReadVarint(&ptr));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string alias = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ModifiableComponent.alias");
+        object = msg->mutable_alias();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // string asset_id = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ModifiableComponent.asset_id");
+        object = msg->mutable_asset_id();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      // .dmi.Uri uri = 7;
+      case 7: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 58) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uri::_InternalParse;
+        object = msg->mutable_uri();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.ComponentAdminState admin_state = 8;
+      case 8: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 64) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_admin_state(static_cast<::dmi::ComponentAdminState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ModifiableComponent::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ModifiableComponent)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // string name = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->name().data(), static_cast<int>(this->name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ModifiableComponent.name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentType class = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_class_(static_cast< ::dmi::ComponentType >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Component parent = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_parent()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // int32 parent_rel_pos = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (32 & 0xFF)) {
+
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &parent_rel_pos_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string alias = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_alias()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->alias().data(), static_cast<int>(this->alias().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ModifiableComponent.alias"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string asset_id = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_asset_id()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ModifiableComponent.asset_id"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uri uri = 7;
+      case 7: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (58 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_uri()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentAdminState admin_state = 8;
+      case 8: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (64 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_admin_state(static_cast< ::dmi::ComponentAdminState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ModifiableComponent)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ModifiableComponent)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ModifiableComponent::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ModifiableComponent)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->class_(), output);
+  }
+
+  // .dmi.Component parent = 3;
+  if (this->has_parent()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::parent(this), output);
+  }
+
+  // int32 parent_rel_pos = 4;
+  if (this->parent_rel_pos() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->parent_rel_pos(), output);
+  }
+
+  // string alias = 5;
+  if (this->alias().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->alias().data(), static_cast<int>(this->alias().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.alias");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      5, this->alias(), output);
+  }
+
+  // string asset_id = 6;
+  if (this->asset_id().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.asset_id");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      6, this->asset_id(), output);
+  }
+
+  // .dmi.Uri uri = 7;
+  if (this->has_uri()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      7, HasBitSetters::uri(this), output);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 8;
+  if (this->admin_state() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      8, this->admin_state(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ModifiableComponent)
+}
+
+::google::protobuf::uint8* ModifiableComponent::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ModifiableComponent)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), static_cast<int>(this->name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->class_(), target);
+  }
+
+  // .dmi.Component parent = 3;
+  if (this->has_parent()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::parent(this), target);
+  }
+
+  // int32 parent_rel_pos = 4;
+  if (this->parent_rel_pos() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->parent_rel_pos(), target);
+  }
+
+  // string alias = 5;
+  if (this->alias().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->alias().data(), static_cast<int>(this->alias().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.alias");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        5, this->alias(), target);
+  }
+
+  // string asset_id = 6;
+  if (this->asset_id().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->asset_id().data(), static_cast<int>(this->asset_id().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ModifiableComponent.asset_id");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        6, this->asset_id(), target);
+  }
+
+  // .dmi.Uri uri = 7;
+  if (this->has_uri()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        7, HasBitSetters::uri(this), target);
+  }
+
+  // .dmi.ComponentAdminState admin_state = 8;
+  if (this->admin_state() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      8, this->admin_state(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ModifiableComponent)
+  return target;
+}
+
+size_t ModifiableComponent::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ModifiableComponent)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string name = 1;
+  if (this->name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->name());
+  }
+
+  // string alias = 5;
+  if (this->alias().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->alias());
+  }
+
+  // string asset_id = 6;
+  if (this->asset_id().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->asset_id());
+  }
+
+  // .dmi.Component parent = 3;
+  if (this->has_parent()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *parent_);
+  }
+
+  // .dmi.Uri uri = 7;
+  if (this->has_uri()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *uri_);
+  }
+
+  // .dmi.ComponentType class = 2;
+  if (this->class_() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->class_());
+  }
+
+  // int32 parent_rel_pos = 4;
+  if (this->parent_rel_pos() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->parent_rel_pos());
+  }
+
+  // .dmi.ComponentAdminState admin_state = 8;
+  if (this->admin_state() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->admin_state());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ModifiableComponent::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ModifiableComponent)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ModifiableComponent* source =
+      ::google::protobuf::DynamicCastToGenerated<ModifiableComponent>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ModifiableComponent)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ModifiableComponent)
+    MergeFrom(*source);
+  }
+}
+
+void ModifiableComponent::MergeFrom(const ModifiableComponent& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ModifiableComponent)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.name().size() > 0) {
+
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  if (from.alias().size() > 0) {
+
+    alias_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.alias_);
+  }
+  if (from.asset_id().size() > 0) {
+
+    asset_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.asset_id_);
+  }
+  if (from.has_parent()) {
+    mutable_parent()->::dmi::Component::MergeFrom(from.parent());
+  }
+  if (from.has_uri()) {
+    mutable_uri()->::dmi::Uri::MergeFrom(from.uri());
+  }
+  if (from.class_() != 0) {
+    set_class_(from.class_());
+  }
+  if (from.parent_rel_pos() != 0) {
+    set_parent_rel_pos(from.parent_rel_pos());
+  }
+  if (from.admin_state() != 0) {
+    set_admin_state(from.admin_state());
+  }
+}
+
+void ModifiableComponent::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ModifiableComponent)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ModifiableComponent::CopyFrom(const ModifiableComponent& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ModifiableComponent)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ModifiableComponent::IsInitialized() const {
+  return true;
+}
+
+void ModifiableComponent::Swap(ModifiableComponent* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ModifiableComponent::InternalSwap(ModifiableComponent* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  alias_.Swap(&other->alias_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  asset_id_.Swap(&other->asset_id_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(parent_, other->parent_);
+  swap(uri_, other->uri_);
+  swap(class__, other->class__);
+  swap(parent_rel_pos_, other->parent_rel_pos_);
+  swap(admin_state_, other->admin_state_);
+}
+
+::google::protobuf::Metadata ModifiableComponent::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
+  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+}  // namespace dmi
+namespace google {
+namespace protobuf {
+template<> PROTOBUF_NOINLINE ::dmi::Uuid* Arena::CreateMaybeMessage< ::dmi::Uuid >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Uuid >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::HardwareID* Arena::CreateMaybeMessage< ::dmi::HardwareID >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::HardwareID >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::Uri* Arena::CreateMaybeMessage< ::dmi::Uri >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Uri >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ComponentState* Arena::CreateMaybeMessage< ::dmi::ComponentState >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ComponentState >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ComponentSensorData* Arena::CreateMaybeMessage< ::dmi::ComponentSensorData >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ComponentSensorData >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::PortComponentAttributes* Arena::CreateMaybeMessage< ::dmi::PortComponentAttributes >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::PortComponentAttributes >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ContainerComponentAttributes* Arena::CreateMaybeMessage< ::dmi::ContainerComponentAttributes >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ContainerComponentAttributes >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::PsuComponentAttributes* Arena::CreateMaybeMessage< ::dmi::PsuComponentAttributes >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::PsuComponentAttributes >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::TransceiverComponentsAttributes* Arena::CreateMaybeMessage< ::dmi::TransceiverComponentsAttributes >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::TransceiverComponentsAttributes >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::Component* Arena::CreateMaybeMessage< ::dmi::Component >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Component >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::Hardware* Arena::CreateMaybeMessage< ::dmi::Hardware >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::Hardware >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ModifiableComponent* Arena::CreateMaybeMessage< ::dmi::ModifiableComponent >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ModifiableComponent >(arena);
+}
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
+#include <google/protobuf/port_undef.inc>
