// 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_TransceiverComponentsAttributes_FormFactor_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  TransceiverComponentsAttributes_FormFactor_TransceiverComponentsAttributes_FormFactor_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool TransceiverComponentsAttributes_FormFactor_IsValid(int value);
const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes_FormFactor_FormFactor_MIN = TransceiverComponentsAttributes_FormFactor_FORM_FACTOR_UNKNOWN;
const TransceiverComponentsAttributes_FormFactor TransceiverComponentsAttributes_FormFactor_FormFactor_MAX = TransceiverComponentsAttributes_FormFactor_CFP2_DCO;
const int TransceiverComponentsAttributes_FormFactor_FormFactor_ARRAYSIZE = TransceiverComponentsAttributes_FormFactor_FormFactor_MAX + 1;

const ::google::protobuf::EnumDescriptor* TransceiverComponentsAttributes_FormFactor_descriptor();
inline const ::std::string& TransceiverComponentsAttributes_FormFactor_Name(TransceiverComponentsAttributes_FormFactor value) {
  return ::google::protobuf::internal::NameOfEnum(
    TransceiverComponentsAttributes_FormFactor_descriptor(), value);
}
inline bool TransceiverComponentsAttributes_FormFactor_Parse(
    const ::std::string& name, TransceiverComponentsAttributes_FormFactor* value) {
  return ::google::protobuf::internal::ParseNamedEnum<TransceiverComponentsAttributes_FormFactor>(
    TransceiverComponentsAttributes_FormFactor_descriptor(), name, value);
}
enum 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 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
