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

#ifndef PROTOBUF_INCLUDED_dmi_2fsw_5fmanagement_5fservice_2eproto
#define PROTOBUF_INCLUDED_dmi_2fsw_5fmanagement_5fservice_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 "dmi/commons.pb.h"
#include "dmi/hw.pb.h"
#include "dmi/sw_image.pb.h"
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_dmi_2fsw_5fmanagement_5fservice_2eproto

// Internal implementation detail -- do not use these members.
struct TableStruct_dmi_2fsw_5fmanagement_5fservice_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[9]
    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_2fsw_5fmanagement_5fservice_2eproto();
namespace dmi {
class ConfigRequest;
class ConfigRequestDefaultTypeInternal;
extern ConfigRequestDefaultTypeInternal _ConfigRequest_default_instance_;
class ConfigResponse;
class ConfigResponseDefaultTypeInternal;
extern ConfigResponseDefaultTypeInternal _ConfigResponse_default_instance_;
class DownloadImageRequest;
class DownloadImageRequestDefaultTypeInternal;
extern DownloadImageRequestDefaultTypeInternal _DownloadImageRequest_default_instance_;
class GetSoftwareVersionInformationResponse;
class GetSoftwareVersionInformationResponseDefaultTypeInternal;
extern GetSoftwareVersionInformationResponseDefaultTypeInternal _GetSoftwareVersionInformationResponse_default_instance_;
class SoftwareVersionInformation;
class SoftwareVersionInformationDefaultTypeInternal;
extern SoftwareVersionInformationDefaultTypeInternal _SoftwareVersionInformation_default_instance_;
class StartupConfigInfoRequest;
class StartupConfigInfoRequestDefaultTypeInternal;
extern StartupConfigInfoRequestDefaultTypeInternal _StartupConfigInfoRequest_default_instance_;
class StartupConfigInfoResponse;
class StartupConfigInfoResponseDefaultTypeInternal;
extern StartupConfigInfoResponseDefaultTypeInternal _StartupConfigInfoResponse_default_instance_;
class UploadDebugInfoRequest;
class UploadDebugInfoRequestDefaultTypeInternal;
extern UploadDebugInfoRequestDefaultTypeInternal _UploadDebugInfoRequest_default_instance_;
class UploadDebugInfoStatus;
class UploadDebugInfoStatusDefaultTypeInternal;
extern UploadDebugInfoStatusDefaultTypeInternal _UploadDebugInfoStatus_default_instance_;
}  // namespace dmi
namespace google {
namespace protobuf {
template<> ::dmi::ConfigRequest* Arena::CreateMaybeMessage<::dmi::ConfigRequest>(Arena*);
template<> ::dmi::ConfigResponse* Arena::CreateMaybeMessage<::dmi::ConfigResponse>(Arena*);
template<> ::dmi::DownloadImageRequest* Arena::CreateMaybeMessage<::dmi::DownloadImageRequest>(Arena*);
template<> ::dmi::GetSoftwareVersionInformationResponse* Arena::CreateMaybeMessage<::dmi::GetSoftwareVersionInformationResponse>(Arena*);
template<> ::dmi::SoftwareVersionInformation* Arena::CreateMaybeMessage<::dmi::SoftwareVersionInformation>(Arena*);
template<> ::dmi::StartupConfigInfoRequest* Arena::CreateMaybeMessage<::dmi::StartupConfigInfoRequest>(Arena*);
template<> ::dmi::StartupConfigInfoResponse* Arena::CreateMaybeMessage<::dmi::StartupConfigInfoResponse>(Arena*);
template<> ::dmi::UploadDebugInfoRequest* Arena::CreateMaybeMessage<::dmi::UploadDebugInfoRequest>(Arena*);
template<> ::dmi::UploadDebugInfoStatus* Arena::CreateMaybeMessage<::dmi::UploadDebugInfoStatus>(Arena*);
}  // namespace protobuf
}  // namespace google
namespace dmi {

enum GetSoftwareVersionInformationResponse_Reason {
  GetSoftwareVersionInformationResponse_Reason_UNDEFINED_REASON = 0,
  GetSoftwareVersionInformationResponse_Reason_UNKNOWN_DEVICE = 1,
  GetSoftwareVersionInformationResponse_Reason_INTERNAL_ERROR = 2,
  GetSoftwareVersionInformationResponse_Reason_DEVICE_UNREACHABLE = 3,
  GetSoftwareVersionInformationResponse_Reason_GetSoftwareVersionInformationResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  GetSoftwareVersionInformationResponse_Reason_GetSoftwareVersionInformationResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool GetSoftwareVersionInformationResponse_Reason_IsValid(int value);
const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse_Reason_Reason_MIN = GetSoftwareVersionInformationResponse_Reason_UNDEFINED_REASON;
const GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse_Reason_Reason_MAX = GetSoftwareVersionInformationResponse_Reason_DEVICE_UNREACHABLE;
const int GetSoftwareVersionInformationResponse_Reason_Reason_ARRAYSIZE = GetSoftwareVersionInformationResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* GetSoftwareVersionInformationResponse_Reason_descriptor();
inline const ::std::string& GetSoftwareVersionInformationResponse_Reason_Name(GetSoftwareVersionInformationResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    GetSoftwareVersionInformationResponse_Reason_descriptor(), value);
}
inline bool GetSoftwareVersionInformationResponse_Reason_Parse(
    const ::std::string& name, GetSoftwareVersionInformationResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<GetSoftwareVersionInformationResponse_Reason>(
    GetSoftwareVersionInformationResponse_Reason_descriptor(), name, value);
}
enum ConfigResponse_Reason {
  ConfigResponse_Reason_UNDEFINED_REASON = 0,
  ConfigResponse_Reason_UNKNOWN_DEVICE = 1,
  ConfigResponse_Reason_INTERNAL_ERROR = 2,
  ConfigResponse_Reason_ERROR_FETCHING_CONFIG = 3,
  ConfigResponse_Reason_INVALID_CONFIG = 4,
  ConfigResponse_Reason_OPERATION_ALREADY_IN_PROGRESS = 5,
  ConfigResponse_Reason_DEVICE_UNREACHABLE = 6,
  ConfigResponse_Reason_ConfigResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ConfigResponse_Reason_ConfigResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ConfigResponse_Reason_IsValid(int value);
const ConfigResponse_Reason ConfigResponse_Reason_Reason_MIN = ConfigResponse_Reason_UNDEFINED_REASON;
const ConfigResponse_Reason ConfigResponse_Reason_Reason_MAX = ConfigResponse_Reason_DEVICE_UNREACHABLE;
const int ConfigResponse_Reason_Reason_ARRAYSIZE = ConfigResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* ConfigResponse_Reason_descriptor();
inline const ::std::string& ConfigResponse_Reason_Name(ConfigResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    ConfigResponse_Reason_descriptor(), value);
}
inline bool ConfigResponse_Reason_Parse(
    const ::std::string& name, ConfigResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ConfigResponse_Reason>(
    ConfigResponse_Reason_descriptor(), name, value);
}
enum StartupConfigInfoResponse_Reason {
  StartupConfigInfoResponse_Reason_UNDEFINED_REASON = 0,
  StartupConfigInfoResponse_Reason_UNKNOWN_DEVICE = 1,
  StartupConfigInfoResponse_Reason_INTERNAL_ERROR = 2,
  StartupConfigInfoResponse_Reason_DEVICE_UNREACHABLE = 3,
  StartupConfigInfoResponse_Reason_StartupConfigInfoResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  StartupConfigInfoResponse_Reason_StartupConfigInfoResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool StartupConfigInfoResponse_Reason_IsValid(int value);
const StartupConfigInfoResponse_Reason StartupConfigInfoResponse_Reason_Reason_MIN = StartupConfigInfoResponse_Reason_UNDEFINED_REASON;
const StartupConfigInfoResponse_Reason StartupConfigInfoResponse_Reason_Reason_MAX = StartupConfigInfoResponse_Reason_DEVICE_UNREACHABLE;
const int StartupConfigInfoResponse_Reason_Reason_ARRAYSIZE = StartupConfigInfoResponse_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* StartupConfigInfoResponse_Reason_descriptor();
inline const ::std::string& StartupConfigInfoResponse_Reason_Name(StartupConfigInfoResponse_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    StartupConfigInfoResponse_Reason_descriptor(), value);
}
inline bool StartupConfigInfoResponse_Reason_Parse(
    const ::std::string& name, StartupConfigInfoResponse_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<StartupConfigInfoResponse_Reason>(
    StartupConfigInfoResponse_Reason_descriptor(), name, value);
}
enum UploadDebugInfoStatus_UploadStatus {
  UploadDebugInfoStatus_UploadStatus_UNDEFINED_UPLOAD_STATUS = 0,
  UploadDebugInfoStatus_UploadStatus_COMPLETE = 1,
  UploadDebugInfoStatus_UploadStatus_IN_PROGRESS = 2,
  UploadDebugInfoStatus_UploadStatus_ERROR = 3,
  UploadDebugInfoStatus_UploadStatus_UploadDebugInfoStatus_UploadStatus_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  UploadDebugInfoStatus_UploadStatus_UploadDebugInfoStatus_UploadStatus_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool UploadDebugInfoStatus_UploadStatus_IsValid(int value);
const UploadDebugInfoStatus_UploadStatus UploadDebugInfoStatus_UploadStatus_UploadStatus_MIN = UploadDebugInfoStatus_UploadStatus_UNDEFINED_UPLOAD_STATUS;
const UploadDebugInfoStatus_UploadStatus UploadDebugInfoStatus_UploadStatus_UploadStatus_MAX = UploadDebugInfoStatus_UploadStatus_ERROR;
const int UploadDebugInfoStatus_UploadStatus_UploadStatus_ARRAYSIZE = UploadDebugInfoStatus_UploadStatus_UploadStatus_MAX + 1;

const ::google::protobuf::EnumDescriptor* UploadDebugInfoStatus_UploadStatus_descriptor();
inline const ::std::string& UploadDebugInfoStatus_UploadStatus_Name(UploadDebugInfoStatus_UploadStatus value) {
  return ::google::protobuf::internal::NameOfEnum(
    UploadDebugInfoStatus_UploadStatus_descriptor(), value);
}
inline bool UploadDebugInfoStatus_UploadStatus_Parse(
    const ::std::string& name, UploadDebugInfoStatus_UploadStatus* value) {
  return ::google::protobuf::internal::ParseNamedEnum<UploadDebugInfoStatus_UploadStatus>(
    UploadDebugInfoStatus_UploadStatus_descriptor(), name, value);
}
enum UploadDebugInfoStatus_Reason {
  UploadDebugInfoStatus_Reason_UNDEFINED_REASON = 0,
  UploadDebugInfoStatus_Reason_UNKNOWN_DEVICE = 1,
  UploadDebugInfoStatus_Reason_INTERNAL_ERROR = 2,
  UploadDebugInfoStatus_Reason_DEVICE_UNREACHABLE = 3,
  UploadDebugInfoStatus_Reason_REMOTE_LOCATION_UNREACHABLE = 4,
  UploadDebugInfoStatus_Reason_REMOTE_LOCATION_PERMISSION_DENIED = 5,
  UploadDebugInfoStatus_Reason_ERROR_DURING_UPLOAD = 6,
  UploadDebugInfoStatus_Reason_UploadDebugInfoStatus_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  UploadDebugInfoStatus_Reason_UploadDebugInfoStatus_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool UploadDebugInfoStatus_Reason_IsValid(int value);
const UploadDebugInfoStatus_Reason UploadDebugInfoStatus_Reason_Reason_MIN = UploadDebugInfoStatus_Reason_UNDEFINED_REASON;
const UploadDebugInfoStatus_Reason UploadDebugInfoStatus_Reason_Reason_MAX = UploadDebugInfoStatus_Reason_ERROR_DURING_UPLOAD;
const int UploadDebugInfoStatus_Reason_Reason_ARRAYSIZE = UploadDebugInfoStatus_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* UploadDebugInfoStatus_Reason_descriptor();
inline const ::std::string& UploadDebugInfoStatus_Reason_Name(UploadDebugInfoStatus_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    UploadDebugInfoStatus_Reason_descriptor(), value);
}
inline bool UploadDebugInfoStatus_Reason_Parse(
    const ::std::string& name, UploadDebugInfoStatus_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<UploadDebugInfoStatus_Reason>(
    UploadDebugInfoStatus_Reason_descriptor(), name, value);
}
// ===================================================================

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

