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

#ifndef PROTOBUF_INCLUDED_dmi_2fsw_5fimage_2eproto
#define PROTOBUF_INCLUDED_dmi_2fsw_5fimage_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"
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_dmi_2fsw_5fimage_2eproto

// Internal implementation detail -- do not use these members.
struct TableStruct_dmi_2fsw_5fimage_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[3]
    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_5fimage_2eproto();
namespace dmi {
class ImageInformation;
class ImageInformationDefaultTypeInternal;
extern ImageInformationDefaultTypeInternal _ImageInformation_default_instance_;
class ImageStatus;
class ImageStatusDefaultTypeInternal;
extern ImageStatusDefaultTypeInternal _ImageStatus_default_instance_;
class ImageVersion;
class ImageVersionDefaultTypeInternal;
extern ImageVersionDefaultTypeInternal _ImageVersion_default_instance_;
}  // namespace dmi
namespace google {
namespace protobuf {
template<> ::dmi::ImageInformation* Arena::CreateMaybeMessage<::dmi::ImageInformation>(Arena*);
template<> ::dmi::ImageStatus* Arena::CreateMaybeMessage<::dmi::ImageStatus>(Arena*);
template<> ::dmi::ImageVersion* Arena::CreateMaybeMessage<::dmi::ImageVersion>(Arena*);
}  // namespace protobuf
}  // namespace google
namespace dmi {

enum ImageStatus_ImageState {
  ImageStatus_ImageState_UNDEFINED_STATE = 0,
  ImageStatus_ImageState_COPYING_IMAGE = 1,
  ImageStatus_ImageState_INSTALLING_IMAGE = 2,
  ImageStatus_ImageState_COMMITTING_IMAGE = 3,
  ImageStatus_ImageState_REBOOTING_DEVICE = 4,
  ImageStatus_ImageState_UPGRADE_COMPLETE = 5,
  ImageStatus_ImageState_UPGRADE_FAILED = 6,
  ImageStatus_ImageState_ACTIVATION_COMPLETE = 7,
  ImageStatus_ImageState_ACTIVATION_FAILED = 8,
  ImageStatus_ImageState_ImageStatus_ImageState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ImageStatus_ImageState_ImageStatus_ImageState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ImageStatus_ImageState_IsValid(int value);
const ImageStatus_ImageState ImageStatus_ImageState_ImageState_MIN = ImageStatus_ImageState_UNDEFINED_STATE;
const ImageStatus_ImageState ImageStatus_ImageState_ImageState_MAX = ImageStatus_ImageState_ACTIVATION_FAILED;
const int ImageStatus_ImageState_ImageState_ARRAYSIZE = ImageStatus_ImageState_ImageState_MAX + 1;

const ::google::protobuf::EnumDescriptor* ImageStatus_ImageState_descriptor();
inline const ::std::string& ImageStatus_ImageState_Name(ImageStatus_ImageState value) {
  return ::google::protobuf::internal::NameOfEnum(
    ImageStatus_ImageState_descriptor(), value);
}
inline bool ImageStatus_ImageState_Parse(
    const ::std::string& name, ImageStatus_ImageState* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ImageStatus_ImageState>(
    ImageStatus_ImageState_descriptor(), name, value);
}
enum ImageStatus_Reason {
  ImageStatus_Reason_UNDEFINED_REASON = 0,
  ImageStatus_Reason_ERROR_IN_REQUEST = 1,
  ImageStatus_Reason_INTERNAL_ERROR = 2,
  ImageStatus_Reason_DEVICE_IN_WRONG_STATE = 3,
  ImageStatus_Reason_INVALID_IMAGE = 4,
  ImageStatus_Reason_WRONG_IMAGE_CHECKSUM = 5,
  ImageStatus_Reason_OPERATION_ALREADY_IN_PROGRESS = 6,
  ImageStatus_Reason_UNKNOWN_DEVICE = 7,
  ImageStatus_Reason_DEVICE_NOT_REACHABLE = 8,
  ImageStatus_Reason_ImageStatus_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
  ImageStatus_Reason_ImageStatus_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
};
bool ImageStatus_Reason_IsValid(int value);
const ImageStatus_Reason ImageStatus_Reason_Reason_MIN = ImageStatus_Reason_UNDEFINED_REASON;
const ImageStatus_Reason ImageStatus_Reason_Reason_MAX = ImageStatus_Reason_DEVICE_NOT_REACHABLE;
const int ImageStatus_Reason_Reason_ARRAYSIZE = ImageStatus_Reason_Reason_MAX + 1;

const ::google::protobuf::EnumDescriptor* ImageStatus_Reason_descriptor();
inline const ::std::string& ImageStatus_Reason_Name(ImageStatus_Reason value) {
  return ::google::protobuf::internal::NameOfEnum(
    ImageStatus_Reason_descriptor(), value);
}
inline bool ImageStatus_Reason_Parse(
    const ::std::string& name, ImageStatus_Reason* value) {
  return ::google::protobuf::internal::ParseNamedEnum<ImageStatus_Reason>(
    ImageStatus_Reason_descriptor(), name, value);
}
// ===================================================================

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

