// 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[16]
    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 PonDistance;
class PonDistanceDefaultTypeInternal;
extern PonDistanceDefaultTypeInternal _PonDistance_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 TransceiverComponentChangeAttributes;
class TransceiverComponentChangeAttributesDefaultTypeInternal;
extern TransceiverComponentChangeAttributesDefaultTypeInternal _TransceiverComponentChangeAttributes_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::PonDistance* Arena::CreateMaybeMessage<::dmi::PonDistance>(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::TransceiverComponentChangeAttributes* Arena::CreateMaybeMessage<::dmi::TransceiverComponentChangeAttributes>(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_QSFP_DD = 15,
  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_QSFP_DD;
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 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,
  VALUE_TYPE_DBM = 16,
  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_DBM;
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);
}
enum TransceiverType {
  TYPE_UNDEFINED = 0,
  ETHERNET = 1,
  GPON = 2,
  XGPON = 3,
  XGSPON = 4,
  CPON = 5,
  NG_PON2 = 6,
  EPON = 7,
  COMBO_GPON_XGSPON = 8,
  TYPE_NOT_DETECTED = 255,
  TransceiverType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  TransceiverType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool TransceiverType_IsValid(int value);
const TransceiverType TransceiverType_MIN = TYPE_UNDEFINED;
const TransceiverType TransceiverType_MAX = TYPE_NOT_DETECTED;
const int TransceiverType_ARRAYSIZE = TransceiverType_MAX + 1;

const ::google::protobuf::EnumDescriptor* TransceiverType_descriptor();
inline const ::std::string& TransceiverType_Name(TransceiverType value) {
  return ::google::protobuf::internal::NameOfEnum(
    TransceiverType_descriptor(), value);
}
inline bool TransceiverType_Parse(
    const ::std::string& name, TransceiverType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<TransceiverType>(
    TransceiverType_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.PonDistance distance = 8;
  bool has_distance() const;
  void clear_distance();
  static const int kDistanceFieldNumber = 8;
  const ::dmi::PonDistance& distance() const;
  ::dmi::PonDistance* release_distance();
  ::dmi::PonDistance* mutable_distance();
  void set_allocated_distance(::dmi::PonDistance* distance);

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

  // bool speed_autonegotiation = 7;
  void clear_speed_autonegotiation();
  static const int kSpeedAutonegotiationFieldNumber = 7;
  bool speed_autonegotiation() const;
  void set_speed_autonegotiation(bool 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_;
  ::dmi::PonDistance* distance_;
  int connector_type_;
  int speed_;
  int protocol_;
  bool speed_autonegotiation_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

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

  PonDistance(const PonDistance& from);

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

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

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

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

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

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

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

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

  // uint32 max_differential_distance = 2;
  void clear_max_differential_distance();
  static const int kMaxDifferentialDistanceFieldNumber = 2;
  ::google::protobuf::uint32 max_differential_distance() const;
  void set_max_differential_distance(::google::protobuf::uint32 value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::uint32 max_distance_;
  ::google::protobuf::uint32 max_differential_distance_;
  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 =
    7;

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

  // .dmi.PonDistance distance = 2;
  bool has_distance() const;
  void clear_distance();
  static const int kDistanceFieldNumber = 2;
  const ::dmi::PonDistance& distance() const;
  ::dmi::PonDistance* release_distance();
  ::dmi::PonDistance* mutable_distance();
  void set_allocated_distance(::dmi::PonDistance* distance);

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

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

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

  TransceiverComponentChangeAttributes(const TransceiverComponentChangeAttributes& from);

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

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

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

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

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

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

  TransceiverComponentChangeAttributes* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<TransceiverComponentChangeAttributes>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const TransceiverComponentChangeAttributes& from);
  void MergeFrom(const TransceiverComponentChangeAttributes& 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(TransceiverComponentChangeAttributes* 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.TransceiverType trans_type = 1;
  void clear_trans_type();
  static const int kTransTypeFieldNumber = 1;
  ::dmi::TransceiverType trans_type() const;
  void set_trans_type(::dmi::TransceiverType value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  int trans_type_;
  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 =
    9;

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

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

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

  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 const FormFactor QSFP_DD =
    TransceiverComponentsAttributes_FormFactor_QSFP_DD;
  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);
  }

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

  // repeated int32 tx_power = 8;
  int tx_power_size() const;
  void clear_tx_power();
  static const int kTxPowerFieldNumber = 8;
  ::google::protobuf::int32 tx_power(int index) const;
  void set_tx_power(int index, ::google::protobuf::int32 value);
  void add_tx_power(::google::protobuf::int32 value);
  const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
      tx_power() const;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
      mutable_tx_power();

  // .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.TransceiverType trans_type = 2;
  void clear_trans_type();
  static const int kTransTypeFieldNumber = 2;
  ::dmi::TransceiverType trans_type() const;
  void set_trans_type(::dmi::TransceiverType 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);

  // .dmi.ValueScale tx_power_scale = 9;
  void clear_tx_power_scale();
  static const int kTxPowerScaleFieldNumber = 9;
  ::dmi::ValueScale tx_power_scale() const;
  void set_tx_power_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_;
  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > tx_power_;
  mutable std::atomic<int> _tx_power_cached_byte_size_;
  int form_factor_;
  int trans_type_;
  ::google::protobuf::uint32 max_distance_;
  int max_distance_scale_;
  int wavelength_scale_;
  int tx_power_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 =
    13;

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

  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,
    kTrxAttr = 51,
    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 =
    15;

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

  // .dmi.TransceiverComponentChangeAttributes trx_attr = 51;
  bool has_trx_attr() const;
  void clear_trx_attr();
  static const int kTrxAttrFieldNumber = 51;
  const ::dmi::TransceiverComponentChangeAttributes& trx_attr() const;
  ::dmi::TransceiverComponentChangeAttributes* release_trx_attr();
  ::dmi::TransceiverComponentChangeAttributes* mutable_trx_attr();
  void set_allocated_trx_attr(::dmi::TransceiverComponentChangeAttributes* trx_attr);

  void clear_specific();
  SpecificCase specific_case() const;
  // @@protoc_insertion_point(class_scope:dmi.ModifiableComponent)
 private:
  class HasBitSetters;
  void set_has_port_attr();
  void set_has_trx_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_;
    ::dmi::TransceiverComponentChangeAttributes* trx_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)
}

// bool speed_autonegotiation = 7;
inline void PortComponentAttributes::clear_speed_autonegotiation() {
  speed_autonegotiation_ = false;
}
inline bool PortComponentAttributes::speed_autonegotiation() const {
  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.speed_autonegotiation)
  return speed_autonegotiation_;
}
inline void PortComponentAttributes::set_speed_autonegotiation(bool value) {
  
  speed_autonegotiation_ = value;
  // @@protoc_insertion_point(field_set:dmi.PortComponentAttributes.speed_autonegotiation)
}

// .dmi.PonDistance distance = 8;
inline bool PortComponentAttributes::has_distance() const {
  return this != internal_default_instance() && distance_ != nullptr;
}
inline void PortComponentAttributes::clear_distance() {
  if (GetArenaNoVirtual() == nullptr && distance_ != nullptr) {
    delete distance_;
  }
  distance_ = nullptr;
}
inline const ::dmi::PonDistance& PortComponentAttributes::distance() const {
  const ::dmi::PonDistance* p = distance_;
  // @@protoc_insertion_point(field_get:dmi.PortComponentAttributes.distance)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::PonDistance*>(
      &::dmi::_PonDistance_default_instance_);
}
inline ::dmi::PonDistance* PortComponentAttributes::release_distance() {
  // @@protoc_insertion_point(field_release:dmi.PortComponentAttributes.distance)
  
  ::dmi::PonDistance* temp = distance_;
  distance_ = nullptr;
  return temp;
}
inline ::dmi::PonDistance* PortComponentAttributes::mutable_distance() {
  
  if (distance_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::PonDistance>(GetArenaNoVirtual());
    distance_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.PortComponentAttributes.distance)
  return distance_;
}
inline void PortComponentAttributes::set_allocated_distance(::dmi::PonDistance* distance) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete distance_;
  }
  if (distance) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      distance = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, distance, submessage_arena);
    }
    
  } else {
    
  }
  distance_ = distance;
  // @@protoc_insertion_point(field_set_allocated:dmi.PortComponentAttributes.distance)
}

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

