// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: dmi/hw.proto

#ifndef PROTOBUF_INCLUDED_dmi_2fhw_2eproto
#define PROTOBUF_INCLUDED_dmi_2fhw_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3007000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3007000 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/inlined_string_field.h>
#include <google/protobuf/metadata.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
#include <google/protobuf/extension_set.h>  // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/timestamp.pb.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto

// Internal implementation detail -- do not use these members.
struct TableStruct_dmi_2fhw_2eproto {
  static const ::google::protobuf::internal::ParseTableField entries[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::ParseTable schema[12]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::FieldMetadata field_metadata[];
  static const ::google::protobuf::internal::SerializationTable serialization_table[];
  static const ::google::protobuf::uint32 offsets[];
};
void AddDescriptors_dmi_2fhw_2eproto();
namespace dmi {
class Component;
class ComponentDefaultTypeInternal;
extern ComponentDefaultTypeInternal _Component_default_instance_;
class ComponentSensorData;
class ComponentSensorDataDefaultTypeInternal;
extern ComponentSensorDataDefaultTypeInternal _ComponentSensorData_default_instance_;
class ComponentState;
class ComponentStateDefaultTypeInternal;
extern ComponentStateDefaultTypeInternal _ComponentState_default_instance_;
class ContainerComponentAttributes;
class ContainerComponentAttributesDefaultTypeInternal;
extern ContainerComponentAttributesDefaultTypeInternal _ContainerComponentAttributes_default_instance_;
class Hardware;
class HardwareDefaultTypeInternal;
extern HardwareDefaultTypeInternal _Hardware_default_instance_;
class HardwareID;
class HardwareIDDefaultTypeInternal;
extern HardwareIDDefaultTypeInternal _HardwareID_default_instance_;
class ModifiableComponent;
class ModifiableComponentDefaultTypeInternal;
extern ModifiableComponentDefaultTypeInternal _ModifiableComponent_default_instance_;
class PortComponentAttributes;
class PortComponentAttributesDefaultTypeInternal;
extern PortComponentAttributesDefaultTypeInternal _PortComponentAttributes_default_instance_;
class PsuComponentAttributes;
class PsuComponentAttributesDefaultTypeInternal;
extern PsuComponentAttributesDefaultTypeInternal _PsuComponentAttributes_default_instance_;
class TransceiverComponentsAttributes;
class TransceiverComponentsAttributesDefaultTypeInternal;
extern TransceiverComponentsAttributesDefaultTypeInternal _TransceiverComponentsAttributes_default_instance_;
class Uri;
class UriDefaultTypeInternal;
extern UriDefaultTypeInternal _Uri_default_instance_;
class Uuid;
class UuidDefaultTypeInternal;
extern UuidDefaultTypeInternal _Uuid_default_instance_;
}  // namespace dmi
namespace google {
namespace protobuf {
template<> ::dmi::Component* Arena::CreateMaybeMessage<::dmi::Component>(Arena*);
template<> ::dmi::ComponentSensorData* Arena::CreateMaybeMessage<::dmi::ComponentSensorData>(Arena*);
template<> ::dmi::ComponentState* Arena::CreateMaybeMessage<::dmi::ComponentState>(Arena*);
template<> ::dmi::ContainerComponentAttributes* Arena::CreateMaybeMessage<::dmi::ContainerComponentAttributes>(Arena*);
template<> ::dmi::Hardware* Arena::CreateMaybeMessage<::dmi::Hardware>(Arena*);
template<> ::dmi::HardwareID* Arena::CreateMaybeMessage<::dmi::HardwareID>(Arena*);
template<> ::dmi::ModifiableComponent* Arena::CreateMaybeMessage<::dmi::ModifiableComponent>(Arena*);
template<> ::dmi::PortComponentAttributes* Arena::CreateMaybeMessage<::dmi::PortComponentAttributes>(Arena*);
template<> ::dmi::PsuComponentAttributes* Arena::CreateMaybeMessage<::dmi::PsuComponentAttributes>(Arena*);
template<> ::dmi::TransceiverComponentsAttributes* Arena::CreateMaybeMessage<::dmi::TransceiverComponentsAttributes>(Arena*);
template<> ::dmi::Uri* Arena::CreateMaybeMessage<::dmi::Uri>(Arena*);
template<> ::dmi::Uuid* Arena::CreateMaybeMessage<::dmi::Uuid>(Arena*);
}  // namespace protobuf
}  // namespace google
namespace dmi {

enum PortComponentAttributes_ConnectorType {
  PortComponentAttributes_ConnectorType_CONNECTOR_TYPE_UNDEFINED = 0,
  PortComponentAttributes_ConnectorType_RJ45 = 1,
  PortComponentAttributes_ConnectorType_FIBER_LC = 2,
  PortComponentAttributes_ConnectorType_FIBER_SC_PC = 3,
  PortComponentAttributes_ConnectorType_FIBER_MPO = 4,
  PortComponentAttributes_ConnectorType_RS232 = 5,
  PortComponentAttributes_ConnectorType_PortComponentAttributes_ConnectorType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  PortComponentAttributes_ConnectorType_PortComponentAttributes_ConnectorType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool PortComponentAttributes_ConnectorType_IsValid(int value);
const PortComponentAttributes_ConnectorType PortComponentAttributes_ConnectorType_ConnectorType_MIN = PortComponentAttributes_ConnectorType_CONNECTOR_TYPE_UNDEFINED;
const PortComponentAttributes_ConnectorType PortComponentAttributes_ConnectorType_ConnectorType_MAX = PortComponentAttributes_ConnectorType_RS232;
const int PortComponentAttributes_ConnectorType_ConnectorType_ARRAYSIZE = PortComponentAttributes_ConnectorType_ConnectorType_MAX + 1;

const ::google::protobuf::EnumDescriptor* PortComponentAttributes_ConnectorType_descriptor();
inline const ::std::string& PortComponentAttributes_ConnectorType_Name(PortComponentAttributes_ConnectorType value) {
  return ::google::protobuf::internal::NameOfEnum(
    PortComponentAttributes_ConnectorType_descriptor(), value);
}
inline bool PortComponentAttributes_ConnectorType_Parse(
    const ::std::string& name, PortComponentAttributes_ConnectorType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<PortComponentAttributes_ConnectorType>(
    PortComponentAttributes_ConnectorType_descriptor(), name, value);
}
enum PortComponentAttributes_Speed {
  PortComponentAttributes_Speed_SPEED_UNDEFINED = 0,
  PortComponentAttributes_Speed_DYNAMIC = 1,
  PortComponentAttributes_Speed_GIGABIT_1 = 2,
  PortComponentAttributes_Speed_GIGABIT_10 = 3,
  PortComponentAttributes_Speed_GIGABIT_25 = 4,
  PortComponentAttributes_Speed_GIGABIT_40 = 5,
  PortComponentAttributes_Speed_GIGABIT_100 = 6,
  PortComponentAttributes_Speed_GIGABIT_400 = 7,
  PortComponentAttributes_Speed_MEGABIT_2500 = 8,
  PortComponentAttributes_Speed_MEGABIT_1250 = 9,
  PortComponentAttributes_Speed_PortComponentAttributes_Speed_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  PortComponentAttributes_Speed_PortComponentAttributes_Speed_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool PortComponentAttributes_Speed_IsValid(int value);
const PortComponentAttributes_Speed PortComponentAttributes_Speed_Speed_MIN = PortComponentAttributes_Speed_SPEED_UNDEFINED;
const PortComponentAttributes_Speed PortComponentAttributes_Speed_Speed_MAX = PortComponentAttributes_Speed_MEGABIT_1250;
const int PortComponentAttributes_Speed_Speed_ARRAYSIZE = PortComponentAttributes_Speed_Speed_MAX + 1;

const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Speed_descriptor();
inline const ::std::string& PortComponentAttributes_Speed_Name(PortComponentAttributes_Speed value) {
  return ::google::protobuf::internal::NameOfEnum(
    PortComponentAttributes_Speed_descriptor(), value);
}
inline bool PortComponentAttributes_Speed_Parse(
    const ::std::string& name, PortComponentAttributes_Speed* value) {
  return ::google::protobuf::internal::ParseNamedEnum<PortComponentAttributes_Speed>(
    PortComponentAttributes_Speed_descriptor(), name, value);
}
enum PortComponentAttributes_Protocol {
  PortComponentAttributes_Protocol_PROTOCOL_UNDEFINED = 0,
  PortComponentAttributes_Protocol_ETHERNET = 1,
  PortComponentAttributes_Protocol_GPON = 2,
  PortComponentAttributes_Protocol_XGPON = 3,
  PortComponentAttributes_Protocol_XGSPON = 4,
  PortComponentAttributes_Protocol_GFAST = 5,
  PortComponentAttributes_Protocol_SERIAL = 6,
  PortComponentAttributes_Protocol_EPON = 7,
  PortComponentAttributes_Protocol_BITS = 8,
  PortComponentAttributes_Protocol_PortComponentAttributes_Protocol_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  PortComponentAttributes_Protocol_PortComponentAttributes_Protocol_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool PortComponentAttributes_Protocol_IsValid(int value);
const PortComponentAttributes_Protocol PortComponentAttributes_Protocol_Protocol_MIN = PortComponentAttributes_Protocol_PROTOCOL_UNDEFINED;
const PortComponentAttributes_Protocol PortComponentAttributes_Protocol_Protocol_MAX = PortComponentAttributes_Protocol_BITS;
const int PortComponentAttributes_Protocol_Protocol_ARRAYSIZE = PortComponentAttributes_Protocol_Protocol_MAX + 1;

const ::google::protobuf::EnumDescriptor* PortComponentAttributes_Protocol_descriptor();
inline const ::std::string& PortComponentAttributes_Protocol_Name(PortComponentAttributes_Protocol value) {
  return ::google::protobuf::internal::NameOfEnum(
    PortComponentAttributes_Protocol_descriptor(), value);
}
inline bool PortComponentAttributes_Protocol_Parse(
    const ::std::string& name, PortComponentAttributes_Protocol* value) {
  return ::google::protobuf::internal::ParseNamedEnum<PortComponentAttributes_Protocol>(
    PortComponentAttributes_Protocol_descriptor(), name, value);
}
enum PsuComponentAttributes_SupportedVoltage {
  PsuComponentAttributes_SupportedVoltage_SUPPORTED_VOLTAGE_UNDEFINED = 0,
  PsuComponentAttributes_SupportedVoltage_V48 = 1,
  PsuComponentAttributes_SupportedVoltage_V230 = 2,
  PsuComponentAttributes_SupportedVoltage_V115 = 3,
  PsuComponentAttributes_SupportedVoltage_PsuComponentAttributes_SupportedVoltage_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  PsuComponentAttributes_SupportedVoltage_PsuComponentAttributes_SupportedVoltage_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool PsuComponentAttributes_SupportedVoltage_IsValid(int value);
const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MIN = PsuComponentAttributes_SupportedVoltage_SUPPORTED_VOLTAGE_UNDEFINED;
const PsuComponentAttributes_SupportedVoltage PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MAX = PsuComponentAttributes_SupportedVoltage_V115;
const int PsuComponentAttributes_SupportedVoltage_SupportedVoltage_ARRAYSIZE = PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MAX + 1;

const ::google::protobuf::EnumDescriptor* PsuComponentAttributes_SupportedVoltage_descriptor();
inline const ::std::string& PsuComponentAttributes_SupportedVoltage_Name(PsuComponentAttributes_SupportedVoltage value) {
  return ::google::protobuf::internal::NameOfEnum(
    PsuComponentAttributes_SupportedVoltage_descriptor(), value);
}
inline bool PsuComponentAttributes_SupportedVoltage_Parse(
    const ::std::string& name, PsuComponentAttributes_SupportedVoltage* value) {
  return ::google::protobuf::internal::ParseNamedEnum<PsuComponentAttributes_SupportedVoltage>(
    PsuComponentAttributes_SupportedVoltage_descriptor(), name, value);
}
enum TransceiverComponentsAttributes_FormFactor {
  TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN = 0,
  TransceiverComponentsAttributes_FormFactor_QSFP = 1,
  TransceiverComponentsAttributes_FormFactor_QSFP_PLUS = 2,
  TransceiverComponentsAttributes_FormFactor_QSFP28 = 3,
  TransceiverComponentsAttributes_FormFactor_SFP = 4,
  TransceiverComponentsAttributes_FormFactor_SFP_PLUS = 5,
  TransceiverComponentsAttributes_FormFactor_XFP = 6,
  TransceiverComponentsAttributes_FormFactor_CFP4 = 7,
  TransceiverComponentsAttributes_FormFactor_CFP2 = 8,
  TransceiverComponentsAttributes_FormFactor_CPAK = 9,
  TransceiverComponentsAttributes_FormFactor_X2 = 10,
  TransceiverComponentsAttributes_FormFactor_OTHER = 11,
  TransceiverComponentsAttributes_FormFactor_CFP = 12,
  TransceiverComponentsAttributes_FormFactor_CFP2_ACO = 13,
  TransceiverComponentsAttributes_FormFactor_CFP2_DCO = 14,
  TransceiverComponentsAttributes_FormFactor_TransceiverComponentsAttributes_FormFactor_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  TransceiverComponentsAttributes_FormFactor_TransceiverComponentsAttributes_FormFactor_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool TransceiverComponentsAttributes_FormFactor_IsValid(int value);
const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes_FormFactor_FormFactor_MIN = TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN;
const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes_FormFactor_FormFactor_MAX = TransceiverComponentsAttributes_FormFactor_CFP2_DCO;
const int TransceiverComponentsAttributes_FormFactor_FormFactor_ARRAYSIZE = TransceiverComponentsAttributes_FormFactor_FormFactor_MAX + 1;

const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_FormFactor_descriptor();
inline const ::std::string& TransceiverComponentsAttributes_FormFactor_Name(TransceiverComponentsAttributes_FormFactor value) {
  return ::google::protobuf::internal::NameOfEnum(
    TransceiverComponentsAttributes_FormFactor_descriptor(), value);
}
inline bool TransceiverComponentsAttributes_FormFactor_Parse(
    const ::std::string& name, TransceiverComponentsAttributes_FormFactor* value) {
  return ::google::protobuf::internal::ParseNamedEnum<TransceiverComponentsAttributes_FormFactor>(
    TransceiverComponentsAttributes_FormFactor_descriptor(), name, value);
}
enum TransceiverComponentsAttributes_Type {
  TransceiverComponentsAttributes_Type_TYPE_UNKNOWN = 0,
  TransceiverComponentsAttributes_Type_ETHERNET = 1,
  TransceiverComponentsAttributes_Type_GPON = 2,
  TransceiverComponentsAttributes_Type_XGPON = 3,
  TransceiverComponentsAttributes_Type_XGSPON = 4,
  TransceiverComponentsAttributes_Type_CPON = 5,
  TransceiverComponentsAttributes_Type_NG_PON2 = 6,
  TransceiverComponentsAttributes_Type_EPON = 7,
  TransceiverComponentsAttributes_Type_TransceiverComponentsAttributes_Type_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  TransceiverComponentsAttributes_Type_TransceiverComponentsAttributes_Type_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool TransceiverComponentsAttributes_Type_IsValid(int value);
const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes_Type_Type_MIN = TransceiverComponentsAttributes_Type_TYPE_UNKNOWN;
const TransceiverComponentsAttributes_Type TransceiverComponentsAttributes_Type_Type_MAX = TransceiverComponentsAttributes_Type_EPON;
const int TransceiverComponentsAttributes_Type_Type_ARRAYSIZE = TransceiverComponentsAttributes_Type_Type_MAX + 1;

const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_Type_descriptor();
inline const ::std::string& TransceiverComponentsAttributes_Type_Name(TransceiverComponentsAttributes_Type value) {
  return ::google::protobuf::internal::NameOfEnum(
    TransceiverComponentsAttributes_Type_descriptor(), value);
}
inline bool TransceiverComponentsAttributes_Type_Parse(
    const ::std::string& name, TransceiverComponentsAttributes_Type* value) {
  return ::google::protobuf::internal::ParseNamedEnum<TransceiverComponentsAttributes_Type>(
    TransceiverComponentsAttributes_Type_descriptor(), name, value);
}
enum ComponentType {
  COMPONENT_TYPE_UNDEFINED = 0,
  COMPONENT_TYPE_UNKNOWN = 1,
  COMPONENT_TYPE_CHASSIS = 2,
  COMPONENT_TYPE_BACKPLANE = 3,
  COMPONENT_TYPE_CONTAINER = 4,
  COMPONENT_TYPE_POWER_SUPPLY = 5,
  COMPONENT_TYPE_FAN = 6,
  COMPONENT_TYPE_SENSOR = 7,
  COMPONENT_TYPE_MODULE = 8,
  COMPONENT_TYPE_PORT = 9,
  COMPONENT_TYPE_CPU = 10,
  COMPONENT_TYPE_BATTERY = 11,
  COMPONENT_TYPE_STORAGE = 12,
  COMPONENT_TYPE_MEMORY = 13,
  COMPONENT_TYPE_TRANSCEIVER = 14,
  ComponentType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ComponentType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ComponentType_IsValid(int value);
const ComponentType ComponentType_MIN = COMPONENT_TYPE_UNDEFINED;
const ComponentType ComponentType_MAX = COMPONENT_TYPE_TRANSCEIVER;
const int ComponentType_ARRAYSIZE = ComponentType_MAX + 1;

const ::google::protobuf::EnumDescriptor* ComponentType_descriptor();
inline const ::std::string& ComponentType_Name(ComponentType value) {
  return ::google::protobuf::internal::NameOfEnum(
    ComponentType_descriptor(), value);
}
inline bool ComponentType_Parse(
    const ::std::string& name, ComponentType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ComponentType>(
    ComponentType_descriptor(), name, value);
}
enum ComponentAdminState {
  COMP_ADMIN_STATE_UNDEFINED = 0,
  COMP_ADMIN_STATE_UNKNOWN = 1,
  COMP_ADMIN_STATE_LOCKED = 2,
  COMP_ADMIN_STATE_SHUTTING_DOWN = 3,
  COMP_ADMIN_STATE_UNLOCKED = 4,
  ComponentAdminState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ComponentAdminState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ComponentAdminState_IsValid(int value);
const ComponentAdminState ComponentAdminState_MIN = COMP_ADMIN_STATE_UNDEFINED;
const ComponentAdminState ComponentAdminState_MAX = COMP_ADMIN_STATE_UNLOCKED;
const int ComponentAdminState_ARRAYSIZE = ComponentAdminState_MAX + 1;

const ::google::protobuf::EnumDescriptor* ComponentAdminState_descriptor();
inline const ::std::string& ComponentAdminState_Name(ComponentAdminState value) {
  return ::google::protobuf::internal::NameOfEnum(
    ComponentAdminState_descriptor(), value);
}
inline bool ComponentAdminState_Parse(
    const ::std::string& name, ComponentAdminState* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ComponentAdminState>(
    ComponentAdminState_descriptor(), name, value);
}
enum ComponentOperState {
  COMP_OPER_STATE_UNDEFINED = 0,
  COMP_OPER_STATE_UNKNOWN = 1,
  COMP_OPER_STATE_DISABLED = 2,
  COMP_OPER_STATE_ENABLED = 3,
  COMP_OPER_STATE_TESTING = 4,
  ComponentOperState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ComponentOperState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ComponentOperState_IsValid(int value);
const ComponentOperState ComponentOperState_MIN = COMP_OPER_STATE_UNDEFINED;
const ComponentOperState ComponentOperState_MAX = COMP_OPER_STATE_TESTING;
const int ComponentOperState_ARRAYSIZE = ComponentOperState_MAX + 1;

const ::google::protobuf::EnumDescriptor* ComponentOperState_descriptor();
inline const ::std::string& ComponentOperState_Name(ComponentOperState value) {
  return ::google::protobuf::internal::NameOfEnum(
    ComponentOperState_descriptor(), value);
}
inline bool ComponentOperState_Parse(
    const ::std::string& name, ComponentOperState* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ComponentOperState>(
    ComponentOperState_descriptor(), name, value);
}
enum ComponentUsageState {
  COMP_USAGE_STATE_UNDEFINED = 0,
  COMP_USAGE_STATE_UNKNOWN = 1,
  COMP_USAGE_STATE_IDLE = 2,
  COMP_USAGE_STATE_ACTIVE = 3,
  COMP_USAGE_STATE_BUSY = 4,
  ComponentUsageState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ComponentUsageState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ComponentUsageState_IsValid(int value);
const ComponentUsageState ComponentUsageState_MIN = COMP_USAGE_STATE_UNDEFINED;
const ComponentUsageState ComponentUsageState_MAX = COMP_USAGE_STATE_BUSY;
const int ComponentUsageState_ARRAYSIZE = ComponentUsageState_MAX + 1;

const ::google::protobuf::EnumDescriptor* ComponentUsageState_descriptor();
inline const ::std::string& ComponentUsageState_Name(ComponentUsageState value) {
  return ::google::protobuf::internal::NameOfEnum(
    ComponentUsageState_descriptor(), value);
}
inline bool ComponentUsageState_Parse(
    const ::std::string& name, ComponentUsageState* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ComponentUsageState>(
    ComponentUsageState_descriptor(), name, value);
}
enum ComponentAlarmState {
  COMP_ALARM_STATE_UNDEFINED = 0,
  COMP_ALARM_STATE_UNKNOWN = 1,
  COMP_ALARM_STATE_UNDER_REPAIR = 2,
  COMP_ALARM_STATE_CRITICAL = 3,
  COMP_ALARM_STATE_MAJOR = 4,
  COMP_ALARM_STATE_MINOR = 5,
  COMP_ALARM_STATE_WARNING = 6,
  COMP_ALARM_STATE_INDETERMINATE = 7,
  ComponentAlarmState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ComponentAlarmState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ComponentAlarmState_IsValid(int value);
const ComponentAlarmState ComponentAlarmState_MIN = COMP_ALARM_STATE_UNDEFINED;
const ComponentAlarmState ComponentAlarmState_MAX = COMP_ALARM_STATE_INDETERMINATE;
const int ComponentAlarmState_ARRAYSIZE = ComponentAlarmState_MAX + 1;

const ::google::protobuf::EnumDescriptor* ComponentAlarmState_descriptor();
inline const ::std::string& ComponentAlarmState_Name(ComponentAlarmState value) {
  return ::google::protobuf::internal::NameOfEnum(
    ComponentAlarmState_descriptor(), value);
}
inline bool ComponentAlarmState_Parse(
    const ::std::string& name, ComponentAlarmState* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ComponentAlarmState>(
    ComponentAlarmState_descriptor(), name, value);
}
enum ComponentStandbyState {
  COMP_STANDBY_STATE_UNDEFINED = 0,
  COMP_STANDBY_STATE_UNKNOWN = 1,
  COMP_STANDBY_STATE_HOT = 2,
  COMP_STANDBY_STATE_COLD = 3,
  COMP_STANDBY_STATE_PROVIDING_SERVICE = 4,
  ComponentStandbyState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ComponentStandbyState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ComponentStandbyState_IsValid(int value);
const ComponentStandbyState ComponentStandbyState_MIN = COMP_STANDBY_STATE_UNDEFINED;
const ComponentStandbyState ComponentStandbyState_MAX = COMP_STANDBY_STATE_PROVIDING_SERVICE;
const int ComponentStandbyState_ARRAYSIZE = ComponentStandbyState_MAX + 1;

const ::google::protobuf::EnumDescriptor* ComponentStandbyState_descriptor();
inline const ::std::string& ComponentStandbyState_Name(ComponentStandbyState value) {
  return ::google::protobuf::internal::NameOfEnum(
    ComponentStandbyState_descriptor(), value);
}
inline bool ComponentStandbyState_Parse(
    const ::std::string& name, ComponentStandbyState* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ComponentStandbyState>(
    ComponentStandbyState_descriptor(), name, value);
}
enum DataValueType {
  VALUE_TYPE_UNDEFINED = 0,
  VALUE_TYPE_OTHER = 1,
  VALUE_TYPE_UNKNOWN = 2,
  VALUE_TYPE_VOLTS_AC = 3,
  VALUE_TYPE_VOLTS_DC = 4,
  VALUE_TYPE_AMPERES = 5,
  VALUE_TYPE_WATTS = 6,
  VALUE_TYPE_HERTZ = 7,
  VALUE_TYPE_CELSIUS = 8,
  VALUE_TYPE_PERCENT_RH = 9,
  VALUE_TYPE_RPM = 10,
  VALUE_TYPE_CMM = 11,
  VALUE_TYPE_TRUTH_VALUE = 12,
  VALUE_TYPE_PERCENT = 13,
  VALUE_TYPE_METERS = 14,
  VALUE_TYPE_BYTES = 15,
  DataValueType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  DataValueType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool DataValueType_IsValid(int value);
const DataValueType DataValueType_MIN = VALUE_TYPE_UNDEFINED;
const DataValueType DataValueType_MAX = VALUE_TYPE_BYTES;
const int DataValueType_ARRAYSIZE = DataValueType_MAX + 1;

const ::google::protobuf::EnumDescriptor* DataValueType_descriptor();
inline const ::std::string& DataValueType_Name(DataValueType value) {
  return ::google::protobuf::internal::NameOfEnum(
    DataValueType_descriptor(), value);
}
inline bool DataValueType_Parse(
    const ::std::string& name, DataValueType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<DataValueType>(
    DataValueType_descriptor(), name, value);
}
enum ValueScale {
  VALUE_SCALE_UNDEFINED = 0,
  VALUE_SCALE_YOCTO = 1,
  VALUE_SCALE_ZEPTO = 2,
  VALUE_SCALE_ATTO = 3,
  VALUE_SCALE_FEMTO = 4,
  VALUE_SCALE_PICO = 5,
  VALUE_SCALE_NANO = 6,
  VALUE_SCALE_MICRO = 7,
  VALUE_SCALE_MILLI = 8,
  VALUE_SCALE_UNITS = 9,
  VALUE_SCALE_KILO = 10,
  VALUE_SCALE_MEGA = 11,
  VALUE_SCALE_GIGA = 12,
  VALUE_SCALE_TERA = 13,
  VALUE_SCALE_PETA = 14,
  VALUE_SCALE_EXA = 15,
  VALUE_SCALE_ZETTA = 16,
  VALUE_SCALE_YOTTA = 17,
  ValueScale_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ValueScale_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ValueScale_IsValid(int value);
const ValueScale ValueScale_MIN = VALUE_SCALE_UNDEFINED;
const ValueScale ValueScale_MAX = VALUE_SCALE_YOTTA;
const int ValueScale_ARRAYSIZE = ValueScale_MAX + 1;

const ::google::protobuf::EnumDescriptor* ValueScale_descriptor();
inline const ::std::string& ValueScale_Name(ValueScale value) {
  return ::google::protobuf::internal::NameOfEnum(
    ValueScale_descriptor(), value);
}
inline bool ValueScale_Parse(
    const ::std::string& name, ValueScale* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ValueScale>(
    ValueScale_descriptor(), name, value);
}
enum SensorStatus {
  SENSOR_STATUS_UNDEFINED = 0,
  SENSOR_STATUS_OK = 1,
  SENSOR_STATUS_UNAVAILABLE = 2,
  SENSOR_STATUS_NONOPERATIONAL = 3,
  SensorStatus_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  SensorStatus_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool SensorStatus_IsValid(int value);
const SensorStatus SensorStatus_MIN = SENSOR_STATUS_UNDEFINED;
const SensorStatus SensorStatus_MAX = SENSOR_STATUS_NONOPERATIONAL;
const int SensorStatus_ARRAYSIZE = SensorStatus_MAX + 1;

const ::google::protobuf::EnumDescriptor* SensorStatus_descriptor();
inline const ::std::string& SensorStatus_Name(SensorStatus value) {
  return ::google::protobuf::internal::NameOfEnum(
    SensorStatus_descriptor(), value);
}
inline bool SensorStatus_Parse(
    const ::std::string& name, SensorStatus* value) {
  return ::google::protobuf::internal::ParseNamedEnum<SensorStatus>(
    SensorStatus_descriptor(), name, value);
}
// ===================================================================

class Uuid final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Uuid) */ {
 public:
  Uuid();
  virtual ~Uuid();