  ImageVersion(const ImageVersion& from);

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

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

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

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

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

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

  ImageVersion* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ImageVersion>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ImageVersion& from);
  void MergeFrom(const ImageVersion& 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(ImageVersion* 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 image_name = 1;
  void clear_image_name();
  static const int kImageNameFieldNumber = 1;
  const ::std::string& image_name() const;
  void set_image_name(const ::std::string& value);
  #if LANG_CXX11
  void set_image_name(::std::string&& value);
  #endif
  void set_image_name(const char* value);
  void set_image_name(const char* value, size_t size);
  ::std::string* mutable_image_name();
  ::std::string* release_image_name();
  void set_allocated_image_name(::std::string* image_name);

  // string version = 2;
  void clear_version();
  static const int kVersionFieldNumber = 2;
  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);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr image_name_;
  ::google::protobuf::internal::ArenaStringPtr version_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fimage_2eproto;
};
// -------------------------------------------------------------------

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

  ImageInformation(const ImageInformation& from);

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

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

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

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

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

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

  ImageInformation* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ImageInformation>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ImageInformation& from);
  void MergeFrom(const ImageInformation& 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(ImageInformation* 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 image_install_script = 2;
  void clear_image_install_script();
  static const int kImageInstallScriptFieldNumber = 2;
  const ::std::string& image_install_script() const;
  void set_image_install_script(const ::std::string& value);
  #if LANG_CXX11
  void set_image_install_script(::std::string&& value);
  #endif
  void set_image_install_script(const char* value);
  void set_image_install_script(const char* value, size_t size);
  ::std::string* mutable_image_install_script();
  ::std::string* release_image_install_script();
  void set_allocated_image_install_script(::std::string* image_install_script);

  // string image_url = 3;
  void clear_image_url();
  static const int kImageUrlFieldNumber = 3;
  const ::std::string& image_url() const;
  void set_image_url(const ::std::string& value);
  #if LANG_CXX11
  void set_image_url(::std::string&& value);
  #endif
  void set_image_url(const char* value);
  void set_image_url(const char* value, size_t size);
  ::std::string* mutable_image_url();
  ::std::string* release_image_url();
  void set_allocated_image_url(::std::string* image_url);

  // string sha256sum = 5;
  void clear_sha256sum();
  static const int kSha256SumFieldNumber = 5;
  const ::std::string& sha256sum() const;
  void set_sha256sum(const ::std::string& value);
  #if LANG_CXX11
  void set_sha256sum(::std::string&& value);
  #endif
  void set_sha256sum(const char* value);
  void set_sha256sum(const char* value, size_t size);
  ::std::string* mutable_sha256sum();
  ::std::string* release_sha256sum();
  void set_allocated_sha256sum(::std::string* sha256sum);

  // .dmi.ImageVersion image = 1;
  bool has_image() const;
  void clear_image();
  static const int kImageFieldNumber = 1;
  const ::dmi::ImageVersion& image() const;
  ::dmi::ImageVersion* release_image();
  ::dmi::ImageVersion* mutable_image();
  void set_allocated_image(::dmi::ImageVersion* image);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr image_install_script_;
  ::google::protobuf::internal::ArenaStringPtr image_url_;
  ::google::protobuf::internal::ArenaStringPtr sha256sum_;
  ::dmi::ImageVersion* image_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fimage_2eproto;
};
// -------------------------------------------------------------------

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

  ImageStatus(const ImageStatus& from);

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

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

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

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

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

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

  ImageStatus* New(::google::protobuf::Arena* arena) const final {
    return CreateMaybeMessage<ImageStatus>(arena);
  }
  void CopyFrom(const ::google::protobuf::Message& from) final;
  void MergeFrom(const ::google::protobuf::Message& from) final;
  void CopyFrom(const ImageStatus& from);
  void MergeFrom(const ImageStatus& 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(ImageStatus* 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 ImageStatus_ImageState ImageState;
  static const ImageState UNDEFINED_STATE =
    ImageStatus_ImageState_UNDEFINED_STATE;
  static const ImageState COPYING_IMAGE =
    ImageStatus_ImageState_COPYING_IMAGE;
  static const ImageState INSTALLING_IMAGE =
    ImageStatus_ImageState_INSTALLING_IMAGE;
  static const ImageState COMMITTING_IMAGE =
    ImageStatus_ImageState_COMMITTING_IMAGE;
  static const ImageState REBOOTING_DEVICE =
    ImageStatus_ImageState_REBOOTING_DEVICE;
  static const ImageState UPGRADE_COMPLETE =
    ImageStatus_ImageState_UPGRADE_COMPLETE;
  static const ImageState UPGRADE_FAILED =
    ImageStatus_ImageState_UPGRADE_FAILED;
  static const ImageState ACTIVATION_COMPLETE =
    ImageStatus_ImageState_ACTIVATION_COMPLETE;
  static const ImageState ACTIVATION_FAILED =
    ImageStatus_ImageState_ACTIVATION_FAILED;
  static inline bool ImageState_IsValid(int value) {
    return ImageStatus_ImageState_IsValid(value);
  }
  static const ImageState ImageState_MIN =
    ImageStatus_ImageState_ImageState_MIN;
  static const ImageState ImageState_MAX =
    ImageStatus_ImageState_ImageState_MAX;
  static const int ImageState_ARRAYSIZE =
    ImageStatus_ImageState_ImageState_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  ImageState_descriptor() {
    return ImageStatus_ImageState_descriptor();
  }
  static inline const ::std::string& ImageState_Name(ImageState value) {
    return ImageStatus_ImageState_Name(value);
  }
  static inline bool ImageState_Parse(const ::std::string& name,
      ImageState* value) {
    return ImageStatus_ImageState_Parse(name, value);
  }

  typedef ImageStatus_Reason Reason;
  static const Reason UNDEFINED_REASON =
    ImageStatus_Reason_UNDEFINED_REASON;
  static const Reason ERROR_IN_REQUEST =
    ImageStatus_Reason_ERROR_IN_REQUEST;
  static const Reason INTERNAL_ERROR =
    ImageStatus_Reason_INTERNAL_ERROR;
  static const Reason DEVICE_IN_WRONG_STATE =
    ImageStatus_Reason_DEVICE_IN_WRONG_STATE;
  static const Reason INVALID_IMAGE =
    ImageStatus_Reason_INVALID_IMAGE;
  static const Reason WRONG_IMAGE_CHECKSUM =
    ImageStatus_Reason_WRONG_IMAGE_CHECKSUM;
  static const Reason OPERATION_ALREADY_IN_PROGRESS =
    ImageStatus_Reason_OPERATION_ALREADY_IN_PROGRESS;
  static const Reason UNKNOWN_DEVICE =
    ImageStatus_Reason_UNKNOWN_DEVICE;
  static const Reason DEVICE_NOT_REACHABLE =
    ImageStatus_Reason_DEVICE_NOT_REACHABLE;
  static inline bool Reason_IsValid(int value) {
    return ImageStatus_Reason_IsValid(value);
  }
  static const Reason Reason_MIN =
    ImageStatus_Reason_Reason_MIN;
  static const Reason Reason_MAX =
    ImageStatus_Reason_Reason_MAX;
  static const int Reason_ARRAYSIZE =
    ImageStatus_Reason_Reason_ARRAYSIZE;
  static inline const ::google::protobuf::EnumDescriptor*
  Reason_descriptor() {
    return ImageStatus_Reason_descriptor();
  }
  static inline const ::std::string& Reason_Name(Reason value) {
    return ImageStatus_Reason_Name(value);
  }
  static inline bool Reason_Parse(const ::std::string& name,
      Reason* value) {
    return ImageStatus_Reason_Parse(name, value);
  }

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

  // string description = 4;
  void clear_description();
  static const int kDescriptionFieldNumber = 4;
  const ::std::string& description() const;
  void set_description(const ::std::string& value);
  #if LANG_CXX11
  void set_description(::std::string&& value);
  #endif
  void set_description(const char* value);
  void set_description(const char* value, size_t size);
  ::std::string* mutable_description();
  ::std::string* release_description();
  void set_allocated_description(::std::string* description);

  // string 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.ImageStatus.Reason reason = 2;
  void clear_reason();
  static const int kReasonFieldNumber = 2;
  ::dmi::ImageStatus_Reason reason() const;
  void set_reason(::dmi::ImageStatus_Reason value);

  // .dmi.ImageStatus.ImageState state = 3;
  void clear_state();
  static const int kStateFieldNumber = 3;
  ::dmi::ImageStatus_ImageState state() const;
  void set_state(::dmi::ImageStatus_ImageState value);

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

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr description_;
  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
  int status_;
  int reason_;
  int state_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_dmi_2fsw_5fimage_2eproto;
};
// ===================================================================


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

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

// string image_name = 1;
inline void ImageVersion::clear_image_name() {
  image_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ImageVersion::image_name() const {
  // @@protoc_insertion_point(field_get:dmi.ImageVersion.image_name)
  return image_name_.GetNoArena();
}
inline void ImageVersion::set_image_name(const ::std::string& value) {
  
  image_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ImageVersion.image_name)
}
#if LANG_CXX11
inline void ImageVersion::set_image_name(::std::string&& value) {
  
  image_name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageVersion.image_name)
}
#endif
inline void ImageVersion::set_image_name(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  image_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ImageVersion.image_name)
}
inline void ImageVersion::set_image_name(const char* value, size_t size) {
  
  image_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ImageVersion.image_name)
}
inline ::std::string* ImageVersion::mutable_image_name() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ImageVersion.image_name)
  return image_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ImageVersion::release_image_name() {
  // @@protoc_insertion_point(field_release:dmi.ImageVersion.image_name)
  
  return image_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ImageVersion::set_allocated_image_name(::std::string* image_name) {
  if (image_name != nullptr) {
    
  } else {
    
  }
  image_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), image_name);
  // @@protoc_insertion_point(field_set_allocated:dmi.ImageVersion.image_name)
}