// PonDistance

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

// uint32 max_differential_distance = 2;
inline void PonDistance::clear_max_differential_distance() {
  max_differential_distance_ = 0u;
}
inline ::google::protobuf::uint32 PonDistance::max_differential_distance() const {
  // @@protoc_insertion_point(field_get:dmi.PonDistance.max_differential_distance)
  return max_differential_distance_;
}
inline void PonDistance::set_max_differential_distance(::google::protobuf::uint32 value) {
  
  max_differential_distance_ = value;
  // @@protoc_insertion_point(field_set:dmi.PonDistance.max_differential_distance)
}

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

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

// .dmi.PonDistance distance = 2;
inline bool PortComponentChangeAttributes::has_distance() const {
  return this != internal_default_instance() && distance_ != nullptr;
}
inline void PortComponentChangeAttributes::clear_distance() {
  if (GetArenaNoVirtual() == nullptr && distance_ != nullptr) {
    delete distance_;
  }
  distance_ = nullptr;
}
inline const ::dmi::PonDistance& PortComponentChangeAttributes::distance() const {
  const ::dmi::PonDistance* p = distance_;
  // @@protoc_insertion_point(field_get:dmi.PortComponentChangeAttributes.distance)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::PonDistance*>(
      &::dmi::_PonDistance_default_instance_);
}
inline ::dmi::PonDistance* PortComponentChangeAttributes::release_distance() {
  // @@protoc_insertion_point(field_release:dmi.PortComponentChangeAttributes.distance)
  
  ::dmi::PonDistance* temp = distance_;
  distance_ = nullptr;
  return temp;
}
inline ::dmi::PonDistance* PortComponentChangeAttributes::mutable_distance() {
  
  if (distance_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::PonDistance>(GetArenaNoVirtual());
    distance_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.PortComponentChangeAttributes.distance)
  return distance_;
}
inline void PortComponentChangeAttributes::set_allocated_distance(::dmi::PonDistance* distance) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete distance_;
  }
  if (distance) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      distance = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, distance, submessage_arena);
    }
    
  } else {
    
  }
  distance_ = distance;
  // @@protoc_insertion_point(field_set_allocated:dmi.PortComponentChangeAttributes.distance)
}

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