  Uuid(const Uuid& from);

  inline Uuid& operator=(const Uuid& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Uuid(Uuid&& from) noexcept
    : Uuid() {
    *this = ::std::move(from);
  }

  inline Uuid& operator=(Uuid&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const Uuid& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Uuid* internal_default_instance() {
    return reinterpret_cast<const Uuid*>(
               &_Uuid_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  void Swap(Uuid* other);
  friend void swap(Uuid& a, Uuid& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline Uuid* New() const final {
    return CreateMaybeMessage<Uuid>(nullptr);
  }

  Uuid* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<Uuid>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const Uuid& from);
  void MergeFrom(const Uuid& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Uuid* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // string uuid = 1;
  void clear_uuid();
  static const int kUuidFieldNumber = 1;
  const ::std::string& uuid() const;
  void set_uuid(const ::std::string& value);
  #if LANG_CXX11
  void set_uuid(::std::string&& value);
  #endif
  void set_uuid(const char* value);
  void set_uuid(const char* value, size_t size);
  ::std::string* mutable_uuid();
  ::std::string* release_uuid();
  void set_allocated_uuid(::std::string* uuid);

  // @@protoc_insertion_point(class_scope:dmi.Uuid)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class HardwareID final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.HardwareID) */ {
 public:
  HardwareID();
  virtual ~HardwareID();

  HardwareID(const HardwareID& from);

  inline HardwareID& operator=(const HardwareID& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  HardwareID(HardwareID&& from) noexcept
    : HardwareID() {
    *this = ::std::move(from);
  }

  inline HardwareID& operator=(HardwareID&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const HardwareID& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const HardwareID* internal_default_instance() {
    return reinterpret_cast<const HardwareID*>(
               &_HardwareID_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  void Swap(HardwareID* other);
  friend void swap(HardwareID& a, HardwareID& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline HardwareID* New() const final {
    return CreateMaybeMessage<HardwareID>(nullptr);
  }

  HardwareID* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<HardwareID>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const HardwareID& from);
  void MergeFrom(const HardwareID& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(HardwareID* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // .dmi.Uuid uuid = 1;
  bool has_uuid() const;
  void clear_uuid();
  static const int kUuidFieldNumber = 1;
  const ::dmi::Uuid& uuid() const;
  ::dmi::Uuid* release_uuid();
  ::dmi::Uuid* mutable_uuid();
  void set_allocated_uuid(::dmi::Uuid* uuid);

  // @@protoc_insertion_point(class_scope:dmi.HardwareID)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::Uuid* uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class Uri final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Uri) */ {
 public:
  Uri();
  virtual ~Uri();

  Uri(const Uri& from);

  inline Uri& operator=(const Uri& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Uri(Uri&& from) noexcept
    : Uri() {
    *this = ::std::move(from);
  }

  inline Uri& operator=(Uri&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const Uri& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Uri* internal_default_instance() {
    return reinterpret_cast<const Uri*>(
               &_Uri_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  void Swap(Uri* other);
  friend void swap(Uri& a, Uri& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline Uri* New() const final {
    return CreateMaybeMessage<Uri>(nullptr);
  }

  Uri* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<Uri>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const Uri& from);
  void MergeFrom(const Uri& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Uri* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // string uri = 1;
  void clear_uri();
  static const int kUriFieldNumber = 1;
  const ::std::string& uri() const;
  void set_uri(const ::std::string& value);
  #if LANG_CXX11
  void set_uri(::std::string&& value);
  #endif
  void set_uri(const char* value);
  void set_uri(const char* value, size_t size);
  ::std::string* mutable_uri();
  ::std::string* release_uri();
  void set_allocated_uri(::std::string* uri);

  // @@protoc_insertion_point(class_scope:dmi.Uri)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr uri_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class ComponentState final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ComponentState) */ {
 public:
  ComponentState();
  virtual ~ComponentState();

  ComponentState(const ComponentState& from);

  inline ComponentState& operator=(const ComponentState& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  ComponentState(ComponentState&& from) noexcept
    : ComponentState() {
    *this = ::std::move(from);
  }

  inline ComponentState& operator=(ComponentState&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const ComponentState& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const ComponentState* internal_default_instance() {
    return reinterpret_cast<const ComponentState*>(
               &_ComponentState_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  void Swap(ComponentState* other);
  friend void swap(ComponentState& a, ComponentState& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline ComponentState* New() const final {
    return CreateMaybeMessage<ComponentState>(nullptr);
  }

  ComponentState* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ComponentState>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ComponentState& from);
  void MergeFrom(const ComponentState& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ComponentState* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // .google.protobuf.Timestamp state_last_changed = 1;
  bool has_state_last_changed() const;
  void clear_state_last_changed();
  static const int kStateLastChangedFieldNumber = 1;
  const ::google::protobuf::Timestamp& state_last_changed() const;
  ::google::protobuf::Timestamp* release_state_last_changed();
  ::google::protobuf::Timestamp* mutable_state_last_changed();
  void set_allocated_state_last_changed(::google::protobuf::Timestamp* state_last_changed);

  // .dmi.ComponentAdminState admin_state = 2;
  void clear_admin_state();
  static const int kAdminStateFieldNumber = 2;
  ::dmi::ComponentAdminState admin_state() const;
  void set_admin_state(::dmi::ComponentAdminState value);

  // .dmi.ComponentOperState oper_state = 3;
  void clear_oper_state();
  static const int kOperStateFieldNumber = 3;
  ::dmi::ComponentOperState oper_state() const;
  void set_oper_state(::dmi::ComponentOperState value);

  // .dmi.ComponentUsageState usage_state = 4;
  void clear_usage_state();
  static const int kUsageStateFieldNumber = 4;
  ::dmi::ComponentUsageState usage_state() const;
  void set_usage_state(::dmi::ComponentUsageState value);

  // .dmi.ComponentAlarmState alarm_state = 5;
  void clear_alarm_state();
  static const int kAlarmStateFieldNumber = 5;
  ::dmi::ComponentAlarmState alarm_state() const;
  void set_alarm_state(::dmi::ComponentAlarmState value);

  // .dmi.ComponentStandbyState standby_state = 6;
  void clear_standby_state();
  static const int kStandbyStateFieldNumber = 6;
  ::dmi::ComponentStandbyState standby_state() const;
  void set_standby_state(::dmi::ComponentStandbyState value);

  // @@protoc_insertion_point(class_scope:dmi.ComponentState)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::Timestamp* state_last_changed_;
  int admin_state_;
  int oper_state_;
  int usage_state_;
  int alarm_state_;
  int standby_state_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class ComponentSensorData final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ComponentSensorData) */ {
 public:
  ComponentSensorData();
  virtual ~ComponentSensorData();

  ComponentSensorData(const ComponentSensorData& from);

  inline ComponentSensorData& operator=(const ComponentSensorData& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  ComponentSensorData(ComponentSensorData&& from) noexcept
    : ComponentSensorData() {
    *this = ::std::move(from);
  }

  inline ComponentSensorData& operator=(ComponentSensorData&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const ComponentSensorData& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const ComponentSensorData* internal_default_instance() {
    return reinterpret_cast<const ComponentSensorData*>(
               &_ComponentSensorData_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    4;

  void Swap(ComponentSensorData* other);
  friend void swap(ComponentSensorData& a, ComponentSensorData& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline ComponentSensorData* New() const final {
    return CreateMaybeMessage<ComponentSensorData>(nullptr);
  }

  ComponentSensorData* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ComponentSensorData>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ComponentSensorData& from);
  void MergeFrom(const ComponentSensorData& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ComponentSensorData* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // string units_display = 6;
  void clear_units_display();
  static const int kUnitsDisplayFieldNumber = 6;
  const ::std::string& units_display() const;
  void set_units_display(const ::std::string& value);
  #if LANG_CXX11
  void set_units_display(::std::string&& value);
  #endif
  void set_units_display(const char* value);
  void set_units_display(const char* value, size_t size);
  ::std::string* mutable_units_display();
  ::std::string* release_units_display();
  void set_allocated_units_display(::std::string* units_display);

  // string data_type = 9;
  void clear_data_type();
  static const int kDataTypeFieldNumber = 9;
  const ::std::string& data_type() const;
  void set_data_type(const ::std::string& value);
  #if LANG_CXX11
  void set_data_type(::std::string&& value);
  #endif
  void set_data_type(const char* value);
  void set_data_type(const char* value, size_t size);
  ::std::string* mutable_data_type();
  ::std::string* release_data_type();
  void set_allocated_data_type(::std::string* data_type);

  // .google.protobuf.Timestamp timestamp = 7;
  bool has_timestamp() const;
  void clear_timestamp();
  static const int kTimestampFieldNumber = 7;
  const ::google::protobuf::Timestamp& timestamp() const;
  ::google::protobuf::Timestamp* release_timestamp();
  ::google::protobuf::Timestamp* mutable_timestamp();
  void set_allocated_timestamp(::google::protobuf::Timestamp* timestamp);

  // int32 value = 1;
  void clear_value();
  static const int kValueFieldNumber = 1;
  ::google::protobuf::int32 value() const;
  void set_value(::google::protobuf::int32 value);

  // .dmi.DataValueType type = 2;
  void clear_type();
  static const int kTypeFieldNumber = 2;
  ::dmi::DataValueType type() const;
  void set_type(::dmi::DataValueType value);

  // .dmi.ValueScale scale = 3;
  void clear_scale();
  static const int kScaleFieldNumber = 3;
  ::dmi::ValueScale scale() const;
  void set_scale(::dmi::ValueScale value);

  // int32 precision = 4;
  void clear_precision();
  static const int kPrecisionFieldNumber = 4;
  ::google::protobuf::int32 precision() const;
  void set_precision(::google::protobuf::int32 value);

  // .dmi.SensorStatus status = 5;
  void clear_status();
  static const int kStatusFieldNumber = 5;
  ::dmi::SensorStatus status() const;
  void set_status(::dmi::SensorStatus value);

  // uint32 value_update_rate = 8;
  void clear_value_update_rate();
  static const int kValueUpdateRateFieldNumber = 8;
  ::google::protobuf::uint32 value_update_rate() const;
  void set_value_update_rate(::google::protobuf::uint32 value);

  // @@protoc_insertion_point(class_scope:dmi.ComponentSensorData)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr units_display_;
  ::google::protobuf::internal::ArenaStringPtr data_type_;
  ::google::protobuf::Timestamp* timestamp_;
  ::google::protobuf::int32 value_;
  int type_;
  int scale_;
  ::google::protobuf::int32 precision_;
  int status_;
  ::google::protobuf::uint32 value_update_rate_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class PortComponentAttributes final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.PortComponentAttributes) */ {
 public:
  PortComponentAttributes();
  virtual ~PortComponentAttributes();

  PortComponentAttributes(const PortComponentAttributes& from);

  inline PortComponentAttributes& operator=(const PortComponentAttributes& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  PortComponentAttributes(PortComponentAttributes&& from) noexcept
    : PortComponentAttributes() {
    *this = ::std::move(from);
  }

  inline PortComponentAttributes& operator=(PortComponentAttributes&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const PortComponentAttributes& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const PortComponentAttributes* internal_default_instance() {
    return reinterpret_cast<const PortComponentAttributes*>(
               &_PortComponentAttributes_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    5;

  void Swap(PortComponentAttributes* other);
  friend void swap(PortComponentAttributes& a, PortComponentAttributes& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline PortComponentAttributes* New() const final {
    return CreateMaybeMessage<PortComponentAttributes>(nullptr);
  }

  PortComponentAttributes* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<PortComponentAttributes>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const PortComponentAttributes& from);
  void MergeFrom(const PortComponentAttributes& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(PortComponentAttributes* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  typedef PortComponentAttributes_ConnectorType ConnectorType;
  static const ConnectorType CONNECTOR_TYPE_UNDEFINED =
    PortComponentAttributes_ConnectorType_CONNECTOR_TYPE_UNDEFINED;
  static const ConnectorType RJ45 =
    PortComponentAttributes_ConnectorType_RJ45;
  static const ConnectorType FIBER_LC =
    PortComponentAttributes_ConnectorType_FIBER_LC;
  static const ConnectorType FIBER_SC_PC =
    PortComponentAttributes_ConnectorType_FIBER_SC_PC;
  static const ConnectorType FIBER_MPO =
    PortComponentAttributes_ConnectorType_FIBER_MPO;
  static const ConnectorType RS232 =
    PortComponentAttributes_ConnectorType_RS232;
  static inline bool ConnectorType_IsValid(int value) {
    return PortComponentAttributes_ConnectorType_IsValid(value);
  }
  static const ConnectorType ConnectorType_MIN =
    PortComponentAttributes_ConnectorType_ConnectorType_MIN;
  static const ConnectorType ConnectorType_MAX =
    PortComponentAttributes_ConnectorType_ConnectorType_MAX;
  static const int ConnectorType_ARRAYSIZE =
    PortComponentAttributes_ConnectorType_ConnectorType_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  ConnectorType_descriptor() {
    return PortComponentAttributes_ConnectorType_descriptor();
  }
  static inline const ::std::string& ConnectorType_Name(ConnectorType value) {
    return PortComponentAttributes_ConnectorType_Name(value);
  }
  static inline bool ConnectorType_Parse(const ::std::string& name,
      ConnectorType* value) {
    return PortComponentAttributes_ConnectorType_Parse(name, value);
  }

  typedef PortComponentAttributes_Speed Speed;
  static const Speed SPEED_UNDEFINED =
    PortComponentAttributes_Speed_SPEED_UNDEFINED;
  static const Speed DYNAMIC =
    PortComponentAttributes_Speed_DYNAMIC;
  static const Speed GIGABIT_1 =
    PortComponentAttributes_Speed_GIGABIT_1;
  static const Speed GIGABIT_10 =
    PortComponentAttributes_Speed_GIGABIT_10;
  static const Speed GIGABIT_25 =
    PortComponentAttributes_Speed_GIGABIT_25;
  static const Speed GIGABIT_40 =
    PortComponentAttributes_Speed_GIGABIT_40;
  static const Speed GIGABIT_100 =
    PortComponentAttributes_Speed_GIGABIT_100;
  static const Speed GIGABIT_400 =
    PortComponentAttributes_Speed_GIGABIT_400;
  static const Speed MEGABIT_2500 =
    PortComponentAttributes_Speed_MEGABIT_2500;
  static const Speed MEGABIT_1250 =
    PortComponentAttributes_Speed_MEGABIT_1250;
  static inline bool Speed_IsValid(int value) {
    return PortComponentAttributes_Speed_IsValid(value);
  }
  static const Speed Speed_MIN =
    PortComponentAttributes_Speed_Speed_MIN;
  static const Speed Speed_MAX =
    PortComponentAttributes_Speed_Speed_MAX;
  static const int Speed_ARRAYSIZE =
    PortComponentAttributes_Speed_Speed_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Speed_descriptor() {
    return PortComponentAttributes_Speed_descriptor();
  }
  static inline const ::std::string& Speed_Name(Speed value) {
    return PortComponentAttributes_Speed_Name(value);
  }
  static inline bool Speed_Parse(const ::std::string& name,
      Speed* value) {
    return PortComponentAttributes_Speed_Parse(name, value);
  }

  typedef PortComponentAttributes_Protocol Protocol;
  static const Protocol PROTOCOL_UNDEFINED =
    PortComponentAttributes_Protocol_PROTOCOL_UNDEFINED;
  static const Protocol ETHERNET =
    PortComponentAttributes_Protocol_ETHERNET;
  static const Protocol GPON =
    PortComponentAttributes_Protocol_GPON;
  static const Protocol XGPON =
    PortComponentAttributes_Protocol_XGPON;
  static const Protocol XGSPON =
    PortComponentAttributes_Protocol_XGSPON;
  static const Protocol GFAST =
    PortComponentAttributes_Protocol_GFAST;
  static const Protocol SERIAL =
    PortComponentAttributes_Protocol_SERIAL;
  static const Protocol EPON =
    PortComponentAttributes_Protocol_EPON;
  static const Protocol BITS =
    PortComponentAttributes_Protocol_BITS;
  static inline bool Protocol_IsValid(int value) {
    return PortComponentAttributes_Protocol_IsValid(value);
  }
  static const Protocol Protocol_MIN =
    PortComponentAttributes_Protocol_Protocol_MIN;
  static const Protocol Protocol_MAX =
    PortComponentAttributes_Protocol_Protocol_MAX;
  static const int Protocol_ARRAYSIZE =
    PortComponentAttributes_Protocol_Protocol_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Protocol_descriptor() {
    return PortComponentAttributes_Protocol_descriptor();
  }
  static inline const ::std::string& Protocol_Name(Protocol value) {
    return PortComponentAttributes_Protocol_Name(value);
  }
  static inline bool Protocol_Parse(const ::std::string& name,
      Protocol* value) {
    return PortComponentAttributes_Protocol_Parse(name, value);
  }

  // accessors -------------------------------------------------------

  // string physical_label = 4;
  void clear_physical_label();
  static const int kPhysicalLabelFieldNumber = 4;
  const ::std::string& physical_label() const;
  void set_physical_label(const ::std::string& value);
  #if LANG_CXX11
  void set_physical_label(::std::string&& value);
  #endif
  void set_physical_label(const char* value);
  void set_physical_label(const char* value, size_t size);
  ::std::string* mutable_physical_label();
  ::std::string* release_physical_label();
  void set_allocated_physical_label(::std::string* physical_label);

  // .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
  void clear_connector_type();
  static const int kConnectorTypeFieldNumber = 1;
  ::dmi::PortComponentAttributes_ConnectorType connector_type() const;
  void set_connector_type(::dmi::PortComponentAttributes_ConnectorType value);

  // .dmi.PortComponentAttributes.Speed speed = 2;
  void clear_speed();
  static const int kSpeedFieldNumber = 2;
  ::dmi::PortComponentAttributes_Speed speed() const;
  void set_speed(::dmi::PortComponentAttributes_Speed value);

  // .dmi.PortComponentAttributes.Protocol protocol = 3;
  void clear_protocol();
  static const int kProtocolFieldNumber = 3;
  ::dmi::PortComponentAttributes_Protocol protocol() const;
  void set_protocol(::dmi::PortComponentAttributes_Protocol value);

  // @@protoc_insertion_point(class_scope:dmi.PortComponentAttributes)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr physical_label_;
  int connector_type_;
  int speed_;
  int protocol_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class ContainerComponentAttributes final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ContainerComponentAttributes) */ {
 public:
  ContainerComponentAttributes();
  virtual ~ContainerComponentAttributes();

  ContainerComponentAttributes(const ContainerComponentAttributes& from);

  inline ContainerComponentAttributes& operator=(const ContainerComponentAttributes& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  ContainerComponentAttributes(ContainerComponentAttributes&& from) noexcept
    : ContainerComponentAttributes() {
    *this = ::std::move(from);
  }

  inline ContainerComponentAttributes& operator=(ContainerComponentAttributes&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const ContainerComponentAttributes& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const ContainerComponentAttributes* internal_default_instance() {
    return reinterpret_cast<const ContainerComponentAttributes*>(
               &_ContainerComponentAttributes_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    6;

  void Swap(ContainerComponentAttributes* other);
  friend void swap(ContainerComponentAttributes& a, ContainerComponentAttributes& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline ContainerComponentAttributes* New() const final {
    return CreateMaybeMessage<ContainerComponentAttributes>(nullptr);
  }

  ContainerComponentAttributes* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ContainerComponentAttributes>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ContainerComponentAttributes& from);
  void MergeFrom(const ContainerComponentAttributes& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ContainerComponentAttributes* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // string physical_label = 1;
  void clear_physical_label();
  static const int kPhysicalLabelFieldNumber = 1;
  const ::std::string& physical_label() const;
  void set_physical_label(const ::std::string& value);
  #if LANG_CXX11
  void set_physical_label(::std::string&& value);
  #endif
  void set_physical_label(const char* value);
  void set_physical_label(const char* value, size_t size);
  ::std::string* mutable_physical_label();
  ::std::string* release_physical_label();
  void set_allocated_physical_label(::std::string* physical_label);

  // @@protoc_insertion_point(class_scope:dmi.ContainerComponentAttributes)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr physical_label_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class PsuComponentAttributes final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.PsuComponentAttributes) */ {
 public:
  PsuComponentAttributes();
  virtual ~PsuComponentAttributes();

  PsuComponentAttributes(const PsuComponentAttributes& from);

  inline PsuComponentAttributes& operator=(const PsuComponentAttributes& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  PsuComponentAttributes(PsuComponentAttributes&& from) noexcept
    : PsuComponentAttributes() {
    *this = ::std::move(from);
  }

  inline PsuComponentAttributes& operator=(PsuComponentAttributes&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const PsuComponentAttributes& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const PsuComponentAttributes* internal_default_instance() {
    return reinterpret_cast<const PsuComponentAttributes*>(
               &_PsuComponentAttributes_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    7;

  void Swap(PsuComponentAttributes* other);
  friend void swap(PsuComponentAttributes& a, PsuComponentAttributes& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline PsuComponentAttributes* New() const final {
    return CreateMaybeMessage<PsuComponentAttributes>(nullptr);
  }

  PsuComponentAttributes* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<PsuComponentAttributes>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const PsuComponentAttributes& from);
  void MergeFrom(const PsuComponentAttributes& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(PsuComponentAttributes* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  typedef PsuComponentAttributes_SupportedVoltage SupportedVoltage;
  static const SupportedVoltage SUPPORTED_VOLTAGE_UNDEFINED =
    PsuComponentAttributes_SupportedVoltage_SUPPORTED_VOLTAGE_UNDEFINED;
  static const SupportedVoltage V48 =
    PsuComponentAttributes_SupportedVoltage_V48;
  static const SupportedVoltage V230 =
    PsuComponentAttributes_SupportedVoltage_V230;
  static const SupportedVoltage V115 =
    PsuComponentAttributes_SupportedVoltage_V115;
  static inline bool SupportedVoltage_IsValid(int value) {
    return PsuComponentAttributes_SupportedVoltage_IsValid(value);
  }
  static const SupportedVoltage SupportedVoltage_MIN =
    PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MIN;
  static const SupportedVoltage SupportedVoltage_MAX =
    PsuComponentAttributes_SupportedVoltage_SupportedVoltage_MAX;
  static const int SupportedVoltage_ARRAYSIZE =
    PsuComponentAttributes_SupportedVoltage_SupportedVoltage_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  SupportedVoltage_descriptor() {
    return PsuComponentAttributes_SupportedVoltage_descriptor();
  }
  static inline const ::std::string& SupportedVoltage_Name(SupportedVoltage value) {
    return PsuComponentAttributes_SupportedVoltage_Name(value);
  }
  static inline bool SupportedVoltage_Parse(const ::std::string& name,
      SupportedVoltage* value) {
    return PsuComponentAttributes_SupportedVoltage_Parse(name, value);
  }

  // accessors -------------------------------------------------------

  // .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
  void clear_supported_voltage();
  static const int kSupportedVoltageFieldNumber = 1;
  ::dmi::PsuComponentAttributes_SupportedVoltage supported_voltage() const;
  void set_supported_voltage(::dmi::PsuComponentAttributes_SupportedVoltage value);

  // @@protoc_insertion_point(class_scope:dmi.PsuComponentAttributes)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  int supported_voltage_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class TransceiverComponentsAttributes final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.TransceiverComponentsAttributes) */ {
 public:
  TransceiverComponentsAttributes();
  virtual ~TransceiverComponentsAttributes();

  TransceiverComponentsAttributes(const TransceiverComponentsAttributes& from);

  inline TransceiverComponentsAttributes& operator=(const TransceiverComponentsAttributes& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  TransceiverComponentsAttributes(TransceiverComponentsAttributes&& from) noexcept
    : TransceiverComponentsAttributes() {
    *this = ::std::move(from);
  }

  inline TransceiverComponentsAttributes& operator=(TransceiverComponentsAttributes&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const TransceiverComponentsAttributes& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const TransceiverComponentsAttributes* internal_default_instance() {
    return reinterpret_cast<const TransceiverComponentsAttributes*>(
               &_TransceiverComponentsAttributes_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    8;

  void Swap(TransceiverComponentsAttributes* other);
  friend void swap(TransceiverComponentsAttributes& a, TransceiverComponentsAttributes& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline TransceiverComponentsAttributes* New() const final {
    return CreateMaybeMessage<TransceiverComponentsAttributes>(nullptr);
  }

  TransceiverComponentsAttributes* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<TransceiverComponentsAttributes>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const TransceiverComponentsAttributes& from);
  void MergeFrom(const TransceiverComponentsAttributes& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(TransceiverComponentsAttributes* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  typedef TransceiverComponentsAttributes_FormFactor FormFactor;
  static const FormFactor FORM_FACTOR_UNKNOWN =
    TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN;
  static const FormFactor QSFP =
    TransceiverComponentsAttributes_FormFactor_QSFP;
  static const FormFactor QSFP_PLUS =
    TransceiverComponentsAttributes_FormFactor_QSFP_PLUS;
  static const FormFactor QSFP28 =
    TransceiverComponentsAttributes_FormFactor_QSFP28;
  static const FormFactor SFP =
    TransceiverComponentsAttributes_FormFactor_SFP;
  static const FormFactor SFP_PLUS =
    TransceiverComponentsAttributes_FormFactor_SFP_PLUS;
  static const FormFactor XFP =
    TransceiverComponentsAttributes_FormFactor_XFP;
  static const FormFactor CFP4 =
    TransceiverComponentsAttributes_FormFactor_CFP4;
  static const FormFactor CFP2 =
    TransceiverComponentsAttributes_FormFactor_CFP2;
  static const FormFactor CPAK =
    TransceiverComponentsAttributes_FormFactor_CPAK;
  static const FormFactor X2 =
    TransceiverComponentsAttributes_FormFactor_X2;
  static const FormFactor OTHER =
    TransceiverComponentsAttributes_FormFactor_OTHER;
  static const FormFactor CFP =
    TransceiverComponentsAttributes_FormFactor_CFP;
  static const FormFactor CFP2_ACO =
    TransceiverComponentsAttributes_FormFactor_CFP2_ACO;
  static const FormFactor CFP2_DCO =
    TransceiverComponentsAttributes_FormFactor_CFP2_DCO;
  static inline bool FormFactor_IsValid(int value) {
    return TransceiverComponentsAttributes_FormFactor_IsValid(value);
  }
  static const FormFactor FormFactor_MIN =
    TransceiverComponentsAttributes_FormFactor_FormFactor_MIN;
  static const FormFactor FormFactor_MAX =
    TransceiverComponentsAttributes_FormFactor_FormFactor_MAX;
  static const int FormFactor_ARRAYSIZE =
    TransceiverComponentsAttributes_FormFactor_FormFactor_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  FormFactor_descriptor() {
    return TransceiverComponentsAttributes_FormFactor_descriptor();
  }
  static inline const ::std::string& FormFactor_Name(FormFactor value) {
    return TransceiverComponentsAttributes_FormFactor_Name(value);
  }
  static inline bool FormFactor_Parse(const ::std::string& name,
      FormFactor* value) {
    return TransceiverComponentsAttributes_FormFactor_Parse(name, value);
  }

  typedef TransceiverComponentsAttributes_Type Type;
  static const Type TYPE_UNKNOWN =
    TransceiverComponentsAttributes_Type_TYPE_UNKNOWN;
  static const Type ETHERNET =
    TransceiverComponentsAttributes_Type_ETHERNET;
  static const Type GPON =
    TransceiverComponentsAttributes_Type_GPON;
  static const Type XGPON =
    TransceiverComponentsAttributes_Type_XGPON;
  static const Type XGSPON =
    TransceiverComponentsAttributes_Type_XGSPON;
  static const Type CPON =
    TransceiverComponentsAttributes_Type_CPON;
  static const Type NG_PON2 =
    TransceiverComponentsAttributes_Type_NG_PON2;
  static const Type EPON =
    TransceiverComponentsAttributes_Type_EPON;
  static inline bool Type_IsValid(int value) {
    return TransceiverComponentsAttributes_Type_IsValid(value);
  }
  static const Type Type_MIN =
    TransceiverComponentsAttributes_Type_Type_MIN;
  static const Type Type_MAX =
    TransceiverComponentsAttributes_Type_Type_MAX;
  static const int Type_ARRAYSIZE =
    TransceiverComponentsAttributes_Type_Type_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Type_descriptor() {
    return TransceiverComponentsAttributes_Type_descriptor();
  }
  static inline const ::std::string& Type_Name(Type value) {
    return TransceiverComponentsAttributes_Type_Name(value);
  }
  static inline bool Type_Parse(const ::std::string& name,
      Type* value) {
    return TransceiverComponentsAttributes_Type_Parse(name, value);
  }

  // accessors -------------------------------------------------------

  // repeated uint32 rx_wavelength = 5;
  int rx_wavelength_size() const;
  void clear_rx_wavelength();
  static const int kRxWavelengthFieldNumber = 5;
  ::google::protobuf::uint32 rx_wavelength(int index) const;
  void set_rx_wavelength(int index, ::google::protobuf::uint32 value);
  void add_rx_wavelength(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      rx_wavelength() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_rx_wavelength();

  // repeated uint32 tx_wavelength = 6;
  int tx_wavelength_size() const;
  void clear_tx_wavelength();
  static const int kTxWavelengthFieldNumber = 6;
  ::google::protobuf::uint32 tx_wavelength(int index) const;
  void set_tx_wavelength(int index, ::google::protobuf::uint32 value);
  void add_tx_wavelength(::google::protobuf::uint32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
      tx_wavelength() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
      mutable_tx_wavelength();

  // .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
  void clear_form_factor();
  static const int kFormFactorFieldNumber = 1;
  ::dmi::TransceiverComponentsAttributes_FormFactor form_factor() const;
  void set_form_factor(::dmi::TransceiverComponentsAttributes_FormFactor value);

  // .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
  void clear_trans_type();
  static const int kTransTypeFieldNumber = 2;
  ::dmi::TransceiverComponentsAttributes_Type trans_type() const;
  void set_trans_type(::dmi::TransceiverComponentsAttributes_Type value);

  // uint32 max_distance = 3;
  void clear_max_distance();
  static const int kMaxDistanceFieldNumber = 3;
  ::google::protobuf::uint32 max_distance() const;
  void set_max_distance(::google::protobuf::uint32 value);

  // .dmi.ValueScale max_distance_scale = 4;
  void clear_max_distance_scale();
  static const int kMaxDistanceScaleFieldNumber = 4;
  ::dmi::ValueScale max_distance_scale() const;
  void set_max_distance_scale(::dmi::ValueScale value);

  // .dmi.ValueScale wavelength_scale = 7;
  void clear_wavelength_scale();
  static const int kWavelengthScaleFieldNumber = 7;
  ::dmi::ValueScale wavelength_scale() const;
  void set_wavelength_scale(::dmi::ValueScale value);

  // @@protoc_insertion_point(class_scope:dmi.TransceiverComponentsAttributes)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > rx_wavelength_;
  mutable std::atomic<int> _rx_wavelength_cached_byte_size_;
  ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > tx_wavelength_;
  mutable std::atomic<int> _tx_wavelength_cached_byte_size_;
  int form_factor_;
  int trans_type_;
  ::google::protobuf::uint32 max_distance_;
  int max_distance_scale_;
  int wavelength_scale_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class Component final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Component) */ {
 public:
  Component();
  virtual ~Component();

  Component(const Component& from);

  inline Component& operator=(const Component& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Component(Component&& from) noexcept
    : Component() {
    *this = ::std::move(from);
  }

  inline Component& operator=(Component&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const Component& default_instance();

  enum SpecificCase {
    kPortAttr = 50,
    kContainerAttr = 51,
    kPsuAttr = 52,
    kTransceiverAttr = 53,
    SPECIFIC_NOT_SET = 0,
  };

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Component* internal_default_instance() {
    return reinterpret_cast<const Component*>(
               &_Component_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    9;

  void Swap(Component* other);
  friend void swap(Component& a, Component& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline Component* New() const final {
    return CreateMaybeMessage<Component>(nullptr);
  }

  Component* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<Component>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const Component& from);
  void MergeFrom(const Component& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Component* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // repeated .dmi.Component children = 6;
  int children_size() const;
  void clear_children();
  static const int kChildrenFieldNumber = 6;
  ::dmi::Component* mutable_children(int index);
  ::google::protobuf::RepeatedPtrField< ::dmi::Component >*
      mutable_children();
  const ::dmi::Component& children(int index) const;
  ::dmi::Component* add_children();
  const ::google::protobuf::RepeatedPtrField< ::dmi::Component >&
      children() const;

  // repeated .dmi.ComponentSensorData sensor_data = 20;
  int sensor_data_size() const;
  void clear_sensor_data();
  static const int kSensorDataFieldNumber = 20;
  ::dmi::ComponentSensorData* mutable_sensor_data(int index);
  ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >*
      mutable_sensor_data();
  const ::dmi::ComponentSensorData& sensor_data(int index) const;
  ::dmi::ComponentSensorData* add_sensor_data();
  const ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >&
      sensor_data() const;

  // string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // string description = 3;
  void clear_description();
  static const int kDescriptionFieldNumber = 3;
  const ::std::string& description() const;
  void set_description(const ::std::string& value);
  #if LANG_CXX11
  void set_description(::std::string&& value);
  #endif
  void set_description(const char* value);
  void set_description(const char* value, size_t size);
  ::std::string* mutable_description();
  ::std::string* release_description();
  void set_allocated_description(::std::string* description);

  // string parent = 4;
  void clear_parent();
  static const int kParentFieldNumber = 4;
  const ::std::string& parent() const;
  void set_parent(const ::std::string& value);
  #if LANG_CXX11
  void set_parent(::std::string&& value);
  #endif
  void set_parent(const char* value);
  void set_parent(const char* value, size_t size);
  ::std::string* mutable_parent();
  ::std::string* release_parent();
  void set_allocated_parent(::std::string* parent);

  // string hardware_rev = 7;
  void clear_hardware_rev();
  static const int kHardwareRevFieldNumber = 7;
  const ::std::string& hardware_rev() const;
  void set_hardware_rev(const ::std::string& value);
  #if LANG_CXX11
  void set_hardware_rev(::std::string&& value);
  #endif
  void set_hardware_rev(const char* value);
  void set_hardware_rev(const char* value, size_t size);
  ::std::string* mutable_hardware_rev();
  ::std::string* release_hardware_rev();
  void set_allocated_hardware_rev(::std::string* hardware_rev);

  // string firmware_rev = 8;
  void clear_firmware_rev();
  static const int kFirmwareRevFieldNumber = 8;
  const ::std::string& firmware_rev() const;
  void set_firmware_rev(const ::std::string& value);
  #if LANG_CXX11
  void set_firmware_rev(::std::string&& value);
  #endif
  void set_firmware_rev(const char* value);
  void set_firmware_rev(const char* value, size_t size);
  ::std::string* mutable_firmware_rev();
  ::std::string* release_firmware_rev();
  void set_allocated_firmware_rev(::std::string* firmware_rev);

  // string software_rev = 9;
  void clear_software_rev();
  static const int kSoftwareRevFieldNumber = 9;
  const ::std::string& software_rev() const;
  void set_software_rev(const ::std::string& value);
  #if LANG_CXX11
  void set_software_rev(::std::string&& value);
  #endif
  void set_software_rev(const char* value);
  void set_software_rev(const char* value, size_t size);
  ::std::string* mutable_software_rev();
  ::std::string* release_software_rev();
  void set_allocated_software_rev(::std::string* software_rev);

  // string serial_num = 10;
  void clear_serial_num();
  static const int kSerialNumFieldNumber = 10;
  const ::std::string& serial_num() const;
  void set_serial_num(const ::std::string& value);
  #if LANG_CXX11
  void set_serial_num(::std::string&& value);
  #endif
  void set_serial_num(const char* value);
  void set_serial_num(const char* value, size_t size);
  ::std::string* mutable_serial_num();
  ::std::string* release_serial_num();
  void set_allocated_serial_num(::std::string* serial_num);

  // string mfg_name = 11;
  void clear_mfg_name();
  static const int kMfgNameFieldNumber = 11;
  const ::std::string& mfg_name() const;
  void set_mfg_name(const ::std::string& value);
  #if LANG_CXX11
  void set_mfg_name(::std::string&& value);
  #endif
  void set_mfg_name(const char* value);
  void set_mfg_name(const char* value, size_t size);
  ::std::string* mutable_mfg_name();
  ::std::string* release_mfg_name();
  void set_allocated_mfg_name(::std::string* mfg_name);

  // string model_name = 12;
  void clear_model_name();
  static const int kModelNameFieldNumber = 12;
  const ::std::string& model_name() const;
  void set_model_name(const ::std::string& value);
  #if LANG_CXX11
  void set_model_name(::std::string&& value);
  #endif
  void set_model_name(const char* value);
  void set_model_name(const char* value, size_t size);
  ::std::string* mutable_model_name();
  ::std::string* release_model_name();
  void set_allocated_model_name(::std::string* model_name);

  // string alias = 13;
  void clear_alias();
  static const int kAliasFieldNumber = 13;
  const ::std::string& alias() const;
  void set_alias(const ::std::string& value);
  #if LANG_CXX11
  void set_alias(::std::string&& value);
  #endif
  void set_alias(const char* value);
  void set_alias(const char* value, size_t size);
  ::std::string* mutable_alias();
  ::std::string* release_alias();
  void set_allocated_alias(::std::string* alias);

  // string asset_id = 14;
  void clear_asset_id();
  static const int kAssetIdFieldNumber = 14;
  const ::std::string& asset_id() const;
  void set_asset_id(const ::std::string& value);
  #if LANG_CXX11
  void set_asset_id(::std::string&& value);
  #endif
  void set_asset_id(const char* value);
  void set_asset_id(const char* value, size_t size);
  ::std::string* mutable_asset_id();
  ::std::string* release_asset_id();
  void set_allocated_asset_id(::std::string* asset_id);

  // .google.protobuf.Timestamp mfg_date = 16;
  bool has_mfg_date() const;
  void clear_mfg_date();
  static const int kMfgDateFieldNumber = 16;
  const ::google::protobuf::Timestamp& mfg_date() const;
  ::google::protobuf::Timestamp* release_mfg_date();
  ::google::protobuf::Timestamp* mutable_mfg_date();
  void set_allocated_mfg_date(::google::protobuf::Timestamp* mfg_date);

  // .dmi.Uri uri = 17;
  bool has_uri() const;
  void clear_uri();
  static const int kUriFieldNumber = 17;
  const ::dmi::Uri& uri() const;
  ::dmi::Uri* release_uri();
  ::dmi::Uri* mutable_uri();
  void set_allocated_uri(::dmi::Uri* uri);

  // .dmi.Uuid uuid = 18;
  bool has_uuid() const;
  void clear_uuid();
  static const int kUuidFieldNumber = 18;
  const ::dmi::Uuid& uuid() const;
  ::dmi::Uuid* release_uuid();
  ::dmi::Uuid* mutable_uuid();
  void set_allocated_uuid(::dmi::Uuid* uuid);

  // .dmi.ComponentState state = 19;
  bool has_state() const;
  void clear_state();
  static const int kStateFieldNumber = 19;
  const ::dmi::ComponentState& state() const;
  ::dmi::ComponentState* release_state();
  ::dmi::ComponentState* mutable_state();
  void set_allocated_state(::dmi::ComponentState* state);

  // .dmi.ComponentType class = 2;
  void clear_class_();
  static const int kClassFieldNumber = 2;
  ::dmi::ComponentType class_() const;
  void set_class_(::dmi::ComponentType value);

  // int32 parent_rel_pos = 5;
  void clear_parent_rel_pos();
  static const int kParentRelPosFieldNumber = 5;
  ::google::protobuf::int32 parent_rel_pos() const;
  void set_parent_rel_pos(::google::protobuf::int32 value);

  // bool is_fru = 15;
  void clear_is_fru();
  static const int kIsFruFieldNumber = 15;
  bool is_fru() const;
  void set_is_fru(bool value);

  // .dmi.PortComponentAttributes port_attr = 50;
  bool has_port_attr() const;
  void clear_port_attr();
  static const int kPortAttrFieldNumber = 50;
  const ::dmi::PortComponentAttributes& port_attr() const;
  ::dmi::PortComponentAttributes* release_port_attr();
  ::dmi::PortComponentAttributes* mutable_port_attr();
  void set_allocated_port_attr(::dmi::PortComponentAttributes* port_attr);

  // .dmi.ContainerComponentAttributes container_attr = 51;
  bool has_container_attr() const;
  void clear_container_attr();
  static const int kContainerAttrFieldNumber = 51;
  const ::dmi::ContainerComponentAttributes& container_attr() const;
  ::dmi::ContainerComponentAttributes* release_container_attr();
  ::dmi::ContainerComponentAttributes* mutable_container_attr();
  void set_allocated_container_attr(::dmi::ContainerComponentAttributes* container_attr);

  // .dmi.PsuComponentAttributes psu_attr = 52;
  bool has_psu_attr() const;
  void clear_psu_attr();
  static const int kPsuAttrFieldNumber = 52;
  const ::dmi::PsuComponentAttributes& psu_attr() const;
  ::dmi::PsuComponentAttributes* release_psu_attr();
  ::dmi::PsuComponentAttributes* mutable_psu_attr();
  void set_allocated_psu_attr(::dmi::PsuComponentAttributes* psu_attr);

  // .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
  bool has_transceiver_attr() const;
  void clear_transceiver_attr();
  static const int kTransceiverAttrFieldNumber = 53;
  const ::dmi::TransceiverComponentsAttributes& transceiver_attr() const;
  ::dmi::TransceiverComponentsAttributes* release_transceiver_attr();
  ::dmi::TransceiverComponentsAttributes* mutable_transceiver_attr();
  void set_allocated_transceiver_attr(::dmi::TransceiverComponentsAttributes* transceiver_attr);

  void clear_specific();
  SpecificCase specific_case() const;
  // @@protoc_insertion_point(class_scope:dmi.Component)
 private:
  class HasBitSetters;
  void set_has_port_attr();
  void set_has_container_attr();
  void set_has_psu_attr();
  void set_has_transceiver_attr();

  inline bool has_specific() const;
  inline void clear_has_specific();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::RepeatedPtrField< ::dmi::Component > children_;
  ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData > sensor_data_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::internal::ArenaStringPtr description_;
  ::google::protobuf::internal::ArenaStringPtr parent_;
  ::google::protobuf::internal::ArenaStringPtr hardware_rev_;
  ::google::protobuf::internal::ArenaStringPtr firmware_rev_;
  ::google::protobuf::internal::ArenaStringPtr software_rev_;
  ::google::protobuf::internal::ArenaStringPtr serial_num_;
  ::google::protobuf::internal::ArenaStringPtr mfg_name_;
  ::google::protobuf::internal::ArenaStringPtr model_name_;
  ::google::protobuf::internal::ArenaStringPtr alias_;
  ::google::protobuf::internal::ArenaStringPtr asset_id_;
  ::google::protobuf::Timestamp* mfg_date_;
  ::dmi::Uri* uri_;
  ::dmi::Uuid* uuid_;
  ::dmi::ComponentState* state_;
  int class__;
  ::google::protobuf::int32 parent_rel_pos_;
  bool is_fru_;
  union SpecificUnion {
    SpecificUnion() {}
    ::dmi::PortComponentAttributes* port_attr_;
    ::dmi::ContainerComponentAttributes* container_attr_;
    ::dmi::PsuComponentAttributes* psu_attr_;
    ::dmi::TransceiverComponentsAttributes* transceiver_attr_;
  } specific_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::uint32 _oneof_case_[1];

  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class Hardware final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Hardware) */ {
 public:
  Hardware();
  virtual ~Hardware();

  Hardware(const Hardware& from);

  inline Hardware& operator=(const Hardware& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  Hardware(Hardware&& from) noexcept
    : Hardware() {
    *this = ::std::move(from);
  }

  inline Hardware& operator=(Hardware&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const Hardware& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const Hardware* internal_default_instance() {
    return reinterpret_cast<const Hardware*>(
               &_Hardware_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    10;

  void Swap(Hardware* other);
  friend void swap(Hardware& a, Hardware& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline Hardware* New() const final {
    return CreateMaybeMessage<Hardware>(nullptr);
  }

  Hardware* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<Hardware>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const Hardware& from);
  void MergeFrom(const Hardware& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Hardware* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // .google.protobuf.Timestamp last_change = 1;
  bool has_last_change() const;
  void clear_last_change();
  static const int kLastChangeFieldNumber = 1;
  const ::google::protobuf::Timestamp& last_change() const;
  ::google::protobuf::Timestamp* release_last_change();
  ::google::protobuf::Timestamp* mutable_last_change();
  void set_allocated_last_change(::google::protobuf::Timestamp* last_change);

  // .dmi.Component root = 2;
  bool has_root() const;
  void clear_root();
  static const int kRootFieldNumber = 2;
  const ::dmi::Component& root() const;
  ::dmi::Component* release_root();
  ::dmi::Component* mutable_root();
  void set_allocated_root(::dmi::Component* root);

  // .google.protobuf.Timestamp last_booted = 3;
  bool has_last_booted() const;
  void clear_last_booted();
  static const int kLastBootedFieldNumber = 3;
  const ::google::protobuf::Timestamp& last_booted() const;
  ::google::protobuf::Timestamp* release_last_booted();
  ::google::protobuf::Timestamp* mutable_last_booted();
  void set_allocated_last_booted(::google::protobuf::Timestamp* last_booted);

  // @@protoc_insertion_point(class_scope:dmi.Hardware)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::Timestamp* last_change_;
  ::dmi::Component* root_;
  ::google::protobuf::Timestamp* last_booted_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

class ModifiableComponent final :
    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ModifiableComponent) */ {
 public:
  ModifiableComponent();
  virtual ~ModifiableComponent();

  ModifiableComponent(const ModifiableComponent& from);

  inline ModifiableComponent& operator=(const ModifiableComponent& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  ModifiableComponent(ModifiableComponent&& from) noexcept
    : ModifiableComponent() {
    *this = ::std::move(from);
  }

  inline ModifiableComponent& operator=(ModifiableComponent&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor() {
    return default_instance().GetDescriptor();
  }
  static const ModifiableComponent& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const ModifiableComponent* internal_default_instance() {
    return reinterpret_cast<const ModifiableComponent*>(
               &_ModifiableComponent_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    11;

  void Swap(ModifiableComponent* other);
  friend void swap(ModifiableComponent& a, ModifiableComponent& b) {
    a.Swap(&b);
  }

  // implements Message ----------------------------------------------

  inline ModifiableComponent* New() const final {
    return CreateMaybeMessage<ModifiableComponent>(nullptr);
  }

  ModifiableComponent* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ModifiableComponent>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ModifiableComponent& from);
  void MergeFrom(const ModifiableComponent& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
  #else
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ModifiableComponent* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return nullptr;
  }
  inline void* MaybeArenaPtr() const {
    return nullptr;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // string name = 1;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // string alias = 5;
  void clear_alias();
  static const int kAliasFieldNumber = 5;
  const ::std::string& alias() const;
  void set_alias(const ::std::string& value);
  #if LANG_CXX11
  void set_alias(::std::string&& value);
  #endif
  void set_alias(const char* value);
  void set_alias(const char* value, size_t size);
  ::std::string* mutable_alias();
  ::std::string* release_alias();
  void set_allocated_alias(::std::string* alias);

  // string asset_id = 6;
  void clear_asset_id();
  static const int kAssetIdFieldNumber = 6;
  const ::std::string& asset_id() const;
  void set_asset_id(const ::std::string& value);
  #if LANG_CXX11
  void set_asset_id(::std::string&& value);
  #endif
  void set_asset_id(const char* value);
  void set_asset_id(const char* value, size_t size);
  ::std::string* mutable_asset_id();
  ::std::string* release_asset_id();
  void set_allocated_asset_id(::std::string* asset_id);

  // .dmi.Component parent = 3;
  bool has_parent() const;
  void clear_parent();
  static const int kParentFieldNumber = 3;
  const ::dmi::Component& parent() const;
  ::dmi::Component* release_parent();
  ::dmi::Component* mutable_parent();
  void set_allocated_parent(::dmi::Component* parent);

  // .dmi.Uri uri = 7;
  bool has_uri() const;
  void clear_uri();
  static const int kUriFieldNumber = 7;
  const ::dmi::Uri& uri() const;
  ::dmi::Uri* release_uri();
  ::dmi::Uri* mutable_uri();
  void set_allocated_uri(::dmi::Uri* uri);

  // .dmi.ComponentType class = 2;
  void clear_class_();
  static const int kClassFieldNumber = 2;
  ::dmi::ComponentType class_() const;
  void set_class_(::dmi::ComponentType value);

  // int32 parent_rel_pos = 4;
  void clear_parent_rel_pos();
  static const int kParentRelPosFieldNumber = 4;
  ::google::protobuf::int32 parent_rel_pos() const;
  void set_parent_rel_pos(::google::protobuf::int32 value);

  // .dmi.ComponentAdminState admin_state = 8;
  void clear_admin_state();
  static const int kAdminStateFieldNumber = 8;
  ::dmi::ComponentAdminState admin_state() const;
  void set_admin_state(::dmi::ComponentAdminState value);

  // @@protoc_insertion_point(class_scope:dmi.ModifiableComponent)
 private:
  class HasBitSetters;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::internal::ArenaStringPtr alias_;
  ::google::protobuf::internal::ArenaStringPtr asset_id_;
  ::dmi::Component* parent_;
  ::dmi::Uri* uri_;
  int class__;
  ::google::protobuf::int32 parent_rel_pos_;
  int admin_state_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// ===================================================================


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

#ifdef __GNUC__
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// Uuid

// string uuid = 1;
inline void Uuid::clear_uuid() {
  uuid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Uuid::uuid() const {
  // @@protoc_insertion_point(field_get:dmi.Uuid.uuid)
  return uuid_.GetNoArena();
}
inline void Uuid::set_uuid(const ::std::string& value) {
  
  uuid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Uuid.uuid)
}
#if LANG_CXX11
inline void Uuid::set_uuid(::std::string&& value) {
  
  uuid_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Uuid.uuid)
}
#endif
inline void Uuid::set_uuid(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  uuid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Uuid.uuid)
}
inline void Uuid::set_uuid(const char* value, size_t size) {
  
  uuid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Uuid.uuid)
}
inline ::std::string* Uuid::mutable_uuid() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Uuid.uuid)
  return uuid_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Uuid::release_uuid() {
  // @@protoc_insertion_point(field_release:dmi.Uuid.uuid)
  
  return uuid_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Uuid::set_allocated_uuid(::std::string* uuid) {
  if (uuid != nullptr) {
    
  } else {
    
  }
  uuid_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), uuid);
  // @@protoc_insertion_point(field_set_allocated:dmi.Uuid.uuid)
}

// -------------------------------------------------------------------

// HardwareID

// .dmi.Uuid uuid = 1;
inline bool HardwareID::has_uuid() const {
  return this != internal_default_instance() && uuid_ != nullptr;
}
inline void HardwareID::clear_uuid() {
  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
    delete uuid_;
  }
  uuid_ = nullptr;
}
inline const ::dmi::Uuid& HardwareID::uuid() const {
  const ::dmi::Uuid* p = uuid_;
  // @@protoc_insertion_point(field_get:dmi.HardwareID.uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* HardwareID::release_uuid() {
  // @@protoc_insertion_point(field_release:dmi.HardwareID.uuid)
  
  ::dmi::Uuid* temp = uuid_;
  uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* HardwareID::mutable_uuid() {
  
  if (uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.HardwareID.uuid)
  return uuid_;
}
inline void HardwareID::set_allocated_uuid(::dmi::Uuid* uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete uuid_;
  }
  if (uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, uuid, submessage_arena);
    }
    
  } else {
    
  }
  uuid_ = uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.HardwareID.uuid)
}

// -------------------------------------------------------------------

// Uri

// string uri = 1;
inline void Uri::clear_uri() {
  uri_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Uri::uri() const {
  // @@protoc_insertion_point(field_get:dmi.Uri.uri)
  return uri_.GetNoArena();
}
inline void Uri::set_uri(const ::std::string& value) {
  
  uri_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Uri.uri)
}
#if LANG_CXX11
inline void Uri::set_uri(::std::string&& value) {
  
  uri_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Uri.uri)
}
#endif
inline void Uri::set_uri(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  uri_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Uri.uri)
}
inline void Uri::set_uri(const char* value, size_t size) {
  
  uri_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Uri.uri)
}
inline ::std::string* Uri::mutable_uri() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Uri.uri)
  return uri_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Uri::release_uri() {
  // @@protoc_insertion_point(field_release:dmi.Uri.uri)
  
  return uri_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Uri::set_allocated_uri(::std::string* uri) {
  if (uri != nullptr) {
    
  } else {
    
  }
  uri_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), uri);
  // @@protoc_insertion_point(field_set_allocated:dmi.Uri.uri)
}

// -------------------------------------------------------------------

// ComponentState

// .google.protobuf.Timestamp state_last_changed = 1;
inline bool ComponentState::has_state_last_changed() const {
  return this != internal_default_instance() && state_last_changed_ != nullptr;
}
inline const ::google::protobuf::Timestamp& ComponentState::state_last_changed() const {
  const ::google::protobuf::Timestamp* p = state_last_changed_;
  // @@protoc_insertion_point(field_get:dmi.ComponentState.state_last_changed)
  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
      &::google::protobuf::_Timestamp_default_instance_);
}
inline ::google::protobuf::Timestamp* ComponentState::release_state_last_changed() {
  // @@protoc_insertion_point(field_release:dmi.ComponentState.state_last_changed)
  
  ::google::protobuf::Timestamp* temp = state_last_changed_;
  state_last_changed_ = nullptr;
  return temp;
}
inline ::google::protobuf::Timestamp* ComponentState::mutable_state_last_changed() {
  
  if (state_last_changed_ == nullptr) {
    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
    state_last_changed_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ComponentState.state_last_changed)
  return state_last_changed_;
}
inline void ComponentState::set_allocated_state_last_changed(::google::protobuf::Timestamp* state_last_changed) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(state_last_changed_);
  }
  if (state_last_changed) {
    ::google::protobuf::Arena* submessage_arena =
      reinterpret_cast<::google::protobuf::MessageLite*>(state_last_changed)->GetArena();
    if (message_arena != submessage_arena) {
      state_last_changed = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, state_last_changed, submessage_arena);
    }
    
  } else {
    
  }
  state_last_changed_ = state_last_changed;
  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentState.state_last_changed)
}

// .dmi.ComponentAdminState admin_state = 2;
inline void ComponentState::clear_admin_state() {
  admin_state_ = 0;
}
inline ::dmi::ComponentAdminState ComponentState::admin_state() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentState.admin_state)
  return static_cast< ::dmi::ComponentAdminState >(admin_state_);
}
inline void ComponentState::set_admin_state(::dmi::ComponentAdminState value) {
  
  admin_state_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentState.admin_state)
}

// .dmi.ComponentOperState oper_state = 3;
inline void ComponentState::clear_oper_state() {
  oper_state_ = 0;
}
inline ::dmi::ComponentOperState ComponentState::oper_state() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentState.oper_state)
  return static_cast< ::dmi::ComponentOperState >(oper_state_);
}
inline void ComponentState::set_oper_state(::dmi::ComponentOperState value) {
  
  oper_state_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentState.oper_state)
}

// .dmi.ComponentUsageState usage_state = 4;
inline void ComponentState::clear_usage_state() {
  usage_state_ = 0;
}
inline ::dmi::ComponentUsageState ComponentState::usage_state() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentState.usage_state)
  return static_cast< ::dmi::ComponentUsageState >(usage_state_);
}
inline void ComponentState::set_usage_state(::dmi::ComponentUsageState value) {
  
  usage_state_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentState.usage_state)
}

// .dmi.ComponentAlarmState alarm_state = 5;
inline void ComponentState::clear_alarm_state() {
  alarm_state_ = 0;
}
inline ::dmi::ComponentAlarmState ComponentState::alarm_state() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentState.alarm_state)
  return static_cast< ::dmi::ComponentAlarmState >(alarm_state_);
}
inline void ComponentState::set_alarm_state(::dmi::ComponentAlarmState value) {
  
  alarm_state_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentState.alarm_state)
}

// .dmi.ComponentStandbyState standby_state = 6;
inline void ComponentState::clear_standby_state() {
  standby_state_ = 0;
}
inline ::dmi::ComponentStandbyState ComponentState::standby_state() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentState.standby_state)
  return static_cast< ::dmi::ComponentStandbyState >(standby_state_);
}
inline void ComponentState::set_standby_state(::dmi::ComponentStandbyState value) {
  
  standby_state_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentState.standby_state)
}

// -------------------------------------------------------------------

// ComponentSensorData

// int32 value = 1;
inline void ComponentSensorData::clear_value() {
  value_ = 0;
}
inline ::google::protobuf::int32 ComponentSensorData::value() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.value)
  return value_;
}
inline void ComponentSensorData::set_value(::google::protobuf::int32 value) {
  
  value_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.value)
}

// .dmi.DataValueType type = 2;
inline void ComponentSensorData::clear_type() {
  type_ = 0;
}
inline ::dmi::DataValueType ComponentSensorData::type() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.type)
  return static_cast< ::dmi::DataValueType >(type_);
}
inline void ComponentSensorData::set_type(::dmi::DataValueType value) {
  
  type_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.type)
}

// .dmi.ValueScale scale = 3;
inline void ComponentSensorData::clear_scale() {
  scale_ = 0;
}
inline ::dmi::ValueScale ComponentSensorData::scale() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.scale)
  return static_cast< ::dmi::ValueScale >(scale_);
}
inline void ComponentSensorData::set_scale(::dmi::ValueScale value) {
  
  scale_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.scale)
}

// int32 precision = 4;
inline void ComponentSensorData::clear_precision() {
  precision_ = 0;
}
inline ::google::protobuf::int32 ComponentSensorData::precision() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.precision)
  return precision_;
}
inline void ComponentSensorData::set_precision(::google::protobuf::int32 value) {
  
  precision_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.precision)
}

// .dmi.SensorStatus status = 5;
inline void ComponentSensorData::clear_status() {
  status_ = 0;
}
inline ::dmi::SensorStatus ComponentSensorData::status() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.status)
  return static_cast< ::dmi::SensorStatus >(status_);
}
inline void ComponentSensorData::set_status(::dmi::SensorStatus value) {
  
  status_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.status)
}

// string units_display = 6;
inline void ComponentSensorData::clear_units_display() {
  units_display_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ComponentSensorData::units_display() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.units_display)
  return units_display_.GetNoArena();
}
inline void ComponentSensorData::set_units_display(const ::std::string& value) {
  
  units_display_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.units_display)
}
#if LANG_CXX11
inline void ComponentSensorData::set_units_display(::std::string&& value) {
  
  units_display_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ComponentSensorData.units_display)
}
#endif
inline void ComponentSensorData::set_units_display(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  units_display_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ComponentSensorData.units_display)
}
inline void ComponentSensorData::set_units_display(const char* value, size_t size) {
  
  units_display_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ComponentSensorData.units_display)
}
inline ::std::string* ComponentSensorData::mutable_units_display() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ComponentSensorData.units_display)
  return units_display_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ComponentSensorData::release_units_display() {
  // @@protoc_insertion_point(field_release:dmi.ComponentSensorData.units_display)
  
  return units_display_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ComponentSensorData::set_allocated_units_display(::std::string* units_display) {
  if (units_display != nullptr) {
    
  } else {
    
  }
  units_display_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), units_display);
  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentSensorData.units_display)
}

// .google.protobuf.Timestamp timestamp = 7;
inline bool ComponentSensorData::has_timestamp() const {
  return this != internal_default_instance() && timestamp_ != nullptr;
}
inline const ::google::protobuf::Timestamp& ComponentSensorData::timestamp() const {
  const ::google::protobuf::Timestamp* p = timestamp_;
  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.timestamp)
  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
      &::google::protobuf::_Timestamp_default_instance_);
}
inline ::google::protobuf::Timestamp* ComponentSensorData::release_timestamp() {
  // @@protoc_insertion_point(field_release:dmi.ComponentSensorData.timestamp)
  
  ::google::protobuf::Timestamp* temp = timestamp_;
  timestamp_ = nullptr;
  return temp;
}
inline ::google::protobuf::Timestamp* ComponentSensorData::mutable_timestamp() {
  
  if (timestamp_ == nullptr) {
    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
    timestamp_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ComponentSensorData.timestamp)
  return timestamp_;
}
inline void ComponentSensorData::set_allocated_timestamp(::google::protobuf::Timestamp* timestamp) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(timestamp_);
  }
  if (timestamp) {
    ::google::protobuf::Arena* submessage_arena =
      reinterpret_cast<::google::protobuf::MessageLite*>(timestamp)->GetArena();
    if (message_arena != submessage_arena) {
      timestamp = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, timestamp, submessage_arena);
    }
    
  } else {
    
  }
  timestamp_ = timestamp;
  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentSensorData.timestamp)
}

// uint32 value_update_rate = 8;
inline void ComponentSensorData::clear_value_update_rate() {
  value_update_rate_ = 0u;
}
inline ::google::protobuf::uint32 ComponentSensorData::value_update_rate() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.value_update_rate)
  return value_update_rate_;
}
inline void ComponentSensorData::set_value_update_rate(::google::protobuf::uint32 value) {
  
  value_update_rate_ = value;
  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.value_update_rate)
}

// string data_type = 9;
inline void ComponentSensorData::clear_data_type() {
  data_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ComponentSensorData::data_type() const {
  // @@protoc_insertion_point(field_get:dmi.ComponentSensorData.data_type)
  return data_type_.GetNoArena();
}
inline void ComponentSensorData::set_data_type(const ::std::string& value) {
  
  data_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ComponentSensorData.data_type)
}
#if LANG_CXX11
inline void ComponentSensorData::set_data_type(::std::string&& value) {
  
  data_type_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ComponentSensorData.data_type)
}
#endif
inline void ComponentSensorData::set_data_type(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  data_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ComponentSensorData.data_type)
}
inline void ComponentSensorData::set_data_type(const char* value, size_t size) {
  
  data_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ComponentSensorData.data_type)
}
inline ::std::string* ComponentSensorData::mutable_data_type() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ComponentSensorData.data_type)
  return data_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ComponentSensorData::release_data_type() {
  // @@protoc_insertion_point(field_release:dmi.ComponentSensorData.data_type)
  
  return data_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ComponentSensorData::set_allocated_data_type(::std::string* data_type) {
  if (data_type != nullptr) {
    
  } else {
    
  }
  data_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), data_type);
  // @@protoc_insertion_point(field_set_allocated:dmi.ComponentSensorData.data_type)
}

// -------------------------------------------------------------------

// PortComponentAttributes

// .dmi.PortComponentAttributes.ConnectorType connector_type = 1;
inline void PortComponentAttributes::clear_connector_type() {
  connector_type_ = 0;
}
inline ::dmi::PortComponentAttributes_ConnectorType PortComponentAttributes::connector_type() const {
  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.connector_type)
  return static_cast< ::dmi::PortComponentAttributes_ConnectorType >(connector_type_);
}
inline void PortComponentAttributes::set_connector_type(::dmi::PortComponentAttributes_ConnectorType value) {
  
  connector_type_ = value;
  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.connector_type)
}

// .dmi.PortComponentAttributes.Speed speed = 2;
inline void PortComponentAttributes::clear_speed() {
  speed_ = 0;
}
inline ::dmi::PortComponentAttributes_Speed PortComponentAttributes::speed() const {
  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.speed)
  return static_cast< ::dmi::PortComponentAttributes_Speed >(speed_);
}
inline void PortComponentAttributes::set_speed(::dmi::PortComponentAttributes_Speed value) {
  
  speed_ = value;
  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.speed)
}

// .dmi.PortComponentAttributes.Protocol protocol = 3;
inline void PortComponentAttributes::clear_protocol() {
  protocol_ = 0;
}
inline ::dmi::PortComponentAttributes_Protocol PortComponentAttributes::protocol() const {
  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.protocol)
  return static_cast< ::dmi::PortComponentAttributes_Protocol >(protocol_);
}
inline void PortComponentAttributes::set_protocol(::dmi::PortComponentAttributes_Protocol value) {
  
  protocol_ = value;
  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.protocol)
}

// string physical_label = 4;
inline void PortComponentAttributes::clear_physical_label() {
  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& PortComponentAttributes::physical_label() const {
  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.physical_label)
  return physical_label_.GetNoArena();
}
inline void PortComponentAttributes::set_physical_label(const ::std::string& value) {
  
  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.physical_label)
}
#if LANG_CXX11
inline void PortComponentAttributes::set_physical_label(::std::string&& value) {
  
  physical_label_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.PortComponentAttributes.physical_label)
}
#endif
inline void PortComponentAttributes::set_physical_label(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.PortComponentAttributes.physical_label)
}
inline void PortComponentAttributes::set_physical_label(const char* value, size_t size) {
  
  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.PortComponentAttributes.physical_label)
}
inline ::std::string* PortComponentAttributes::mutable_physical_label() {
  
  // @@protoc_insertion_point(field_mutable:dmi.PortComponentAttributes.physical_label)
  return physical_label_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* PortComponentAttributes::release_physical_label() {
  // @@protoc_insertion_point(field_release:dmi.PortComponentAttributes.physical_label)
  
  return physical_label_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void PortComponentAttributes::set_allocated_physical_label(::std::string* physical_label) {
  if (physical_label != nullptr) {
    
  } else {
    
  }
  physical_label_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), physical_label);
  // @@protoc_insertion_point(field_set_allocated:dmi.PortComponentAttributes.physical_label)
}

// -------------------------------------------------------------------

// ContainerComponentAttributes

// string physical_label = 1;
inline void ContainerComponentAttributes::clear_physical_label() {
  physical_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ContainerComponentAttributes::physical_label() const {
  // @@protoc_insertion_point(field_get:dmi.ContainerComponentAttributes.physical_label)
  return physical_label_.GetNoArena();
}
inline void ContainerComponentAttributes::set_physical_label(const ::std::string& value) {
  
  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ContainerComponentAttributes.physical_label)
}
#if LANG_CXX11
inline void ContainerComponentAttributes::set_physical_label(::std::string&& value) {
  
  physical_label_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ContainerComponentAttributes.physical_label)
}
#endif
inline void ContainerComponentAttributes::set_physical_label(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ContainerComponentAttributes.physical_label)
}
inline void ContainerComponentAttributes::set_physical_label(const char* value, size_t size) {
  
  physical_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ContainerComponentAttributes.physical_label)
}
inline ::std::string* ContainerComponentAttributes::mutable_physical_label() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ContainerComponentAttributes.physical_label)
  return physical_label_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ContainerComponentAttributes::release_physical_label() {
  // @@protoc_insertion_point(field_release:dmi.ContainerComponentAttributes.physical_label)
  
  return physical_label_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ContainerComponentAttributes::set_allocated_physical_label(::std::string* physical_label) {
  if (physical_label != nullptr) {
    
  } else {
    
  }
  physical_label_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), physical_label);
  // @@protoc_insertion_point(field_set_allocated:dmi.ContainerComponentAttributes.physical_label)
}