  SoftwareVersionInformation(const SoftwareVersionInformation& from);

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

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

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

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

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

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

  SoftwareVersionInformation* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<SoftwareVersionInformation>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const SoftwareVersionInformation& from);
  void MergeFrom(const SoftwareVersionInformation& 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(SoftwareVersionInformation* 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.ImageVersion active_versions = 1;
  int active_versions_size() const;
  void clear_active_versions();
  static const int kActiveVersionsFieldNumber = 1;
  ::dmi::ImageVersion* mutable_active_versions(int index);
  ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >*
      mutable_active_versions();
  const ::dmi::ImageVersion& active_versions(int index) const;
  ::dmi::ImageVersion* add_active_versions();
  const ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >&
      active_versions() const;

  // repeated .dmi.ImageVersion standby_versions = 2;
  int standby_versions_size() const;
  void clear_standby_versions();
  static const int kStandbyVersionsFieldNumber = 2;
  ::dmi::ImageVersion* mutable_standby_versions(int index);
  ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >*
      mutable_standby_versions();
  const ::dmi::ImageVersion& standby_versions(int index) const;
  ::dmi::ImageVersion* add_standby_versions();
  const ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >&
      standby_versions() const;

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion > active_versions_;
  ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion > standby_versions_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  GetSoftwareVersionInformationResponse(const GetSoftwareVersionInformationResponse& from);

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

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

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

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

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

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

  GetSoftwareVersionInformationResponse* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<GetSoftwareVersionInformationResponse>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const GetSoftwareVersionInformationResponse& from);
  void MergeFrom(const GetSoftwareVersionInformationResponse& 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(GetSoftwareVersionInformationResponse* 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 GetSoftwareVersionInformationResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    GetSoftwareVersionInformationResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    GetSoftwareVersionInformationResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    GetSoftwareVersionInformationResponse_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    GetSoftwareVersionInformationResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return GetSoftwareVersionInformationResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    GetSoftwareVersionInformationResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    GetSoftwareVersionInformationResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    GetSoftwareVersionInformationResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return GetSoftwareVersionInformationResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return GetSoftwareVersionInformationResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return GetSoftwareVersionInformationResponse_Reason_Parse(name, value);
  }

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

  // string reason_detail = 4;
  void clear_reason_detail();
  static const int kReasonDetailFieldNumber = 4;
  const ::std::string& reason_detail() const;
  void set_reason_detail(const ::std::string& value);
  #if LANG_CXX11
  void set_reason_detail(::std::string&& value);
  #endif
  void set_reason_detail(const char* value);
  void set_reason_detail(const char* value, size_t size);
  ::std::string* mutable_reason_detail();
  ::std::string* release_reason_detail();
  void set_allocated_reason_detail(::std::string* reason_detail);

  // .dmi.SoftwareVersionInformation info = 3;
  bool has_info() const;
  void clear_info();
  static const int kInfoFieldNumber = 3;
  const ::dmi::SoftwareVersionInformation& info() const;
  ::dmi::SoftwareVersionInformation* release_info();
  ::dmi::SoftwareVersionInformation* mutable_info();
  void set_allocated_info(::dmi::SoftwareVersionInformation* info);

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

  // .dmi.GetSoftwareVersionInformationResponse.Reason reason = 2;
  void clear_reason();
  static const int kReasonFieldNumber = 2;
  ::dmi::GetSoftwareVersionInformationResponse_Reason reason() const;
  void set_reason(::dmi::GetSoftwareVersionInformationResponse_Reason value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  ::dmi::SoftwareVersionInformation* info_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  DownloadImageRequest(const DownloadImageRequest& from);

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

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

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

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

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

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

  DownloadImageRequest* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<DownloadImageRequest>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const DownloadImageRequest& from);
  void MergeFrom(const DownloadImageRequest& 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(DownloadImageRequest* 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 device_uuid = 1;
  bool has_device_uuid() const;
  void clear_device_uuid();
  static const int kDeviceUuidFieldNumber = 1;
  const ::dmi::Uuid& device_uuid() const;
  ::dmi::Uuid* release_device_uuid();
  ::dmi::Uuid* mutable_device_uuid();
  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);

  // .dmi.ImageInformation image_info = 2;
  bool has_image_info() const;
  void clear_image_info();
  static const int kImageInfoFieldNumber = 2;
  const ::dmi::ImageInformation& image_info() const;
  ::dmi::ImageInformation* release_image_info();
  ::dmi::ImageInformation* mutable_image_info();
  void set_allocated_image_info(::dmi::ImageInformation* image_info);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::dmi::Uuid* device_uuid_;
  ::dmi::ImageInformation* image_info_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  ConfigRequest(const ConfigRequest& from);

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

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

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

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

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

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

  ConfigRequest* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ConfigRequest>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ConfigRequest& from);
  void MergeFrom(const ConfigRequest& 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(ConfigRequest* 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 config_url = 2;
  void clear_config_url();
  static const int kConfigUrlFieldNumber = 2;
  const ::std::string& config_url() const;
  void set_config_url(const ::std::string& value);
  #if LANG_CXX11
  void set_config_url(::std::string&& value);
  #endif
  void set_config_url(const char* value);
  void set_config_url(const char* value, size_t size);
  ::std::string* mutable_config_url();
  ::std::string* release_config_url();
  void set_allocated_config_url(::std::string* config_url);

  // .dmi.Uuid device_uuid = 1;
  bool has_device_uuid() const;
  void clear_device_uuid();
  static const int kDeviceUuidFieldNumber = 1;
  const ::dmi::Uuid& device_uuid() const;
  ::dmi::Uuid* release_device_uuid();
  ::dmi::Uuid* mutable_device_uuid();
  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr config_url_;
  ::dmi::Uuid* device_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  ConfigResponse(const ConfigResponse& from);

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

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

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

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

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

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

  ConfigResponse* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ConfigResponse>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ConfigResponse& from);
  void MergeFrom(const ConfigResponse& 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(ConfigResponse* 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 ConfigResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    ConfigResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    ConfigResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    ConfigResponse_Reason_INTERNAL_ERROR;
  static const Reason ERROR_FETCHING_CONFIG =
    ConfigResponse_Reason_ERROR_FETCHING_CONFIG;
  static const Reason INVALID_CONFIG =
    ConfigResponse_Reason_INVALID_CONFIG;
  static const Reason OPERATION_ALREADY_IN_PROGRESS =
    ConfigResponse_Reason_OPERATION_ALREADY_IN_PROGRESS;
  static const Reason DEVICE_UNREACHABLE =
    ConfigResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return ConfigResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    ConfigResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    ConfigResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    ConfigResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return ConfigResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return ConfigResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return ConfigResponse_Reason_Parse(name, value);
  }

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

  // string reason_detail = 3;
  void clear_reason_detail();
  static const int kReasonDetailFieldNumber = 3;
  const ::std::string& reason_detail() const;
  void set_reason_detail(const ::std::string& value);
  #if LANG_CXX11
  void set_reason_detail(::std::string&& value);
  #endif
  void set_reason_detail(const char* value);
  void set_reason_detail(const char* value, size_t size);
  ::std::string* mutable_reason_detail();
  ::std::string* release_reason_detail();
  void set_allocated_reason_detail(::std::string* reason_detail);

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

  // .dmi.ConfigResponse.Reason reason = 2;
  void clear_reason();
  static const int kReasonFieldNumber = 2;
  ::dmi::ConfigResponse_Reason reason() const;
  void set_reason(::dmi::ConfigResponse_Reason value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  StartupConfigInfoRequest(const StartupConfigInfoRequest& from);

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

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

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

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

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

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

  StartupConfigInfoRequest* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<StartupConfigInfoRequest>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const StartupConfigInfoRequest& from);
  void MergeFrom(const StartupConfigInfoRequest& 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(StartupConfigInfoRequest* 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 device_uuid = 1;
  bool has_device_uuid() const;
  void clear_device_uuid();
  static const int kDeviceUuidFieldNumber = 1;
  const ::dmi::Uuid& device_uuid() const;
  ::dmi::Uuid* release_device_uuid();
  ::dmi::Uuid* mutable_device_uuid();
  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);

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

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

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

  StartupConfigInfoResponse(const StartupConfigInfoResponse& from);

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

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

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

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

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

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

  StartupConfigInfoResponse* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<StartupConfigInfoResponse>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const StartupConfigInfoResponse& from);
  void MergeFrom(const StartupConfigInfoResponse& 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(StartupConfigInfoResponse* 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 StartupConfigInfoResponse_Reason Reason;
  static const Reason UNDEFINED_REASON =
    StartupConfigInfoResponse_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    StartupConfigInfoResponse_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    StartupConfigInfoResponse_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    StartupConfigInfoResponse_Reason_DEVICE_UNREACHABLE;
  static inline bool Reason_IsValid(int value) {
    return StartupConfigInfoResponse_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    StartupConfigInfoResponse_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    StartupConfigInfoResponse_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    StartupConfigInfoResponse_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return StartupConfigInfoResponse_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return StartupConfigInfoResponse_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return StartupConfigInfoResponse_Reason_Parse(name, value);
  }

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

  // string config_url = 3;
  void clear_config_url();
  static const int kConfigUrlFieldNumber = 3;
  const ::std::string& config_url() const;
  void set_config_url(const ::std::string& value);
  #if LANG_CXX11
  void set_config_url(::std::string&& value);
  #endif
  void set_config_url(const char* value);
  void set_config_url(const char* value, size_t size);
  ::std::string* mutable_config_url();
  ::std::string* release_config_url();
  void set_allocated_config_url(::std::string* config_url);

  // string version = 4;
  void clear_version();
  static const int kVersionFieldNumber = 4;
  const ::std::string& version() const;
  void set_version(const ::std::string& value);
  #if LANG_CXX11
  void set_version(::std::string&& value);
  #endif
  void set_version(const char* value);
  void set_version(const char* value, size_t size);
  ::std::string* mutable_version();
  ::std::string* release_version();
  void set_allocated_version(::std::string* version);

  // string reason_detail = 5;
  void clear_reason_detail();
  static const int kReasonDetailFieldNumber = 5;
  const ::std::string& reason_detail() const;
  void set_reason_detail(const ::std::string& value);
  #if LANG_CXX11
  void set_reason_detail(::std::string&& value);
  #endif
  void set_reason_detail(const char* value);
  void set_reason_detail(const char* value, size_t size);
  ::std::string* mutable_reason_detail();
  ::std::string* release_reason_detail();
  void set_allocated_reason_detail(::std::string* reason_detail);

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

  // .dmi.StartupConfigInfoResponse.Reason reason = 2;
  void clear_reason();
  static const int kReasonFieldNumber = 2;
  ::dmi::StartupConfigInfoResponse_Reason reason() const;
  void set_reason(::dmi::StartupConfigInfoResponse_Reason value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr config_url_;
  ::google::protobuf::internal::ArenaStringPtr version_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  int status_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  UploadDebugInfoRequest(const UploadDebugInfoRequest& from);

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

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

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

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

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

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

  UploadDebugInfoRequest* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<UploadDebugInfoRequest>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const UploadDebugInfoRequest& from);
  void MergeFrom(const UploadDebugInfoRequest& 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(UploadDebugInfoRequest* 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 location_url = 3;
  void clear_location_url();
  static const int kLocationUrlFieldNumber = 3;
  const ::std::string& location_url() const;
  void set_location_url(const ::std::string& value);
  #if LANG_CXX11
  void set_location_url(::std::string&& value);
  #endif
  void set_location_url(const char* value);
  void set_location_url(const char* value, size_t size);
  ::std::string* mutable_location_url();
  ::std::string* release_location_url();
  void set_allocated_location_url(::std::string* location_url);

  // .dmi.Uuid device_uuid = 1;
  bool has_device_uuid() const;
  void clear_device_uuid();
  static const int kDeviceUuidFieldNumber = 1;
  const ::dmi::Uuid& device_uuid() const;
  ::dmi::Uuid* release_device_uuid();
  ::dmi::Uuid* mutable_device_uuid();
  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr location_url_;
  ::dmi::Uuid* device_uuid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
};
// -------------------------------------------------------------------

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

  UploadDebugInfoStatus(const UploadDebugInfoStatus& from);

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

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

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

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

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

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

  UploadDebugInfoStatus* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<UploadDebugInfoStatus>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const UploadDebugInfoStatus& from);
  void MergeFrom(const UploadDebugInfoStatus& 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(UploadDebugInfoStatus* 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 UploadDebugInfoStatus_UploadStatus UploadStatus;
  static const UploadStatus UNDEFINED_UPLOAD_STATUS =
    UploadDebugInfoStatus_UploadStatus_UNDEFINED_UPLOAD_STATUS;
  static const UploadStatus COMPLETE =
    UploadDebugInfoStatus_UploadStatus_COMPLETE;
  static const UploadStatus IN_PROGRESS =
    UploadDebugInfoStatus_UploadStatus_IN_PROGRESS;
  static const UploadStatus ERROR =
    UploadDebugInfoStatus_UploadStatus_ERROR;
  static inline bool UploadStatus_IsValid(int value) {
    return UploadDebugInfoStatus_UploadStatus_IsValid(value);
  }
  static const UploadStatus UploadStatus_MIN =
    UploadDebugInfoStatus_UploadStatus_UploadStatus_MIN;
  static const UploadStatus UploadStatus_MAX =
    UploadDebugInfoStatus_UploadStatus_UploadStatus_MAX;
  static const int UploadStatus_ARRAYSIZE =
    UploadDebugInfoStatus_UploadStatus_UploadStatus_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  UploadStatus_descriptor() {
    return UploadDebugInfoStatus_UploadStatus_descriptor();
  }
  static inline const ::std::string& UploadStatus_Name(UploadStatus value) {
    return UploadDebugInfoStatus_UploadStatus_Name(value);
  }
  static inline bool UploadStatus_Parse(const ::std::string& name,
      UploadStatus* value) {
    return UploadDebugInfoStatus_UploadStatus_Parse(name, value);
  }

  typedef UploadDebugInfoStatus_Reason Reason;
  static const Reason UNDEFINED_REASON =
    UploadDebugInfoStatus_Reason_UNDEFINED_REASON;
  static const Reason UNKNOWN_DEVICE =
    UploadDebugInfoStatus_Reason_UNKNOWN_DEVICE;
  static const Reason INTERNAL_ERROR =
    UploadDebugInfoStatus_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_UNREACHABLE =
    UploadDebugInfoStatus_Reason_DEVICE_UNREACHABLE;
  static const Reason REMOTE_LOCATION_UNREACHABLE =
    UploadDebugInfoStatus_Reason_REMOTE_LOCATION_UNREACHABLE;
  static const Reason REMOTE_LOCATION_PERMISSION_DENIED =
    UploadDebugInfoStatus_Reason_REMOTE_LOCATION_PERMISSION_DENIED;
  static const Reason ERROR_DURING_UPLOAD =
    UploadDebugInfoStatus_Reason_ERROR_DURING_UPLOAD;
  static inline bool Reason_IsValid(int value) {
    return UploadDebugInfoStatus_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    UploadDebugInfoStatus_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    UploadDebugInfoStatus_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    UploadDebugInfoStatus_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return UploadDebugInfoStatus_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return UploadDebugInfoStatus_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return UploadDebugInfoStatus_Reason_Parse(name, value);
  }

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

  // string location_url = 5;
  void clear_location_url();
  static const int kLocationUrlFieldNumber = 5;
  const ::std::string& location_url() const;
  void set_location_url(const ::std::string& value);
  #if LANG_CXX11
  void set_location_url(::std::string&& value);
  #endif
  void set_location_url(const char* value);
  void set_location_url(const char* value, size_t size);
  ::std::string* mutable_location_url();
  ::std::string* release_location_url();
  void set_allocated_location_url(::std::string* location_url);

  // string file_name = 6;
  void clear_file_name();
  static const int kFileNameFieldNumber = 6;
  const ::std::string& file_name() const;
  void set_file_name(const ::std::string& value);
  #if LANG_CXX11
  void set_file_name(::std::string&& value);
  #endif
  void set_file_name(const char* value);
  void set_file_name(const char* value, size_t size);
  ::std::string* mutable_file_name();
  ::std::string* release_file_name();
  void set_allocated_file_name(::std::string* file_name);

  // .dmi.Uuid device_uuid = 1;
  bool has_device_uuid() const;
  void clear_device_uuid();
  static const int kDeviceUuidFieldNumber = 1;
  const ::dmi::Uuid& device_uuid() const;
  ::dmi::Uuid* release_device_uuid();
  ::dmi::Uuid* mutable_device_uuid();
  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);

  // .dmi.UploadDebugInfoStatus.UploadStatus status = 2;
  void clear_status();
  static const int kStatusFieldNumber = 2;
  ::dmi::UploadDebugInfoStatus_UploadStatus status() const;
  void set_status(::dmi::UploadDebugInfoStatus_UploadStatus value);

  // int32 percent_uploaded = 3;
  void clear_percent_uploaded();
  static const int kPercentUploadedFieldNumber = 3;
  ::google::protobuf::int32 percent_uploaded() const;
  void set_percent_uploaded(::google::protobuf::int32 value);

  // .dmi.UploadDebugInfoStatus.Reason reason = 4;
  void clear_reason();
  static const int kReasonFieldNumber = 4;
  ::dmi::UploadDebugInfoStatus_Reason reason() const;
  void set_reason(::dmi::UploadDebugInfoStatus_Reason value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr location_url_;
  ::google::protobuf::internal::ArenaStringPtr file_name_;
  ::dmi::Uuid* device_uuid_;
  int status_;
  ::google::protobuf::int32 percent_uploaded_;
  int reason_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fmanagement_5fservice_2eproto;
};
// ===================================================================


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

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

// repeated .dmi.ImageVersion active_versions = 1;
inline int SoftwareVersionInformation::active_versions_size() const {
  return active_versions_.size();
}
inline ::dmi::ImageVersion* SoftwareVersionInformation::mutable_active_versions(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.SoftwareVersionInformation.active_versions)
  return active_versions_.Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >*
SoftwareVersionInformation::mutable_active_versions() {
  // @@protoc_insertion_point(field_mutable_list:dmi.SoftwareVersionInformation.active_versions)
  return &active_versions_;
}
inline const ::dmi::ImageVersion& SoftwareVersionInformation::active_versions(int index) const {
  // @@protoc_insertion_point(field_get:dmi.SoftwareVersionInformation.active_versions)
  return active_versions_.Get(index);
}
inline ::dmi::ImageVersion* SoftwareVersionInformation::add_active_versions() {
  // @@protoc_insertion_point(field_add:dmi.SoftwareVersionInformation.active_versions)
  return active_versions_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >&
SoftwareVersionInformation::active_versions() const {
  // @@protoc_insertion_point(field_list:dmi.SoftwareVersionInformation.active_versions)
  return active_versions_;
}

// repeated .dmi.ImageVersion standby_versions = 2;
inline int SoftwareVersionInformation::standby_versions_size() const {
  return standby_versions_.size();
}
inline ::dmi::ImageVersion* SoftwareVersionInformation::mutable_standby_versions(int index) {
  // @@protoc_insertion_point(field_mutable:dmi.SoftwareVersionInformation.standby_versions)
  return standby_versions_.Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >*
SoftwareVersionInformation::mutable_standby_versions() {
  // @@protoc_insertion_point(field_mutable_list:dmi.SoftwareVersionInformation.standby_versions)
  return &standby_versions_;
}
inline const ::dmi::ImageVersion& SoftwareVersionInformation::standby_versions(int index) const {
  // @@protoc_insertion_point(field_get:dmi.SoftwareVersionInformation.standby_versions)
  return standby_versions_.Get(index);
}
inline ::dmi::ImageVersion* SoftwareVersionInformation::add_standby_versions() {
  // @@protoc_insertion_point(field_add:dmi.SoftwareVersionInformation.standby_versions)
  return standby_versions_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::dmi::ImageVersion >&
SoftwareVersionInformation::standby_versions() const {
  // @@protoc_insertion_point(field_list:dmi.SoftwareVersionInformation.standby_versions)
  return standby_versions_;
}

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

// GetSoftwareVersionInformationResponse

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

// .dmi.GetSoftwareVersionInformationResponse.Reason reason = 2;
inline void GetSoftwareVersionInformationResponse::clear_reason() {
  reason_ = 0;
}
inline ::dmi::GetSoftwareVersionInformationResponse_Reason GetSoftwareVersionInformationResponse::reason() const {
  // @@protoc_insertion_point(field_get:dmi.GetSoftwareVersionInformationResponse.reason)
  return static_cast< ::dmi::GetSoftwareVersionInformationResponse_Reason >(reason_);
}
inline void GetSoftwareVersionInformationResponse::set_reason(::dmi::GetSoftwareVersionInformationResponse_Reason value) {
  
  reason_ = value;
  // @@protoc_insertion_point(field_set:dmi.GetSoftwareVersionInformationResponse.reason)
}

// .dmi.SoftwareVersionInformation info = 3;
inline bool GetSoftwareVersionInformationResponse::has_info() const {
  return this != internal_default_instance() && info_ != nullptr;
}
inline void GetSoftwareVersionInformationResponse::clear_info() {
  if (GetArenaNoVirtual() == nullptr && info_ != nullptr) {
    delete info_;
  }
  info_ = nullptr;
}
inline const ::dmi::SoftwareVersionInformation& GetSoftwareVersionInformationResponse::info() const {
  const ::dmi::SoftwareVersionInformation* p = info_;
  // @@protoc_insertion_point(field_get:dmi.GetSoftwareVersionInformationResponse.info)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::SoftwareVersionInformation*>(
      &::dmi::_SoftwareVersionInformation_default_instance_);
}
inline ::dmi::SoftwareVersionInformation* GetSoftwareVersionInformationResponse::release_info() {
  // @@protoc_insertion_point(field_release:dmi.GetSoftwareVersionInformationResponse.info)
  
  ::dmi::SoftwareVersionInformation* temp = info_;
  info_ = nullptr;
  return temp;
}
inline ::dmi::SoftwareVersionInformation* GetSoftwareVersionInformationResponse::mutable_info() {
  
  if (info_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::SoftwareVersionInformation>(GetArenaNoVirtual());
    info_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.GetSoftwareVersionInformationResponse.info)
  return info_;
}
inline void GetSoftwareVersionInformationResponse::set_allocated_info(::dmi::SoftwareVersionInformation* info) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete info_;
  }
  if (info) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      info = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, info, submessage_arena);
    }
    
  } else {
    
  }
  info_ = info;
  // @@protoc_insertion_point(field_set_allocated:dmi.GetSoftwareVersionInformationResponse.info)
}

// string reason_detail = 4;
inline void GetSoftwareVersionInformationResponse::clear_reason_detail() {
  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& GetSoftwareVersionInformationResponse::reason_detail() const {
  // @@protoc_insertion_point(field_get:dmi.GetSoftwareVersionInformationResponse.reason_detail)
  return reason_detail_.GetNoArena();
}
inline void GetSoftwareVersionInformationResponse::set_reason_detail(const ::std::string& value) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.GetSoftwareVersionInformationResponse.reason_detail)
}
#if LANG_CXX11
inline void GetSoftwareVersionInformationResponse::set_reason_detail(::std::string&& value) {
  
  reason_detail_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.GetSoftwareVersionInformationResponse.reason_detail)
}
#endif
inline void GetSoftwareVersionInformationResponse::set_reason_detail(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.GetSoftwareVersionInformationResponse.reason_detail)
}
inline void GetSoftwareVersionInformationResponse::set_reason_detail(const char* value, size_t size) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.GetSoftwareVersionInformationResponse.reason_detail)
}
inline ::std::string* GetSoftwareVersionInformationResponse::mutable_reason_detail() {
  
  // @@protoc_insertion_point(field_mutable:dmi.GetSoftwareVersionInformationResponse.reason_detail)
  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* GetSoftwareVersionInformationResponse::release_reason_detail() {
  // @@protoc_insertion_point(field_release:dmi.GetSoftwareVersionInformationResponse.reason_detail)
  
  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void GetSoftwareVersionInformationResponse::set_allocated_reason_detail(::std::string* reason_detail) {
  if (reason_detail != nullptr) {
    
  } else {
    
  }
  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
  // @@protoc_insertion_point(field_set_allocated:dmi.GetSoftwareVersionInformationResponse.reason_detail)
}

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

// DownloadImageRequest

// .dmi.Uuid device_uuid = 1;
inline bool DownloadImageRequest::has_device_uuid() const {
  return this != internal_default_instance() && device_uuid_ != nullptr;
}
inline const ::dmi::Uuid& DownloadImageRequest::device_uuid() const {
  const ::dmi::Uuid* p = device_uuid_;
  // @@protoc_insertion_point(field_get:dmi.DownloadImageRequest.device_uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* DownloadImageRequest::release_device_uuid() {
  // @@protoc_insertion_point(field_release:dmi.DownloadImageRequest.device_uuid)
  
  ::dmi::Uuid* temp = device_uuid_;
  device_uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* DownloadImageRequest::mutable_device_uuid() {
  
  if (device_uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    device_uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.DownloadImageRequest.device_uuid)
  return device_uuid_;
}
inline void DownloadImageRequest::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
  }
  if (device_uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, device_uuid, submessage_arena);
    }
    
  } else {
    
  }
  device_uuid_ = device_uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.DownloadImageRequest.device_uuid)
}