// string version = 2;
inline void ImageVersion::clear_version() {
  version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ImageVersion::version() const {
  // @@protoc_insertion_point(field_get:dmi.ImageVersion.version)
  return version_.GetNoArena();
}
inline void ImageVersion::set_version(const ::std::string& value) {
  
  version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ImageVersion.version)
}
#if LANG_CXX11
inline void ImageVersion::set_version(::std::string&& value) {
  
  version_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageVersion.version)
}
#endif
inline void ImageVersion::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.ImageVersion.version)
}
inline void ImageVersion::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.ImageVersion.version)
}
inline ::std::string* ImageVersion::mutable_version() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ImageVersion.version)
  return version_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ImageVersion::release_version() {
  // @@protoc_insertion_point(field_release:dmi.ImageVersion.version)
  
  return version_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ImageVersion::set_allocated_version(::std::string* version) {
  if (version != nullptr) {
    
  } else {
    
  }
  version_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), version);
  // @@protoc_insertion_point(field_set_allocated:dmi.ImageVersion.version)
}

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

// ImageInformation

// .dmi.ImageVersion image = 1;
inline bool ImageInformation::has_image() const {
  return this != internal_default_instance() && image_ != nullptr;
}
inline void ImageInformation::clear_image() {
  if (GetArenaNoVirtual() == nullptr && image_ != nullptr) {
    delete image_;
  }
  image_ = nullptr;
}
inline const ::dmi::ImageVersion& ImageInformation::image() const {
  const ::dmi::ImageVersion* p = image_;
  // @@protoc_insertion_point(field_get:dmi.ImageInformation.image)
  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::ImageVersion*>(
      &::dmi::_ImageVersion_default_instance_);
}
inline ::dmi::ImageVersion* ImageInformation::release_image() {
  // @@protoc_insertion_point(field_release:dmi.ImageInformation.image)
  
  ::dmi::ImageVersion* temp = image_;
  image_ = nullptr;
  return temp;
}
inline ::dmi::ImageVersion* ImageInformation::mutable_image() {
  
  if (image_ == nullptr) {
    auto* p = CreateMaybeMessage<::dmi::ImageVersion>(GetArenaNoVirtual());
    image_ = p;
  }
  // @@protoc_insertion_point(field_mutable:dmi.ImageInformation.image)
  return image_;
}
inline void ImageInformation::set_allocated_image(::dmi::ImageVersion* image) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == nullptr) {
    delete image_;
  }
  if (image) {
    ::google::protobuf::Arena* submessage_arena = nullptr;
    if (message_arena != submessage_arena) {
      image = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, image, submessage_arena);
    }
    
  } else {
    
  }
  image_ = image;
  // @@protoc_insertion_point(field_set_allocated:dmi.ImageInformation.image)
}