// -------------------------------------------------------------------

// PsuComponentAttributes

// .dmi.PsuComponentAttributes.SupportedVoltage supported_voltage = 1;
inline void PsuComponentAttributes::clear_supported_voltage() {
  supported_voltage_ = 0;
}
inline ::dmi::PsuComponentAttributes_SupportedVoltage PsuComponentAttributes::supported_voltage() const {
  // @@protoc_insertion_point(field_get:dmi.PsuComponentAttributes.supported_voltage)
  return static_cast< ::dmi::PsuComponentAttributes_SupportedVoltage >(supported_voltage_);
}
inline void PsuComponentAttributes::set_supported_voltage(::dmi::PsuComponentAttributes_SupportedVoltage value) {
  
  supported_voltage_ = value;
  // @@protoc_insertion_point(field_set:dmi.PsuComponentAttributes.supported_voltage)
}

// -------------------------------------------------------------------

// TransceiverComponentsAttributes

// .dmi.TransceiverComponentsAttributes.FormFactor form_factor = 1;
inline void TransceiverComponentsAttributes::clear_form_factor() {
  form_factor_ = 0;
}
inline ::dmi::TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes::form_factor() const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.form_factor)
  return static_cast< ::dmi::TransceiverComponentsAttributes_FormFactor >(form_factor_);
}
inline void TransceiverComponentsAttributes::set_form_factor(::dmi::TransceiverComponentsAttributes_FormFactor value) {
  
  form_factor_ = value;
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.form_factor)
}

