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

#ifndef PROTOBUF_installation_5fstore_2eproto__INCLUDED
#define PROTOBUF_installation_5fstore_2eproto__INCLUDED

#include <string>

#include <google/protobuf/stubs/common.h>

#if GOOGLE_PROTOBUF_VERSION < 3000000
#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 3000000 < GOOGLE_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/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
// @@protoc_insertion_point(includes)

namespace cobalt {
namespace loader {

// Internal implementation detail -- do not call these.
void protobuf_AddDesc_installation_5fstore_2eproto();
void protobuf_AssignDesc_installation_5fstore_2eproto();
void protobuf_ShutdownFile_installation_5fstore_2eproto();

class Installation;
class InstallationStore;

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

class Installation : public ::google::protobuf::MessageLite {
 public:
  Installation();
  virtual ~Installation();

  Installation(const Installation& from);

  inline Installation& operator=(const Installation& from) {
    CopyFrom(from);
    return *this;
  }

  static const Installation& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const Installation* internal_default_instance() {
    return default_instance_;
  }
  #endif

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(Installation* other);

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

  inline Installation* New() const { return New(NULL); }

  Installation* New(::google::protobuf::Arena* arena) const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const Installation& from);
  void MergeFrom(const Installation& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(Installation* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _arena_ptr_;
  }
  inline ::google::protobuf::Arena* MaybeArenaPtr() const {
    return _arena_ptr_;
  }
  public:

  ::std::string GetTypeName() const;

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

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

  // optional bool is_successful = 1;
  void clear_is_successful();
  static const int kIsSuccessfulFieldNumber = 1;
  bool is_successful() const;
  void set_is_successful(bool value);

  // optional int32 num_tries_left = 2;
  void clear_num_tries_left();
  static const int kNumTriesLeftFieldNumber = 2;
  ::google::protobuf::int32 num_tries_left() const;
  void set_num_tries_left(::google::protobuf::int32 value);

  // optional int32 priority = 3;
  void clear_priority();
  static const int kPriorityFieldNumber = 3;
  ::google::protobuf::int32 priority() const;
  void set_priority(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:cobalt.loader.Installation)
 private:

  ::google::protobuf::internal::ArenaStringPtr _unknown_fields_;
  ::google::protobuf::Arena* _arena_ptr_;

  bool _is_default_instance_;
  bool is_successful_;
  ::google::protobuf::int32 num_tries_left_;
  ::google::protobuf::int32 priority_;
  mutable int _cached_size_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_installation_5fstore_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_installation_5fstore_2eproto();
  #endif
  friend void protobuf_AssignDesc_installation_5fstore_2eproto();
  friend void protobuf_ShutdownFile_installation_5fstore_2eproto();

  void InitAsDefaultInstance();
  static Installation* default_instance_;
};
// -------------------------------------------------------------------

class InstallationStore : public ::google::protobuf::MessageLite {
 public:
  InstallationStore();
  virtual ~InstallationStore();

  InstallationStore(const InstallationStore& from);

  inline InstallationStore& operator=(const InstallationStore& from) {
    CopyFrom(from);
    return *this;
  }

  static const InstallationStore& default_instance();

  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  // Returns the internal default instance pointer. This function can
  // return NULL thus should not be used by the user. This is intended
  // for Protobuf internal code. Please use default_instance() declared
  // above instead.
  static inline const InstallationStore* internal_default_instance() {
    return default_instance_;
  }
  #endif

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(InstallationStore* other);

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

  inline InstallationStore* New() const { return New(NULL); }

