diff --git a/cpp/dmi/sw_image.pb.h b/cpp/dmi/sw_image.pb.h
new file mode 100644
index 0000000..8803132
--- /dev/null
+++ b/cpp/dmi/sw_image.pb.h
@@ -0,0 +1,1175 @@
+// 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