// .dmi.TransceiverComponentsAttributes.Type trans_type = 2;
inline void TransceiverComponentsAttributes::clear_trans_type() {
  trans_type_ = 0;
}
inline ::dmi::TransceiverComponentsAttributes_Type TransceiverComponentsAttributes::trans_type() const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.trans_type)
  return static_cast< ::dmi::TransceiverComponentsAttributes_Type >(trans_type_);
}
inline void TransceiverComponentsAttributes::set_trans_type(::dmi::TransceiverComponentsAttributes_Type value) {
  
  trans_type_ = value;
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.trans_type)
}

// uint32 max_distance = 3;
inline void TransceiverComponentsAttributes::clear_max_distance() {
  max_distance_ = 0u;
}
inline ::google::protobuf::uint32 TransceiverComponentsAttributes::max_distance() const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.max_distance)
  return max_distance_;
}
inline void TransceiverComponentsAttributes::set_max_distance(::google::protobuf::uint32 value) {
  
  max_distance_ = value;
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.max_distance)
}

// .dmi.ValueScale max_distance_scale = 4;
inline void TransceiverComponentsAttributes::clear_max_distance_scale() {
  max_distance_scale_ = 0;
}
inline ::dmi::ValueScale TransceiverComponentsAttributes::max_distance_scale() const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.max_distance_scale)
  return static_cast< ::dmi::ValueScale >(max_distance_scale_);
}
inline void TransceiverComponentsAttributes::set_max_distance_scale(::dmi::ValueScale value) {
  
  max_distance_scale_ = value;
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.max_distance_scale)
}

