// 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_PonDistance_dmi_2fhw_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_PonIdConfig_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_TransceiverComponentChangeAttributes_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<2> scc_info_PortComponentAttributes_dmi_2fhw_2eproto;
extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_PortComponentChangeAttributes_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 PonDistanceDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<PonDistance> _instance;
} _PonDistance_default_instance_;
class PortComponentChangeAttributesDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<PortComponentChangeAttributes> _instance;
} _PortComponentChangeAttributes_default_instance_;
class TransceiverComponentChangeAttributesDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<TransceiverComponentChangeAttributes> _instance;
} _TransceiverComponentChangeAttributes_default_instance_;
class PonIdConfigDefaultTypeInternal {
 public:
  ::google::protobuf::internal::ExplicitlyConstructed<PonIdConfig> _instance;
} _PonIdConfig_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;
  const ::dmi::PortComponentChangeAttributes* port_attr_;
  const ::dmi::TransceiverComponentChangeAttributes* trx_attr_;
} _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<2> scc_info_PortComponentAttributes_dmi_2fhw_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsPortComponentAttributes_dmi_2fhw_2eproto}, {
      &scc_info_PonIdConfig_dmi_2fhw_2eproto.base,
      &scc_info_PonDistance_dmi_2fhw_2eproto.base,}};

static void InitDefaultsPonDistance_dmi_2fhw_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_PonDistance_default_instance_;
    new (ptr) ::dmi::PonDistance();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::PonDistance::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_PonDistance_dmi_2fhw_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsPonDistance_dmi_2fhw_2eproto}, {}};

static void InitDefaultsPortComponentChangeAttributes_dmi_2fhw_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_PortComponentChangeAttributes_default_instance_;
    new (ptr) ::dmi::PortComponentChangeAttributes();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::PortComponentChangeAttributes::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<2> scc_info_PortComponentChangeAttributes_dmi_2fhw_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsPortComponentChangeAttributes_dmi_2fhw_2eproto}, {
      &scc_info_PonIdConfig_dmi_2fhw_2eproto.base,
      &scc_info_PonDistance_dmi_2fhw_2eproto.base,}};

static void InitDefaultsTransceiverComponentChangeAttributes_dmi_2fhw_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_TransceiverComponentChangeAttributes_default_instance_;
    new (ptr) ::dmi::TransceiverComponentChangeAttributes();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::TransceiverComponentChangeAttributes::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_TransceiverComponentChangeAttributes_dmi_2fhw_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsTransceiverComponentChangeAttributes_dmi_2fhw_2eproto}, {}};

static void InitDefaultsPonIdConfig_dmi_2fhw_2eproto() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  {
    void* ptr = &::dmi::_PonIdConfig_default_instance_;
    new (ptr) ::dmi::PonIdConfig();
    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
  }
  ::dmi::PonIdConfig::InitAsDefaultInstance();
}