// .dmi.ImageInformation image_info = 2;
inline bool DownloadImageRequest::has_image_info() const {
  return this != internal_default_instance() && image_info_ != nullptr;
}
inline const ::dmi::ImageInformation& DownloadImageRequest::image_info() const {
  const ::dmi::ImageInformation* p = image_info_;
  // @@protoc_insertion_point(field_get:dmi.DownloadImageRequest.image_info)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ImageInformation*>(
      &::dmi::_ImageInformation_default_instance_);
}
inline ::dmi::ImageInformation* DownloadImageRequest::release_image_info() {
  // @@protoc_insertion_point(field_release:dmi.DownloadImageRequest.image_info)
  
  ::dmi::ImageInformation* temp = image_info_;
  image_info_ = nullptr;
  return temp;
}
inline ::dmi::ImageInformation* DownloadImageRequest::mutable_image_info() {
  
  if (image_info_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::ImageInformation>(GetArenaNoVirtual());
    image_info_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.DownloadImageRequest.image_info)
  return image_info_;
}
inline void DownloadImageRequest::set_allocated_image_info(::dmi::ImageInformation* image_info) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(image_info_);
  }
  if (image_info) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      image_info = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, image_info, submessage_arena);
    }
    
  } else {
    
  }
  image_info_ = image_info;
  // @@protoc_insertion_point(field_set_allocated:dmi.DownloadImageRequest.image_info)
}

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