// TransceiverComponentChangeAttributes

// .dmi.TransceiverType trans_type = 1;
inline void TransceiverComponentChangeAttributes::clear_trans_type() {
  trans_type_ = 0;
}
inline ::dmi::TransceiverType TransceiverComponentChangeAttributes::trans_type() const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentChangeAttributes.trans_type)
  return static_cast< ::dmi::TransceiverType >(trans_type_);
}
inline void TransceiverComponentChangeAttributes::set_trans_type(::dmi::TransceiverType value) {
  
  trans_type_ = value;
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentChangeAttributes.trans_type)
}

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

// 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.TransceiverType trans_type = 2;
inline void TransceiverComponentsAttributes::clear_trans_type() {
  trans_type_ = 0;
}
inline ::dmi::TransceiverType TransceiverComponentsAttributes::trans_type() const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.trans_type)
  return static_cast< ::dmi::TransceiverType >(trans_type_);
}
inline void TransceiverComponentsAttributes::set_trans_type(::dmi::TransceiverType 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)
}

// repeated int32 tx_power = 8;
inline int TransceiverComponentsAttributes::tx_power_size() const {
  return tx_power_.size();
}
inline void TransceiverComponentsAttributes::clear_tx_power() {
  tx_power_.Clear();
}
inline ::google::protobuf::int32 TransceiverComponentsAttributes::tx_power(int index) const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.tx_power)
  return tx_power_.Get(index);
}
inline void TransceiverComponentsAttributes::set_tx_power(int index, ::google::protobuf::int32 value) {
  tx_power_.Set(index, value);
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.tx_power)
}
inline void TransceiverComponentsAttributes::add_tx_power(::google::protobuf::int32 value) {
  tx_power_.Add(value);
  // @@protoc_insertion_point(field_add:dmi.TransceiverComponentsAttributes.tx_power)
}
inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
TransceiverComponentsAttributes::tx_power() const {
  // @@protoc_insertion_point(field_list:dmi.TransceiverComponentsAttributes.tx_power)
  return tx_power_;
}
inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
TransceiverComponentsAttributes::mutable_tx_power() {
  // @@protoc_insertion_point(field_mutable_list:dmi.TransceiverComponentsAttributes.tx_power)
  return &tx_power_;
}

