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

#ifndef PROTOBUF_metrics_2eproto__INCLUDED
#define PROTOBUF_metrics_2eproto__INCLUDED

#include <string>

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

#if GOOGLE_PROTOBUF_VERSION < 2006000
#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 2006001 < 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/generated_message_util.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)

namespace io {
namespace prometheus {
namespace client {

// Internal implementation detail -- do not call these.
void  protobuf_AddDesc_metrics_2eproto();
void protobuf_AssignDesc_metrics_2eproto();
void protobuf_ShutdownFile_metrics_2eproto();

class LabelPair;
class Gauge;
class Counter;
class Quantile;
class Summary;
class Untyped;
class Histogram;
class Bucket;
class Metric;
class MetricFamily;

enum MetricType {
  COUNTER = 0,
  GAUGE = 1,
  SUMMARY = 2,
  UNTYPED = 3,
  HISTOGRAM = 4
};
bool MetricType_IsValid(int value);
const MetricType MetricType_MIN = COUNTER;
const MetricType MetricType_MAX = HISTOGRAM;
const int MetricType_ARRAYSIZE = MetricType_MAX + 1;

const ::google::protobuf::EnumDescriptor* MetricType_descriptor();
inline const ::std::string& MetricType_Name(MetricType value) {
  return ::google::protobuf::internal::NameOfEnum(
    MetricType_descriptor(), value);
}
inline bool MetricType_Parse(
    const ::std::string& name, MetricType* value) {
  return ::google::protobuf::internal::ParseNamedEnum<MetricType>(
    MetricType_descriptor(), name, value);
}
// ===================================================================

class LabelPair : public ::google::protobuf::Message {
 public:
  LabelPair();
  virtual ~LabelPair();