::google::protobuf::internal::SCCInfo<0> scc_info_PonIdConfig_dmi_2fhw_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsPonIdConfig_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<4> scc_info_ModifiableComponent_dmi_2fhw_2eproto =
    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 4, InitDefaultsModifiableComponent_dmi_2fhw_2eproto}, {
      &scc_info_Component_dmi_2fhw_2eproto.base,
      &scc_info_Uri_dmi_2fhw_2eproto.base,
      &scc_info_PortComponentChangeAttributes_dmi_2fhw_2eproto.base,
      &scc_info_TransceiverComponentChangeAttributes_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_PonDistance_dmi_2fhw_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_PortComponentChangeAttributes_dmi_2fhw_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_TransceiverComponentChangeAttributes_dmi_2fhw_2eproto.base);
  ::google::protobuf::internal::InitSCC(&scc_info_PonIdConfig_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[16];
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_),
  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, mapping_label_),
  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, pon_id_config_),
  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, speed_autonegotiation_),
  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentAttributes, distance_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::PonDistance, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::PonDistance, max_distance_),
  PROTOBUF_FIELD_OFFSET(::dmi::PonDistance, max_differential_distance_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentChangeAttributes, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentChangeAttributes, pon_id_config_),
  PROTOBUF_FIELD_OFFSET(::dmi::PortComponentChangeAttributes, distance_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentChangeAttributes, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentChangeAttributes, trans_type_),
  ~0u,  // no _has_bits_
  PROTOBUF_FIELD_OFFSET(::dmi::PonIdConfig, _internal_metadata_),
  ~0u,  // no _extensions_
  ~0u,  // no _oneof_case_
  ~0u,  // no _weak_field_map_
  PROTOBUF_FIELD_OFFSET(::dmi::PonIdConfig, pon_id_),
  PROTOBUF_FIELD_OFFSET(::dmi::PonIdConfig, pon_id_transmit_periodicity_),
  ~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_),
  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, tx_power_),
  PROTOBUF_FIELD_OFFSET(::dmi::TransceiverComponentsAttributes, tx_power_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_
  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, _oneof_case_[0]),
  ~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_),
  offsetof(::dmi::ModifiableComponentDefaultTypeInternal, port_attr_),
  offsetof(::dmi::ModifiableComponentDefaultTypeInternal, trx_attr_),
  PROTOBUF_FIELD_OFFSET(::dmi::ModifiableComponent, specific_),
};
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)},
  { 56, -1, sizeof(::dmi::PonDistance)},
  { 63, -1, sizeof(::dmi::PortComponentChangeAttributes)},
  { 70, -1, sizeof(::dmi::TransceiverComponentChangeAttributes)},
  { 76, -1, sizeof(::dmi::PonIdConfig)},
  { 83, -1, sizeof(::dmi::ContainerComponentAttributes)},
  { 89, -1, sizeof(::dmi::PsuComponentAttributes)},
  { 95, -1, sizeof(::dmi::TransceiverComponentsAttributes)},
  { 109, -1, sizeof(::dmi::Component)},
  { 139, -1, sizeof(::dmi::Hardware)},
  { 147, -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::_PonDistance_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_PortComponentChangeAttributes_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_TransceiverComponentChangeAttributes_default_instance_),
  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_PonIdConfig_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, 16, 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"
  "\"\205\006\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\022\025\n\rmapping_"
  "label\030\005 \001(\t\022\'\n\rpon_id_config\030\006 \001(\0132\020.dmi"
  ".PonIdConfig\022\035\n\025speed_autonegotiation\030\007 "
  "\001(\010\022\"\n\010distance\030\010 \001(\0132\020.dmi.PonDistance\""
  "p\n\rConnectorType\022\034\n\030CONNECTOR_TYPE_UNDEF"
  "INED\020\000\022\010\n\004RJ45\020\001\022\014\n\010FIBER_LC\020\002\022\017\n\013FIBER_"
  "SC_PC\020\003\022\r\n\tFIBER_MPO\020\004\022\t\n\005RS232\020\005\"\256\001\n\005Sp"
  "eed\022\023\n\017SPEED_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\nGIGABIT_40\020\005\022\017\n\013GIGABIT_100\020\006\022\017\n"
  "\013GIGABIT_400\020\007\022\020\n\014MEGABIT_2500\020\010\022\020\n\014MEGA"
  "BIT_1250\020\t\"|\n\010Protocol\022\026\n\022PROTOCOL_UNDEF"
  "INED\020\000\022\014\n\010ETHERNET\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\004"
  "EPON\020\007\022\010\n\004BITS\020\010\"F\n\013PonDistance\022\024\n\014max_d"
  "istance\030\001 \001(\r\022!\n\031max_differential_distan"
  "ce\030\002 \001(\r\"l\n\035PortComponentChangeAttribute"
  "s\022\'\n\rpon_id_config\030\001 \001(\0132\020.dmi.PonIdConf"
  "ig\022\"\n\010distance\030\002 \001(\0132\020.dmi.PonDistance\"P"
  "\n$TransceiverComponentChangeAttributes\022("
  "\n\ntrans_type\030\001 \001(\0162\024.dmi.TransceiverType"
  "\"B\n\013PonIdConfig\022\016\n\006pon_id\030\001 \001(\014\022#\n\033pon_i"
  "d_transmit_periodicity\030\002 \001(\r\"6\n\034Containe"
  "rComponentAttributes\022\026\n\016physical_label\030\001"
  " \001(\t\"\263\001\n\026PsuComponentAttributes\022G\n\021suppo"
  "rted_voltage\030\001 \001(\0162,.dmi.PsuComponentAtt"
  "ributes.SupportedVoltage\"P\n\020SupportedVol"
  "tage\022\037\n\033SUPPORTED_VOLTAGE_UNDEFINED\020\000\022\007\n"
  "\003V48\020\001\022\010\n\004V230\020\002\022\010\n\004V115\020\003\"\270\004\n\037Transceiv"
  "erComponentsAttributes\022D\n\013form_factor\030\001 "
  "\001(\0162/.dmi.TransceiverComponentsAttribute"
  "s.FormFactor\022(\n\ntrans_type\030\002 \001(\0162\024.dmi.T"
  "ransceiverType\022\024\n\014max_distance\030\003 \001(\r\022+\n\022"
  "max_distance_scale\030\004 \001(\0162\017.dmi.ValueScal"
  "e\022\025\n\rrx_wavelength\030\005 \003(\r\022\025\n\rtx_wavelengt"
  "h\030\006 \003(\r\022)\n\020wavelength_scale\030\007 \001(\0162\017.dmi."
  "ValueScale\022\020\n\010tx_power\030\010 \003(\005\022\'\n\016tx_power"
  "_scale\030\t \001(\0162\017.dmi.ValueScale\"\315\001\n\nFormFa"
  "ctor\022\027\n\023FORM_FACTOR_UNKNOWN\020\000\022\010\n\004QSFP\020\001\022"
  "\r\n\tQSFP_PLUS\020\002\022\n\n\006QSFP28\020\003\022\007\n\003SFP\020\004\022\014\n\010S"
  "FP_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\005OTHER\020\013\022\007\n\003CFP\020\014\022\014\n\010"
  "CFP2_ACO\020\r\022\014\n\010CFP2_DCO\020\016\022\013\n\007QSFP_DD\020\017\"\350\005"
  "\n\tComponent\022\014\n\004name\030\001 \001(\t\022!\n\005class\030\002 \001(\016"
  "2\022.dmi.ComponentType\022\023\n\013description\030\003 \001("
  "\t\022\016\n\006parent\030\004 \001(\t\022\026\n\016parent_rel_pos\030\005 \001("
  "\005\022 \n\010children\030\006 \003(\0132\016.dmi.Component\022\024\n\014h"
  "ardware_rev\030\007 \001(\t\022\024\n\014firmware_rev\030\010 \001(\t\022"
  "\024\n\014software_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_f"
  "ru\030\017 \001(\010\022,\n\010mfg_date\030\020 \001(\0132\032.google.prot"
  "obuf.Timestamp\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.ComponentState\022-\n\013sensor_data\030\024 \003(\0132"
  "\030.dmi.ComponentSensorData\0221\n\tport_attr\0302"
  " \001(\0132\034.dmi.PortComponentAttributesH\000\022;\n\016"
  "container_attr\0303 \001(\0132!.dmi.ContainerComp"
  "onentAttributesH\000\022/\n\010psu_attr\0304 \001(\0132\033.dm"
  "i.PsuComponentAttributesH\000\022@\n\020transceive"
  "r_attr\0305 \001(\0132$.dmi.TransceiverComponents"
  "AttributesH\000B\n\n\010specific\"\212\001\n\010Hardware\022/\n"
  "\013last_change\030\001 \001(\0132\032.google.protobuf.Tim"
  "estamp\022\034\n\004root\030\002 \001(\0132\016.dmi.Component\022/\n\013"
  "last_booted\030\003 \001(\0132\032.google.protobuf.Time"
  "stamp\"\351\002\n\023ModifiableComponent\022\014\n\004name\030\001 "
  "\001(\t\022!\n\005class\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_i"
  "d\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\0227\n"
  "\tport_attr\0302 \001(\0132\".dmi.PortComponentChan"
  "geAttributesH\000\022=\n\010trx_attr\0303 \001(\0132).dmi.T"
  "ransceiverComponentChangeAttributesH\000B\n\n"
  "\010specific*\264\003\n\rComponentType\022\034\n\030COMPONENT"
  "_TYPE_UNDEFINED\020\000\022\032\n\026COMPONENT_TYPE_UNKN"
  "OWN\020\001\022\032\n\026COMPONENT_TYPE_CHASSIS\020\002\022\034\n\030COM"
  "PONENT_TYPE_BACKPLANE\020\003\022\034\n\030COMPONENT_TYP"
  "E_CONTAINER\020\004\022\037\n\033COMPONENT_TYPE_POWER_SU"
  "PPLY\020\005\022\026\n\022COMPONENT_TYPE_FAN\020\006\022\031\n\025COMPON"
  "ENT_TYPE_SENSOR\020\007\022\031\n\025COMPONENT_TYPE_MODU"
  "LE\020\010\022\027\n\023COMPONENT_TYPE_PORT\020\t\022\026\n\022COMPONE"
  "NT_TYPE_CPU\020\n\022\032\n\026COMPONENT_TYPE_BATTERY\020"
  "\013\022\032\n\026COMPONENT_TYPE_STORAGE\020\014\022\031\n\025COMPONE"
  "NT_TYPE_MEMORY\020\r\022\036\n\032COMPONENT_TYPE_TRANS"
  "CEIVER\020\016*\363\001\n\023ComponentAdminState\022\036\n\032COMP"
  "_ADMIN_STATE_UNDEFINED\020\000\022\034\n\030COMP_ADMIN_S"
  "TATE_UNKNOWN\020\001\022\033\n\027COMP_ADMIN_STATE_LOCKE"
  "D\020\002\022\"\n\036COMP_ADMIN_STATE_SHUTTING_DOWN\020\003\022"
  "\035\n\031COMP_ADMIN_STATE_UNLOCKED\020\004\022\035\n\031COMP_A"
  "DMIN_STATE_ISOLATED\020\006\022\037\n\033COMP_ADMIN_STAT"
  "E_PROHIBITED\020\005*\303\003\n\022ComponentOperState\022\035\n"
  "\031COMP_OPER_STATE_UNDEFINED\020\000\022\033\n\027COMP_OPE"
  "R_STATE_UNKNOWN\020\001\022\034\n\030COMP_OPER_STATE_DIS"
  "ABLED\020\002\022\033\n\027COMP_OPER_STATE_ENABLED\020\003\022\033\n\027"
  "COMP_OPER_STATE_TESTING\020\004\022\032\n\026COMP_OPER_S"
  "TATE_NORMAL\020\005\022\037\n\033COMP_OPER_STATE_CONFIGU"
  "RING\020\006\022%\n!COMP_OPER_STATE_AUTOMATIC_LOAD"
  "ING\020\007\022\032\n\026COMP_OPER_STATE_FAILED\020\010\022&\n\"COM"
  "P_OPER_STATE_HIGH_TEMP_SHUTDOWN\020\t\022#\n\037COM"
  "P_OPER_STATE_MANUAL_SHUTDOWN\020\n\022)\n%COMP_O"
  "PER_STATE_POWER_SAVING_SHUTDOWN\020\013\022!\n\035COM"
  "P_OPER_STATE_TYPE_MISMATCH\020\014*\246\001\n\023Compone"
  "ntUsageState\022\036\n\032COMP_USAGE_STATE_UNDEFIN"
  "ED\020\000\022\034\n\030COMP_USAGE_STATE_UNKNOWN\020\001\022\031\n\025CO"
  "MP_USAGE_STATE_IDLE\020\002\022\033\n\027COMP_USAGE_STAT"
  "E_ACTIVE\020\003\022\031\n\025COMP_USAGE_STATE_BUSY\020\004*\217\002"
  "\n\023ComponentAlarmState\022\036\n\032COMP_ALARM_STAT"
  "E_UNDEFINED\020\000\022\034\n\030COMP_ALARM_STATE_UNKNOW"
  "N\020\001\022!\n\035COMP_ALARM_STATE_UNDER_REPAIR\020\002\022\035"
  "\n\031COMP_ALARM_STATE_CRITICAL\020\003\022\032\n\026COMP_AL"
  "ARM_STATE_MAJOR\020\004\022\032\n\026COMP_ALARM_STATE_MI"
  "NOR\020\005\022\034\n\030COMP_ALARM_STATE_WARNING\020\006\022\"\n\036C"
  "OMP_ALARM_STATE_INDETERMINATE\020\007*\274\001\n\025Comp"
  "onentStandbyState\022 \n\034COMP_STANDBY_STATE_"
  "UNDEFINED\020\000\022\036\n\032COMP_STANDBY_STATE_UNKNOW"
  "N\020\001\022\032\n\026COMP_STANDBY_STATE_HOT\020\002\022\033\n\027COMP_"
  "STANDBY_STATE_COLD\020\003\022(\n$COMP_STANDBY_STA"
  "TE_PROVIDING_SERVICE\020\004*\235\003\n\rDataValueType"
  "\022\030\n\024VALUE_TYPE_UNDEFINED\020\000\022\024\n\020VALUE_TYPE"
  "_OTHER\020\001\022\026\n\022VALUE_TYPE_UNKNOWN\020\002\022\027\n\023VALU"
  "E_TYPE_VOLTS_AC\020\003\022\027\n\023VALUE_TYPE_VOLTS_DC"
  "\020\004\022\026\n\022VALUE_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_CELSIUS\020\010\022\031\n\025VALUE_TYPE_PERCENT_RH\020"
  "\t\022\022\n\016VALUE_TYPE_RPM\020\n\022\022\n\016VALUE_TYPE_CMM\020"
  "\013\022\032\n\026VALUE_TYPE_TRUTH_VALUE\020\014\022\026\n\022VALUE_T"
  "YPE_PERCENT\020\r\022\025\n\021VALUE_TYPE_METERS\020\016\022\024\n\020"
  "VALUE_TYPE_BYTES\020\017\022\022\n\016VALUE_TYPE_DBM\020\020*\244"
  "\003\n\nValueScale\022\031\n\025VALUE_SCALE_UNDEFINED\020\000"
  "\022\025\n\021VALUE_SCALE_YOCTO\020\001\022\025\n\021VALUE_SCALE_Z"
  "EPTO\020\002\022\024\n\020VALUE_SCALE_ATTO\020\003\022\025\n\021VALUE_SC"
  "ALE_FEMTO\020\004\022\024\n\020VALUE_SCALE_PICO\020\005\022\024\n\020VAL"
  "UE_SCALE_NANO\020\006\022\025\n\021VALUE_SCALE_MICRO\020\007\022\025"
  "\n\021VALUE_SCALE_MILLI\020\010\022\025\n\021VALUE_SCALE_UNI"
  "TS\020\t\022\024\n\020VALUE_SCALE_KILO\020\n\022\024\n\020VALUE_SCAL"
  "E_MEGA\020\013\022\024\n\020VALUE_SCALE_GIGA\020\014\022\024\n\020VALUE_"
  "SCALE_TERA\020\r\022\024\n\020VALUE_SCALE_PETA\020\016\022\023\n\017VA"
  "LUE_SCALE_EXA\020\017\022\025\n\021VALUE_SCALE_ZETTA\020\020\022\025"
  "\n\021VALUE_SCALE_YOTTA\020\021*\202\001\n\014SensorStatus\022\033"
  "\n\027SENSOR_STATUS_UNDEFINED\020\000\022\024\n\020SENSOR_ST"
  "ATUS_OK\020\001\022\035\n\031SENSOR_STATUS_UNAVAILABLE\020\002"
  "\022 \n\034SENSOR_STATUS_NONOPERATIONAL\020\003*\244\001\n\017T"
  "ransceiverType\022\022\n\016TYPE_UNDEFINED\020\000\022\014\n\010ET"
  "HERNET\020\001\022\010\n\004GPON\020\002\022\t\n\005XGPON\020\003\022\n\n\006XGSPON\020"
  "\004\022\010\n\004CPON\020\005\022\013\n\007NG_PON2\020\006\022\010\n\004EPON\020\007\022\025\n\021CO"
  "MBO_GPON_XGSPON\020\010\022\026\n\021TYPE_NOT_DETECTED\020\377"
  "\001B;Z9github.com/opencord/device-manageme"
  "nt-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, 6870,
};

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:
    case 15:
      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::QSFP_DD;
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* ComponentType_descriptor() {
  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
  return file_level_enum_descriptors_dmi_2fhw_2eproto[5];
}
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[6];
}
bool ComponentAdminState_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
      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[7];
}
bool ComponentOperState_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:
      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[8];
}
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[9];
}
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[10];
}
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[11];
}
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:
    case 16:
      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[12];
}
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[13];
}
bool SensorStatus_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

