// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/compiler/profile.proto

#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED
#define PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED

#include <string>

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

#if GOOGLE_PROTOBUF_VERSION < 3003000
#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 3003000 < 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/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/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/unknown_field_set.h>
// @@protoc_insertion_point(includes)
namespace google {
namespace protobuf {
namespace compiler {
class AccessInfo;
class AccessInfoDefaultTypeInternal;
LIBPROTOC_EXPORT extern AccessInfoDefaultTypeInternal _AccessInfo_default_instance_;
class FieldAccessInfo;
class FieldAccessInfoDefaultTypeInternal;
LIBPROTOC_EXPORT extern FieldAccessInfoDefaultTypeInternal _FieldAccessInfo_default_instance_;
class MessageAccessInfo;
class MessageAccessInfoDefaultTypeInternal;
LIBPROTOC_EXPORT extern MessageAccessInfoDefaultTypeInternal _MessageAccessInfo_default_instance_;
}  // namespace compiler
}  // namespace protobuf
}  // namespace google

namespace google {
namespace protobuf {
namespace compiler {

namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto {
// Internal implementation detail -- do not call these.
struct LIBPROTOC_EXPORT TableStruct {
  static const ::google::protobuf::internal::ParseTableField entries[];
  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
  static const ::google::protobuf::internal::ParseTable schema[];
  static const ::google::protobuf::uint32 offsets[];
  static void InitDefaultsImpl();
  static void Shutdown();
};
void LIBPROTOC_EXPORT AddDescriptors();
void LIBPROTOC_EXPORT InitDefaults();
}  // namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto

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

class LIBPROTOC_EXPORT FieldAccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.FieldAccessInfo) */ {
 public:
  FieldAccessInfo();
  virtual ~FieldAccessInfo();