// string image_install_script = 2;
inline void ImageInformation::clear_image_install_script() {
  image_install_script_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ImageInformation::image_install_script() const {
  // @@protoc_insertion_point(field_get:dmi.ImageInformation.image_install_script)
  return image_install_script_.GetNoArena();
}
inline void ImageInformation::set_image_install_script(const ::std::string& value) {
  
  image_install_script_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ImageInformation.image_install_script)
}
#if LANG_CXX11
inline void ImageInformation::set_image_install_script(::std::string&& value) {
  
  image_install_script_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageInformation.image_install_script)
}
#endif
inline void ImageInformation::set_image_install_script(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  image_install_script_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ImageInformation.image_install_script)
}
inline void ImageInformation::set_image_install_script(const char* value, size_t size) {
  
  image_install_script_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ImageInformation.image_install_script)
}
inline ::std::string* ImageInformation::mutable_image_install_script() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ImageInformation.image_install_script)
  return image_install_script_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ImageInformation::release_image_install_script() {
  // @@protoc_insertion_point(field_release:dmi.ImageInformation.image_install_script)
  
  return image_install_script_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ImageInformation::set_allocated_image_install_script(::std::string* image_install_script) {
  if (image_install_script != nullptr) {
    
  } else {
    
  }
  image_install_script_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), image_install_script);
  // @@protoc_insertion_point(field_set_allocated:dmi.ImageInformation.image_install_script)
}