const ::google::protobuf::EnumDescriptor* TransceiverType_descriptor() {
  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_2eproto);
  return file_level_enum_descriptors_dmi_2fhw_2eproto[14];
}
bool TransceiverType_IsValid(int value) {
  switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 255:
      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() {
  ::dmi::_PortComponentAttributes_default_instance_._instance.get_mutable()->pon_id_config_ = const_cast< ::dmi::PonIdConfig*>(
      ::dmi::PonIdConfig::internal_default_instance());
  ::dmi::_PortComponentAttributes_default_instance_._instance.get_mutable()->distance_ = const_cast< ::dmi::PonDistance*>(
      ::dmi::PonDistance::internal_default_instance());
}
class PortComponentAttributes::HasBitSetters {
 public:
  static const ::dmi::PonIdConfig& pon_id_config(const PortComponentAttributes* msg);
  static const ::dmi::PonDistance& distance(const PortComponentAttributes* msg);
};

const ::dmi::PonIdConfig&
PortComponentAttributes::HasBitSetters::pon_id_config(const PortComponentAttributes* msg) {
  return *msg->pon_id_config_;
}
const ::dmi::PonDistance&
PortComponentAttributes::HasBitSetters::distance(const PortComponentAttributes* msg) {
  return *msg->distance_;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int PortComponentAttributes::kConnectorTypeFieldNumber;
const int PortComponentAttributes::kSpeedFieldNumber;
const int PortComponentAttributes::kProtocolFieldNumber;
const int PortComponentAttributes::kPhysicalLabelFieldNumber;
const int PortComponentAttributes::kMappingLabelFieldNumber;
const int PortComponentAttributes::kPonIdConfigFieldNumber;
const int PortComponentAttributes::kSpeedAutonegotiationFieldNumber;
const int PortComponentAttributes::kDistanceFieldNumber;
#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_);
  }
  mapping_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.mapping_label().size() > 0) {
    mapping_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.mapping_label_);
  }
  if (from.has_pon_id_config()) {
    pon_id_config_ = new ::dmi::PonIdConfig(*from.pon_id_config_);
  } else {
    pon_id_config_ = nullptr;
  }
  if (from.has_distance()) {
    distance_ = new ::dmi::PonDistance(*from.distance_);
  } else {
    distance_ = nullptr;
  }
  ::memcpy(&connector_type_, &from.connector_type_,
    static_cast<size_t>(reinterpret_cast<char*>(&speed_autonegotiation_) -
    reinterpret_cast<char*>(&connector_type_)) + sizeof(speed_autonegotiation_));
  // @@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());
  mapping_label_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  ::memset(&pon_id_config_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&speed_autonegotiation_) -
      reinterpret_cast<char*>(&pon_id_config_)) + sizeof(speed_autonegotiation_));
}