// repeated uint32 rx_wavelength = 5;
inline int TransceiverComponentsAttributes::rx_wavelength_size() const {
  return rx_wavelength_.size();
}
inline void TransceiverComponentsAttributes::clear_rx_wavelength() {
  rx_wavelength_.Clear();
}
inline ::google::protobuf::uint32 TransceiverComponentsAttributes::rx_wavelength(int index) const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.rx_wavelength)
  return rx_wavelength_.Get(index);
}
inline void TransceiverComponentsAttributes::set_rx_wavelength(int index, ::google::protobuf::uint32 value) {
  rx_wavelength_.Set(index, value);
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.rx_wavelength)
}
inline void TransceiverComponentsAttributes::add_rx_wavelength(::google::protobuf::uint32 value) {
  rx_wavelength_.Add(value);
  // @@protoc_insertion_point(field_add:dmi.TransceiverComponentsAttributes.rx_wavelength)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
TransceiverComponentsAttributes::rx_wavelength() const {
  // @@protoc_insertion_point(field_list:dmi.TransceiverComponentsAttributes.rx_wavelength)
  return rx_wavelength_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
TransceiverComponentsAttributes::mutable_rx_wavelength() {
  // @@protoc_insertion_point(field_mutable_list:dmi.TransceiverComponentsAttributes.rx_wavelength)
  return &rx_wavelength_;
}

// repeated uint32 tx_wavelength = 6;
inline int TransceiverComponentsAttributes::tx_wavelength_size() const {
  return tx_wavelength_.size();
}
inline void TransceiverComponentsAttributes::clear_tx_wavelength() {
  tx_wavelength_.Clear();
}
inline ::google::protobuf::uint32 TransceiverComponentsAttributes::tx_wavelength(int index) const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.tx_wavelength)
  return tx_wavelength_.Get(index);
}
inline void TransceiverComponentsAttributes::set_tx_wavelength(int index, ::google::protobuf::uint32 value) {
  tx_wavelength_.Set(index, value);
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.tx_wavelength)
}
inline void TransceiverComponentsAttributes::add_tx_wavelength(::google::protobuf::uint32 value) {
  tx_wavelength_.Add(value);
  // @@protoc_insertion_point(field_add:dmi.TransceiverComponentsAttributes.tx_wavelength)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >&
TransceiverComponentsAttributes::tx_wavelength() const {
  // @@protoc_insertion_point(field_list:dmi.TransceiverComponentsAttributes.tx_wavelength)
  return tx_wavelength_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >*
TransceiverComponentsAttributes::mutable_tx_wavelength() {
  // @@protoc_insertion_point(field_mutable_list:dmi.TransceiverComponentsAttributes.tx_wavelength)
  return &tx_wavelength_;
}

// .dmi.ValueScale wavelength_scale = 7;
inline void TransceiverComponentsAttributes::clear_wavelength_scale() {
  wavelength_scale_ = 0;
}
inline ::dmi::ValueScale TransceiverComponentsAttributes::wavelength_scale() const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.wavelength_scale)
  return static_cast< ::dmi::ValueScale >(wavelength_scale_);
}
inline void TransceiverComponentsAttributes::set_wavelength_scale(::dmi::ValueScale value) {
  
  wavelength_scale_ = value;
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.wavelength_scale)
}