  LabelPair(const LabelPair& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(LabelPair* other);

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

  LabelPair* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const LabelPair& from);
  void MergeFrom(const LabelPair& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

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

  // optional string value = 2;
  inline bool has_value() const;
  inline void clear_value();
  static const int kValueFieldNumber = 2;
  inline const ::std::string& value() const;
  inline void set_value(const ::std::string& value);
  inline void set_value(const char* value);
  inline void set_value(const char* value, size_t size);
  inline ::std::string* mutable_value();
  inline ::std::string* release_value();
  inline void set_allocated_value(::std::string* value);

  // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_value();
  inline void clear_has_value();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  ::std::string* value_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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

class Gauge : public ::google::protobuf::Message {
 public:
  Gauge();
  virtual ~Gauge();

  Gauge(const Gauge& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(Gauge* other);

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

  Gauge* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const Gauge& from);
  void MergeFrom(const Gauge& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional double value = 1;
  inline bool has_value() const;
  inline void clear_value();
  static const int kValueFieldNumber = 1;
  inline double value() const;
  inline void set_value(double value);

  // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge)
 private:
  inline void set_has_value();
  inline void clear_has_value();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  double value_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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

class Counter : public ::google::protobuf::Message {
 public:
  Counter();
  virtual ~Counter();

  Counter(const Counter& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(Counter* other);

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

  Counter* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const Counter& from);
  void MergeFrom(const Counter& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional double value = 1;
  inline bool has_value() const;
  inline void clear_value();
  static const int kValueFieldNumber = 1;
  inline double value() const;
  inline void set_value(double value);

  // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter)
 private:
  inline void set_has_value();
  inline void clear_has_value();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  double value_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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

class Quantile : public ::google::protobuf::Message {
 public:
  Quantile();
  virtual ~Quantile();

  Quantile(const Quantile& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(Quantile* other);

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

  Quantile* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const Quantile& from);
  void MergeFrom(const Quantile& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional double quantile = 1;
  inline bool has_quantile() const;
  inline void clear_quantile();
  static const int kQuantileFieldNumber = 1;
  inline double quantile() const;
  inline void set_quantile(double value);

  // optional double value = 2;
  inline bool has_value() const;
  inline void clear_value();
  static const int kValueFieldNumber = 2;
  inline double value() const;
  inline void set_value(double value);

  // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile)
 private:
  inline void set_has_quantile();
  inline void clear_has_quantile();
  inline void set_has_value();
  inline void clear_has_value();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  double quantile_;
  double value_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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

class Summary : public ::google::protobuf::Message {
 public:
  Summary();
  virtual ~Summary();

  Summary(const Summary& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(Summary* other);

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

  Summary* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const Summary& from);
  void MergeFrom(const Summary& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional uint64 sample_count = 1;
  inline bool has_sample_count() const;
  inline void clear_sample_count();
  static const int kSampleCountFieldNumber = 1;
  inline ::google::protobuf::uint64 sample_count() const;
  inline void set_sample_count(::google::protobuf::uint64 value);

  // optional double sample_sum = 2;
  inline bool has_sample_sum() const;
  inline void clear_sample_sum();
  static const int kSampleSumFieldNumber = 2;
  inline double sample_sum() const;
  inline void set_sample_sum(double value);

  // repeated .io.prometheus.client.Quantile quantile = 3;
  inline int quantile_size() const;
  inline void clear_quantile();
  static const int kQuantileFieldNumber = 3;
  inline const ::io::prometheus::client::Quantile& quantile(int index) const;
  inline ::io::prometheus::client::Quantile* mutable_quantile(int index);
  inline ::io::prometheus::client::Quantile* add_quantile();
  inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile >&
      quantile() const;
  inline ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile >*
      mutable_quantile();

  // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary)
 private:
  inline void set_has_sample_count();
  inline void clear_has_sample_count();
  inline void set_has_sample_sum();
  inline void clear_has_sample_sum();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 sample_count_;
  double sample_sum_;
  ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile > quantile_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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

class Untyped : public ::google::protobuf::Message {
 public:
  Untyped();
  virtual ~Untyped();

  Untyped(const Untyped& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(Untyped* other);

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

  Untyped* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const Untyped& from);
  void MergeFrom(const Untyped& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional double value = 1;
  inline bool has_value() const;
  inline void clear_value();
  static const int kValueFieldNumber = 1;
  inline double value() const;
  inline void set_value(double value);

  // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped)
 private:
  inline void set_has_value();
  inline void clear_has_value();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  double value_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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

class Histogram : public ::google::protobuf::Message {
 public:
  Histogram();
  virtual ~Histogram();

  Histogram(const Histogram& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(Histogram* other);

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

  Histogram* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const Histogram& from);
  void MergeFrom(const Histogram& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional uint64 sample_count = 1;
  inline bool has_sample_count() const;
  inline void clear_sample_count();
  static const int kSampleCountFieldNumber = 1;
  inline ::google::protobuf::uint64 sample_count() const;
  inline void set_sample_count(::google::protobuf::uint64 value);

  // optional double sample_sum = 2;
  inline bool has_sample_sum() const;
  inline void clear_sample_sum();
  static const int kSampleSumFieldNumber = 2;
  inline double sample_sum() const;
  inline void set_sample_sum(double value);

  // repeated .io.prometheus.client.Bucket bucket = 3;
  inline int bucket_size() const;
  inline void clear_bucket();
  static const int kBucketFieldNumber = 3;
  inline const ::io::prometheus::client::Bucket& bucket(int index) const;
  inline ::io::prometheus::client::Bucket* mutable_bucket(int index);
  inline ::io::prometheus::client::Bucket* add_bucket();
  inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket >&
      bucket() const;
  inline ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket >*
      mutable_bucket();

  // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
 private:
  inline void set_has_sample_count();
  inline void clear_has_sample_count();
  inline void set_has_sample_sum();
  inline void clear_has_sample_sum();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 sample_count_;
  double sample_sum_;
  ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket > bucket_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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

class Bucket : public ::google::protobuf::Message {
 public:
  Bucket();
  virtual ~Bucket();

  Bucket(const Bucket& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(Bucket* other);

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

  Bucket* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const Bucket& from);
  void MergeFrom(const Bucket& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // optional uint64 cumulative_count = 1;
  inline bool has_cumulative_count() const;
  inline void clear_cumulative_count();
  static const int kCumulativeCountFieldNumber = 1;
  inline ::google::protobuf::uint64 cumulative_count() const;
  inline void set_cumulative_count(::google::protobuf::uint64 value);

  // optional double upper_bound = 2;
  inline bool has_upper_bound() const;
  inline void clear_upper_bound();
  static const int kUpperBoundFieldNumber = 2;
  inline double upper_bound() const;
  inline void set_upper_bound(double value);

  // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
 private:
  inline void set_has_cumulative_count();
  inline void clear_has_cumulative_count();
  inline void set_has_upper_bound();
  inline void clear_has_upper_bound();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::uint64 cumulative_count_;
  double upper_bound_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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

class Metric : public ::google::protobuf::Message {
 public:
  Metric();
  virtual ~Metric();

  Metric(const Metric& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(Metric* other);

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

  Metric* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const Metric& from);
  void MergeFrom(const Metric& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

  // repeated .io.prometheus.client.LabelPair label = 1;
  inline int label_size() const;
  inline void clear_label();
  static const int kLabelFieldNumber = 1;
  inline const ::io::prometheus::client::LabelPair& label(int index) const;
  inline ::io::prometheus::client::LabelPair* mutable_label(int index);
  inline ::io::prometheus::client::LabelPair* add_label();
  inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair >&
      label() const;
  inline ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair >*
      mutable_label();

  // optional .io.prometheus.client.Gauge gauge = 2;
  inline bool has_gauge() const;
  inline void clear_gauge();
  static const int kGaugeFieldNumber = 2;
  inline const ::io::prometheus::client::Gauge& gauge() const;
  inline ::io::prometheus::client::Gauge* mutable_gauge();
  inline ::io::prometheus::client::Gauge* release_gauge();
  inline void set_allocated_gauge(::io::prometheus::client::Gauge* gauge);

  // optional .io.prometheus.client.Counter counter = 3;
  inline bool has_counter() const;
  inline void clear_counter();
  static const int kCounterFieldNumber = 3;
  inline const ::io::prometheus::client::Counter& counter() const;
  inline ::io::prometheus::client::Counter* mutable_counter();
  inline ::io::prometheus::client::Counter* release_counter();
  inline void set_allocated_counter(::io::prometheus::client::Counter* counter);

  // optional .io.prometheus.client.Summary summary = 4;
  inline bool has_summary() const;
  inline void clear_summary();
  static const int kSummaryFieldNumber = 4;
  inline const ::io::prometheus::client::Summary& summary() const;
  inline ::io::prometheus::client::Summary* mutable_summary();
  inline ::io::prometheus::client::Summary* release_summary();
  inline void set_allocated_summary(::io::prometheus::client::Summary* summary);

  // optional .io.prometheus.client.Untyped untyped = 5;
  inline bool has_untyped() const;
  inline void clear_untyped();
  static const int kUntypedFieldNumber = 5;
  inline const ::io::prometheus::client::Untyped& untyped() const;
  inline ::io::prometheus::client::Untyped* mutable_untyped();
  inline ::io::prometheus::client::Untyped* release_untyped();
  inline void set_allocated_untyped(::io::prometheus::client::Untyped* untyped);

  // optional .io.prometheus.client.Histogram histogram = 7;
  inline bool has_histogram() const;
  inline void clear_histogram();
  static const int kHistogramFieldNumber = 7;
  inline const ::io::prometheus::client::Histogram& histogram() const;
  inline ::io::prometheus::client::Histogram* mutable_histogram();
  inline ::io::prometheus::client::Histogram* release_histogram();
  inline void set_allocated_histogram(::io::prometheus::client::Histogram* histogram);

  // optional int64 timestamp_ms = 6;
  inline bool has_timestamp_ms() const;
  inline void clear_timestamp_ms();
  static const int kTimestampMsFieldNumber = 6;
  inline ::google::protobuf::int64 timestamp_ms() const;
  inline void set_timestamp_ms(::google::protobuf::int64 value);

  // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
 private:
  inline void set_has_gauge();
  inline void clear_has_gauge();
  inline void set_has_counter();
  inline void clear_has_counter();
  inline void set_has_summary();
  inline void clear_has_summary();
  inline void set_has_untyped();
  inline void clear_has_untyped();
  inline void set_has_histogram();
  inline void clear_has_histogram();
  inline void set_has_timestamp_ms();
  inline void clear_has_timestamp_ms();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair > label_;
  ::io::prometheus::client::Gauge* gauge_;
  ::io::prometheus::client::Counter* counter_;
  ::io::prometheus::client::Summary* summary_;
  ::io::prometheus::client::Untyped* untyped_;
  ::io::prometheus::client::Histogram* histogram_;
  ::google::protobuf::int64 timestamp_ms_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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

class MetricFamily : public ::google::protobuf::Message {
 public:
  MetricFamily();
  virtual ~MetricFamily();

  MetricFamily(const MetricFamily& from);

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

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

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return &_unknown_fields_;
  }

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

  void Swap(MetricFamily* other);

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

  MetricFamily* New() const;
  void CopyFrom(const ::google::protobuf::Message& from);
  void MergeFrom(const ::google::protobuf::Message& from);
  void CopyFrom(const MetricFamily& from);
  void MergeFrom(const MetricFamily& from);
  void Clear();
  bool IsInitialized() const;

  int ByteSize() const;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input);
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const;
  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
  int GetCachedSize() const { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const;
  public:
  ::google::protobuf::Metadata GetMetadata() const;

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

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

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

  // optional string help = 2;
  inline bool has_help() const;
  inline void clear_help();
  static const int kHelpFieldNumber = 2;
  inline const ::std::string& help() const;
  inline void set_help(const ::std::string& value);
  inline void set_help(const char* value);
  inline void set_help(const char* value, size_t size);
  inline ::std::string* mutable_help();
  inline ::std::string* release_help();
  inline void set_allocated_help(::std::string* help);

  // optional .io.prometheus.client.MetricType type = 3;
  inline bool has_type() const;
  inline void clear_type();
  static const int kTypeFieldNumber = 3;
  inline ::io::prometheus::client::MetricType type() const;
  inline void set_type(::io::prometheus::client::MetricType value);

  // repeated .io.prometheus.client.Metric metric = 4;
  inline int metric_size() const;
  inline void clear_metric();
  static const int kMetricFieldNumber = 4;
  inline const ::io::prometheus::client::Metric& metric(int index) const;
  inline ::io::prometheus::client::Metric* mutable_metric(int index);
  inline ::io::prometheus::client::Metric* add_metric();
  inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric >&
      metric() const;
  inline ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric >*
      mutable_metric();

  // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
 private:
  inline void set_has_name();
  inline void clear_has_name();
  inline void set_has_help();
  inline void clear_has_help();
  inline void set_has_type();
  inline void clear_has_type();

  ::google::protobuf::UnknownFieldSet _unknown_fields_;

  ::google::protobuf::uint32 _has_bits_[1];
  mutable int _cached_size_;
  ::std::string* name_;
  ::std::string* help_;
  ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric > metric_;
  int type_;
  friend void  protobuf_AddDesc_metrics_2eproto();
  friend void protobuf_AssignDesc_metrics_2eproto();
  friend void protobuf_ShutdownFile_metrics_2eproto();

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


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

// LabelPair

// optional string name = 1;
inline bool LabelPair::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void LabelPair::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void LabelPair::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void LabelPair::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& LabelPair::name() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.LabelPair.name)
  return *name_;
}
inline void LabelPair::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:io.prometheus.client.LabelPair.name)
}
inline void LabelPair::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:io.prometheus.client.LabelPair.name)
}
inline void LabelPair::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:io.prometheus.client.LabelPair.name)
}
inline ::std::string* LabelPair::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.LabelPair.name)
  return name_;
}
inline ::std::string* LabelPair::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void LabelPair::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.LabelPair.name)
}

// optional string value = 2;
inline bool LabelPair::has_value() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void LabelPair::set_has_value() {
  _has_bits_[0] |= 0x00000002u;
}
inline void LabelPair::clear_has_value() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void LabelPair::clear_value() {
  if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_->clear();
  }
  clear_has_value();
}
inline const ::std::string& LabelPair::value() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.LabelPair.value)
  return *value_;
}
inline void LabelPair::set_value(const ::std::string& value) {
  set_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_ = new ::std::string;
  }
  value_->assign(value);
  // @@protoc_insertion_point(field_set:io.prometheus.client.LabelPair.value)
}
inline void LabelPair::set_value(const char* value) {
  set_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_ = new ::std::string;
  }
  value_->assign(value);
  // @@protoc_insertion_point(field_set_char:io.prometheus.client.LabelPair.value)
}
inline void LabelPair::set_value(const char* value, size_t size) {
  set_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_ = new ::std::string;
  }
  value_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:io.prometheus.client.LabelPair.value)
}
inline ::std::string* LabelPair::mutable_value() {
  set_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    value_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.LabelPair.value)
  return value_;
}
inline ::std::string* LabelPair::release_value() {
  clear_has_value();
  if (value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = value_;
    value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void LabelPair::set_allocated_value(::std::string* value) {
  if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete value_;
  }
  if (value) {
    set_has_value();
    value_ = value;
  } else {
    clear_has_value();
    value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.LabelPair.value)
}

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

// Gauge

// optional double value = 1;
inline bool Gauge::has_value() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void Gauge::set_has_value() {
  _has_bits_[0] |= 0x00000001u;
}
inline void Gauge::clear_has_value() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void Gauge::clear_value() {
  value_ = 0;
  clear_has_value();
}
inline double Gauge::value() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Gauge.value)
  return value_;
}
inline void Gauge::set_value(double value) {
  set_has_value();
  value_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Gauge.value)
}

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