PortComponentAttributes::~PortComponentAttributes() {
  // @@protoc_insertion_point(destructor:dmi.PortComponentAttributes)
  SharedDtor();
}

void PortComponentAttributes::SharedDtor() {
  physical_label_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  mapping_label_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (this != internal_default_instance()) delete pon_id_config_;
  if (this != internal_default_instance()) delete distance_;
}

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());
  mapping_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (GetArenaNoVirtual() == nullptr && pon_id_config_ != nullptr) {
    delete pon_id_config_;
  }
  pon_id_config_ = nullptr;
  if (GetArenaNoVirtual() == nullptr && distance_ != nullptr) {
    delete distance_;
  }
  distance_ = nullptr;
  ::memset(&connector_type_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&speed_autonegotiation_) -
      reinterpret_cast<char*>(&connector_type_)) + sizeof(speed_autonegotiation_));
  _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;
      }
      // string mapping_label = 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.PortComponentAttributes.mapping_label");
        object = msg->mutable_mapping_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;
      }
      // .dmi.PonIdConfig pon_id_config = 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);
        parser_till_end = ::dmi::PonIdConfig::_InternalParse;
        object = msg->mutable_pon_id_config();
        if (size > end - ptr) goto len_delim_till_end;
        ptr += size;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
            {parser_till_end, object}, ptr - size, ptr));
        break;
      }
      // bool speed_autonegotiation = 7;
      case 7: {
        if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
        msg->set_speed_autonegotiation(::google::protobuf::internal::ReadVarint(&ptr));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // .dmi.PonDistance distance = 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);
        parser_till_end = ::dmi::PonDistance::_InternalParse;
        object = msg->mutable_distance();
        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 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;
      }

      // string mapping_label = 5;
      case 5: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_mapping_label()));
          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
            this->mapping_label().data(), static_cast<int>(this->mapping_label().length()),
            ::google::protobuf::internal::WireFormatLite::PARSE,
            "dmi.PortComponentAttributes.mapping_label"));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.PonIdConfig pon_id_config = 6;
      case 6: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_pon_id_config()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // bool speed_autonegotiation = 7;
      case 7: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (56 & 0xFF)) {

          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &speed_autonegotiation_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.PonDistance distance = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (66 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_distance()));
        } 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);
  }

  // string mapping_label = 5;
  if (this->mapping_label().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->mapping_label().data(), static_cast<int>(this->mapping_label().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.PortComponentAttributes.mapping_label");
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      5, this->mapping_label(), output);
  }

  // .dmi.PonIdConfig pon_id_config = 6;
  if (this->has_pon_id_config()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      6, HasBitSetters::pon_id_config(this), output);
  }

  // bool speed_autonegotiation = 7;
  if (this->speed_autonegotiation() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->speed_autonegotiation(), output);
  }

  // .dmi.PonDistance distance = 8;
  if (this->has_distance()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      8, HasBitSetters::distance(this), 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);
  }

  // string mapping_label = 5;
  if (this->mapping_label().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
      this->mapping_label().data(), static_cast<int>(this->mapping_label().length()),
      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
      "dmi.PortComponentAttributes.mapping_label");
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        5, this->mapping_label(), target);
  }

  // .dmi.PonIdConfig pon_id_config = 6;
  if (this->has_pon_id_config()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        6, HasBitSetters::pon_id_config(this), target);
  }

  // bool speed_autonegotiation = 7;
  if (this->speed_autonegotiation() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->speed_autonegotiation(), target);
  }

  // .dmi.PonDistance distance = 8;
  if (this->has_distance()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        8, HasBitSetters::distance(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.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());
  }

  // string mapping_label = 5;
  if (this->mapping_label().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::StringSize(
        this->mapping_label());
  }

  // .dmi.PonIdConfig pon_id_config = 6;
  if (this->has_pon_id_config()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *pon_id_config_);
  }

  // .dmi.PonDistance distance = 8;
  if (this->has_distance()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *distance_);
  }

  // .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());
  }

  // bool speed_autonegotiation = 7;
  if (this->speed_autonegotiation() != 0) {
    total_size += 1 + 1;
  }

  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.mapping_label().size() > 0) {

    mapping_label_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.mapping_label_);
  }
  if (from.has_pon_id_config()) {
    mutable_pon_id_config()->::dmi::PonIdConfig::MergeFrom(from.pon_id_config());
  }
  if (from.has_distance()) {
    mutable_distance()->::dmi::PonDistance::MergeFrom(from.distance());
  }
  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());
  }
  if (from.speed_autonegotiation() != 0) {
    set_speed_autonegotiation(from.speed_autonegotiation());
  }
}

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());
  mapping_label_.Swap(&other->mapping_label_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(pon_id_config_, other->pon_id_config_);
  swap(distance_, other->distance_);
  swap(connector_type_, other->connector_type_);
  swap(speed_, other->speed_);
  swap(protocol_, other->protocol_);
  swap(speed_autonegotiation_, other->speed_autonegotiation_);
}

::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 PonDistance::InitAsDefaultInstance() {
}
class PonDistance::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int PonDistance::kMaxDistanceFieldNumber;
const int PonDistance::kMaxDifferentialDistanceFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

PonDistance::PonDistance()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.PonDistance)
}
PonDistance::PonDistance(const PonDistance& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&max_distance_, &from.max_distance_,
    static_cast<size_t>(reinterpret_cast<char*>(&max_differential_distance_) -
    reinterpret_cast<char*>(&max_distance_)) + sizeof(max_differential_distance_));
  // @@protoc_insertion_point(copy_constructor:dmi.PonDistance)
}

void PonDistance::SharedCtor() {
  ::memset(&max_distance_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&max_differential_distance_) -
      reinterpret_cast<char*>(&max_distance_)) + sizeof(max_differential_distance_));
}

PonDistance::~PonDistance() {
  // @@protoc_insertion_point(destructor:dmi.PonDistance)
  SharedDtor();
}

void PonDistance::SharedDtor() {
}

