// 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[15]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::google::protobuf::internal::FieldMetadata field_metadata[];
  static const ::google::protobuf::internal::SerializationTable serialization_table[];
  static const ::google::protobuf::uint32 offsets[];
};
void AddDescriptors_dmi_2fhw_2eproto();
namespace dmi {
class Component;
class ComponentDefaultTypeInternal;
extern ComponentDefaultTypeInternal _Component_default_instance_;
class ComponentSensorData;
class ComponentSensorDataDefaultTypeInternal;
extern ComponentSensorDataDefaultTypeInternal _ComponentSensorData_default_instance_;
class ComponentState;
class ComponentStateDefaultTypeInternal;
extern ComponentStateDefaultTypeInternal _ComponentState_default_instance_;
class ContainerComponentAttributes;
class ContainerComponentAttributesDefaultTypeInternal;
extern ContainerComponentAttributesDefaultTypeInternal _ContainerComponentAttributes_default_instance_;
class Hardware;
class HardwareDefaultTypeInternal;
extern HardwareDefaultTypeInternal _Hardware_default_instance_;
class HardwareID;
class HardwareIDDefaultTypeInternal;
extern HardwareIDDefaultTypeInternal _HardwareID_default_instance_;
class ModifiableComponent;
class ModifiableComponentDefaultTypeInternal;
extern ModifiableComponentDefaultTypeInternal _ModifiableComponent_default_instance_;
class PonIdConfig;
class PonIdConfigDefaultTypeInternal;
extern PonIdConfigDefaultTypeInternal _PonIdConfig_default_instance_;
class PortComponentAttributes;
class PortComponentAttributesDefaultTypeInternal;
extern PortComponentAttributesDefaultTypeInternal _PortComponentAttributes_default_instance_;
class PortComponentChangeAttributes;
class PortComponentChangeAttributesDefaultTypeInternal;
extern PortComponentChangeAttributesDefaultTypeInternal _PortComponentChangeAttributes_default_instance_;
class PsuComponentAttributes;
class PsuComponentAttributesDefaultTypeInternal;
extern PsuComponentAttributesDefaultTypeInternal _PsuComponentAttributes_default_instance_;
class 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::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.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_;
  int connector_type_;
  int speed_;
  int protocol_;
  bool speed_autonegotiation_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fhw_2eproto;
};
// -------------------------------------------------------------------

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

  PortComponentChangeAttributes(const PortComponentChangeAttributes& from);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  Component(const Component& from);

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

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

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

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

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

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

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

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

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

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

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

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

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