// Counter

// optional double value = 1;
inline bool Counter::has_value() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void Counter::set_has_value() {
  _has_bits_[0] |= 0x00000001u;
}
inline void Counter::clear_has_value() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void Counter::clear_value() {
  value_ = 0;
  clear_has_value();
}
inline double Counter::value() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Counter.value)
  return value_;
}
inline void Counter::set_value(double value) {
  set_has_value();
  value_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Counter.value)
}

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

// Quantile

// optional double quantile = 1;
inline bool Quantile::has_quantile() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void Quantile::set_has_quantile() {
  _has_bits_[0] |= 0x00000001u;
}
inline void Quantile::clear_has_quantile() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void Quantile::clear_quantile() {
  quantile_ = 0;
  clear_has_quantile();
}
inline double Quantile::quantile() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Quantile.quantile)
  return quantile_;
}
inline void Quantile::set_quantile(double value) {
  set_has_quantile();
  quantile_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Quantile.quantile)
}

// optional double value = 2;
inline bool Quantile::has_value() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void Quantile::set_has_value() {
  _has_bits_[0] |= 0x00000002u;
}
inline void Quantile::clear_has_value() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void Quantile::clear_value() {
  value_ = 0;
  clear_has_value();
}
inline double Quantile::value() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Quantile.value)
  return value_;
}
inline void Quantile::set_value(double value) {
  set_has_value();
  value_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Quantile.value)
}

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