void PonDistance::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const PonDistance& PonDistance::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_PonDistance_dmi_2fhw_2eproto.base);
  return *internal_default_instance();
}


void PonDistance::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.PonDistance)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  ::memset(&max_distance_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&max_differential_distance_) -
      reinterpret_cast<char*>(&max_distance_)) + sizeof(max_differential_distance_));
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* PonDistance::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<PonDistance*>(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) {
      // uint32 max_distance = 1;
      case 1: {
        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
        msg->set_max_distance(::google::protobuf::internal::ReadVarint(&ptr));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      // uint32 max_differential_distance = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        msg->set_max_differential_distance(::google::protobuf::internal::ReadVarint(&ptr));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
}
#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
bool PonDistance::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.PonDistance)
  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)) {
      // uint32 max_distance = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {

          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &max_distance_)));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // uint32 max_differential_distance = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {

          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &max_differential_distance_)));
        } 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.PonDistance)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.PonDistance)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void PonDistance::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.PonDistance)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // uint32 max_distance = 1;
  if (this->max_distance() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->max_distance(), output);
  }

  // uint32 max_differential_distance = 2;
  if (this->max_differential_distance() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->max_differential_distance(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.PonDistance)
}

::google::protobuf::uint8* PonDistance::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.PonDistance)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // uint32 max_distance = 1;
  if (this->max_distance() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->max_distance(), target);
  }

  // uint32 max_differential_distance = 2;
  if (this->max_differential_distance() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->max_differential_distance(), 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.PonDistance)
  return target;
}

size_t PonDistance::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.PonDistance)
  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;

  // uint32 max_distance = 1;
  if (this->max_distance() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::UInt32Size(
        this->max_distance());
  }

  // uint32 max_differential_distance = 2;
  if (this->max_differential_distance() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::UInt32Size(
        this->max_differential_distance());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void PonDistance::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.PonDistance)
  GOOGLE_DCHECK_NE(&from, this);
  const PonDistance* source =
      ::google::protobuf::DynamicCastToGenerated<PonDistance>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.PonDistance)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.PonDistance)
    MergeFrom(*source);
  }
}

void PonDistance::MergeFrom(const PonDistance& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.PonDistance)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.max_distance() != 0) {
    set_max_distance(from.max_distance());
  }
  if (from.max_differential_distance() != 0) {
    set_max_differential_distance(from.max_differential_distance());
  }
}

void PonDistance::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.PonDistance)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void PonDistance::CopyFrom(const PonDistance& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.PonDistance)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool PonDistance::IsInitialized() const {
  return true;
}

void PonDistance::Swap(PonDistance* other) {
  if (other == this) return;
  InternalSwap(other);
}
void PonDistance::InternalSwap(PonDistance* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(max_distance_, other->max_distance_);
  swap(max_differential_distance_, other->max_differential_distance_);
}

::google::protobuf::Metadata PonDistance::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
}


// ===================================================================

void PortComponentChangeAttributes::InitAsDefaultInstance() {
  ::dmi::_PortComponentChangeAttributes_default_instance_._instance.get_mutable()->pon_id_config_ = const_cast< ::dmi::PonIdConfig*>(
      ::dmi::PonIdConfig::internal_default_instance());
  ::dmi::_PortComponentChangeAttributes_default_instance_._instance.get_mutable()->distance_ = const_cast< ::dmi::PonDistance*>(
      ::dmi::PonDistance::internal_default_instance());
}
class PortComponentChangeAttributes::HasBitSetters {
 public:
  static const ::dmi::PonIdConfig& pon_id_config(const PortComponentChangeAttributes* msg);
  static const ::dmi::PonDistance& distance(const PortComponentChangeAttributes* msg);
};

const ::dmi::PonIdConfig&
PortComponentChangeAttributes::HasBitSetters::pon_id_config(const PortComponentChangeAttributes* msg) {
  return *msg->pon_id_config_;
}
const ::dmi::PonDistance&
PortComponentChangeAttributes::HasBitSetters::distance(const PortComponentChangeAttributes* msg) {
  return *msg->distance_;
}
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int PortComponentChangeAttributes::kPonIdConfigFieldNumber;
const int PortComponentChangeAttributes::kDistanceFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

PortComponentChangeAttributes::PortComponentChangeAttributes()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.PortComponentChangeAttributes)
}
PortComponentChangeAttributes::PortComponentChangeAttributes(const PortComponentChangeAttributes& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  if (from.has_pon_id_config()) {
    pon_id_config_ = new ::dmi::PonIdConfig(*from.pon_id_config_);
  } else {
    pon_id_config_ = nullptr;
  }
  if (from.has_distance()) {
    distance_ = new ::dmi::PonDistance(*from.distance_);
  } else {
    distance_ = nullptr;
  }
  // @@protoc_insertion_point(copy_constructor:dmi.PortComponentChangeAttributes)
}

void PortComponentChangeAttributes::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_PortComponentChangeAttributes_dmi_2fhw_2eproto.base);
  ::memset(&pon_id_config_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&distance_) -
      reinterpret_cast<char*>(&pon_id_config_)) + sizeof(distance_));
}

PortComponentChangeAttributes::~PortComponentChangeAttributes() {
  // @@protoc_insertion_point(destructor:dmi.PortComponentChangeAttributes)
  SharedDtor();
}

void PortComponentChangeAttributes::SharedDtor() {
  if (this != internal_default_instance()) delete pon_id_config_;
  if (this != internal_default_instance()) delete distance_;
}

void PortComponentChangeAttributes::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const PortComponentChangeAttributes& PortComponentChangeAttributes::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_PortComponentChangeAttributes_dmi_2fhw_2eproto.base);
  return *internal_default_instance();
}


void PortComponentChangeAttributes::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.PortComponentChangeAttributes)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  if (GetArenaNoVirtual() == nullptr && pon_id_config_ != nullptr) {
    delete pon_id_config_;
  }
  pon_id_config_ = nullptr;
  if (GetArenaNoVirtual() == nullptr && distance_ != nullptr) {
    delete distance_;
  }
  distance_ = nullptr;
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* PortComponentChangeAttributes::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<PortComponentChangeAttributes*>(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.PonIdConfig pon_id_config = 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::PonIdConfig::_InternalParse;
        object = msg->mutable_pon_id_config();
        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.PonDistance distance = 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::PonDistance::_InternalParse;
        object = msg->mutable_distance();
        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 PortComponentChangeAttributes::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.PortComponentChangeAttributes)
  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.PonIdConfig pon_id_config = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_pon_id_config()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.PonDistance distance = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_distance()));
        } 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.PortComponentChangeAttributes)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.PortComponentChangeAttributes)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void PortComponentChangeAttributes::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.PortComponentChangeAttributes)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.PonIdConfig pon_id_config = 1;
  if (this->has_pon_id_config()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, HasBitSetters::pon_id_config(this), output);
  }

  // .dmi.PonDistance distance = 2;
  if (this->has_distance()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, HasBitSetters::distance(this), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.PortComponentChangeAttributes)
}

::google::protobuf::uint8* PortComponentChangeAttributes::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.PortComponentChangeAttributes)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.PonIdConfig pon_id_config = 1;
  if (this->has_pon_id_config()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        1, HasBitSetters::pon_id_config(this), target);
  }

  // .dmi.PonDistance distance = 2;
  if (this->has_distance()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        2, HasBitSetters::distance(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.PortComponentChangeAttributes)
  return target;
}