// string image_url = 3;
inline void ImageInformation::clear_image_url() {
  image_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ImageInformation::image_url() const {
  // @@protoc_insertion_point(field_get:dmi.ImageInformation.image_url)
  return image_url_.GetNoArena();
}
inline void ImageInformation::set_image_url(const ::std::string& value) {
  
  image_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ImageInformation.image_url)
}
#if LANG_CXX11
inline void ImageInformation::set_image_url(::std::string&& value) {
  
  image_url_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageInformation.image_url)
}
#endif
inline void ImageInformation::set_image_url(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  image_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ImageInformation.image_url)
}
inline void ImageInformation::set_image_url(const char* value, size_t size) {
  
  image_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ImageInformation.image_url)
}
inline ::std::string* ImageInformation::mutable_image_url() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ImageInformation.image_url)
  return image_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ImageInformation::release_image_url() {
  // @@protoc_insertion_point(field_release:dmi.ImageInformation.image_url)
  
  return image_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ImageInformation::set_allocated_image_url(::std::string* image_url) {
  if (image_url != nullptr) {
    
  } else {
    
  }
  image_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), image_url);
  // @@protoc_insertion_point(field_set_allocated:dmi.ImageInformation.image_url)
}

// string sha256sum = 5;
inline void ImageInformation::clear_sha256sum() {
  sha256sum_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ImageInformation::sha256sum() const {
  // @@protoc_insertion_point(field_get:dmi.ImageInformation.sha256sum)
  return sha256sum_.GetNoArena();
}
inline void ImageInformation::set_sha256sum(const ::std::string& value) {
  
  sha256sum_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ImageInformation.sha256sum)
}
#if LANG_CXX11
inline void ImageInformation::set_sha256sum(::std::string&& value) {
  
  sha256sum_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageInformation.sha256sum)
}
#endif
inline void ImageInformation::set_sha256sum(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  sha256sum_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ImageInformation.sha256sum)
}
inline void ImageInformation::set_sha256sum(const char* value, size_t size) {
  
  sha256sum_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ImageInformation.sha256sum)
}
inline ::std::string* ImageInformation::mutable_sha256sum() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ImageInformation.sha256sum)
  return sha256sum_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ImageInformation::release_sha256sum() {
  // @@protoc_insertion_point(field_release:dmi.ImageInformation.sha256sum)
  
  return sha256sum_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ImageInformation::set_allocated_sha256sum(::std::string* sha256sum) {
  if (sha256sum != nullptr) {
    
  } else {
    
  }
  sha256sum_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), sha256sum);
  // @@protoc_insertion_point(field_set_allocated:dmi.ImageInformation.sha256sum)
}

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