// Summary

// optional uint64 sample_count = 1;
inline bool Summary::has_sample_count() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void Summary::set_has_sample_count() {
  _has_bits_[0] |= 0x00000001u;
}
inline void Summary::clear_has_sample_count() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void Summary::clear_sample_count() {
  sample_count_ = GOOGLE_ULONGLONG(0);
  clear_has_sample_count();
}
inline ::google::protobuf::uint64 Summary::sample_count() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Summary.sample_count)
  return sample_count_;
}
inline void Summary::set_sample_count(::google::protobuf::uint64 value) {
  set_has_sample_count();
  sample_count_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Summary.sample_count)
}

// optional double sample_sum = 2;
inline bool Summary::has_sample_sum() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void Summary::set_has_sample_sum() {
  _has_bits_[0] |= 0x00000002u;
}
inline void Summary::clear_has_sample_sum() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void Summary::clear_sample_sum() {
  sample_sum_ = 0;
  clear_has_sample_sum();
}
inline double Summary::sample_sum() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Summary.sample_sum)
  return sample_sum_;
}
inline void Summary::set_sample_sum(double value) {
  set_has_sample_sum();
  sample_sum_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Summary.sample_sum)
}

// repeated .io.prometheus.client.Quantile quantile = 3;
inline int Summary::quantile_size() const {
  return quantile_.size();
}
inline void Summary::clear_quantile() {
  quantile_.Clear();
}
inline const ::io::prometheus::client::Quantile& Summary::quantile(int index) const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Summary.quantile)
  return quantile_.Get(index);
}
inline ::io::prometheus::client::Quantile* Summary::mutable_quantile(int index) {
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Summary.quantile)
  return quantile_.Mutable(index);
}
inline ::io::prometheus::client::Quantile* Summary::add_quantile() {
  // @@protoc_insertion_point(field_add:io.prometheus.client.Summary.quantile)
  return quantile_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile >&
Summary::quantile() const {
  // @@protoc_insertion_point(field_list:io.prometheus.client.Summary.quantile)
  return quantile_;
}
inline ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile >*
Summary::mutable_quantile() {
  // @@protoc_insertion_point(field_mutable_list:io.prometheus.client.Summary.quantile)
  return &quantile_;
}

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

// Untyped

// optional double value = 1;
inline bool Untyped::has_value() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void Untyped::set_has_value() {
  _has_bits_[0] |= 0x00000001u;
}
inline void Untyped::clear_has_value() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void Untyped::clear_value() {
  value_ = 0;
  clear_has_value();
}
inline double Untyped::value() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Untyped.value)
  return value_;
}
inline void Untyped::set_value(double value) {
  set_has_value();
  value_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Untyped.value)
}

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

// Histogram

// optional uint64 sample_count = 1;
inline bool Histogram::has_sample_count() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void Histogram::set_has_sample_count() {
  _has_bits_[0] |= 0x00000001u;
}
inline void Histogram::clear_has_sample_count() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void Histogram::clear_sample_count() {
  sample_count_ = GOOGLE_ULONGLONG(0);
  clear_has_sample_count();
}
inline ::google::protobuf::uint64 Histogram::sample_count() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Histogram.sample_count)
  return sample_count_;
}
inline void Histogram::set_sample_count(::google::protobuf::uint64 value) {
  set_has_sample_count();
  sample_count_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Histogram.sample_count)
}

// optional double sample_sum = 2;
inline bool Histogram::has_sample_sum() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void Histogram::set_has_sample_sum() {
  _has_bits_[0] |= 0x00000002u;
}
inline void Histogram::clear_has_sample_sum() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void Histogram::clear_sample_sum() {
  sample_sum_ = 0;
  clear_has_sample_sum();
}
inline double Histogram::sample_sum() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Histogram.sample_sum)
  return sample_sum_;
}
inline void Histogram::set_sample_sum(double value) {
  set_has_sample_sum();
  sample_sum_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Histogram.sample_sum)
}

// repeated .io.prometheus.client.Bucket bucket = 3;
inline int Histogram::bucket_size() const {
  return bucket_.size();
}
inline void Histogram::clear_bucket() {
  bucket_.Clear();
}
inline const ::io::prometheus::client::Bucket& Histogram::bucket(int index) const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Histogram.bucket)
  return bucket_.Get(index);
}
inline ::io::prometheus::client::Bucket* Histogram::mutable_bucket(int index) {
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Histogram.bucket)
  return bucket_.Mutable(index);
}
inline ::io::prometheus::client::Bucket* Histogram::add_bucket() {
  // @@protoc_insertion_point(field_add:io.prometheus.client.Histogram.bucket)
  return bucket_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket >&
Histogram::bucket() const {
  // @@protoc_insertion_point(field_list:io.prometheus.client.Histogram.bucket)
  return bucket_;
}
inline ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket >*
Histogram::mutable_bucket() {
  // @@protoc_insertion_point(field_mutable_list:io.prometheus.client.Histogram.bucket)
  return &bucket_;
}

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

// Bucket

// optional uint64 cumulative_count = 1;
inline bool Bucket::has_cumulative_count() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void Bucket::set_has_cumulative_count() {
  _has_bits_[0] |= 0x00000001u;
}
inline void Bucket::clear_has_cumulative_count() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void Bucket::clear_cumulative_count() {
  cumulative_count_ = GOOGLE_ULONGLONG(0);
  clear_has_cumulative_count();
}
inline ::google::protobuf::uint64 Bucket::cumulative_count() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Bucket.cumulative_count)
  return cumulative_count_;
}
inline void Bucket::set_cumulative_count(::google::protobuf::uint64 value) {
  set_has_cumulative_count();
  cumulative_count_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Bucket.cumulative_count)
}

// optional double upper_bound = 2;
inline bool Bucket::has_upper_bound() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void Bucket::set_has_upper_bound() {
  _has_bits_[0] |= 0x00000002u;
}
inline void Bucket::clear_has_upper_bound() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void Bucket::clear_upper_bound() {
  upper_bound_ = 0;
  clear_has_upper_bound();
}
inline double Bucket::upper_bound() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Bucket.upper_bound)
  return upper_bound_;
}
inline void Bucket::set_upper_bound(double value) {
  set_has_upper_bound();
  upper_bound_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Bucket.upper_bound)
}

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

// Metric

// repeated .io.prometheus.client.LabelPair label = 1;
inline int Metric::label_size() const {
  return label_.size();
}
inline void Metric::clear_label() {
  label_.Clear();
}
inline const ::io::prometheus::client::LabelPair& Metric::label(int index) const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Metric.label)
  return label_.Get(index);
}
inline ::io::prometheus::client::LabelPair* Metric::mutable_label(int index) {
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.label)
  return label_.Mutable(index);
}
inline ::io::prometheus::client::LabelPair* Metric::add_label() {
  // @@protoc_insertion_point(field_add:io.prometheus.client.Metric.label)
  return label_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair >&
Metric::label() const {
  // @@protoc_insertion_point(field_list:io.prometheus.client.Metric.label)
  return label_;
}
inline ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair >*
Metric::mutable_label() {
  // @@protoc_insertion_point(field_mutable_list:io.prometheus.client.Metric.label)
  return &label_;
}

// optional .io.prometheus.client.Gauge gauge = 2;
inline bool Metric::has_gauge() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void Metric::set_has_gauge() {
  _has_bits_[0] |= 0x00000002u;
}
inline void Metric::clear_has_gauge() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void Metric::clear_gauge() {
  if (gauge_ != NULL) gauge_->::io::prometheus::client::Gauge::Clear();
  clear_has_gauge();
}
inline const ::io::prometheus::client::Gauge& Metric::gauge() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Metric.gauge)
  return gauge_ != NULL ? *gauge_ : *default_instance_->gauge_;
}
inline ::io::prometheus::client::Gauge* Metric::mutable_gauge() {
  set_has_gauge();
  if (gauge_ == NULL) gauge_ = new ::io::prometheus::client::Gauge;
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.gauge)
  return gauge_;
}
inline ::io::prometheus::client::Gauge* Metric::release_gauge() {
  clear_has_gauge();
  ::io::prometheus::client::Gauge* temp = gauge_;
  gauge_ = NULL;
  return temp;
}
inline void Metric::set_allocated_gauge(::io::prometheus::client::Gauge* gauge) {
  delete gauge_;
  gauge_ = gauge;
  if (gauge) {
    set_has_gauge();
  } else {
    clear_has_gauge();
  }
  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.gauge)
}

// optional .io.prometheus.client.Counter counter = 3;
inline bool Metric::has_counter() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void Metric::set_has_counter() {
  _has_bits_[0] |= 0x00000004u;
}
inline void Metric::clear_has_counter() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void Metric::clear_counter() {
  if (counter_ != NULL) counter_->::io::prometheus::client::Counter::Clear();
  clear_has_counter();
}
inline const ::io::prometheus::client::Counter& Metric::counter() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Metric.counter)
  return counter_ != NULL ? *counter_ : *default_instance_->counter_;
}
inline ::io::prometheus::client::Counter* Metric::mutable_counter() {
  set_has_counter();
  if (counter_ == NULL) counter_ = new ::io::prometheus::client::Counter;
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.counter)
  return counter_;
}
inline ::io::prometheus::client::Counter* Metric::release_counter() {
  clear_has_counter();
  ::io::prometheus::client::Counter* temp = counter_;
  counter_ = NULL;
  return temp;
}
inline void Metric::set_allocated_counter(::io::prometheus::client::Counter* counter) {
  delete counter_;
  counter_ = counter;
  if (counter) {
    set_has_counter();
  } else {
    clear_has_counter();
  }
  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.counter)
}

// optional .io.prometheus.client.Summary summary = 4;
inline bool Metric::has_summary() const {
  return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void Metric::set_has_summary() {
  _has_bits_[0] |= 0x00000008u;
}
inline void Metric::clear_has_summary() {
  _has_bits_[0] &= ~0x00000008u;
}
inline void Metric::clear_summary() {
  if (summary_ != NULL) summary_->::io::prometheus::client::Summary::Clear();
  clear_has_summary();
}
inline const ::io::prometheus::client::Summary& Metric::summary() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Metric.summary)
  return summary_ != NULL ? *summary_ : *default_instance_->summary_;
}
inline ::io::prometheus::client::Summary* Metric::mutable_summary() {
  set_has_summary();
  if (summary_ == NULL) summary_ = new ::io::prometheus::client::Summary;
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.summary)
  return summary_;
}
inline ::io::prometheus::client::Summary* Metric::release_summary() {
  clear_has_summary();
  ::io::prometheus::client::Summary* temp = summary_;
  summary_ = NULL;
  return temp;
}
inline void Metric::set_allocated_summary(::io::prometheus::client::Summary* summary) {
  delete summary_;
  summary_ = summary;
  if (summary) {
    set_has_summary();
  } else {
    clear_has_summary();
  }
  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.summary)
}

// optional .io.prometheus.client.Untyped untyped = 5;
inline bool Metric::has_untyped() const {
  return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void Metric::set_has_untyped() {
  _has_bits_[0] |= 0x00000010u;
}
inline void Metric::clear_has_untyped() {
  _has_bits_[0] &= ~0x00000010u;
}
inline void Metric::clear_untyped() {
  if (untyped_ != NULL) untyped_->::io::prometheus::client::Untyped::Clear();
  clear_has_untyped();
}
inline const ::io::prometheus::client::Untyped& Metric::untyped() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Metric.untyped)
  return untyped_ != NULL ? *untyped_ : *default_instance_->untyped_;
}
inline ::io::prometheus::client::Untyped* Metric::mutable_untyped() {
  set_has_untyped();
  if (untyped_ == NULL) untyped_ = new ::io::prometheus::client::Untyped;
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.untyped)
  return untyped_;
}
inline ::io::prometheus::client::Untyped* Metric::release_untyped() {
  clear_has_untyped();
  ::io::prometheus::client::Untyped* temp = untyped_;
  untyped_ = NULL;
  return temp;
}
inline void Metric::set_allocated_untyped(::io::prometheus::client::Untyped* untyped) {
  delete untyped_;
  untyped_ = untyped;
  if (untyped) {
    set_has_untyped();
  } else {
    clear_has_untyped();
  }
  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.untyped)
}

// optional .io.prometheus.client.Histogram histogram = 7;
inline bool Metric::has_histogram() const {
  return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void Metric::set_has_histogram() {
  _has_bits_[0] |= 0x00000020u;
}
inline void Metric::clear_has_histogram() {
  _has_bits_[0] &= ~0x00000020u;
}
inline void Metric::clear_histogram() {
  if (histogram_ != NULL) histogram_->::io::prometheus::client::Histogram::Clear();
  clear_has_histogram();
}
inline const ::io::prometheus::client::Histogram& Metric::histogram() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Metric.histogram)
  return histogram_ != NULL ? *histogram_ : *default_instance_->histogram_;
}
inline ::io::prometheus::client::Histogram* Metric::mutable_histogram() {
  set_has_histogram();
  if (histogram_ == NULL) histogram_ = new ::io::prometheus::client::Histogram;
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.histogram)
  return histogram_;
}
inline ::io::prometheus::client::Histogram* Metric::release_histogram() {
  clear_has_histogram();
  ::io::prometheus::client::Histogram* temp = histogram_;
  histogram_ = NULL;
  return temp;
}
inline void Metric::set_allocated_histogram(::io::prometheus::client::Histogram* histogram) {
  delete histogram_;
  histogram_ = histogram;
  if (histogram) {
    set_has_histogram();
  } else {
    clear_has_histogram();
  }
  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.histogram)
}

// optional int64 timestamp_ms = 6;
inline bool Metric::has_timestamp_ms() const {
  return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void Metric::set_has_timestamp_ms() {
  _has_bits_[0] |= 0x00000040u;
}
inline void Metric::clear_has_timestamp_ms() {
  _has_bits_[0] &= ~0x00000040u;
}
inline void Metric::clear_timestamp_ms() {
  timestamp_ms_ = GOOGLE_LONGLONG(0);
  clear_has_timestamp_ms();
}
inline ::google::protobuf::int64 Metric::timestamp_ms() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.Metric.timestamp_ms)
  return timestamp_ms_;
}
inline void Metric::set_timestamp_ms(::google::protobuf::int64 value) {
  set_has_timestamp_ms();
  timestamp_ms_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.Metric.timestamp_ms)
}

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

// MetricFamily

// optional string name = 1;
inline bool MetricFamily::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void MetricFamily::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void MetricFamily::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void MetricFamily::clear_name() {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_->clear();
  }
  clear_has_name();
}
inline const ::std::string& MetricFamily::name() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.MetricFamily.name)
  return *name_;
}
inline void MetricFamily::set_name(const ::std::string& value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set:io.prometheus.client.MetricFamily.name)
}
inline void MetricFamily::set_name(const char* value) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(value);
  // @@protoc_insertion_point(field_set_char:io.prometheus.client.MetricFamily.name)
}
inline void MetricFamily::set_name(const char* value, size_t size) {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  name_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:io.prometheus.client.MetricFamily.name)
}
inline ::std::string* MetricFamily::mutable_name() {
  set_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    name_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.MetricFamily.name)
  return name_;
}
inline ::std::string* MetricFamily::release_name() {
  clear_has_name();
  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = name_;
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void MetricFamily::set_allocated_name(::std::string* name) {
  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete name_;
  }
  if (name) {
    set_has_name();
    name_ = name;
  } else {
    clear_has_name();
    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.MetricFamily.name)
}

// optional string help = 2;
inline bool MetricFamily::has_help() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void MetricFamily::set_has_help() {
  _has_bits_[0] |= 0x00000002u;
}
inline void MetricFamily::clear_has_help() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void MetricFamily::clear_help() {
  if (help_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    help_->clear();
  }
  clear_has_help();
}
inline const ::std::string& MetricFamily::help() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.MetricFamily.help)
  return *help_;
}
inline void MetricFamily::set_help(const ::std::string& value) {
  set_has_help();
  if (help_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    help_ = new ::std::string;
  }
  help_->assign(value);
  // @@protoc_insertion_point(field_set:io.prometheus.client.MetricFamily.help)
}
inline void MetricFamily::set_help(const char* value) {
  set_has_help();
  if (help_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    help_ = new ::std::string;
  }
  help_->assign(value);
  // @@protoc_insertion_point(field_set_char:io.prometheus.client.MetricFamily.help)
}
inline void MetricFamily::set_help(const char* value, size_t size) {
  set_has_help();
  if (help_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    help_ = new ::std::string;
  }
  help_->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:io.prometheus.client.MetricFamily.help)
}
inline ::std::string* MetricFamily::mutable_help() {
  set_has_help();
  if (help_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    help_ = new ::std::string;
  }
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.MetricFamily.help)
  return help_;
}
inline ::std::string* MetricFamily::release_help() {
  clear_has_help();
  if (help_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    return NULL;
  } else {
    ::std::string* temp = help_;
    help_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    return temp;
  }
}
inline void MetricFamily::set_allocated_help(::std::string* help) {
  if (help_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
    delete help_;
  }
  if (help) {
    set_has_help();
    help_ = help;
  } else {
    clear_has_help();
    help_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  }
  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.MetricFamily.help)
}

// optional .io.prometheus.client.MetricType type = 3;
inline bool MetricFamily::has_type() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void MetricFamily::set_has_type() {
  _has_bits_[0] |= 0x00000004u;
}
inline void MetricFamily::clear_has_type() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void MetricFamily::clear_type() {
  type_ = 0;
  clear_has_type();
}
inline ::io::prometheus::client::MetricType MetricFamily::type() const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.MetricFamily.type)
  return static_cast< ::io::prometheus::client::MetricType >(type_);
}
inline void MetricFamily::set_type(::io::prometheus::client::MetricType value) {
  assert(::io::prometheus::client::MetricType_IsValid(value));
  set_has_type();
  type_ = value;
  // @@protoc_insertion_point(field_set:io.prometheus.client.MetricFamily.type)
}

// repeated .io.prometheus.client.Metric metric = 4;
inline int MetricFamily::metric_size() const {
  return metric_.size();
}
inline void MetricFamily::clear_metric() {
  metric_.Clear();
}
inline const ::io::prometheus::client::Metric& MetricFamily::metric(int index) const {
  // @@protoc_insertion_point(field_get:io.prometheus.client.MetricFamily.metric)
  return metric_.Get(index);
}
inline ::io::prometheus::client::Metric* MetricFamily::mutable_metric(int index) {
  // @@protoc_insertion_point(field_mutable:io.prometheus.client.MetricFamily.metric)
  return metric_.Mutable(index);
}
inline ::io::prometheus::client::Metric* MetricFamily::add_metric() {
  // @@protoc_insertion_point(field_add:io.prometheus.client.MetricFamily.metric)
  return metric_.Add();
}
inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric >&
MetricFamily::metric() const {
  // @@protoc_insertion_point(field_list:io.prometheus.client.MetricFamily.metric)
  return metric_;
}
inline ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric >*
MetricFamily::mutable_metric() {
  // @@protoc_insertion_point(field_mutable_list:io.prometheus.client.MetricFamily.metric)
  return &metric_;
}


// @@protoc_insertion_point(namespace_scope)

}  // namespace client
}  // namespace prometheus
}  // namespace io

#ifndef SWIG
namespace google {
namespace protobuf {

template <> struct is_proto_enum< ::io::prometheus::client::MetricType> : ::google::protobuf::internal::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::io::prometheus::client::MetricType>() {
  return ::io::prometheus::client::MetricType_descriptor();
}

}  // namespace google
}  // namespace protobuf
#endif  // SWIG

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_metrics_2eproto__INCLUDED