size_t PortComponentChangeAttributes::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.PortComponentChangeAttributes)
  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.PonIdConfig pon_id_config = 1;
  if (this->has_pon_id_config()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *pon_id_config_);
  }

  // .dmi.PonDistance distance = 2;
  if (this->has_distance()) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::MessageSize(
        *distance_);
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void PortComponentChangeAttributes::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.PortComponentChangeAttributes)
  GOOGLE_DCHECK_NE(&from, this);
  const PortComponentChangeAttributes* source =
      ::google::protobuf::DynamicCastToGenerated<PortComponentChangeAttributes>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.PortComponentChangeAttributes)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.PortComponentChangeAttributes)
    MergeFrom(*source);
  }
}

void PortComponentChangeAttributes::MergeFrom(const PortComponentChangeAttributes& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.PortComponentChangeAttributes)
  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_pon_id_config()) {
    mutable_pon_id_config()->::dmi::PonIdConfig::MergeFrom(from.pon_id_config());
  }
  if (from.has_distance()) {
    mutable_distance()->::dmi::PonDistance::MergeFrom(from.distance());
  }
}

void PortComponentChangeAttributes::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.PortComponentChangeAttributes)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void PortComponentChangeAttributes::CopyFrom(const PortComponentChangeAttributes& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.PortComponentChangeAttributes)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool PortComponentChangeAttributes::IsInitialized() const {
  return true;
}

void PortComponentChangeAttributes::Swap(PortComponentChangeAttributes* other) {
  if (other == this) return;
  InternalSwap(other);
}
void PortComponentChangeAttributes::InternalSwap(PortComponentChangeAttributes* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(pon_id_config_, other->pon_id_config_);
  swap(distance_, other->distance_);
}

::google::protobuf::Metadata PortComponentChangeAttributes::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
}


// ===================================================================

void TransceiverComponentChangeAttributes::InitAsDefaultInstance() {
}
class TransceiverComponentChangeAttributes::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int TransceiverComponentChangeAttributes::kTransTypeFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

TransceiverComponentChangeAttributes::TransceiverComponentChangeAttributes()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.TransceiverComponentChangeAttributes)
}
TransceiverComponentChangeAttributes::TransceiverComponentChangeAttributes(const TransceiverComponentChangeAttributes& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  trans_type_ = from.trans_type_;
  // @@protoc_insertion_point(copy_constructor:dmi.TransceiverComponentChangeAttributes)
}

void TransceiverComponentChangeAttributes::SharedCtor() {
  trans_type_ = 0;
}

TransceiverComponentChangeAttributes::~TransceiverComponentChangeAttributes() {
  // @@protoc_insertion_point(destructor:dmi.TransceiverComponentChangeAttributes)
  SharedDtor();
}

void TransceiverComponentChangeAttributes::SharedDtor() {
}

void TransceiverComponentChangeAttributes::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const TransceiverComponentChangeAttributes& TransceiverComponentChangeAttributes::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_TransceiverComponentChangeAttributes_dmi_2fhw_2eproto.base);
  return *internal_default_instance();
}


void TransceiverComponentChangeAttributes::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.TransceiverComponentChangeAttributes)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  trans_type_ = 0;
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* TransceiverComponentChangeAttributes::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<TransceiverComponentChangeAttributes*>(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.TransceiverType trans_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_trans_type(static_cast<::dmi::TransceiverType>(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 TransceiverComponentChangeAttributes::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.TransceiverComponentChangeAttributes)
  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.TransceiverType trans_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_trans_type(static_cast< ::dmi::TransceiverType >(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.TransceiverComponentChangeAttributes)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.TransceiverComponentChangeAttributes)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void TransceiverComponentChangeAttributes::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.TransceiverComponentChangeAttributes)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.TransceiverType trans_type = 1;
  if (this->trans_type() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->trans_type(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.TransceiverComponentChangeAttributes)
}

::google::protobuf::uint8* TransceiverComponentChangeAttributes::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.TransceiverComponentChangeAttributes)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // .dmi.TransceiverType trans_type = 1;
  if (this->trans_type() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->trans_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.TransceiverComponentChangeAttributes)
  return target;
}

size_t TransceiverComponentChangeAttributes::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.TransceiverComponentChangeAttributes)
  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.TransceiverType trans_type = 1;
  if (this->trans_type() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->trans_type());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void TransceiverComponentChangeAttributes::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.TransceiverComponentChangeAttributes)
  GOOGLE_DCHECK_NE(&from, this);
  const TransceiverComponentChangeAttributes* source =
      ::google::protobuf::DynamicCastToGenerated<TransceiverComponentChangeAttributes>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.TransceiverComponentChangeAttributes)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.TransceiverComponentChangeAttributes)
    MergeFrom(*source);
  }
}

void TransceiverComponentChangeAttributes::MergeFrom(const TransceiverComponentChangeAttributes& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.TransceiverComponentChangeAttributes)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.trans_type() != 0) {
    set_trans_type(from.trans_type());
  }
}

void TransceiverComponentChangeAttributes::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.TransceiverComponentChangeAttributes)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void TransceiverComponentChangeAttributes::CopyFrom(const TransceiverComponentChangeAttributes& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.TransceiverComponentChangeAttributes)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool TransceiverComponentChangeAttributes::IsInitialized() const {
  return true;
}

void TransceiverComponentChangeAttributes::Swap(TransceiverComponentChangeAttributes* other) {
  if (other == this) return;
  InternalSwap(other);
}
void TransceiverComponentChangeAttributes::InternalSwap(TransceiverComponentChangeAttributes* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  swap(trans_type_, other->trans_type_);
}

::google::protobuf::Metadata TransceiverComponentChangeAttributes::GetMetadata() const {
  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_2eproto);
  return ::file_level_metadata_dmi_2fhw_2eproto[kIndexInFileMessages];
}


// ===================================================================

void PonIdConfig::InitAsDefaultInstance() {
}
class PonIdConfig::HasBitSetters {
 public:
};

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int PonIdConfig::kPonIdFieldNumber;
const int PonIdConfig::kPonIdTransmitPeriodicityFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

PonIdConfig::PonIdConfig()
  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:dmi.PonIdConfig)
}
PonIdConfig::PonIdConfig(const PonIdConfig& from)
  : ::google::protobuf::Message(),
      _internal_metadata_(nullptr) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  pon_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  if (from.pon_id().size() > 0) {
    pon_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.pon_id_);
  }
  pon_id_transmit_periodicity_ = from.pon_id_transmit_periodicity_;
  // @@protoc_insertion_point(copy_constructor:dmi.PonIdConfig)
}

void PonIdConfig::SharedCtor() {
  ::google::protobuf::internal::InitSCC(
      &scc_info_PonIdConfig_dmi_2fhw_2eproto.base);
  pon_id_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  pon_id_transmit_periodicity_ = 0u;
}

PonIdConfig::~PonIdConfig() {
  // @@protoc_insertion_point(destructor:dmi.PonIdConfig)
  SharedDtor();
}