// ConfigRequest

// .dmi.Uuid device_uuid = 1;
inline bool ConfigRequest::has_device_uuid() const {
  return this != internal_default_instance() && device_uuid_ != nullptr;
}
inline const ::dmi::Uuid& ConfigRequest::device_uuid() const {
  const ::dmi::Uuid* p = device_uuid_;
  // @@protoc_insertion_point(field_get:dmi.ConfigRequest.device_uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* ConfigRequest::release_device_uuid() {
  // @@protoc_insertion_point(field_release:dmi.ConfigRequest.device_uuid)
  
  ::dmi::Uuid* temp = device_uuid_;
  device_uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* ConfigRequest::mutable_device_uuid() {
  
  if (device_uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    device_uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ConfigRequest.device_uuid)
  return device_uuid_;
}
inline void ConfigRequest::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
  }
  if (device_uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, device_uuid, submessage_arena);
    }
    
  } else {
    
  }
  device_uuid_ = device_uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.ConfigRequest.device_uuid)
}

// string config_url = 2;
inline void ConfigRequest::clear_config_url() {
  config_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ConfigRequest::config_url() const {
  // @@protoc_insertion_point(field_get:dmi.ConfigRequest.config_url)
  return config_url_.GetNoArena();
}
inline void ConfigRequest::set_config_url(const ::std::string& value) {
  
  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ConfigRequest.config_url)
}
#if LANG_CXX11
inline void ConfigRequest::set_config_url(::std::string&& value) {
  
  config_url_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ConfigRequest.config_url)
}
#endif
inline void ConfigRequest::set_config_url(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ConfigRequest.config_url)
}
inline void ConfigRequest::set_config_url(const char* value, size_t size) {
  
  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ConfigRequest.config_url)
}
inline ::std::string* ConfigRequest::mutable_config_url() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ConfigRequest.config_url)
  return config_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ConfigRequest::release_config_url() {
  // @@protoc_insertion_point(field_release:dmi.ConfigRequest.config_url)
  
  return config_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ConfigRequest::set_allocated_config_url(::std::string* config_url) {
  if (config_url != nullptr) {
    
  } else {
    
  }
  config_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), config_url);
  // @@protoc_insertion_point(field_set_allocated:dmi.ConfigRequest.config_url)
}

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