// -------------------------------------------------------------------

// Component

// string name = 1;
inline void Component::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::name() const {
  // @@protoc_insertion_point(field_get:dmi.Component.name)
  return name_.GetNoArena();
}
inline void Component::set_name(const ::std::string& value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.name)
}
#if LANG_CXX11
inline void Component::set_name(::std::string&& value) {
  
  name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.name)
}
#endif
inline void Component::set_name(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.name)
}
inline void Component::set_name(const char* value, size_t size) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.name)
}
inline ::std::string* Component::mutable_name() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.name)
  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_name() {
  // @@protoc_insertion_point(field_release:dmi.Component.name)
  
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_name(::std::string* name) {
  if (name != nullptr) {
    
  } else {
    
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.name)
}

// .dmi.ComponentType class = 2;
inline void Component::clear_class_() {
  class__ = 0;
}
inline ::dmi::ComponentType Component::class_() const {
  // @@protoc_insertion_point(field_get:dmi.Component.class)
  return static_cast< ::dmi::ComponentType >(class__);
}
inline void Component::set_class_(::dmi::ComponentType value) {
  
  class__ = value;
  // @@protoc_insertion_point(field_set:dmi.Component.class)
}

// string description = 3;
inline void Component::clear_description() {
  description_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::description() const {
  // @@protoc_insertion_point(field_get:dmi.Component.description)
  return description_.GetNoArena();
}
inline void Component::set_description(const ::std::string& value) {
  
  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.description)
}
#if LANG_CXX11
inline void Component::set_description(::std::string&& value) {
  
  description_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.description)
}
#endif
inline void Component::set_description(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.description)
}
inline void Component::set_description(const char* value, size_t size) {
  
  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.description)
}
inline ::std::string* Component::mutable_description() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.description)
  return description_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_description() {
  // @@protoc_insertion_point(field_release:dmi.Component.description)
  
  return description_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_description(::std::string* description) {
  if (description != nullptr) {
    
  } else {
    
  }
  description_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), description);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.description)
}

// string parent = 4;
inline void Component::clear_parent() {
  parent_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::parent() const {
  // @@protoc_insertion_point(field_get:dmi.Component.parent)
  return parent_.GetNoArena();
}
inline void Component::set_parent(const ::std::string& value) {
  
  parent_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.parent)
}
#if LANG_CXX11
inline void Component::set_parent(::std::string&& value) {
  
  parent_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.parent)
}
#endif
inline void Component::set_parent(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  parent_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.parent)
}
inline void Component::set_parent(const char* value, size_t size) {
  
  parent_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.parent)
}
inline ::std::string* Component::mutable_parent() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.parent)
  return parent_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_parent() {
  // @@protoc_insertion_point(field_release:dmi.Component.parent)
  
  return parent_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_parent(::std::string* parent) {
  if (parent != nullptr) {
    
  } else {
    
  }
  parent_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), parent);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.parent)
}

// int32 parent_rel_pos = 5;
inline void Component::clear_parent_rel_pos() {
  parent_rel_pos_ = 0;
}
inline ::google::protobuf::int32 Component::parent_rel_pos() const {
  // @@protoc_insertion_point(field_get:dmi.Component.parent_rel_pos)
  return parent_rel_pos_;
}
inline void Component::set_parent_rel_pos(::google::protobuf::int32 value) {
  
  parent_rel_pos_ = value;
  // @@protoc_insertion_point(field_set:dmi.Component.parent_rel_pos)
}