void PonIdConfig::SharedDtor() {
  pon_id_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

void PonIdConfig::SetCachedSize(int size) const {
  _cached_size_.Set(size);
}
const PonIdConfig& PonIdConfig::default_instance() {
  ::google::protobuf::internal::InitSCC(&::scc_info_PonIdConfig_dmi_2fhw_2eproto.base);
  return *internal_default_instance();
}


void PonIdConfig::Clear() {
// @@protoc_insertion_point(message_clear_start:dmi.PonIdConfig)
  ::google::protobuf::uint32 cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  pon_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  pon_id_transmit_periodicity_ = 0u;
  _internal_metadata_.Clear();
}

#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
const char* PonIdConfig::_InternalParse(const char* begin, const char* end, void* object,
                  ::google::protobuf::internal::ParseContext* ctx) {
  auto msg = static_cast<PonIdConfig*>(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) {
      // bytes pon_id = 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);
        object = msg->mutable_pon_id();
        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
          parser_till_end = ::google::protobuf::internal::GreedyStringParser;
          goto string_till_end;
        }
        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheck(ptr, size, ctx));
        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
        ptr += size;
        break;
      }
      // uint32 pon_id_transmit_periodicity = 2;
      case 2: {
        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
        msg->set_pon_id_transmit_periodicity(::google::protobuf::internal::ReadVarint(&ptr));
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        break;
      }
      default: {
      handle_unusual:
        if ((tag & 7) == 4 || tag == 0) {
          ctx->EndGroup(tag);
          return ptr;
        }
        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
        ptr = res.first;
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
        if (res.second) return ptr;
      }
    }  // switch
  }  // while
  return ptr;
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 PonIdConfig::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.PonIdConfig)
  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)) {
      // bytes pon_id = 1;
      case 1: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                input, this->mutable_pon_id()));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // uint32 pon_id_transmit_periodicity = 2;
      case 2: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {

          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
                 input, &pon_id_transmit_periodicity_)));
        } 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.PonIdConfig)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:dmi.PonIdConfig)
  return false;
#undef DO_
}
#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER

void PonIdConfig::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:dmi.PonIdConfig)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // bytes pon_id = 1;
  if (this->pon_id().size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
      1, this->pon_id(), output);
  }

  // uint32 pon_id_transmit_periodicity = 2;
  if (this->pon_id_transmit_periodicity() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->pon_id_transmit_periodicity(), output);
  }

  if (_internal_metadata_.have_unknown_fields()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        _internal_metadata_.unknown_fields(), output);
  }
  // @@protoc_insertion_point(serialize_end:dmi.PonIdConfig)
}

::google::protobuf::uint8* PonIdConfig::InternalSerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // @@protoc_insertion_point(serialize_to_array_start:dmi.PonIdConfig)
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  // bytes pon_id = 1;
  if (this->pon_id().size() > 0) {
    target =
      ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
        1, this->pon_id(), target);
  }

  // uint32 pon_id_transmit_periodicity = 2;
  if (this->pon_id_transmit_periodicity() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->pon_id_transmit_periodicity(), 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.PonIdConfig)
  return target;
}

size_t PonIdConfig::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:dmi.PonIdConfig)
  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;

  // bytes pon_id = 1;
  if (this->pon_id().size() > 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::BytesSize(
        this->pon_id());
  }

  // uint32 pon_id_transmit_periodicity = 2;
  if (this->pon_id_transmit_periodicity() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::UInt32Size(
        this->pon_id_transmit_periodicity());
  }

  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
  SetCachedSize(cached_size);
  return total_size;
}

void PonIdConfig::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:dmi.PonIdConfig)
  GOOGLE_DCHECK_NE(&from, this);
  const PonIdConfig* source =
      ::google::protobuf::DynamicCastToGenerated<PonIdConfig>(
          &from);
  if (source == nullptr) {
  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.PonIdConfig)
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.PonIdConfig)
    MergeFrom(*source);
  }
}

void PonIdConfig::MergeFrom(const PonIdConfig& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:dmi.PonIdConfig)
  GOOGLE_DCHECK_NE(&from, this);
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::google::protobuf::uint32 cached_has_bits = 0;
  (void) cached_has_bits;

  if (from.pon_id().size() > 0) {

    pon_id_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.pon_id_);
  }
  if (from.pon_id_transmit_periodicity() != 0) {
    set_pon_id_transmit_periodicity(from.pon_id_transmit_periodicity());
  }
}

void PonIdConfig::CopyFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_copy_from_start:dmi.PonIdConfig)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void PonIdConfig::CopyFrom(const PonIdConfig& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:dmi.PonIdConfig)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool PonIdConfig::IsInitialized() const {
  return true;
}

void PonIdConfig::Swap(PonIdConfig* other) {
  if (other == this) return;
  InternalSwap(other);
}
void PonIdConfig::InternalSwap(PonIdConfig* other) {
  using std::swap;
  _internal_metadata_.Swap(&other->_internal_metadata_);
  pon_id_.Swap(&other->pon_id_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
    GetArenaNoVirtual());
  swap(pon_id_transmit_periodicity_, other->pon_id_transmit_periodicity_);
}

::google::protobuf::Metadata PonIdConfig::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;
const int TransceiverComponentsAttributes::kTxPowerFieldNumber;
const int TransceiverComponentsAttributes::kTxPowerScaleFieldNumber;
#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_),
      tx_power_(from.tx_power_) {
  _internal_metadata_.MergeFrom(from._internal_metadata_);
  ::memcpy(&form_factor_, &from.form_factor_,
    static_cast<size_t>(reinterpret_cast<char*>(&tx_power_scale_) -
    reinterpret_cast<char*>(&form_factor_)) + sizeof(tx_power_scale_));
  // @@protoc_insertion_point(copy_constructor:dmi.TransceiverComponentsAttributes)
}