// ConfigResponse

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

// .dmi.ConfigResponse.Reason reason = 2;
inline void ConfigResponse::clear_reason() {
  reason_ = 0;
}
inline ::dmi::ConfigResponse_Reason ConfigResponse::reason() const {
  // @@protoc_insertion_point(field_get:dmi.ConfigResponse.reason)
  return static_cast< ::dmi::ConfigResponse_Reason >(reason_);
}
inline void ConfigResponse::set_reason(::dmi::ConfigResponse_Reason value) {
  
  reason_ = value;
  // @@protoc_insertion_point(field_set:dmi.ConfigResponse.reason)
}

// string reason_detail = 3;
inline void ConfigResponse::clear_reason_detail() {
  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ConfigResponse::reason_detail() const {
  // @@protoc_insertion_point(field_get:dmi.ConfigResponse.reason_detail)
  return reason_detail_.GetNoArena();
}
inline void ConfigResponse::set_reason_detail(const ::std::string& value) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ConfigResponse.reason_detail)
}
#if LANG_CXX11
inline void ConfigResponse::set_reason_detail(::std::string&& value) {
  
  reason_detail_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ConfigResponse.reason_detail)
}
#endif
inline void ConfigResponse::set_reason_detail(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ConfigResponse.reason_detail)
}
inline void ConfigResponse::set_reason_detail(const char* value, size_t size) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ConfigResponse.reason_detail)
}
inline ::std::string* ConfigResponse::mutable_reason_detail() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ConfigResponse.reason_detail)
  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ConfigResponse::release_reason_detail() {
  // @@protoc_insertion_point(field_release:dmi.ConfigResponse.reason_detail)
  
  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ConfigResponse::set_allocated_reason_detail(::std::string* reason_detail) {
  if (reason_detail != nullptr) {
    
  } else {
    
  }
  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
  // @@protoc_insertion_point(field_set_allocated:dmi.ConfigResponse.reason_detail)
}

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

// StartupConfigInfoRequest

// .dmi.Uuid device_uuid = 1;
inline bool StartupConfigInfoRequest::has_device_uuid() const {
  return this != internal_default_instance() && device_uuid_ != nullptr;
}
inline const ::dmi::Uuid& StartupConfigInfoRequest::device_uuid() const {
  const ::dmi::Uuid* p = device_uuid_;
  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoRequest.device_uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* StartupConfigInfoRequest::release_device_uuid() {
  // @@protoc_insertion_point(field_release:dmi.StartupConfigInfoRequest.device_uuid)
  
  ::dmi::Uuid* temp = device_uuid_;
  device_uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* StartupConfigInfoRequest::mutable_device_uuid() {
  
  if (device_uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    device_uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.StartupConfigInfoRequest.device_uuid)
  return device_uuid_;
}
inline void StartupConfigInfoRequest::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
  }
  if (device_uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, device_uuid, submessage_arena);
    }
    
  } else {
    
  }
  device_uuid_ = device_uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.StartupConfigInfoRequest.device_uuid)
}

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

// StartupConfigInfoResponse

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

// .dmi.StartupConfigInfoResponse.Reason reason = 2;
inline void StartupConfigInfoResponse::clear_reason() {
  reason_ = 0;
}
inline ::dmi::StartupConfigInfoResponse_Reason StartupConfigInfoResponse::reason() const {
  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoResponse.reason)
  return static_cast< ::dmi::StartupConfigInfoResponse_Reason >(reason_);
}
inline void StartupConfigInfoResponse::set_reason(::dmi::StartupConfigInfoResponse_Reason value) {
  
  reason_ = value;
  // @@protoc_insertion_point(field_set:dmi.StartupConfigInfoResponse.reason)
}

// string config_url = 3;
inline void StartupConfigInfoResponse::clear_config_url() {
  config_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& StartupConfigInfoResponse::config_url() const {
  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoResponse.config_url)
  return config_url_.GetNoArena();
}
inline void StartupConfigInfoResponse::set_config_url(const ::std::string& value) {
  
  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.StartupConfigInfoResponse.config_url)
}
#if LANG_CXX11
inline void StartupConfigInfoResponse::set_config_url(::std::string&& value) {
  
  config_url_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.StartupConfigInfoResponse.config_url)
}
#endif
inline void StartupConfigInfoResponse::set_config_url(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.StartupConfigInfoResponse.config_url)
}
inline void StartupConfigInfoResponse::set_config_url(const char* value, size_t size) {
  
  config_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.StartupConfigInfoResponse.config_url)
}
inline ::std::string* StartupConfigInfoResponse::mutable_config_url() {
  
  // @@protoc_insertion_point(field_mutable:dmi.StartupConfigInfoResponse.config_url)
  return config_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* StartupConfigInfoResponse::release_config_url() {
  // @@protoc_insertion_point(field_release:dmi.StartupConfigInfoResponse.config_url)
  
  return config_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void StartupConfigInfoResponse::set_allocated_config_url(::std::string* config_url) {
  if (config_url != nullptr) {
    
  } else {
    
  }
  config_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), config_url);
  // @@protoc_insertion_point(field_set_allocated:dmi.StartupConfigInfoResponse.config_url)
}

// string version = 4;
inline void StartupConfigInfoResponse::clear_version() {
  version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& StartupConfigInfoResponse::version() const {
  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoResponse.version)
  return version_.GetNoArena();
}
inline void StartupConfigInfoResponse::set_version(const ::std::string& value) {
  
  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.StartupConfigInfoResponse.version)
}
#if LANG_CXX11
inline void StartupConfigInfoResponse::set_version(::std::string&& value) {
  
  version_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.StartupConfigInfoResponse.version)
}
#endif
inline void StartupConfigInfoResponse::set_version(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.StartupConfigInfoResponse.version)
}
inline void StartupConfigInfoResponse::set_version(const char* value, size_t size) {
  
  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.StartupConfigInfoResponse.version)
}
inline ::std::string* StartupConfigInfoResponse::mutable_version() {
  
  // @@protoc_insertion_point(field_mutable:dmi.StartupConfigInfoResponse.version)
  return version_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* StartupConfigInfoResponse::release_version() {
  // @@protoc_insertion_point(field_release:dmi.StartupConfigInfoResponse.version)
  
  return version_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void StartupConfigInfoResponse::set_allocated_version(::std::string* version) {
  if (version != nullptr) {
    
  } else {
    
  }
  version_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), version);
  // @@protoc_insertion_point(field_set_allocated:dmi.StartupConfigInfoResponse.version)
}

// string reason_detail = 5;
inline void StartupConfigInfoResponse::clear_reason_detail() {
  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& StartupConfigInfoResponse::reason_detail() const {
  // @@protoc_insertion_point(field_get:dmi.StartupConfigInfoResponse.reason_detail)
  return reason_detail_.GetNoArena();
}
inline void StartupConfigInfoResponse::set_reason_detail(const ::std::string& value) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.StartupConfigInfoResponse.reason_detail)
}
#if LANG_CXX11
inline void StartupConfigInfoResponse::set_reason_detail(::std::string&& value) {
  
  reason_detail_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.StartupConfigInfoResponse.reason_detail)
}
#endif
inline void StartupConfigInfoResponse::set_reason_detail(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.StartupConfigInfoResponse.reason_detail)
}
inline void StartupConfigInfoResponse::set_reason_detail(const char* value, size_t size) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.StartupConfigInfoResponse.reason_detail)
}
inline ::std::string* StartupConfigInfoResponse::mutable_reason_detail() {
  
  // @@protoc_insertion_point(field_mutable:dmi.StartupConfigInfoResponse.reason_detail)
  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* StartupConfigInfoResponse::release_reason_detail() {
  // @@protoc_insertion_point(field_release:dmi.StartupConfigInfoResponse.reason_detail)
  
  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void StartupConfigInfoResponse::set_allocated_reason_detail(::std::string* reason_detail) {
  if (reason_detail != nullptr) {
    
  } else {
    
  }
  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
  // @@protoc_insertion_point(field_set_allocated:dmi.StartupConfigInfoResponse.reason_detail)
}

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

// UploadDebugInfoRequest

// .dmi.Uuid device_uuid = 1;
inline bool UploadDebugInfoRequest::has_device_uuid() const {
  return this != internal_default_instance() && device_uuid_ != nullptr;
}
inline const ::dmi::Uuid& UploadDebugInfoRequest::device_uuid() const {
  const ::dmi::Uuid* p = device_uuid_;
  // @@protoc_insertion_point(field_get:dmi.UploadDebugInfoRequest.device_uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* UploadDebugInfoRequest::release_device_uuid() {
  // @@protoc_insertion_point(field_release:dmi.UploadDebugInfoRequest.device_uuid)
  
  ::dmi::Uuid* temp = device_uuid_;
  device_uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* UploadDebugInfoRequest::mutable_device_uuid() {
  
  if (device_uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    device_uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.UploadDebugInfoRequest.device_uuid)
  return device_uuid_;
}
inline void UploadDebugInfoRequest::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
  }
  if (device_uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, device_uuid, submessage_arena);
    }
    
  } else {
    
  }
  device_uuid_ = device_uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.UploadDebugInfoRequest.device_uuid)
}

// string location_url = 3;
inline void UploadDebugInfoRequest::clear_location_url() {
  location_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& UploadDebugInfoRequest::location_url() const {
  // @@protoc_insertion_point(field_get:dmi.UploadDebugInfoRequest.location_url)
  return location_url_.GetNoArena();
}
inline void UploadDebugInfoRequest::set_location_url(const ::std::string& value) {
  
  location_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.UploadDebugInfoRequest.location_url)
}
#if LANG_CXX11
inline void UploadDebugInfoRequest::set_location_url(::std::string&& value) {
  
  location_url_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.UploadDebugInfoRequest.location_url)
}
#endif
inline void UploadDebugInfoRequest::set_location_url(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  location_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.UploadDebugInfoRequest.location_url)
}
inline void UploadDebugInfoRequest::set_location_url(const char* value, size_t size) {
  
  location_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.UploadDebugInfoRequest.location_url)
}
inline ::std::string* UploadDebugInfoRequest::mutable_location_url() {
  
  // @@protoc_insertion_point(field_mutable:dmi.UploadDebugInfoRequest.location_url)
  return location_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* UploadDebugInfoRequest::release_location_url() {
  // @@protoc_insertion_point(field_release:dmi.UploadDebugInfoRequest.location_url)
  
  return location_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void UploadDebugInfoRequest::set_allocated_location_url(::std::string* location_url) {
  if (location_url != nullptr) {
    
  } else {
    
  }
  location_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), location_url);
  // @@protoc_insertion_point(field_set_allocated:dmi.UploadDebugInfoRequest.location_url)
}

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

// UploadDebugInfoStatus

// .dmi.Uuid device_uuid = 1;
inline bool UploadDebugInfoStatus::has_device_uuid() const {
  return this != internal_default_instance() && device_uuid_ != nullptr;
}
inline const ::dmi::Uuid& UploadDebugInfoStatus::device_uuid() const {
  const ::dmi::Uuid* p = device_uuid_;
  // @@protoc_insertion_point(field_get:dmi.UploadDebugInfoStatus.device_uuid)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
      &::dmi::_Uuid_default_instance_);
}
inline ::dmi::Uuid* UploadDebugInfoStatus::release_device_uuid() {
  // @@protoc_insertion_point(field_release:dmi.UploadDebugInfoStatus.device_uuid)
  
  ::dmi::Uuid* temp = device_uuid_;
  device_uuid_ = nullptr;
  return temp;
}
inline ::dmi::Uuid* UploadDebugInfoStatus::mutable_device_uuid() {
  
  if (device_uuid_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
    device_uuid_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.UploadDebugInfoStatus.device_uuid)
  return device_uuid_;
}
inline void UploadDebugInfoStatus::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
  }
  if (device_uuid) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, device_uuid, submessage_arena);
    }
    
  } else {
    
  }
  device_uuid_ = device_uuid;
  // @@protoc_insertion_point(field_set_allocated:dmi.UploadDebugInfoStatus.device_uuid)
}

// .dmi.UploadDebugInfoStatus.UploadStatus status = 2;
inline void UploadDebugInfoStatus::clear_status() {
  status_ = 0;
}
inline ::dmi::UploadDebugInfoStatus_UploadStatus UploadDebugInfoStatus::status() const {
  // @@protoc_insertion_point(field_get:dmi.UploadDebugInfoStatus.status)
  return static_cast< ::dmi::UploadDebugInfoStatus_UploadStatus >(status_);
}
inline void UploadDebugInfoStatus::set_status(::dmi::UploadDebugInfoStatus_UploadStatus value) {
  
  status_ = value;
  // @@protoc_insertion_point(field_set:dmi.UploadDebugInfoStatus.status)
}

// int32 percent_uploaded = 3;
inline void UploadDebugInfoStatus::clear_percent_uploaded() {
  percent_uploaded_ = 0;
}
inline ::google::protobuf::int32 UploadDebugInfoStatus::percent_uploaded() const {
  // @@protoc_insertion_point(field_get:dmi.UploadDebugInfoStatus.percent_uploaded)
  return percent_uploaded_;
}
inline void UploadDebugInfoStatus::set_percent_uploaded(::google::protobuf::int32 value) {
  
  percent_uploaded_ = value;
  // @@protoc_insertion_point(field_set:dmi.UploadDebugInfoStatus.percent_uploaded)
}

// .dmi.UploadDebugInfoStatus.Reason reason = 4;
inline void UploadDebugInfoStatus::clear_reason() {
  reason_ = 0;
}
inline ::dmi::UploadDebugInfoStatus_Reason UploadDebugInfoStatus::reason() const {
  // @@protoc_insertion_point(field_get:dmi.UploadDebugInfoStatus.reason)
  return static_cast< ::dmi::UploadDebugInfoStatus_Reason >(reason_);
}
inline void UploadDebugInfoStatus::set_reason(::dmi::UploadDebugInfoStatus_Reason value) {
  
  reason_ = value;
  // @@protoc_insertion_point(field_set:dmi.UploadDebugInfoStatus.reason)
}

// string location_url = 5;
inline void UploadDebugInfoStatus::clear_location_url() {
  location_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& UploadDebugInfoStatus::location_url() const {
  // @@protoc_insertion_point(field_get:dmi.UploadDebugInfoStatus.location_url)
  return location_url_.GetNoArena();
}
inline void UploadDebugInfoStatus::set_location_url(const ::std::string& value) {
  
  location_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.UploadDebugInfoStatus.location_url)
}
#if LANG_CXX11
inline void UploadDebugInfoStatus::set_location_url(::std::string&& value) {
  
  location_url_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.UploadDebugInfoStatus.location_url)
}
#endif
inline void UploadDebugInfoStatus::set_location_url(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  location_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.UploadDebugInfoStatus.location_url)
}
inline void UploadDebugInfoStatus::set_location_url(const char* value, size_t size) {
  
  location_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.UploadDebugInfoStatus.location_url)
}
inline ::std::string* UploadDebugInfoStatus::mutable_location_url() {
  
  // @@protoc_insertion_point(field_mutable:dmi.UploadDebugInfoStatus.location_url)
  return location_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* UploadDebugInfoStatus::release_location_url() {
  // @@protoc_insertion_point(field_release:dmi.UploadDebugInfoStatus.location_url)
  
  return location_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void UploadDebugInfoStatus::set_allocated_location_url(::std::string* location_url) {
  if (location_url != nullptr) {
    
  } else {
    
  }
  location_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), location_url);
  // @@protoc_insertion_point(field_set_allocated:dmi.UploadDebugInfoStatus.location_url)
}

// string file_name = 6;
inline void UploadDebugInfoStatus::clear_file_name() {
  file_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& UploadDebugInfoStatus::file_name() const {
  // @@protoc_insertion_point(field_get:dmi.UploadDebugInfoStatus.file_name)
  return file_name_.GetNoArena();
}
inline void UploadDebugInfoStatus::set_file_name(const ::std::string& value) {
  
  file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.UploadDebugInfoStatus.file_name)
}
#if LANG_CXX11
inline void UploadDebugInfoStatus::set_file_name(::std::string&& value) {
  
  file_name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.UploadDebugInfoStatus.file_name)
}
#endif
inline void UploadDebugInfoStatus::set_file_name(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.UploadDebugInfoStatus.file_name)
}
inline void UploadDebugInfoStatus::set_file_name(const char* value, size_t size) {
  
  file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.UploadDebugInfoStatus.file_name)
}
inline ::std::string* UploadDebugInfoStatus::mutable_file_name() {
  
  // @@protoc_insertion_point(field_mutable:dmi.UploadDebugInfoStatus.file_name)
  return file_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* UploadDebugInfoStatus::release_file_name() {
  // @@protoc_insertion_point(field_release:dmi.UploadDebugInfoStatus.file_name)
  
  return file_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void UploadDebugInfoStatus::set_allocated_file_name(::std::string* file_name) {
  if (file_name != nullptr) {
    
  } else {
    
  }
  file_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), file_name);
  // @@protoc_insertion_point(field_set_allocated:dmi.UploadDebugInfoStatus.file_name)
}

#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::GetSoftwareVersionInformationResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::GetSoftwareVersionInformationResponse_Reason>() {
  return ::dmi::GetSoftwareVersionInformationResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::ConfigResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ConfigResponse_Reason>() {
  return ::dmi::ConfigResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::StartupConfigInfoResponse_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::StartupConfigInfoResponse_Reason>() {
  return ::dmi::StartupConfigInfoResponse_Reason_descriptor();
}
template <> struct is_proto_enum< ::dmi::UploadDebugInfoStatus_UploadStatus> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::UploadDebugInfoStatus_UploadStatus>() {
  return ::dmi::UploadDebugInfoStatus_UploadStatus_descriptor();
}
template <> struct is_proto_enum< ::dmi::UploadDebugInfoStatus_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::UploadDebugInfoStatus_Reason>() {
  return ::dmi::UploadDebugInfoStatus_Reason_descriptor();
}

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

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