  InstallationStore* New(::google::protobuf::Arena* arena) const;
  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
  void CopyFrom(const InstallationStore& from);
  void MergeFrom(const InstallationStore& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  void DiscardUnknownFields();
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  void InternalSwap(InstallationStore* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return _arena_ptr_;
  }
  inline ::google::protobuf::Arena* MaybeArenaPtr() const {
    return _arena_ptr_;
  }
  public:

  ::std::string GetTypeName() const;

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

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

  // repeated .cobalt.loader.Installation installations = 1;
  int installations_size() const;
  void clear_installations();
  static const int kInstallationsFieldNumber = 1;
  const ::cobalt::loader::Installation& installations(int index) const;
  ::cobalt::loader::Installation* mutable_installations(int index);
  ::cobalt::loader::Installation* add_installations();
  ::google::protobuf::RepeatedPtrField< ::cobalt::loader::Installation >*
      mutable_installations();
  const ::google::protobuf::RepeatedPtrField< ::cobalt::loader::Installation >&
      installations() const;

  // optional int32 roll_forward_to_installation = 2;
  void clear_roll_forward_to_installation();
  static const int kRollForwardToInstallationFieldNumber = 2;
  ::google::protobuf::int32 roll_forward_to_installation() const;
  void set_roll_forward_to_installation(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:cobalt.loader.InstallationStore)
 private:

  ::google::protobuf::internal::ArenaStringPtr _unknown_fields_;
  ::google::protobuf::Arena* _arena_ptr_;

  bool _is_default_instance_;
  ::google::protobuf::RepeatedPtrField< ::cobalt::loader::Installation > installations_;
  ::google::protobuf::int32 roll_forward_to_installation_;
  mutable int _cached_size_;
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  friend void  protobuf_AddDesc_installation_5fstore_2eproto_impl();
  #else
  friend void  protobuf_AddDesc_installation_5fstore_2eproto();
  #endif
  friend void protobuf_AssignDesc_installation_5fstore_2eproto();
  friend void protobuf_ShutdownFile_installation_5fstore_2eproto();

  void InitAsDefaultInstance();
  static InstallationStore* default_instance_;
};
// ===================================================================


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

#if !PROTOBUF_INLINE_NOT_IN_HEADERS
// Installation

// optional bool is_successful = 1;
inline void Installation::clear_is_successful() {
  is_successful_ = false;
}
inline bool Installation::is_successful() const {
  // @@protoc_insertion_point(field_get:cobalt.loader.Installation.is_successful)
  return is_successful_;
}
inline void Installation::set_is_successful(bool value) {
  
  is_successful_ = value;
  // @@protoc_insertion_point(field_set:cobalt.loader.Installation.is_successful)
}

// optional int32 num_tries_left = 2;
inline void Installation::clear_num_tries_left() {
  num_tries_left_ = 0;
}
inline ::google::protobuf::int32 Installation::num_tries_left() const {
  // @@protoc_insertion_point(field_get:cobalt.loader.Installation.num_tries_left)
  return num_tries_left_;
}
inline void Installation::set_num_tries_left(::google::protobuf::int32 value) {
  
  num_tries_left_ = value;
  // @@protoc_insertion_point(field_set:cobalt.loader.Installation.num_tries_left)
}

// optional int32 priority = 3;
inline void Installation::clear_priority() {
  priority_ = 0;
}
inline ::google::protobuf::int32 Installation::priority() const {
  // @@protoc_insertion_point(field_get:cobalt.loader.Installation.priority)
  return priority_;
}
inline void Installation::set_priority(::google::protobuf::int32 value) {
  
  priority_ = value;
  // @@protoc_insertion_point(field_set:cobalt.loader.Installation.priority)
}

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

// InstallationStore

// repeated .cobalt.loader.Installation installations = 1;
inline int InstallationStore::installations_size() const {
  return installations_.size();
}
inline void InstallationStore::clear_installations() {
  installations_.Clear();
}
inline const ::cobalt::loader::Installation& InstallationStore::installations(int index) const {
  // @@protoc_insertion_point(field_get:cobalt.loader.InstallationStore.installations)
  return installations_.Get(index);
}
inline ::cobalt::loader::Installation* InstallationStore::mutable_installations(int index) {
  // @@protoc_insertion_point(field_mutable:cobalt.loader.InstallationStore.installations)
  return installations_.Mutable(index);
}
inline ::cobalt::loader::Installation* InstallationStore::add_installations() {
  // @@protoc_insertion_point(field_add:cobalt.loader.InstallationStore.installations)
  return installations_.Add();
}
inline ::google::protobuf::RepeatedPtrField< ::cobalt::loader::Installation >*
InstallationStore::mutable_installations() {
  // @@protoc_insertion_point(field_mutable_list:cobalt.loader.InstallationStore.installations)
  return &installations_;
}
inline const ::google::protobuf::RepeatedPtrField< ::cobalt::loader::Installation >&
InstallationStore::installations() const {
  // @@protoc_insertion_point(field_list:cobalt.loader.InstallationStore.installations)
  return installations_;
}

// optional int32 roll_forward_to_installation = 2;
inline void InstallationStore::clear_roll_forward_to_installation() {
  roll_forward_to_installation_ = 0;
}
inline ::google::protobuf::int32 InstallationStore::roll_forward_to_installation() const {
  // @@protoc_insertion_point(field_get:cobalt.loader.InstallationStore.roll_forward_to_installation)
  return roll_forward_to_installation_;
}
inline void InstallationStore::set_roll_forward_to_installation(::google::protobuf::int32 value) {
  
  roll_forward_to_installation_ = value;
  // @@protoc_insertion_point(field_set:cobalt.loader.InstallationStore.roll_forward_to_installation)
}

#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------


// @@protoc_insertion_point(namespace_scope)

}  // namespace loader
}  // namespace cobalt

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_installation_5fstore_2eproto__INCLUDED