  FieldAccessInfo(const FieldAccessInfo& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const FieldAccessInfo& default_instance();

  static inline const FieldAccessInfo* internal_default_instance() {
    return reinterpret_cast<const FieldAccessInfo*>(
               &_FieldAccessInfo_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    0;

  void Swap(FieldAccessInfo* other);

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

  inline FieldAccessInfo* New() const PROTOBUF_FINAL { return New(NULL); }

  FieldAccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const FieldAccessInfo& from);
  void MergeFrom(const FieldAccessInfo& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(FieldAccessInfo* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // optional string name = 1;
  bool has_name() const;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // optional uint64 getters_count = 2;
  bool has_getters_count() const;
  void clear_getters_count();
  static const int kGettersCountFieldNumber = 2;
  ::google::protobuf::uint64 getters_count() const;
  void set_getters_count(::google::protobuf::uint64 value);

  // optional uint64 setters_count = 3;
  bool has_setters_count() const;
  void clear_setters_count();
  static const int kSettersCountFieldNumber = 3;
  ::google::protobuf::uint64 setters_count() const;
  void set_setters_count(::google::protobuf::uint64 value);

  // optional uint64 configs_count = 4;
  bool has_configs_count() const;
  void clear_configs_count();
  static const int kConfigsCountFieldNumber = 4;
  ::google::protobuf::uint64 configs_count() const;
  void set_configs_count(::google::protobuf::uint64 value);

  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.FieldAccessInfo)
 private:
  void set_has_name();
  void clear_has_name();
  void set_has_getters_count();
  void clear_has_getters_count();
  void set_has_setters_count();
  void clear_has_setters_count();
  void set_has_configs_count();
  void clear_has_configs_count();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::uint64 getters_count_;
  ::google::protobuf::uint64 setters_count_;
  ::google::protobuf::uint64 configs_count_;
  friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class LIBPROTOC_EXPORT MessageAccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.MessageAccessInfo) */ {
 public:
  MessageAccessInfo();
  virtual ~MessageAccessInfo();

  MessageAccessInfo(const MessageAccessInfo& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const MessageAccessInfo& default_instance();

  static inline const MessageAccessInfo* internal_default_instance() {
    return reinterpret_cast<const MessageAccessInfo*>(
               &_MessageAccessInfo_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    1;

  void Swap(MessageAccessInfo* other);

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

  inline MessageAccessInfo* New() const PROTOBUF_FINAL { return New(NULL); }

  MessageAccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const MessageAccessInfo& from);
  void MergeFrom(const MessageAccessInfo& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(MessageAccessInfo* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // repeated .google.protobuf.compiler.FieldAccessInfo field = 3;
  int field_size() const;
  void clear_field();
  static const int kFieldFieldNumber = 3;
  const ::google::protobuf::compiler::FieldAccessInfo& field(int index) const;
  ::google::protobuf::compiler::FieldAccessInfo* mutable_field(int index);
  ::google::protobuf::compiler::FieldAccessInfo* add_field();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >*
      mutable_field();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >&
      field() const;

  // optional string name = 1;
  bool has_name() const;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // optional uint64 count = 2;
  bool has_count() const;
  void clear_count();
  static const int kCountFieldNumber = 2;
  ::google::protobuf::uint64 count() const;
  void set_count(::google::protobuf::uint64 value);

  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.MessageAccessInfo)
 private:
  void set_has_name();
  void clear_has_name();
  void set_has_count();
  void clear_has_count();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo > field_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::google::protobuf::uint64 count_;
  friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class LIBPROTOC_EXPORT AccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.AccessInfo) */ {
 public:
  AccessInfo();
  virtual ~AccessInfo();

  AccessInfo(const AccessInfo& from);

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

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const AccessInfo& default_instance();

  static inline const AccessInfo* internal_default_instance() {
    return reinterpret_cast<const AccessInfo*>(
               &_AccessInfo_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    2;

  void Swap(AccessInfo* other);

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

  inline AccessInfo* New() const PROTOBUF_FINAL { return New(NULL); }

  AccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const AccessInfo& from);
  void MergeFrom(const AccessInfo& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(AccessInfo* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // repeated .google.protobuf.compiler.MessageAccessInfo message = 1;
  int message_size() const;
  void clear_message();
  static const int kMessageFieldNumber = 1;
  const ::google::protobuf::compiler::MessageAccessInfo& message(int index) const;
  ::google::protobuf::compiler::MessageAccessInfo* mutable_message(int index);
  ::google::protobuf::compiler::MessageAccessInfo* add_message();
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >*
      mutable_message();
  const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >&
      message() const;

  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.AccessInfo)
 private:

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo > message_;
  friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct;
};
// ===================================================================


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

#if !PROTOBUF_INLINE_NOT_IN_HEADERS
// FieldAccessInfo

// optional string name = 1;
inline bool FieldAccessInfo::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void FieldAccessInfo::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void FieldAccessInfo::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void FieldAccessInfo::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_name();
}
inline const ::std::string& FieldAccessInfo::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.name)
  return name_.GetNoArena();
}
inline void FieldAccessInfo::set_name(const ::std::string& value) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.name)
}
#if LANG_CXX11
inline void FieldAccessInfo::set_name(::std::string&& value) {
  set_has_name();
  name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.FieldAccessInfo.name)
}
#endif
inline void FieldAccessInfo::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.FieldAccessInfo.name)
}
inline void FieldAccessInfo::set_name(const char* value, size_t size) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.FieldAccessInfo.name)
}
inline ::std::string* FieldAccessInfo::mutable_name() {
  set_has_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.FieldAccessInfo.name)
  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FieldAccessInfo::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.FieldAccessInfo.name)
  clear_has_name();
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FieldAccessInfo::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    set_has_name();
  } else {
    clear_has_name();
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.FieldAccessInfo.name)
}

// optional uint64 getters_count = 2;
inline bool FieldAccessInfo::has_getters_count() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void FieldAccessInfo::set_has_getters_count() {
  _has_bits_[0] |= 0x00000002u;
}
inline void FieldAccessInfo::clear_has_getters_count() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void FieldAccessInfo::clear_getters_count() {
  getters_count_ = GOOGLE_ULONGLONG(0);
  clear_has_getters_count();
}
inline ::google::protobuf::uint64 FieldAccessInfo::getters_count() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.getters_count)
  return getters_count_;
}
inline void FieldAccessInfo::set_getters_count(::google::protobuf::uint64 value) {
  set_has_getters_count();
  getters_count_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.getters_count)
}

// optional uint64 setters_count = 3;
inline bool FieldAccessInfo::has_setters_count() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void FieldAccessInfo::set_has_setters_count() {
  _has_bits_[0] |= 0x00000004u;
}
inline void FieldAccessInfo::clear_has_setters_count() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void FieldAccessInfo::clear_setters_count() {
  setters_count_ = GOOGLE_ULONGLONG(0);
  clear_has_setters_count();
}
inline ::google::protobuf::uint64 FieldAccessInfo::setters_count() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.setters_count)
  return setters_count_;
}
inline void FieldAccessInfo::set_setters_count(::google::protobuf::uint64 value) {
  set_has_setters_count();
  setters_count_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.setters_count)
}