void TransceiverComponentsAttributes::SharedCtor() {
  ::memset(&form_factor_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&tx_power_scale_) -
      reinterpret_cast<char*>(&form_factor_)) + sizeof(tx_power_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();
  tx_power_.Clear();
  ::memset(&form_factor_, 0, static_cast<size_t>(
      reinterpret_cast<char*>(&tx_power_scale_) -
      reinterpret_cast<char*>(&form_factor_)) + sizeof(tx_power_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.TransceiverType 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::TransceiverType>(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;
      }
      // repeated int32 tx_power = 8;
      case 8: {
        if (static_cast<::google::protobuf::uint8>(tag) == 66) {
          ptr = ::google::protobuf::io::ReadSize(ptr, &size);
          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
          parser_till_end = ::google::protobuf::internal::PackedInt32Parser;
          object = msg->mutable_tx_power();
          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) != 64) goto handle_unusual;
        do {
          msg->add_tx_power(::google::protobuf::internal::ReadVarint(&ptr));
          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
          if (ptr >= end) break;
        } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 64 && (ptr += 1));
        break;
      }
      // .dmi.ValueScale tx_power_scale = 9;
      case 9: {
        if (static_cast<::google::protobuf::uint8>(tag) != 72) goto handle_unusual;
        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
        msg->set_tx_power_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.TransceiverType 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::TransceiverType >(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;
      }

      // repeated int32 tx_power = 8;
      case 8: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (66 & 0xFF)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_tx_power())));
        } else if (static_cast< ::google::protobuf::uint8>(tag) == (64 & 0xFF)) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 66u, input, this->mutable_tx_power())));
        } else {
          goto handle_unusual;
        }
        break;
      }

      // .dmi.ValueScale tx_power_scale = 9;
      case 9: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (72 & 0xFF)) {
          int value = 0;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          set_tx_power_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.TransceiverType 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);
  }

  // repeated int32 tx_power = 8;
  if (this->tx_power_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(8, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_tx_power_cached_byte_size_.load(
        std::memory_order_relaxed));
  }
  for (int i = 0, n = this->tx_power_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
      this->tx_power(i), output);
  }

  // .dmi.ValueScale tx_power_scale = 9;
  if (this->tx_power_scale() != 0) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      9, this->tx_power_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.TransceiverType 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);
  }

  // repeated int32 tx_power = 8;
  if (this->tx_power_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      8,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
        _tx_power_cached_byte_size_.load(std::memory_order_relaxed),
         target);
    target = ::google::protobuf::internal::WireFormatLite::
      WriteInt32NoTagToArray(this->tx_power_, target);
  }

  // .dmi.ValueScale tx_power_scale = 9;
  if (this->tx_power_scale() != 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      9, this->tx_power_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;
  }

  // repeated int32 tx_power = 8;
  {
    size_t data_size = ::google::protobuf::internal::WireFormatLite::
      Int32Size(this->tx_power_);
    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_power_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.TransceiverType 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());
  }

  // .dmi.ValueScale tx_power_scale = 9;
  if (this->tx_power_scale() != 0) {
    total_size += 1 +
      ::google::protobuf::internal::WireFormatLite::EnumSize(this->tx_power_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_);
  tx_power_.MergeFrom(from.tx_power_);
  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());
  }
  if (from.tx_power_scale() != 0) {
    set_tx_power_scale(from.tx_power_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_);
  tx_power_.InternalSwap(&other->tx_power_);
  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_);
  swap(tx_power_scale_, other->tx_power_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());
  ::dmi::_ModifiableComponent_default_instance_.port_attr_ = const_cast< ::dmi::PortComponentChangeAttributes*>(
      ::dmi::PortComponentChangeAttributes::internal_default_instance());
  ::dmi::_ModifiableComponent_default_instance_.trx_attr_ = const_cast< ::dmi::TransceiverComponentChangeAttributes*>(
      ::dmi::TransceiverComponentChangeAttributes::internal_default_instance());
}
class ModifiableComponent::HasBitSetters {
 public:
  static const ::dmi::Component& parent(const ModifiableComponent* msg);
  static const ::dmi::Uri& uri(const ModifiableComponent* msg);
  static const ::dmi::PortComponentChangeAttributes& port_attr(const ModifiableComponent* msg);
  static const ::dmi::TransceiverComponentChangeAttributes& trx_attr(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_;
}
const ::dmi::PortComponentChangeAttributes&
ModifiableComponent::HasBitSetters::port_attr(const ModifiableComponent* msg) {
  return *msg->specific_.port_attr_;
}
const ::dmi::TransceiverComponentChangeAttributes&
ModifiableComponent::HasBitSetters::trx_attr(const ModifiableComponent* msg) {
  return *msg->specific_.trx_attr_;
}
void ModifiableComponent::set_allocated_port_attr(::dmi::PortComponentChangeAttributes* 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.ModifiableComponent.port_attr)
}
void ModifiableComponent::set_allocated_trx_attr(::dmi::TransceiverComponentChangeAttributes* trx_attr) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  clear_specific();
  if (trx_attr) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      trx_attr = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, trx_attr, submessage_arena);
    }
    set_has_trx_attr();
    specific_.trx_attr_ = trx_attr;
  }
  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.trx_attr)
}
#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;
const int ModifiableComponent::kPortAttrFieldNumber;
const int ModifiableComponent::kTrxAttrFieldNumber;
#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_));
  clear_has_specific();
  switch (from.specific_case()) {
    case kPortAttr: {
      mutable_port_attr()->::dmi::PortComponentChangeAttributes::MergeFrom(from.port_attr());
      break;
    }
    case kTrxAttr: {
      mutable_trx_attr()->::dmi::TransceiverComponentChangeAttributes::MergeFrom(from.trx_attr());
      break;
    }
    case SPECIFIC_NOT_SET: {
      break;
    }
  }
  // @@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_));
  clear_has_specific();
}

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_;
  if (has_specific()) {
    clear_specific();
  }
}

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_specific() {
// @@protoc_insertion_point(one_of_clear_start:dmi.ModifiableComponent)
  switch (specific_case()) {
    case kPortAttr: {
      delete specific_.port_attr_;
      break;
    }
    case kTrxAttr: {
      delete specific_.trx_attr_;
      break;
    }
    case SPECIFIC_NOT_SET: {
      break;
    }
  }
  _oneof_case_[0] = SPECIFIC_NOT_SET;
}


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_));
  clear_specific();
  _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;
      }
      // .dmi.PortComponentChangeAttributes 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::PortComponentChangeAttributes::_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.TransceiverComponentChangeAttributes trx_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::TransceiverComponentChangeAttributes::_InternalParse;
        object = msg->mutable_trx_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 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(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.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;
      }

      // .dmi.PortComponentChangeAttributes 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.TransceiverComponentChangeAttributes trx_attr = 51;
      case 51: {
        if (static_cast< ::google::protobuf::uint8>(tag) == (410 & 0xFF)) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
               input, mutable_trx_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.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);
  }

  // .dmi.PortComponentChangeAttributes port_attr = 50;
  if (has_port_attr()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      50, HasBitSetters::port_attr(this), output);
  }

  // .dmi.TransceiverComponentChangeAttributes trx_attr = 51;
  if (has_trx_attr()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      51, HasBitSetters::trx_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.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);
  }

  // .dmi.PortComponentChangeAttributes port_attr = 50;
  if (has_port_attr()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        50, HasBitSetters::port_attr(this), target);
  }

  // .dmi.TransceiverComponentChangeAttributes trx_attr = 51;
  if (has_trx_attr()) {
    target = ::google::protobuf::internal::WireFormatLite::
      InternalWriteMessageToArray(
        51, HasBitSetters::trx_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.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());
  }

  switch (specific_case()) {
    // .dmi.PortComponentChangeAttributes port_attr = 50;
    case kPortAttr: {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *specific_.port_attr_);
      break;
    }
    // .dmi.TransceiverComponentChangeAttributes trx_attr = 51;
    case kTrxAttr: {
      total_size += 2 +
        ::google::protobuf::internal::WireFormatLite::MessageSize(
          *specific_.trx_attr_);
      break;
    }
    case SPECIFIC_NOT_SET: {
      break;
    }
  }
  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());
  }
  switch (from.specific_case()) {
    case kPortAttr: {
      mutable_port_attr()->::dmi::PortComponentChangeAttributes::MergeFrom(from.port_attr());
      break;
    }
    case kTrxAttr: {
      mutable_trx_attr()->::dmi::TransceiverComponentChangeAttributes::MergeFrom(from.trx_attr());
      break;
    }
    case SPECIFIC_NOT_SET: {
      break;
    }
  }
}

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_);
  swap(specific_, other->specific_);
  swap(_oneof_case_[0], other->_oneof_case_[0]);
}

::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::PonDistance* Arena::CreateMaybeMessage< ::dmi::PonDistance >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::PonDistance >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::PortComponentChangeAttributes* Arena::CreateMaybeMessage< ::dmi::PortComponentChangeAttributes >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::PortComponentChangeAttributes >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::TransceiverComponentChangeAttributes* Arena::CreateMaybeMessage< ::dmi::TransceiverComponentChangeAttributes >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::TransceiverComponentChangeAttributes >(arena);
}
template<> PROTOBUF_NOINLINE ::dmi::PonIdConfig* Arena::CreateMaybeMessage< ::dmi::PonIdConfig >(Arena* arena) {
  return Arena::CreateInternal< ::dmi::PonIdConfig >(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>