// ImageStatus

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

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

// .dmi.ImageStatus.ImageState state = 3;
inline void ImageStatus::clear_state() {
  state_ = 0;
}
inline ::dmi::ImageStatus_ImageState ImageStatus::state() const {
  // @@protoc_insertion_point(field_get:dmi.ImageStatus.state)
  return static_cast< ::dmi::ImageStatus_ImageState >(state_);
}
inline void ImageStatus::set_state(::dmi::ImageStatus_ImageState value) {
  
  state_ = value;
  // @@protoc_insertion_point(field_set:dmi.ImageStatus.state)
}

// string description = 4;
inline void ImageStatus::clear_description() {
  description_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ImageStatus::description() const {
  // @@protoc_insertion_point(field_get:dmi.ImageStatus.description)
  return description_.GetNoArena();
}
inline void ImageStatus::set_description(const ::std::string& value) {
  
  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ImageStatus.description)
}
#if LANG_CXX11
inline void ImageStatus::set_description(::std::string&& value) {
  
  description_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageStatus.description)
}
#endif
inline void ImageStatus::set_description(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  
  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:dmi.ImageStatus.description)
}
inline void ImageStatus::set_description(const char* value, size_t size) {
  
  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:dmi.ImageStatus.description)
}
inline ::std::string* ImageStatus::mutable_description() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ImageStatus.description)
  return description_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ImageStatus::release_description() {
  // @@protoc_insertion_point(field_release:dmi.ImageStatus.description)
  
  return description_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ImageStatus::set_allocated_description(::std::string* description) {
  if (description != nullptr) {
    
  } else {
    
  }
  description_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), description);
  // @@protoc_insertion_point(field_set_allocated:dmi.ImageStatus.description)
}

// string reason_detail = 5;
inline void ImageStatus::clear_reason_detail() {
  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& ImageStatus::reason_detail() const {
  // @@protoc_insertion_point(field_get:dmi.ImageStatus.reason_detail)
  return reason_detail_.GetNoArena();
}
inline void ImageStatus::set_reason_detail(const ::std::string& value) {
  
  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:dmi.ImageStatus.reason_detail)
}
#if LANG_CXX11
inline void ImageStatus::set_reason_detail(::std::string&& value) {
  
  reason_detail_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:dmi.ImageStatus.reason_detail)
}
#endif
inline void ImageStatus::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.ImageStatus.reason_detail)
}
inline void ImageStatus::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.ImageStatus.reason_detail)
}
inline ::std::string* ImageStatus::mutable_reason_detail() {
  
  // @@protoc_insertion_point(field_mutable:dmi.ImageStatus.reason_detail)
  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ImageStatus::release_reason_detail() {
  // @@protoc_insertion_point(field_release:dmi.ImageStatus.reason_detail)
  
  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void ImageStatus::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.ImageStatus.reason_detail)
}

#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::ImageStatus_ImageState> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ImageStatus_ImageState>() {
  return ::dmi::ImageStatus_ImageState_descriptor();
}
template <> struct is_proto_enum< ::dmi::ImageStatus_Reason> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ImageStatus_Reason>() {
  return ::dmi::ImageStatus_Reason_descriptor();
}

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

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