// optional uint64 configs_count = 4;
inline bool FieldAccessInfo::has_configs_count() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void FieldAccessInfo::set_has_configs_count() {
  _has_bits_[0] |= 0x00000008u;
}
inline void FieldAccessInfo::clear_has_configs_count() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void FieldAccessInfo::clear_configs_count() {
  configs_count_ = GOOGLE_ULONGLONG(0);
  clear_has_configs_count();
}
inline ::google::protobuf::uint64 FieldAccessInfo::configs_count() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.configs_count)
  return configs_count_;
}
inline void FieldAccessInfo::set_configs_count(::google::protobuf::uint64 value) {
  set_has_configs_count();
  configs_count_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.configs_count)
}

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

// MessageAccessInfo

// optional string name = 1;
inline bool MessageAccessInfo::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MessageAccessInfo::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MessageAccessInfo::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MessageAccessInfo::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_name();
}
inline const ::std::string& MessageAccessInfo::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.name)
  return name_.GetNoArena();
}
inline void MessageAccessInfo::set_name(const ::std::string& value) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.name)
}
#if LANG_CXX11
inline void MessageAccessInfo::set_name(::std::string&& value) {
  set_has_name();
  name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.MessageAccessInfo.name)
}
#endif
inline void MessageAccessInfo::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.MessageAccessInfo.name)
}
inline void MessageAccessInfo::set_name(const char* value, size_t size) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.MessageAccessInfo.name)
}
inline ::std::string* MessageAccessInfo::mutable_name() {
  set_has_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.name)
  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* MessageAccessInfo::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.MessageAccessInfo.name)
  clear_has_name();
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void MessageAccessInfo::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    set_has_name();
  } else {
    clear_has_name();
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.MessageAccessInfo.name)
}

// optional uint64 count = 2;
inline bool MessageAccessInfo::has_count() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MessageAccessInfo::set_has_count() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MessageAccessInfo::clear_has_count() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MessageAccessInfo::clear_count() {
  count_ = GOOGLE_ULONGLONG(0);
  clear_has_count();
}
inline ::google::protobuf::uint64 MessageAccessInfo::count() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.count)
  return count_;
}
inline void MessageAccessInfo::set_count(::google::protobuf::uint64 value) {
  set_has_count();
  count_ = value;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.count)
}

// repeated .google.protobuf.compiler.FieldAccessInfo field = 3;
inline int MessageAccessInfo::field_size() const {
  return field_.size();
}
inline void MessageAccessInfo::clear_field() {
  field_.Clear();
}
inline const ::google::protobuf::compiler::FieldAccessInfo& MessageAccessInfo::field(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.field)
  return field_.Get(index);
}
inline ::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::mutable_field(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.field)
  return field_.Mutable(index);
}
inline ::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::add_field() {
  // @@protoc_insertion_point(field_add:google.protobuf.compiler.MessageAccessInfo.field)
  return field_.Add();
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >*
MessageAccessInfo::mutable_field() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.MessageAccessInfo.field)
  return &field_;
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >&
MessageAccessInfo::field() const {
  // @@protoc_insertion_point(field_list:google.protobuf.compiler.MessageAccessInfo.field)
  return field_;
}

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

// AccessInfo

// repeated .google.protobuf.compiler.MessageAccessInfo message = 1;
inline int AccessInfo::message_size() const {
  return message_.size();
}
inline void AccessInfo::clear_message() {
  message_.Clear();
}
inline const ::google::protobuf::compiler::MessageAccessInfo& AccessInfo::message(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.AccessInfo.message)
  return message_.Get(index);
}
inline ::google::protobuf::compiler::MessageAccessInfo* AccessInfo::mutable_message(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.AccessInfo.message)
  return message_.Mutable(index);
}
inline ::google::protobuf::compiler::MessageAccessInfo* AccessInfo::add_message() {
  // @@protoc_insertion_point(field_add:google.protobuf.compiler.AccessInfo.message)
  return message_.Add();
}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >*
AccessInfo::mutable_message() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.AccessInfo.message)
  return &message_;
}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >&
AccessInfo::message() const {
  // @@protoc_insertion_point(field_list:google.protobuf.compiler.AccessInfo.message)
  return message_;
}

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

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


// @@protoc_insertion_point(namespace_scope)


}  // namespace compiler
}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED
