// 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[14]
    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 PonIdConfig;
class PonIdConfigDefaultTypeInternal;
extern PonIdConfigDefaultTypeInternal _PonIdConfig_default_instance_;
class PortComponentAttributes;
class PortComponentAttributesDefaultTypeInternal;
extern PortComponentAttributesDefaultTypeInternal _PortComponentAttributes_default_instance_;
class PortComponentChangeAttributes;
class PortComponentChangeAttributesDefaultTypeInternal;
extern PortComponentChangeAttributesDefaultTypeInternal _PortComponentChangeAttributes_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::PonIdConfig* Arena::CreateMaybeMessage<::dmi::PonIdConfig>(Arena*);
template<> ::dmi::PortComponentAttributes* Arena::CreateMaybeMessage<::dmi::PortComponentAttributes>(Arena*);
template<> ::dmi::PortComponentChangeAttributes* Arena::CreateMaybeMessage<::dmi::PortComponentChangeAttributes>(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);

  // string mapping_label = 5;
  void clear_mapping_label();
  static const int kMappingLabelFieldNumber = 5;
  const ::std::string& mapping_label() const;
  void set_mapping_label(const ::std::string& value);
  #if LANG_CXX11
  void set_mapping_label(::std::string&& value);
  #endif
  void set_mapping_label(const char* value);
  void set_mapping_label(const char* value, size_t size);
  ::std::string* mutable_mapping_label();
  ::std::string* release_mapping_label();
  void set_allocated_mapping_label(::std::string* mapping_label);

  // .dmi.PonIdConfig pon_id_config = 6;
  bool has_pon_id_config() const;
  void clear_pon_id_config();
  static const int kPonIdConfigFieldNumber = 6;
  const ::dmi::PonIdConfig& pon_id_config() const;
  ::dmi::PonIdConfig* release_pon_id_config();
  ::dmi::PonIdConfig* mutable_pon_id_config();
  void set_allocated_pon_id_config(::dmi::PonIdConfig* pon_id_config);

  // .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_;
  ::google::protobuf::internal::ArenaStringPtr mapping_label_;
  ::dmi::PonIdConfig* pon_id_config_;
  int connector_type_;
  int speed_;
  int protocol_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

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

  PortComponentChangeAttributes(const PortComponentChangeAttributes& from);

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

  inline PortComponentChangeAttributes& operator=(PortComponentChangeAttributes&& 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 PortComponentChangeAttributes& default_instance();

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

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

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

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

  PortComponentChangeAttributes* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<PortComponentChangeAttributes>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const PortComponentChangeAttributes& from);
  void MergeFrom(const PortComponentChangeAttributes& 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(PortComponentChangeAttributes* 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.PonIdConfig pon_id_config = 1;
  bool has_pon_id_config() const;
  void clear_pon_id_config();
  static const int kPonIdConfigFieldNumber = 1;
  const ::dmi::PonIdConfig& pon_id_config() const;
  ::dmi::PonIdConfig* release_pon_id_config();
  ::dmi::PonIdConfig* mutable_pon_id_config();
  void set_allocated_pon_id_config(::dmi::PonIdConfig* pon_id_config);

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

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

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

  PonIdConfig(const PonIdConfig& from);

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

  inline PonIdConfig& operator=(PonIdConfig&& 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 PonIdConfig& default_instance();

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

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

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

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

  PonIdConfig* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<PonIdConfig>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const PonIdConfig& from);
  void MergeFrom(const PonIdConfig& 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(PonIdConfig* 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 -------------------------------------------------------

  // bytes pon_id = 1;
  void clear_pon_id();
  static const int kPonIdFieldNumber = 1;
  const ::std::string& pon_id() const;
  void set_pon_id(const ::std::string& value);
  #if LANG_CXX11
  void set_pon_id(::std::string&& value);
  #endif
  void set_pon_id(const char* value);
  void set_pon_id(const void* value, size_t size);
  ::std::string* mutable_pon_id();
  ::std::string* release_pon_id();
  void set_allocated_pon_id(::std::string* pon_id);

  // uint32 pon_id_transmit_periodicity = 2;
  void clear_pon_id_transmit_periodicity();
  static const int kPonIdTransmitPeriodicityFieldNumber = 2;
  ::google::protobuf::uint32 pon_id_transmit_periodicity() const;
  void set_pon_id_transmit_periodicity(::google::protobuf::uint32 value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr pon_id_;
  ::google::protobuf::uint32 pon_id_transmit_periodicity_;
  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 =
    8;

  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 =
    9;

  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 =
    10;

  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 =
    11;

  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 =
    12;

  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();

  enum SpecificCase {
    kPortAttr = 50,
    SPECIFIC_NOT_SET = 0,
  };

  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 =
    13;

  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);

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

  void clear_specific();
  SpecificCase specific_case() const;
  // @@protoc_insertion_point(class_scope:dmi.ModifiableComponent)
 private:
  class HasBitSetters;
  void set_has_port_attr();

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

  ::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_;
  union SpecificUnion {
    SpecificUnion() {}
    ::dmi::PortComponentChangeAttributes* port_attr_;
  } specific_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  ::google::protobuf::uint32 _oneof_case_[1];

  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)
}

// string mapping_label = 5;
inline void PortComponentAttributes::clear_mapping_label() {
  mapping_label_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& PortComponentAttributes::mapping_label() const {
  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.mapping_label)
  return mapping_label_.GetNoArena();
}
inline void PortComponentAttributes::set_mapping_label(const ::std::string& value) {
  
  mapping_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.mapping_label)
}
#if LANG_CXX11
inline void PortComponentAttributes::set_mapping_label(::std::string&& value) {
  
  mapping_label_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.PortComponentAttributes.mapping_label)
}
#endif
inline void PortComponentAttributes::set_mapping_label(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  mapping_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.PortComponentAttributes.mapping_label)
}
inline void PortComponentAttributes::set_mapping_label(const char* value, size_t size) {
  
  mapping_label_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.PortComponentAttributes.mapping_label)
}
inline ::std::string* PortComponentAttributes::mutable_mapping_label() {
  
  // @@protoc_insertion_point(field_mutable:dmi.PortComponentAttributes.mapping_label)
  return mapping_label_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* PortComponentAttributes::release_mapping_label() {
  // @@protoc_insertion_point(field_release:dmi.PortComponentAttributes.mapping_label)
  
  return mapping_label_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void PortComponentAttributes::set_allocated_mapping_label(::std::string* mapping_label) {
  if (mapping_label != nullptr) {
    
  } else {
    
  }
  mapping_label_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), mapping_label);
  // @@protoc_insertion_point(field_set_allocated:dmi.PortComponentAttributes.mapping_label)
}