// repeated .dmi.Component children = 6;
inline int Component::children_size() const {
  return children_.size();
}
inline void Component::clear_children() {
  children_.Clear();
}
inline ::dmi::Component* Component::mutable_children(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.Component.children)
  return children_.Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField< ::dmi::Component >*
Component::mutable_children() {
  // @@protoc_insertion_point(field_mutable_list:dmi.Component.children)
  return &children_;
}
inline const ::dmi::Component& Component::children(int index) const {
  // @@protoc_insertion_point(field_get:dmi.Component.children)
  return children_.Get(index);
}
inline ::dmi::Component* Component::add_children() {
  // @@protoc_insertion_point(field_add:dmi.Component.children)
  return children_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::dmi::Component >&
Component::children() const {
  // @@protoc_insertion_point(field_list:dmi.Component.children)
  return children_;
}

// string hardware_rev = 7;
inline void Component::clear_hardware_rev() {
  hardware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::hardware_rev() const {
  // @@protoc_insertion_point(field_get:dmi.Component.hardware_rev)
  return hardware_rev_.GetNoArena();
}
inline void Component::set_hardware_rev(const ::std::string& value) {
  
  hardware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.hardware_rev)
}
#if LANG_CXX11
inline void Component::set_hardware_rev(::std::string&& value) {
  
  hardware_rev_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.hardware_rev)
}
#endif
inline void Component::set_hardware_rev(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  hardware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.hardware_rev)
}
inline void Component::set_hardware_rev(const char* value, size_t size) {
  
  hardware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.hardware_rev)
}
inline ::std::string* Component::mutable_hardware_rev() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.hardware_rev)
  return hardware_rev_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_hardware_rev() {
  // @@protoc_insertion_point(field_release:dmi.Component.hardware_rev)
  
  return hardware_rev_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_hardware_rev(::std::string* hardware_rev) {
  if (hardware_rev != nullptr) {
    
  } else {
    
  }
  hardware_rev_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), hardware_rev);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.hardware_rev)
}

// string firmware_rev = 8;
inline void Component::clear_firmware_rev() {
  firmware_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::firmware_rev() const {
  // @@protoc_insertion_point(field_get:dmi.Component.firmware_rev)
  return firmware_rev_.GetNoArena();
}
inline void Component::set_firmware_rev(const ::std::string& value) {
  
  firmware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.firmware_rev)
}
#if LANG_CXX11
inline void Component::set_firmware_rev(::std::string&& value) {
  
  firmware_rev_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.firmware_rev)
}
#endif
inline void Component::set_firmware_rev(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  firmware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.firmware_rev)
}
inline void Component::set_firmware_rev(const char* value, size_t size) {
  
  firmware_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.firmware_rev)
}
inline ::std::string* Component::mutable_firmware_rev() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.firmware_rev)
  return firmware_rev_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_firmware_rev() {
  // @@protoc_insertion_point(field_release:dmi.Component.firmware_rev)
  
  return firmware_rev_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_firmware_rev(::std::string* firmware_rev) {
  if (firmware_rev != nullptr) {
    
  } else {
    
  }
  firmware_rev_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), firmware_rev);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.firmware_rev)
}

// string software_rev = 9;
inline void Component::clear_software_rev() {
  software_rev_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::software_rev() const {
  // @@protoc_insertion_point(field_get:dmi.Component.software_rev)
  return software_rev_.GetNoArena();
}
inline void Component::set_software_rev(const ::std::string& value) {
  
  software_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.software_rev)
}
#if LANG_CXX11
inline void Component::set_software_rev(::std::string&& value) {
  
  software_rev_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.software_rev)
}
#endif
inline void Component::set_software_rev(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  software_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.software_rev)
}
inline void Component::set_software_rev(const char* value, size_t size) {
  
  software_rev_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.software_rev)
}
inline ::std::string* Component::mutable_software_rev() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.software_rev)
  return software_rev_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_software_rev() {
  // @@protoc_insertion_point(field_release:dmi.Component.software_rev)
  
  return software_rev_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_software_rev(::std::string* software_rev) {
  if (software_rev != nullptr) {
    
  } else {
    
  }
  software_rev_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), software_rev);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.software_rev)
}

// string serial_num = 10;
inline void Component::clear_serial_num() {
  serial_num_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::serial_num() const {
  // @@protoc_insertion_point(field_get:dmi.Component.serial_num)
  return serial_num_.GetNoArena();
}
inline void Component::set_serial_num(const ::std::string& value) {
  
  serial_num_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.serial_num)
}
#if LANG_CXX11
inline void Component::set_serial_num(::std::string&& value) {
  
  serial_num_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.serial_num)
}
#endif
inline void Component::set_serial_num(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  serial_num_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.serial_num)
}
inline void Component::set_serial_num(const char* value, size_t size) {
  
  serial_num_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.serial_num)
}
inline ::std::string* Component::mutable_serial_num() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.serial_num)
  return serial_num_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_serial_num() {
  // @@protoc_insertion_point(field_release:dmi.Component.serial_num)
  
  return serial_num_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_serial_num(::std::string* serial_num) {
  if (serial_num != nullptr) {
    
  } else {
    
  }
  serial_num_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), serial_num);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.serial_num)
}

// string mfg_name = 11;
inline void Component::clear_mfg_name() {
  mfg_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::mfg_name() const {
  // @@protoc_insertion_point(field_get:dmi.Component.mfg_name)
  return mfg_name_.GetNoArena();
}
inline void Component::set_mfg_name(const ::std::string& value) {
  
  mfg_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.mfg_name)
}
#if LANG_CXX11
inline void Component::set_mfg_name(::std::string&& value) {
  
  mfg_name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.mfg_name)
}
#endif
inline void Component::set_mfg_name(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  mfg_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.mfg_name)
}
inline void Component::set_mfg_name(const char* value, size_t size) {
  
  mfg_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.mfg_name)
}
inline ::std::string* Component::mutable_mfg_name() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.mfg_name)
  return mfg_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_mfg_name() {
  // @@protoc_insertion_point(field_release:dmi.Component.mfg_name)
  
  return mfg_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_mfg_name(::std::string* mfg_name) {
  if (mfg_name != nullptr) {
    
  } else {
    
  }
  mfg_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), mfg_name);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.mfg_name)
}

// string model_name = 12;
inline void Component::clear_model_name() {
  model_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::model_name() const {
  // @@protoc_insertion_point(field_get:dmi.Component.model_name)
  return model_name_.GetNoArena();
}
inline void Component::set_model_name(const ::std::string& value) {
  
  model_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.model_name)
}
#if LANG_CXX11
inline void Component::set_model_name(::std::string&& value) {
  
  model_name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.model_name)
}
#endif
inline void Component::set_model_name(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  model_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.model_name)
}
inline void Component::set_model_name(const char* value, size_t size) {
  
  model_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.model_name)
}
inline ::std::string* Component::mutable_model_name() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.model_name)
  return model_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_model_name() {
  // @@protoc_insertion_point(field_release:dmi.Component.model_name)
  
  return model_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_model_name(::std::string* model_name) {
  if (model_name != nullptr) {
    
  } else {
    
  }
  model_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), model_name);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.model_name)
}

// string alias = 13;
inline void Component::clear_alias() {
  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::alias() const {
  // @@protoc_insertion_point(field_get:dmi.Component.alias)
  return alias_.GetNoArena();
}
inline void Component::set_alias(const ::std::string& value) {
  
  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.alias)
}
#if LANG_CXX11
inline void Component::set_alias(::std::string&& value) {
  
  alias_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.alias)
}
#endif
inline void Component::set_alias(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.alias)
}
inline void Component::set_alias(const char* value, size_t size) {
  
  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.alias)
}
inline ::std::string* Component::mutable_alias() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.alias)
  return alias_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_alias() {
  // @@protoc_insertion_point(field_release:dmi.Component.alias)
  
  return alias_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_alias(::std::string* alias) {
  if (alias != nullptr) {
    
  } else {
    
  }
  alias_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), alias);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.alias)
}

// string asset_id = 14;
inline void Component::clear_asset_id() {
  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& Component::asset_id() const {
  // @@protoc_insertion_point(field_get:dmi.Component.asset_id)
  return asset_id_.GetNoArena();
}
inline void Component::set_asset_id(const ::std::string& value) {
  
  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.Component.asset_id)
}
#if LANG_CXX11
inline void Component::set_asset_id(::std::string&& value) {
  
  asset_id_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.Component.asset_id)
}
#endif
inline void Component::set_asset_id(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.Component.asset_id)
}
inline void Component::set_asset_id(const char* value, size_t size) {
  
  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.Component.asset_id)
}
inline ::std::string* Component::mutable_asset_id() {
  
  // @@protoc_insertion_point(field_mutable:dmi.Component.asset_id)
  return asset_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Component::release_asset_id() {
  // @@protoc_insertion_point(field_release:dmi.Component.asset_id)
  
  return asset_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void Component::set_allocated_asset_id(::std::string* asset_id) {
  if (asset_id != nullptr) {
    
  } else {
    
  }
  asset_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), asset_id);
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.asset_id)
}

// bool is_fru = 15;
inline void Component::clear_is_fru() {
  is_fru_ = false;
}
inline bool Component::is_fru() const {
  // @@protoc_insertion_point(field_get:dmi.Component.is_fru)
  return is_fru_;
}
inline void Component::set_is_fru(bool value) {
  
  is_fru_ = value;
  // @@protoc_insertion_point(field_set:dmi.Component.is_fru)
}

// .google.protobuf.Timestamp mfg_date = 16;
inline bool Component::has_mfg_date() const {
  return this != internal_default_instance() && mfg_date_ != nullptr;
}
inline const ::google::protobuf::Timestamp& Component::mfg_date() const {
  const ::google::protobuf::Timestamp* p = mfg_date_;
  // @@protoc_insertion_point(field_get:dmi.Component.mfg_date)
  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
      &::google::protobuf::_Timestamp_default_instance_);
}
inline ::google::protobuf::Timestamp* Component::release_mfg_date() {
  // @@protoc_insertion_point(field_release:dmi.Component.mfg_date)
  
  ::google::protobuf::Timestamp* temp = mfg_date_;
  mfg_date_ = nullptr;
  return temp;
}
inline ::google::protobuf::Timestamp* Component::mutable_mfg_date() {
  
  if (mfg_date_ == nullptr) {
    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
    mfg_date_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Component.mfg_date)
  return mfg_date_;
}
inline void Component::set_allocated_mfg_date(::google::protobuf::Timestamp* mfg_date) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(mfg_date_);
  }
  if (mfg_date) {
    ::google::protobuf::Arena* submessage_arena =
      reinterpret_cast<::google::protobuf::MessageLite*>(mfg_date)->GetArena();
    if (message_arena != submessage_arena) {
      mfg_date = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, mfg_date, submessage_arena);
    }
    
  } else {
    
  }
  mfg_date_ = mfg_date;
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.mfg_date)
}

// .dmi.Uri uri = 17;
inline bool Component::has_uri() const {
  return this != internal_default_instance() && uri_ != nullptr;
}
inline void Component::clear_uri() {
  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
    delete uri_;
  }
  uri_ = nullptr;
}
inline const ::dmi::Uri& Component::uri() const {
  const ::dmi::Uri* p = uri_;
  // @@protoc_insertion_point(field_get:dmi.Component.uri)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uri*>(
      &::dmi::_Uri_default_instance_);
}
inline ::dmi::Uri* Component::release_uri() {
  // @@protoc_insertion_point(field_release:dmi.Component.uri)
  
  ::dmi::Uri* temp = uri_;
  uri_ = nullptr;
  return temp;
}
inline ::dmi::Uri* Component::mutable_uri() {
  
  if (uri_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uri>(GetArenaNoVirtual());
    uri_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Component.uri)
  return uri_;
}
inline void Component::set_allocated_uri(::dmi::Uri* uri) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete uri_;
  }
  if (uri) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      uri = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, uri, submessage_arena);
    }
    
  } else {
    
  }
  uri_ = uri;
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.uri)
}

// .dmi.Uuid uuid = 18;
inline bool Component::has_uuid() const {
  return this != internal_default_instance() && uuid_ != nullptr;
}
inline void Component::clear_uuid() {
  if (GetArenaNoVirtual() == nullptr && uuid_ != nullptr) {
    delete uuid_;
  }
  uuid_ = nullptr;
}
inline const ::dmi::Uuid& Component::uuid() const {
  const ::dmi::Uuid* p = uuid_;
  // @@protoc_insertion_point(field_get:dmi.Component.uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* Component::release_uuid() {
  // @@protoc_insertion_point(field_release:dmi.Component.uuid)
  
  ::dmi::Uuid* temp = uuid_;
  uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* Component::mutable_uuid() {
  
  if (uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Component.uuid)
  return uuid_;
}
inline void Component::set_allocated_uuid(::dmi::Uuid* uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete uuid_;
  }
  if (uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, uuid, submessage_arena);
    }
    
  } else {
    
  }
  uuid_ = uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.uuid)
}

// .dmi.ComponentState state = 19;
inline bool Component::has_state() const {
  return this != internal_default_instance() && state_ != nullptr;
}
inline void Component::clear_state() {
  if (GetArenaNoVirtual() == nullptr && state_ != nullptr) {
    delete state_;
  }
  state_ = nullptr;
}
inline const ::dmi::ComponentState& Component::state() const {
  const ::dmi::ComponentState* p = state_;
  // @@protoc_insertion_point(field_get:dmi.Component.state)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ComponentState*>(
      &::dmi::_ComponentState_default_instance_);
}
inline ::dmi::ComponentState* Component::release_state() {
  // @@protoc_insertion_point(field_release:dmi.Component.state)
  
  ::dmi::ComponentState* temp = state_;
  state_ = nullptr;
  return temp;
}
inline ::dmi::ComponentState* Component::mutable_state() {
  
  if (state_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::ComponentState>(GetArenaNoVirtual());
    state_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Component.state)
  return state_;
}
inline void Component::set_allocated_state(::dmi::ComponentState* state) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete state_;
  }
  if (state) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      state = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, state, submessage_arena);
    }
    
  } else {
    
  }
  state_ = state;
  // @@protoc_insertion_point(field_set_allocated:dmi.Component.state)
}

// repeated .dmi.ComponentSensorData sensor_data = 20;
inline int Component::sensor_data_size() const {
  return sensor_data_.size();
}
inline void Component::clear_sensor_data() {
  sensor_data_.Clear();
}
inline ::dmi::ComponentSensorData* Component::mutable_sensor_data(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.Component.sensor_data)
  return sensor_data_.Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >*