// .dmi.ValueScale tx_power_scale = 9;
inline void TransceiverComponentsAttributes::clear_tx_power_scale() {
  tx_power_scale_ = 0;
}
inline ::dmi::ValueScale TransceiverComponentsAttributes::tx_power_scale() const {
  // @@protoc_insertion_point(field_get:dmi.TransceiverComponentsAttributes.tx_power_scale)
  return static_cast< ::dmi::ValueScale >(tx_power_scale_);
}
inline void TransceiverComponentsAttributes::set_tx_power_scale(::dmi::ValueScale value) {
  
  tx_power_scale_ = value;
  // @@protoc_insertion_point(field_set:dmi.TransceiverComponentsAttributes.tx_power_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_;
}

// .dmi.TransceiverComponentChangeAttributes trx_attr = 51;
inline bool ModifiableComponent::has_trx_attr() const {
  return specific_case() == kTrxAttr;
}
inline void ModifiableComponent::set_has_trx_attr() {
  _oneof_case_[0] = kTrxAttr;
}
inline void ModifiableComponent::clear_trx_attr() {
  if (has_trx_attr()) {
    delete specific_.trx_attr_;
    clear_has_specific();
  }
}
inline ::dmi::TransceiverComponentChangeAttributes* ModifiableComponent::release_trx_attr() {
  // @@protoc_insertion_point(field_release:dmi.ModifiableComponent.trx_attr)
  if (has_trx_attr()) {
    clear_has_specific();
      ::dmi::TransceiverComponentChangeAttributes* temp = specific_.trx_attr_;
    specific_.trx_attr_ = nullptr;
    return temp;
  } else {
    return nullptr;
  }
}
inline const ::dmi::TransceiverComponentChangeAttributes& ModifiableComponent::trx_attr() const {
  // @@protoc_insertion_point(field_get:dmi.ModifiableComponent.trx_attr)
  return has_trx_attr()
      ? *specific_.trx_attr_
      : *reinterpret_cast< ::dmi::TransceiverComponentChangeAttributes*>(&::dmi::_TransceiverComponentChangeAttributes_default_instance_);
}
inline ::dmi::TransceiverComponentChangeAttributes* ModifiableComponent::mutable_trx_attr() {
  if (!has_trx_attr()) {
    clear_specific();
    set_has_trx_attr();
    specific_.trx_attr_ = CreateMaybeMessage< ::dmi::TransceiverComponentChangeAttributes >(
        GetArenaNoVirtual());
  }
  // @@protoc_insertion_point(field_mutable:dmi.ModifiableComponent.trx_attr)
  return specific_.trx_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::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();
}
template <> struct is_proto_enum< ::dmi::TransceiverType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::TransceiverType>() {
  return ::dmi::TransceiverType_descriptor();
}

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

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