// .dmi.PonIdConfig pon_id_config = 6;
inline bool PortComponentAttributes::has_pon_id_config() const {
  return this != internal_default_instance() && pon_id_config_ != nullptr;
}
inline void PortComponentAttributes::clear_pon_id_config() {
  if (GetArenaNoVirtual() == nullptr && pon_id_config_ != nullptr) {
    delete pon_id_config_;
  }
  pon_id_config_ = nullptr;
}
inline const ::dmi::PonIdConfig& PortComponentAttributes::pon_id_config() const {
  const ::dmi::PonIdConfig* p = pon_id_config_;
  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.pon_id_config)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::PonIdConfig*>(
      &::dmi::_PonIdConfig_default_instance_);
}
inline ::dmi::PonIdConfig* PortComponentAttributes::release_pon_id_config() {
  // @@protoc_insertion_point(field_release:dmi.PortComponentAttributes.pon_id_config)
  
  ::dmi::PonIdConfig* temp = pon_id_config_;
  pon_id_config_ = nullptr;
  return temp;
}
inline ::dmi::PonIdConfig* PortComponentAttributes::mutable_pon_id_config() {
  
  if (pon_id_config_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::PonIdConfig>(GetArenaNoVirtual());
    pon_id_config_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.PortComponentAttributes.pon_id_config)
  return pon_id_config_;
}
inline void PortComponentAttributes::set_allocated_pon_id_config(::dmi::PonIdConfig* pon_id_config) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete pon_id_config_;
  }
  if (pon_id_config) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      pon_id_config = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, pon_id_config, submessage_arena);
    }
    
  } else {
    
  }
  pon_id_config_ = pon_id_config;
  // @@protoc_insertion_point(field_set_allocated:dmi.PortComponentAttributes.pon_id_config)
}

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

// PortComponentChangeAttributes