Component::mutable_sensor_data() {
  // @@protoc_insertion_point(field_mutable_list:dmi.Component.sensor_data)
  return &sensor_data_;
}
inline const ::dmi::ComponentSensorData& Component::sensor_data(int index) const {
  // @@protoc_insertion_point(field_get:dmi.Component.sensor_data)
  return sensor_data_.Get(index);
}
inline ::dmi::ComponentSensorData* Component::add_sensor_data() {
  // @@protoc_insertion_point(field_add:dmi.Component.sensor_data)
  return sensor_data_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::dmi::ComponentSensorData >&
Component::sensor_data() const {
  // @@protoc_insertion_point(field_list:dmi.Component.sensor_data)
  return sensor_data_;
}

// .dmi.PortComponentAttributes port_attr = 50;
inline bool Component::has_port_attr() const {
  return specific_case() == kPortAttr;
}
inline void Component::set_has_port_attr() {
  _oneof_case_[0] = kPortAttr;
}
inline void Component::clear_port_attr() {
  if (has_port_attr()) {
    delete specific_.port_attr_;
    clear_has_specific();
  }
}
inline ::dmi::PortComponentAttributes* Component::release_port_attr() {
  // @@protoc_insertion_point(field_release:dmi.Component.port_attr)
  if (has_port_attr()) {
    clear_has_specific();
      ::dmi::PortComponentAttributes* temp = specific_.port_attr_;
    specific_.port_attr_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::PortComponentAttributes& Component::port_attr() const {
  // @@protoc_insertion_point(field_get:dmi.Component.port_attr)
  return has_port_attr()
      ? *specific_.port_attr_
      : *reinterpret_cast< ::dmi::PortComponentAttributes*>(&::dmi::_PortComponentAttributes_default_instance_);
}
inline ::dmi::PortComponentAttributes* Component::mutable_port_attr() {
  if (!has_port_attr()) {
    clear_specific();
    set_has_port_attr();
    specific_.port_attr_ = CreateMaybeMessage< ::dmi::PortComponentAttributes >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.Component.port_attr)
  return specific_.port_attr_;
}

// .dmi.ContainerComponentAttributes container_attr = 51;
inline bool Component::has_container_attr() const {
  return specific_case() == kContainerAttr;
}
inline void Component::set_has_container_attr() {
  _oneof_case_[0] = kContainerAttr;
}
inline void Component::clear_container_attr() {
  if (has_container_attr()) {
    delete specific_.container_attr_;
    clear_has_specific();
  }
}
inline ::dmi::ContainerComponentAttributes* Component::release_container_attr() {
  // @@protoc_insertion_point(field_release:dmi.Component.container_attr)
  if (has_container_attr()) {
    clear_has_specific();
      ::dmi::ContainerComponentAttributes* temp = specific_.container_attr_;
    specific_.container_attr_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::ContainerComponentAttributes& Component::container_attr() const {
  // @@protoc_insertion_point(field_get:dmi.Component.container_attr)
  return has_container_attr()
      ? *specific_.container_attr_
      : *reinterpret_cast< ::dmi::ContainerComponentAttributes*>(&::dmi::_ContainerComponentAttributes_default_instance_);
}
inline ::dmi::ContainerComponentAttributes* Component::mutable_container_attr() {
  if (!has_container_attr()) {
    clear_specific();
    set_has_container_attr();
    specific_.container_attr_ = CreateMaybeMessage< ::dmi::ContainerComponentAttributes >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.Component.container_attr)
  return specific_.container_attr_;
}

// .dmi.PsuComponentAttributes psu_attr = 52;
inline bool Component::has_psu_attr() const {
  return specific_case() == kPsuAttr;
}
inline void Component::set_has_psu_attr() {
  _oneof_case_[0] = kPsuAttr;
}
inline void Component::clear_psu_attr() {
  if (has_psu_attr()) {
    delete specific_.psu_attr_;
    clear_has_specific();
  }
}
inline ::dmi::PsuComponentAttributes* Component::release_psu_attr() {
  // @@protoc_insertion_point(field_release:dmi.Component.psu_attr)
  if (has_psu_attr()) {
    clear_has_specific();
      ::dmi::PsuComponentAttributes* temp = specific_.psu_attr_;
    specific_.psu_attr_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::PsuComponentAttributes& Component::psu_attr() const {
  // @@protoc_insertion_point(field_get:dmi.Component.psu_attr)
  return has_psu_attr()
      ? *specific_.psu_attr_
      : *reinterpret_cast< ::dmi::PsuComponentAttributes*>(&::dmi::_PsuComponentAttributes_default_instance_);
}
inline ::dmi::PsuComponentAttributes* Component::mutable_psu_attr() {
  if (!has_psu_attr()) {
    clear_specific();
    set_has_psu_attr();
    specific_.psu_attr_ = CreateMaybeMessage< ::dmi::PsuComponentAttributes >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.Component.psu_attr)
  return specific_.psu_attr_;
}

// .dmi.TransceiverComponentsAttributes transceiver_attr = 53;
inline bool Component::has_transceiver_attr() const {
  return specific_case() == kTransceiverAttr;
}
inline void Component::set_has_transceiver_attr() {
  _oneof_case_[0] = kTransceiverAttr;
}
inline void Component::clear_transceiver_attr() {
  if (has_transceiver_attr()) {
    delete specific_.transceiver_attr_;
    clear_has_specific();
  }
}
inline ::dmi::TransceiverComponentsAttributes* Component::release_transceiver_attr() {
  // @@protoc_insertion_point(field_release:dmi.Component.transceiver_attr)
  if (has_transceiver_attr()) {
    clear_has_specific();
      ::dmi::TransceiverComponentsAttributes* temp = specific_.transceiver_attr_;
    specific_.transceiver_attr_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::TransceiverComponentsAttributes& Component::transceiver_attr() const {
  // @@protoc_insertion_point(field_get:dmi.Component.transceiver_attr)
  return has_transceiver_attr()
      ? *specific_.transceiver_attr_
      : *reinterpret_cast< ::dmi::TransceiverComponentsAttributes*>(&::dmi::_TransceiverComponentsAttributes_default_instance_);
}
inline ::dmi::TransceiverComponentsAttributes* Component::mutable_transceiver_attr() {
  if (!has_transceiver_attr()) {
    clear_specific();
    set_has_transceiver_attr();
    specific_.transceiver_attr_ = CreateMaybeMessage< ::dmi::TransceiverComponentsAttributes >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.Component.transceiver_attr)
  return specific_.transceiver_attr_;
}

inline bool Component::has_specific() const {
  return specific_case() != SPECIFIC_NOT_SET;
}
inline void Component::clear_has_specific() {
  _oneof_case_[0] = SPECIFIC_NOT_SET;
}
inline Component::SpecificCase Component::specific_case() const {
  return Component::SpecificCase(_oneof_case_[0]);
}
// -------------------------------------------------------------------

// Hardware

// .google.protobuf.Timestamp last_change = 1;
inline bool Hardware::has_last_change() const {
  return this != internal_default_instance() && last_change_ != nullptr;
}
inline const ::google::protobuf::Timestamp& Hardware::last_change() const {
  const ::google::protobuf::Timestamp* p = last_change_;
  // @@protoc_insertion_point(field_get:dmi.Hardware.last_change)
  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
      &::google::protobuf::_Timestamp_default_instance_);
}
inline ::google::protobuf::Timestamp* Hardware::release_last_change() {
  // @@protoc_insertion_point(field_release:dmi.Hardware.last_change)
  
  ::google::protobuf::Timestamp* temp = last_change_;
  last_change_ = nullptr;
  return temp;
}
inline ::google::protobuf::Timestamp* Hardware::mutable_last_change() {
  
  if (last_change_ == nullptr) {
    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
    last_change_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Hardware.last_change)
  return last_change_;
}
inline void Hardware::set_allocated_last_change(::google::protobuf::Timestamp* last_change) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(last_change_);
  }
  if (last_change) {
    ::google::protobuf::Arena* submessage_arena =
      reinterpret_cast<::google::protobuf::MessageLite*>(last_change)->GetArena();
    if (message_arena != submessage_arena) {
      last_change = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, last_change, submessage_arena);
    }
    
  } else {
    
  }
  last_change_ = last_change;
  // @@protoc_insertion_point(field_set_allocated:dmi.Hardware.last_change)
}

// .dmi.Component root = 2;
inline bool Hardware::has_root() const {
  return this != internal_default_instance() && root_ != nullptr;
}
inline void Hardware::clear_root() {
  if (GetArenaNoVirtual() == nullptr && root_ != nullptr) {
    delete root_;
  }
  root_ = nullptr;
}
inline const ::dmi::Component& Hardware::root() const {
  const ::dmi::Component* p = root_;
  // @@protoc_insertion_point(field_get:dmi.Hardware.root)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Component*>(
      &::dmi::_Component_default_instance_);
}
inline ::dmi::Component* Hardware::release_root() {
  // @@protoc_insertion_point(field_release:dmi.Hardware.root)
  
  ::dmi::Component* temp = root_;
  root_ = nullptr;
  return temp;
}
inline ::dmi::Component* Hardware::mutable_root() {
  
  if (root_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Component>(GetArenaNoVirtual());
    root_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Hardware.root)
  return root_;
}
inline void Hardware::set_allocated_root(::dmi::Component* root) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete root_;
  }
  if (root) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      root = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, root, submessage_arena);
    }
    
  } else {
    
  }
  root_ = root;
  // @@protoc_insertion_point(field_set_allocated:dmi.Hardware.root)
}

// .google.protobuf.Timestamp last_booted = 3;
inline bool Hardware::has_last_booted() const {
  return this != internal_default_instance() && last_booted_ != nullptr;
}
inline const ::google::protobuf::Timestamp& Hardware::last_booted() const {
  const ::google::protobuf::Timestamp* p = last_booted_;
  // @@protoc_insertion_point(field_get:dmi.Hardware.last_booted)
  return p != nullptr ? *p : *reinterpret_cast<const ::google::protobuf::Timestamp*>(
      &::google::protobuf::_Timestamp_default_instance_);
}
inline ::google::protobuf::Timestamp* Hardware::release_last_booted() {
  // @@protoc_insertion_point(field_release:dmi.Hardware.last_booted)
  
  ::google::protobuf::Timestamp* temp = last_booted_;
  last_booted_ = nullptr;
  return temp;
}
inline ::google::protobuf::Timestamp* Hardware::mutable_last_booted() {
  
  if (last_booted_ == nullptr) {
    auto* p = CreateMaybeMessage<::google::protobuf::Timestamp>(GetArenaNoVirtual());
    last_booted_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.Hardware.last_booted)
  return last_booted_;
}
inline void Hardware::set_allocated_last_booted(::google::protobuf::Timestamp* last_booted) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(last_booted_);
  }
  if (last_booted) {
    ::google::protobuf::Arena* submessage_arena =
      reinterpret_cast<::google::protobuf::MessageLite*>(last_booted)->GetArena();
    if (message_arena != submessage_arena) {
      last_booted = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, last_booted, submessage_arena);
    }
    
  } else {
    
  }
  last_booted_ = last_booted;
  // @@protoc_insertion_point(field_set_allocated:dmi.Hardware.last_booted)
}

// -------------------------------------------------------------------

// ModifiableComponent

// string name = 1;
inline void ModifiableComponent::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ModifiableComponent::name() const {
  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.name)
  return name_.GetNoArena();
}
inline void ModifiableComponent::set_name(const ::std::string& value) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.name)
}
#if LANG_CXX11
inline void ModifiableComponent::set_name(::std::string&& value) {
  
  name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ModifiableComponent.name)
}
#endif
inline void ModifiableComponent::set_name(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ModifiableComponent.name)
}
inline void ModifiableComponent::set_name(const char* value, size_t size) {
  
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ModifiableComponent.name)
}
inline ::std::string* ModifiableComponent::mutable_name() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.name)
  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ModifiableComponent::release_name() {
  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.name)
  
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ModifiableComponent::set_allocated_name(::std::string* name) {
  if (name != nullptr) {
    
  } else {
    
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.name)
}

// .dmi.ComponentType class = 2;
inline void ModifiableComponent::clear_class_() {
  class__ = 0;
}
inline ::dmi::ComponentType ModifiableComponent::class_() const {
  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.class)
  return static_cast< ::dmi::ComponentType >(class__);
}
inline void ModifiableComponent::set_class_(::dmi::ComponentType value) {
  
  class__ = value;
  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.class)
}

// .dmi.Component parent = 3;
inline bool ModifiableComponent::has_parent() const {
  return this != internal_default_instance() && parent_ != nullptr;
}
inline void ModifiableComponent::clear_parent() {
  if (GetArenaNoVirtual() == nullptr && parent_ != nullptr) {
    delete parent_;
  }
  parent_ = nullptr;
}
inline const ::dmi::Component& ModifiableComponent::parent() const {
  const ::dmi::Component* p = parent_;
  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.parent)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Component*>(
      &::dmi::_Component_default_instance_);
}
inline ::dmi::Component* ModifiableComponent::release_parent() {
  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.parent)
  
  ::dmi::Component* temp = parent_;
  parent_ = nullptr;
  return temp;
}
inline ::dmi::Component* ModifiableComponent::mutable_parent() {
  
  if (parent_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Component>(GetArenaNoVirtual());
    parent_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.parent)
  return parent_;
}
inline void ModifiableComponent::set_allocated_parent(::dmi::Component* parent) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete parent_;
  }
  if (parent) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      parent = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, parent, submessage_arena);
    }
    
  } else {
    
  }
  parent_ = parent;
  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.parent)
}

// int32 parent_rel_pos = 4;
inline void ModifiableComponent::clear_parent_rel_pos() {
  parent_rel_pos_ = 0;
}
inline ::google::protobuf::int32 ModifiableComponent::parent_rel_pos() const {
  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.parent_rel_pos)
  return parent_rel_pos_;
}
inline void ModifiableComponent::set_parent_rel_pos(::google::protobuf::int32 value) {
  
  parent_rel_pos_ = value;
  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.parent_rel_pos)
}

// string alias = 5;
inline void ModifiableComponent::clear_alias() {
  alias_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ModifiableComponent::alias() const {
  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.alias)
  return alias_.GetNoArena();
}
inline void ModifiableComponent::set_alias(const ::std::string& value) {
  
  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.alias)
}
#if LANG_CXX11
inline void ModifiableComponent::set_alias(::std::string&& value) {
  
  alias_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ModifiableComponent.alias)
}
#endif
inline void ModifiableComponent::set_alias(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ModifiableComponent.alias)
}
inline void ModifiableComponent::set_alias(const char* value, size_t size) {
  
  alias_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ModifiableComponent.alias)
}
inline ::std::string* ModifiableComponent::mutable_alias() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.alias)
  return alias_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ModifiableComponent::release_alias() {
  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.alias)
  
  return alias_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ModifiableComponent::set_allocated_alias(::std::string* alias) {
  if (alias != nullptr) {
    
  } else {
    
  }
  alias_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), alias);
  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.alias)
}

// string asset_id = 6;
inline void ModifiableComponent::clear_asset_id() {
  asset_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ModifiableComponent::asset_id() const {
  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.asset_id)
  return asset_id_.GetNoArena();
}
inline void ModifiableComponent::set_asset_id(const ::std::string& value) {
  
  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.asset_id)
}
#if LANG_CXX11
inline void ModifiableComponent::set_asset_id(::std::string&& value) {
  
  asset_id_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ModifiableComponent.asset_id)
}
#endif
inline void ModifiableComponent::set_asset_id(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ModifiableComponent.asset_id)
}
inline void ModifiableComponent::set_asset_id(const char* value, size_t size) {
  
  asset_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ModifiableComponent.asset_id)
}
inline ::std::string* ModifiableComponent::mutable_asset_id() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.asset_id)
  return asset_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ModifiableComponent::release_asset_id() {
  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.asset_id)
  
  return asset_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ModifiableComponent::set_allocated_asset_id(::std::string* asset_id) {
  if (asset_id != nullptr) {
    
  } else {
    
  }
  asset_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), asset_id);
  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.asset_id)
}

// .dmi.Uri uri = 7;
inline bool ModifiableComponent::has_uri() const {
  return this != internal_default_instance() && uri_ != nullptr;
}
inline void ModifiableComponent::clear_uri() {
  if (GetArenaNoVirtual() == nullptr && uri_ != nullptr) {
    delete uri_;
  }
  uri_ = nullptr;
}
inline const ::dmi::Uri& ModifiableComponent::uri() const {
  const ::dmi::Uri* p = uri_;
  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.uri)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uri*>(
      &::dmi::_Uri_default_instance_);
}
inline ::dmi::Uri* ModifiableComponent::release_uri() {
  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.uri)
  
  ::dmi::Uri* temp = uri_;
  uri_ = nullptr;
  return temp;
}
inline ::dmi::Uri* ModifiableComponent::mutable_uri() {
  
  if (uri_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uri>(GetArenaNoVirtual());
    uri_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.uri)
  return uri_;
}
inline void ModifiableComponent::set_allocated_uri(::dmi::Uri* uri) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete uri_;
  }
  if (uri) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      uri = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, uri, submessage_arena);
    }
    
  } else {
    
  }
  uri_ = uri;
  // @@protoc_insertion_point(field_set_allocated:dmi.ModifiableComponent.uri)
}

// .dmi.ComponentAdminState admin_state = 8;
inline void ModifiableComponent::clear_admin_state() {
  admin_state_ = 0;
}
inline ::dmi::ComponentAdminState ModifiableComponent::admin_state() const {
  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.admin_state)
  return static_cast< ::dmi::ComponentAdminState >(admin_state_);
}
inline void ModifiableComponent::set_admin_state(::dmi::ComponentAdminState value) {
  
  admin_state_ = value;
  // @@protoc_insertion_point(field_set:dmi.ModifiableComponent.admin_state)
}

#ifdef __GNUC__
  #pragma GCC diagnostic pop
#endif  // __GNUC__
// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------


// @@protoc_insertion_point(namespace_scope)

}  // namespace dmi

namespace google {
namespace protobuf {

template <> struct is_proto_enum< ::dmi::PortComponentAttributes_ConnectorType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PortComponentAttributes_ConnectorType>() {
  return ::dmi::PortComponentAttributes_ConnectorType_descriptor();
}
template <> struct is_proto_enum< ::dmi::PortComponentAttributes_Speed> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PortComponentAttributes_Speed>() {
  return ::dmi::PortComponentAttributes_Speed_descriptor();
}
template <> struct is_proto_enum< ::dmi::PortComponentAttributes_Protocol> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PortComponentAttributes_Protocol>() {
  return ::dmi::PortComponentAttributes_Protocol_descriptor();
}
template <> struct is_proto_enum< ::dmi::PsuComponentAttributes_SupportedVoltage> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::PsuComponentAttributes_SupportedVoltage>() {
  return ::dmi::PsuComponentAttributes_SupportedVoltage_descriptor();
}
template <> struct is_proto_enum< ::dmi::TransceiverComponentsAttributes_FormFactor> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::TransceiverComponentsAttributes_FormFactor>() {
  return ::dmi::TransceiverComponentsAttributes_FormFactor_descriptor();
}
template <> struct is_proto_enum< ::dmi::TransceiverComponentsAttributes_Type> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::TransceiverComponentsAttributes_Type>() {
  return ::dmi::TransceiverComponentsAttributes_Type_descriptor();
}
template <> struct is_proto_enum< ::dmi::ComponentType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentType>() {
  return ::dmi::ComponentType_descriptor();
}
template <> struct is_proto_enum< ::dmi::ComponentAdminState> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentAdminState>() {
  return ::dmi::ComponentAdminState_descriptor();
}
template <> struct is_proto_enum< ::dmi::ComponentOperState> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentOperState>() {
  return ::dmi::ComponentOperState_descriptor();
}
template <> struct is_proto_enum< ::dmi::ComponentUsageState> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentUsageState>() {
  return ::dmi::ComponentUsageState_descriptor();
}
template <> struct is_proto_enum< ::dmi::ComponentAlarmState> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentAlarmState>() {
  return ::dmi::ComponentAlarmState_descriptor();
}
template <> struct is_proto_enum< ::dmi::ComponentStandbyState> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ComponentStandbyState>() {
  return ::dmi::ComponentStandbyState_descriptor();
}
template <> struct is_proto_enum< ::dmi::DataValueType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::DataValueType>() {
  return ::dmi::DataValueType_descriptor();
}
template <> struct is_proto_enum< ::dmi::ValueScale> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ValueScale>() {
  return ::dmi::ValueScale_descriptor();
}
template <> struct is_proto_enum< ::dmi::SensorStatus> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::SensorStatus>() {
  return ::dmi::SensorStatus_descriptor();
}

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

#include <google/protobuf/port_undef.inc>
#endif  // PROTOBUF_INCLUDED_dmi_2fhw_2eproto