// .dmi.PonIdConfig pon_id_config = 1;
inline bool PortComponentChangeAttributes::has_pon_id_config() const {
  return this != internal_default_instance() && pon_id_config_ != nullptr;
}
inline void PortComponentChangeAttributes::clear_pon_id_config() {
  if (GetArenaNoVirtual() == nullptr && pon_id_config_ != nullptr) {
    delete pon_id_config_;
  }
  pon_id_config_ = nullptr;
}
inline const ::dmi::PonIdConfig& PortComponentChangeAttributes::pon_id_config() const {
  const ::dmi::PonIdConfig* p = pon_id_config_;
  // @@protoc_insertion_point(field_get:dmi.PortComponentChangeAttributes.pon_id_config)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::PonIdConfig*>(
      &::dmi::_PonIdConfig_default_instance_);
}
inline ::dmi::PonIdConfig* PortComponentChangeAttributes::release_pon_id_config() {
  // @@protoc_insertion_point(field_release:dmi.PortComponentChangeAttributes.pon_id_config)
  
  ::dmi::PonIdConfig* temp = pon_id_config_;
  pon_id_config_ = nullptr;
  return temp;
}
inline ::dmi::PonIdConfig* PortComponentChangeAttributes::mutable_pon_id_config() {
  
  if (pon_id_config_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::PonIdConfig>(GetArenaNoVirtual());
    pon_id_config_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.PortComponentChangeAttributes.pon_id_config)
  return pon_id_config_;
}
inline void PortComponentChangeAttributes::set_allocated_pon_id_config(::dmi::PonIdConfig* pon_id_config) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete pon_id_config_;
  }
  if (pon_id_config) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      pon_id_config = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, pon_id_config, submessage_arena);
    }
    
  } else {
    
  }
  pon_id_config_ = pon_id_config;
  // @@protoc_insertion_point(field_set_allocated:dmi.PortComponentChangeAttributes.pon_id_config)
}

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

// PonIdConfig

// bytes pon_id = 1;
inline void PonIdConfig::clear_pon_id() {
  pon_id_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& PonIdConfig::pon_id() const {
  // @@protoc_insertion_point(field_get:dmi.PonIdConfig.pon_id)
  return pon_id_.GetNoArena();
}
inline void PonIdConfig::set_pon_id(const ::std::string& value) {
  
  pon_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.PonIdConfig.pon_id)
}
#if LANG_CXX11
inline void PonIdConfig::set_pon_id(::std::string&& value) {
  
  pon_id_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.PonIdConfig.pon_id)
}
#endif
inline void PonIdConfig::set_pon_id(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  pon_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.PonIdConfig.pon_id)
}
inline void PonIdConfig::set_pon_id(const void* value, size_t size) {
  
  pon_id_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.PonIdConfig.pon_id)
}
inline ::std::string* PonIdConfig::mutable_pon_id() {
  
  // @@protoc_insertion_point(field_mutable:dmi.PonIdConfig.pon_id)
  return pon_id_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* PonIdConfig::release_pon_id() {
  // @@protoc_insertion_point(field_release:dmi.PonIdConfig.pon_id)
  
  return pon_id_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void PonIdConfig::set_allocated_pon_id(::std::string* pon_id) {
  if (pon_id != nullptr) {
    
  } else {
    
  }
  pon_id_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), pon_id);
  // @@protoc_insertion_point(field_set_allocated:dmi.PonIdConfig.pon_id)
}

// uint32 pon_id_transmit_periodicity = 2;
inline void PonIdConfig::clear_pon_id_transmit_periodicity() {
  pon_id_transmit_periodicity_ = 0u;
}
inline ::google::protobuf::uint32 PonIdConfig::pon_id_transmit_periodicity() const {
  // @@protoc_insertion_point(field_get:dmi.PonIdConfig.pon_id_transmit_periodicity)
  return pon_id_transmit_periodicity_;
}
inline void PonIdConfig::set_pon_id_transmit_periodicity(::google::protobuf::uint32 value) {
  
  pon_id_transmit_periodicity_ = value;
  // @@protoc_insertion_point(field_set:dmi.PonIdConfig.pon_id_transmit_periodicity)
}

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

// 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)
}

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

inline bool ModifiableComponent::has_specific() const {
  return specific_case() != SPECIFIC_NOT_SET;
}
inline void ModifiableComponent::clear_has_specific() {
  _oneof_case_[0] = SPECIFIC_NOT_SET;
}
inline ModifiableComponent::SpecificCase ModifiableComponent::specific_case() const {
  return ModifiableComponent::SpecificCase(_oneof_case_[0]);
}
#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
