diff --git a/cpp/metrics.pb.cc b/cpp/metrics.pb.cc
index 1ff893b..9987599 100644
--- a/cpp/metrics.pb.cc
+++ b/cpp/metrics.pb.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 
 #include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
 #include <google/protobuf/stubs/once.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/wire_format_lite_inl.h>
@@ -57,6 +58,7 @@
 }  // namespace
 
 
+void protobuf_AssignDesc_metrics_2eproto() GOOGLE_ATTRIBUTE_COLD;
 void protobuf_AssignDesc_metrics_2eproto() {
   protobuf_AddDesc_metrics_2eproto();
   const ::google::protobuf::FileDescriptor* file =
@@ -69,62 +71,62 @@
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LabelPair, value_),
   };
   LabelPair_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       LabelPair_descriptor_,
       LabelPair::default_instance_,
       LabelPair_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LabelPair, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LabelPair, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(LabelPair));
+      -1,
+      -1,
+      sizeof(LabelPair),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LabelPair, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LabelPair, _is_default_instance_));
   Gauge_descriptor_ = file->message_type(1);
   static const int Gauge_offsets_[1] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Gauge, value_),
   };
   Gauge_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       Gauge_descriptor_,
       Gauge::default_instance_,
       Gauge_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Gauge, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Gauge, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(Gauge));
+      -1,
+      -1,
+      sizeof(Gauge),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Gauge, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Gauge, _is_default_instance_));
   Counter_descriptor_ = file->message_type(2);
   static const int Counter_offsets_[1] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Counter, value_),
   };
   Counter_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       Counter_descriptor_,
       Counter::default_instance_,
       Counter_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Counter, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Counter, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(Counter));
+      -1,
+      -1,
+      sizeof(Counter),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Counter, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Counter, _is_default_instance_));
   Quantile_descriptor_ = file->message_type(3);
   static const int Quantile_offsets_[2] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Quantile, quantile_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Quantile, value_),
   };
   Quantile_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       Quantile_descriptor_,
       Quantile::default_instance_,
       Quantile_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Quantile, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Quantile, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(Quantile));
+      -1,
+      -1,
+      sizeof(Quantile),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Quantile, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Quantile, _is_default_instance_));
   Summary_descriptor_ = file->message_type(4);
   static const int Summary_offsets_[3] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Summary, sample_count_),
@@ -132,31 +134,31 @@
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Summary, quantile_),
   };
   Summary_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       Summary_descriptor_,
       Summary::default_instance_,
       Summary_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Summary, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Summary, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(Summary));
+      -1,
+      -1,
+      sizeof(Summary),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Summary, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Summary, _is_default_instance_));
   Untyped_descriptor_ = file->message_type(5);
   static const int Untyped_offsets_[1] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Untyped, value_),
   };
   Untyped_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       Untyped_descriptor_,
       Untyped::default_instance_,
       Untyped_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Untyped, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Untyped, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(Untyped));
+      -1,
+      -1,
+      sizeof(Untyped),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Untyped, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Untyped, _is_default_instance_));
   Histogram_descriptor_ = file->message_type(6);
   static const int Histogram_offsets_[3] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Histogram, sample_count_),
@@ -164,32 +166,32 @@
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Histogram, bucket_),
   };
   Histogram_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       Histogram_descriptor_,
       Histogram::default_instance_,
       Histogram_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Histogram, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Histogram, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(Histogram));
+      -1,
+      -1,
+      sizeof(Histogram),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Histogram, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Histogram, _is_default_instance_));
   Bucket_descriptor_ = file->message_type(7);
   static const int Bucket_offsets_[2] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bucket, cumulative_count_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bucket, upper_bound_),
   };
   Bucket_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       Bucket_descriptor_,
       Bucket::default_instance_,
       Bucket_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bucket, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bucket, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(Bucket));
+      -1,
+      -1,
+      sizeof(Bucket),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bucket, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bucket, _is_default_instance_));
   Metric_descriptor_ = file->message_type(8);
   static const int Metric_offsets_[7] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metric, label_),
@@ -201,16 +203,16 @@
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metric, timestamp_ms_),
   };
   Metric_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       Metric_descriptor_,
       Metric::default_instance_,
       Metric_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metric, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metric, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(Metric));
+      -1,
+      -1,
+      sizeof(Metric),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metric, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Metric, _is_default_instance_));
   MetricFamily_descriptor_ = file->message_type(9);
   static const int MetricFamily_offsets_[4] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MetricFamily, name_),
@@ -219,16 +221,16 @@
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MetricFamily, metric_),
   };
   MetricFamily_reflection_ =
-    new ::google::protobuf::internal::GeneratedMessageReflection(
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
       MetricFamily_descriptor_,
       MetricFamily::default_instance_,
       MetricFamily_offsets_,
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MetricFamily, _has_bits_[0]),
-      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MetricFamily, _unknown_fields_),
       -1,
-      ::google::protobuf::DescriptorPool::generated_pool(),
-      ::google::protobuf::MessageFactory::generated_factory(),
-      sizeof(MetricFamily));
+      -1,
+      -1,
+      sizeof(MetricFamily),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MetricFamily, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MetricFamily, _is_default_instance_));
   MetricType_descriptor_ = file->enum_type(0);
 }
 
@@ -240,28 +242,29 @@
                  &protobuf_AssignDesc_metrics_2eproto);
 }
 
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
 void protobuf_RegisterTypes(const ::std::string&) {
   protobuf_AssignDescriptorsOnce();
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    LabelPair_descriptor_, &LabelPair::default_instance());
+      LabelPair_descriptor_, &LabelPair::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    Gauge_descriptor_, &Gauge::default_instance());
+      Gauge_descriptor_, &Gauge::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    Counter_descriptor_, &Counter::default_instance());
+      Counter_descriptor_, &Counter::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    Quantile_descriptor_, &Quantile::default_instance());
+      Quantile_descriptor_, &Quantile::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    Summary_descriptor_, &Summary::default_instance());
+      Summary_descriptor_, &Summary::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    Untyped_descriptor_, &Untyped::default_instance());
+      Untyped_descriptor_, &Untyped::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    Histogram_descriptor_, &Histogram::default_instance());
+      Histogram_descriptor_, &Histogram::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    Bucket_descriptor_, &Bucket::default_instance());
+      Bucket_descriptor_, &Bucket::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    Metric_descriptor_, &Metric::default_instance());
+      Metric_descriptor_, &Metric::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
-    MetricFamily_descriptor_, &MetricFamily::default_instance());
+      MetricFamily_descriptor_, &MetricFamily::default_instance());
 }
 
 }  // namespace
@@ -289,6 +292,7 @@
   delete MetricFamily_reflection_;
 }
 
+void protobuf_AddDesc_metrics_2eproto() GOOGLE_ATTRIBUTE_COLD;
 void protobuf_AddDesc_metrics_2eproto() {
   static bool already_here = false;
   if (already_here) return;
@@ -321,7 +325,7 @@
     "etric\030\004 \003(\0132\034.io.prometheus.client.Metri"
     "c*M\n\nMetricType\022\013\n\007COUNTER\020\000\022\t\n\005GAUGE\020\001\022"
     "\013\n\007SUMMARY\020\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004"
-    "B\026\n\024io.prometheus.client", 1024);
+    "B\026\n\024io.prometheus.clientb\006proto3", 1032);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "metrics.proto", &protobuf_RegisterTypes);
   LabelPair::default_instance_ = new LabelPair();
@@ -373,33 +377,35 @@
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int LabelPair::kNameFieldNumber;
 const int LabelPair::kValueFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 LabelPair::LabelPair()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.LabelPair)
 }
 
 void LabelPair::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
 }
 
 LabelPair::LabelPair(const LabelPair& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.LabelPair)
 }
 
 void LabelPair::SharedCtor() {
+    _is_default_instance_ = false;
   ::google::protobuf::internal::GetEmptyString();
   _cached_size_ = 0;
-  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 
 LabelPair::~LabelPair() {
@@ -408,12 +414,8 @@
 }
 
 void LabelPair::SharedDtor() {
-  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete name_;
-  }
-  if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete value_;
-  }
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (this != default_instance_) {
   }
 }
@@ -435,30 +437,23 @@
 
 LabelPair* LabelPair::default_instance_ = NULL;
 
-LabelPair* LabelPair::New() const {
-  return new LabelPair;
+LabelPair* LabelPair::New(::google::protobuf::Arena* arena) const {
+  LabelPair* n = new LabelPair;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void LabelPair::Clear() {
-  if (_has_bits_[0 / 32] & 3) {
-    if (has_name()) {
-      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-        name_->clear();
-      }
-    }
-    if (has_value()) {
-      if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-        value_->clear();
-      }
-    }
-  }
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.LabelPair)
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 
 bool LabelPair::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.LabelPair)
   for (;;) {
@@ -471,10 +466,10 @@
         if (tag == 10) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
-          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
             this->name().data(), this->name().length(),
-            ::google::protobuf::internal::WireFormat::PARSE,
-            "name");
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "io.prometheus.client.LabelPair.name"));
         } else {
           goto handle_unusual;
         }
@@ -488,10 +483,10 @@
          parse_value:
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_value()));
-          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
             this->value().data(), this->value().length(),
-            ::google::protobuf::internal::WireFormat::PARSE,
-            "value");
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "io.prometheus.client.LabelPair.value"));
         } else {
           goto handle_unusual;
         }
@@ -506,8 +501,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -525,89 +519,75 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.LabelPair)
   // optional string name = 1;
-  if (has_name()) {
-    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
       this->name().data(), this->name().length(),
-      ::google::protobuf::internal::WireFormat::SERIALIZE,
-      "name");
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "io.prometheus.client.LabelPair.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
       1, this->name(), output);
   }
 
   // optional string value = 2;
-  if (has_value()) {
-    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+  if (this->value().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
       this->value().data(), this->value().length(),
-      ::google::protobuf::internal::WireFormat::SERIALIZE,
-      "value");
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "io.prometheus.client.LabelPair.value");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
       2, this->value(), output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.LabelPair)
 }
 
-::google::protobuf::uint8* LabelPair::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* LabelPair::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.LabelPair)
   // optional string name = 1;
-  if (has_name()) {
-    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
       this->name().data(), this->name().length(),
-      ::google::protobuf::internal::WireFormat::SERIALIZE,
-      "name");
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "io.prometheus.client.LabelPair.name");
     target =
       ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
         1, this->name(), target);
   }
 
   // optional string value = 2;
-  if (has_value()) {
-    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+  if (this->value().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
       this->value().data(), this->value().length(),
-      ::google::protobuf::internal::WireFormat::SERIALIZE,
-      "value");
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "io.prometheus.client.LabelPair.value");
     target =
       ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
         2, this->value(), target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.LabelPair)
   return target;
 }
 
 int LabelPair::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.LabelPair)
   int total_size = 0;
 
-  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    // optional string name = 1;
-    if (has_name()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::StringSize(
-          this->name());
-    }
-
-    // optional string value = 2;
-    if (has_value()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::StringSize(
-          this->value());
-    }
-
+  // optional string name = 1;
+  if (this->name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->name());
   }
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
+
+  // optional string value = 2;
+  if (this->value().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->value());
   }
+
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -615,37 +595,46 @@
 }
 
 void LabelPair::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const LabelPair* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const LabelPair*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.LabelPair)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const LabelPair* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const LabelPair>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.LabelPair)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.LabelPair)
     MergeFrom(*source);
   }
 }
 
 void LabelPair::MergeFrom(const LabelPair& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    if (from.has_name()) {
-      set_name(from.name());
-    }
-    if (from.has_value()) {
-      set_value(from.value());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.LabelPair)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  if (from.name().size() > 0) {
+
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  if (from.value().size() > 0) {
+
+    value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_);
+  }
 }
 
 void LabelPair::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.LabelPair)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void LabelPair::CopyFrom(const LabelPair& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.LabelPair)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -657,13 +646,14 @@
 }
 
 void LabelPair::Swap(LabelPair* other) {
-  if (other != this) {
-    std::swap(name_, other->name_);
-    std::swap(value_, other->value_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void LabelPair::InternalSwap(LabelPair* other) {
+  name_.Swap(&other->name_);
+  value_.Swap(&other->value_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata LabelPair::GetMetadata() const {
@@ -674,33 +664,127 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// LabelPair
+
+// optional string name = 1;
+void LabelPair::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& LabelPair::name() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.LabelPair.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void LabelPair::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:io.prometheus.client.LabelPair.name)
+}
+ void LabelPair::set_name(const char* value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:io.prometheus.client.LabelPair.name)
+}
+ void LabelPair::set_name(const char* value, size_t size) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:io.prometheus.client.LabelPair.name)
+}
+ ::std::string* LabelPair::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.LabelPair.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* LabelPair::release_name() {
+  // @@protoc_insertion_point(field_release:io.prometheus.client.LabelPair.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void LabelPair::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.LabelPair.name)
+}
+
+// optional string value = 2;
+void LabelPair::clear_value() {
+  value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& LabelPair::value() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.LabelPair.value)
+  return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void LabelPair::set_value(const ::std::string& value) {
+  
+  value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:io.prometheus.client.LabelPair.value)
+}
+ void LabelPair::set_value(const char* value) {
+  
+  value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:io.prometheus.client.LabelPair.value)
+}
+ void LabelPair::set_value(const char* value, size_t size) {
+  
+  value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:io.prometheus.client.LabelPair.value)
+}
+ ::std::string* LabelPair::mutable_value() {
+  
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.LabelPair.value)
+  return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* LabelPair::release_value() {
+  // @@protoc_insertion_point(field_release:io.prometheus.client.LabelPair.value)
+  
+  return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void LabelPair::set_allocated_value(::std::string* value) {
+  if (value != NULL) {
+    
+  } else {
+    
+  }
+  value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.LabelPair.value)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Gauge::kValueFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Gauge::Gauge()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.Gauge)
 }
 
 void Gauge::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
 }
 
 Gauge::Gauge(const Gauge& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.Gauge)
 }
 
 void Gauge::SharedCtor() {
+    _is_default_instance_ = false;
   _cached_size_ = 0;
   value_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
 Gauge::~Gauge() {
@@ -730,19 +814,22 @@
 
 Gauge* Gauge::default_instance_ = NULL;
 
-Gauge* Gauge::New() const {
-  return new Gauge;
+Gauge* Gauge::New(::google::protobuf::Arena* arena) const {
+  Gauge* n = new Gauge;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void Gauge::Clear() {
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.Gauge)
   value_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
 }
 
 bool Gauge::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.Gauge)
   for (;;) {
@@ -756,7 +843,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                  input, &value_)));
-          set_has_value();
+
         } else {
           goto handle_unusual;
         }
@@ -771,8 +858,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -790,48 +876,34 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.Gauge)
   // optional double value = 1;
-  if (has_value()) {
+  if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->value(), output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.Gauge)
 }
 
-::google::protobuf::uint8* Gauge::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Gauge::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.Gauge)
   // optional double value = 1;
-  if (has_value()) {
+  if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->value(), target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.Gauge)
   return target;
 }
 
 int Gauge::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.Gauge)
   int total_size = 0;
 
-  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    // optional double value = 1;
-    if (has_value()) {
-      total_size += 1 + 8;
-    }
+  // optional double value = 1;
+  if (this->value() != 0) {
+    total_size += 1 + 8;
+  }
 
-  }
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
-  }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -839,34 +911,41 @@
 }
 
 void Gauge::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const Gauge* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const Gauge*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.Gauge)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const Gauge* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const Gauge>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.Gauge)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.Gauge)
     MergeFrom(*source);
   }
 }
 
 void Gauge::MergeFrom(const Gauge& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    if (from.has_value()) {
-      set_value(from.value());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.Gauge)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  if (from.value() != 0) {
+    set_value(from.value());
+  }
 }
 
 void Gauge::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.Gauge)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void Gauge::CopyFrom(const Gauge& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.Gauge)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -878,12 +957,13 @@
 }
 
 void Gauge::Swap(Gauge* other) {
-  if (other != this) {
-    std::swap(value_, other->value_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Gauge::InternalSwap(Gauge* other) {
+  std::swap(value_, other->value_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata Gauge::GetMetadata() const {
@@ -894,33 +974,53 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Gauge
+
+// optional double value = 1;
+void Gauge::clear_value() {
+  value_ = 0;
+}
+ double Gauge::value() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Gauge.value)
+  return value_;
+}
+ void Gauge::set_value(double value) {
+  
+  value_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Gauge.value)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Counter::kValueFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Counter::Counter()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.Counter)
 }
 
 void Counter::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
 }
 
 Counter::Counter(const Counter& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.Counter)
 }
 
 void Counter::SharedCtor() {
+    _is_default_instance_ = false;
   _cached_size_ = 0;
   value_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
 Counter::~Counter() {
@@ -950,19 +1050,22 @@
 
 Counter* Counter::default_instance_ = NULL;
 
-Counter* Counter::New() const {
-  return new Counter;
+Counter* Counter::New(::google::protobuf::Arena* arena) const {
+  Counter* n = new Counter;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void Counter::Clear() {
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.Counter)
   value_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
 }
 
 bool Counter::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.Counter)
   for (;;) {
@@ -976,7 +1079,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                  input, &value_)));
-          set_has_value();
+
         } else {
           goto handle_unusual;
         }
@@ -991,8 +1094,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -1010,48 +1112,34 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.Counter)
   // optional double value = 1;
-  if (has_value()) {
+  if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->value(), output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.Counter)
 }
 
-::google::protobuf::uint8* Counter::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Counter::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.Counter)
   // optional double value = 1;
-  if (has_value()) {
+  if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->value(), target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.Counter)
   return target;
 }
 
 int Counter::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.Counter)
   int total_size = 0;
 
-  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    // optional double value = 1;
-    if (has_value()) {
-      total_size += 1 + 8;
-    }
+  // optional double value = 1;
+  if (this->value() != 0) {
+    total_size += 1 + 8;
+  }
 
-  }
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
-  }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -1059,34 +1147,41 @@
 }
 
 void Counter::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const Counter* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const Counter*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.Counter)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const Counter* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const Counter>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.Counter)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.Counter)
     MergeFrom(*source);
   }
 }
 
 void Counter::MergeFrom(const Counter& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    if (from.has_value()) {
-      set_value(from.value());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.Counter)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  if (from.value() != 0) {
+    set_value(from.value());
+  }
 }
 
 void Counter::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.Counter)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void Counter::CopyFrom(const Counter& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.Counter)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -1098,12 +1193,13 @@
 }
 
 void Counter::Swap(Counter* other) {
-  if (other != this) {
-    std::swap(value_, other->value_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Counter::InternalSwap(Counter* other) {
+  std::swap(value_, other->value_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata Counter::GetMetadata() const {
@@ -1114,35 +1210,55 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Counter
+
+// optional double value = 1;
+void Counter::clear_value() {
+  value_ = 0;
+}
+ double Counter::value() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Counter.value)
+  return value_;
+}
+ void Counter::set_value(double value) {
+  
+  value_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Counter.value)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Quantile::kQuantileFieldNumber;
 const int Quantile::kValueFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Quantile::Quantile()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.Quantile)
 }
 
 void Quantile::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
 }
 
 Quantile::Quantile(const Quantile& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.Quantile)
 }
 
 void Quantile::SharedCtor() {
+    _is_default_instance_ = false;
   _cached_size_ = 0;
   quantile_ = 0;
   value_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
 Quantile::~Quantile() {
@@ -1172,33 +1288,42 @@
 
 Quantile* Quantile::default_instance_ = NULL;
 
-Quantile* Quantile::New() const {
-  return new Quantile;
+Quantile* Quantile::New(::google::protobuf::Arena* arena) const {
+  Quantile* n = new Quantile;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void Quantile::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<Quantile*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.Quantile)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+  _Pragma("clang diagnostic push") \
+  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+  __builtin_offsetof(Quantile, f) \
+  _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<Quantile*>(16)->f)
+#endif
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   ZR_(quantile_, value_);
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
 }
 
 bool Quantile::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.Quantile)
   for (;;) {
@@ -1212,7 +1337,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                  input, &quantile_)));
-          set_has_quantile();
+
         } else {
           goto handle_unusual;
         }
@@ -1227,7 +1352,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                  input, &value_)));
-          set_has_value();
+
         } else {
           goto handle_unusual;
         }
@@ -1242,8 +1367,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -1261,63 +1385,49 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.Quantile)
   // optional double quantile = 1;
-  if (has_quantile()) {
+  if (this->quantile() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->quantile(), output);
   }
 
   // optional double value = 2;
-  if (has_value()) {
+  if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->value(), output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.Quantile)
 }
 
-::google::protobuf::uint8* Quantile::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Quantile::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.Quantile)
   // optional double quantile = 1;
-  if (has_quantile()) {
+  if (this->quantile() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->quantile(), target);
   }
 
   // optional double value = 2;
-  if (has_value()) {
+  if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->value(), target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.Quantile)
   return target;
 }
 
 int Quantile::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.Quantile)
   int total_size = 0;
 
-  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    // optional double quantile = 1;
-    if (has_quantile()) {
-      total_size += 1 + 8;
-    }
-
-    // optional double value = 2;
-    if (has_value()) {
-      total_size += 1 + 8;
-    }
-
+  // optional double quantile = 1;
+  if (this->quantile() != 0) {
+    total_size += 1 + 8;
   }
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
+
+  // optional double value = 2;
+  if (this->value() != 0) {
+    total_size += 1 + 8;
   }
+
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -1325,37 +1435,44 @@
 }
 
 void Quantile::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const Quantile* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const Quantile*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.Quantile)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const Quantile* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const Quantile>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.Quantile)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.Quantile)
     MergeFrom(*source);
   }
 }
 
 void Quantile::MergeFrom(const Quantile& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    if (from.has_quantile()) {
-      set_quantile(from.quantile());
-    }
-    if (from.has_value()) {
-      set_value(from.value());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.Quantile)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  if (from.quantile() != 0) {
+    set_quantile(from.quantile());
+  }
+  if (from.value() != 0) {
+    set_value(from.value());
+  }
 }
 
 void Quantile::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.Quantile)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void Quantile::CopyFrom(const Quantile& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.Quantile)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -1367,13 +1484,14 @@
 }
 
 void Quantile::Swap(Quantile* other) {
-  if (other != this) {
-    std::swap(quantile_, other->quantile_);
-    std::swap(value_, other->value_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Quantile::InternalSwap(Quantile* other) {
+  std::swap(quantile_, other->quantile_);
+  std::swap(value_, other->value_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata Quantile::GetMetadata() const {
@@ -1384,36 +1502,70 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Quantile
+
+// optional double quantile = 1;
+void Quantile::clear_quantile() {
+  quantile_ = 0;
+}
+ double Quantile::quantile() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Quantile.quantile)
+  return quantile_;
+}
+ void Quantile::set_quantile(double value) {
+  
+  quantile_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Quantile.quantile)
+}
+
+// optional double value = 2;
+void Quantile::clear_value() {
+  value_ = 0;
+}
+ double Quantile::value() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Quantile.value)
+  return value_;
+}
+ void Quantile::set_value(double value) {
+  
+  value_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Quantile.value)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Summary::kSampleCountFieldNumber;
 const int Summary::kSampleSumFieldNumber;
 const int Summary::kQuantileFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Summary::Summary()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.Summary)
 }
 
 void Summary::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
 }
 
 Summary::Summary(const Summary& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.Summary)
 }
 
 void Summary::SharedCtor() {
+    _is_default_instance_ = false;
   _cached_size_ = 0;
   sample_count_ = GOOGLE_ULONGLONG(0);
   sample_sum_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
 Summary::~Summary() {
@@ -1443,34 +1595,43 @@
 
 Summary* Summary::default_instance_ = NULL;
 
-Summary* Summary::New() const {
-  return new Summary;
+Summary* Summary::New(::google::protobuf::Arena* arena) const {
+  Summary* n = new Summary;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void Summary::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<Summary*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.Summary)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+  _Pragma("clang diagnostic push") \
+  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+  __builtin_offsetof(Summary, f) \
+  _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<Summary*>(16)->f)
+#endif
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   ZR_(sample_count_, sample_sum_);
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
   quantile_.Clear();
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
 }
 
 bool Summary::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.Summary)
   for (;;) {
@@ -1484,7 +1645,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                  input, &sample_count_)));
-          set_has_sample_count();
+
         } else {
           goto handle_unusual;
         }
@@ -1499,7 +1660,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                  input, &sample_sum_)));
-          set_has_sample_sum();
+
         } else {
           goto handle_unusual;
         }
@@ -1511,12 +1672,15 @@
       case 3: {
         if (tag == 26) {
          parse_quantile:
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+          DO_(input->IncrementRecursionDepth());
+         parse_loop_quantile:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
                 input, add_quantile()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(26)) goto parse_quantile;
+        if (input->ExpectTag(26)) goto parse_loop_quantile;
+        input->UnsafeDecrementRecursionDepth();
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -1528,8 +1692,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -1547,73 +1710,64 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.Summary)
   // optional uint64 sample_count = 1;
-  if (has_sample_count()) {
+  if (this->sample_count() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->sample_count(), output);
   }
 
   // optional double sample_sum = 2;
-  if (has_sample_sum()) {
+  if (this->sample_sum() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->sample_sum(), output);
   }
 
   // repeated .io.prometheus.client.Quantile quantile = 3;
-  for (int i = 0; i < this->quantile_size(); i++) {
+  for (unsigned int i = 0, n = this->quantile_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       3, this->quantile(i), output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.Summary)
 }
 
-::google::protobuf::uint8* Summary::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Summary::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.Summary)
   // optional uint64 sample_count = 1;
-  if (has_sample_count()) {
+  if (this->sample_count() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->sample_count(), target);
   }
 
   // optional double sample_sum = 2;
-  if (has_sample_sum()) {
+  if (this->sample_sum() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->sample_sum(), target);
   }
 
   // repeated .io.prometheus.client.Quantile quantile = 3;
-  for (int i = 0; i < this->quantile_size(); i++) {
+  for (unsigned int i = 0, n = this->quantile_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteMessageNoVirtualToArray(
-        3, this->quantile(i), target);
+      InternalWriteMessageNoVirtualToArray(
+        3, this->quantile(i), false, target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.Summary)
   return target;
 }
 
 int Summary::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.Summary)
   int total_size = 0;
 
-  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    // optional uint64 sample_count = 1;
-    if (has_sample_count()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::UInt64Size(
-          this->sample_count());
-    }
-
-    // optional double sample_sum = 2;
-    if (has_sample_sum()) {
-      total_size += 1 + 8;
-    }
-
+  // optional uint64 sample_count = 1;
+  if (this->sample_count() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::UInt64Size(
+        this->sample_count());
   }
+
+  // optional double sample_sum = 2;
+  if (this->sample_sum() != 0) {
+    total_size += 1 + 8;
+  }
+
   // repeated .io.prometheus.client.Quantile quantile = 3;
   total_size += 1 * this->quantile_size();
   for (int i = 0; i < this->quantile_size(); i++) {
@@ -1622,11 +1776,6 @@
         this->quantile(i));
   }
 
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
-  }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -1634,38 +1783,45 @@
 }
 
 void Summary::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const Summary* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const Summary*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.Summary)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const Summary* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const Summary>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.Summary)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.Summary)
     MergeFrom(*source);
   }
 }
 
 void Summary::MergeFrom(const Summary& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  quantile_.MergeFrom(from.quantile_);
-  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    if (from.has_sample_count()) {
-      set_sample_count(from.sample_count());
-    }
-    if (from.has_sample_sum()) {
-      set_sample_sum(from.sample_sum());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.Summary)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  quantile_.MergeFrom(from.quantile_);
+  if (from.sample_count() != 0) {
+    set_sample_count(from.sample_count());
+  }
+  if (from.sample_sum() != 0) {
+    set_sample_sum(from.sample_sum());
+  }
 }
 
 void Summary::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.Summary)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void Summary::CopyFrom(const Summary& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.Summary)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -1677,14 +1833,15 @@
 }
 
 void Summary::Swap(Summary* other) {
-  if (other != this) {
-    std::swap(sample_count_, other->sample_count_);
-    std::swap(sample_sum_, other->sample_sum_);
-    quantile_.Swap(&other->quantile_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Summary::InternalSwap(Summary* other) {
+  std::swap(sample_count_, other->sample_count_);
+  std::swap(sample_sum_, other->sample_sum_);
+  quantile_.UnsafeArenaSwap(&other->quantile_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata Summary::GetMetadata() const {
@@ -1695,33 +1852,97 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Summary
+
+// optional uint64 sample_count = 1;
+void Summary::clear_sample_count() {
+  sample_count_ = GOOGLE_ULONGLONG(0);
+}
+ ::google::protobuf::uint64 Summary::sample_count() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Summary.sample_count)
+  return sample_count_;
+}
+ void Summary::set_sample_count(::google::protobuf::uint64 value) {
+  
+  sample_count_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Summary.sample_count)
+}
+
+// optional double sample_sum = 2;
+void Summary::clear_sample_sum() {
+  sample_sum_ = 0;
+}
+ double Summary::sample_sum() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Summary.sample_sum)
+  return sample_sum_;
+}
+ void Summary::set_sample_sum(double value) {
+  
+  sample_sum_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Summary.sample_sum)
+}
+
+// repeated .io.prometheus.client.Quantile quantile = 3;
+int Summary::quantile_size() const {
+  return quantile_.size();
+}
+void Summary::clear_quantile() {
+  quantile_.Clear();
+}
+const ::io::prometheus::client::Quantile& Summary::quantile(int index) const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Summary.quantile)
+  return quantile_.Get(index);
+}
+::io::prometheus::client::Quantile* Summary::mutable_quantile(int index) {
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Summary.quantile)
+  return quantile_.Mutable(index);
+}
+::io::prometheus::client::Quantile* Summary::add_quantile() {
+  // @@protoc_insertion_point(field_add:io.prometheus.client.Summary.quantile)
+  return quantile_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile >*
+Summary::mutable_quantile() {
+  // @@protoc_insertion_point(field_mutable_list:io.prometheus.client.Summary.quantile)
+  return &quantile_;
+}
+const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile >&
+Summary::quantile() const {
+  // @@protoc_insertion_point(field_list:io.prometheus.client.Summary.quantile)
+  return quantile_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Untyped::kValueFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Untyped::Untyped()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.Untyped)
 }
 
 void Untyped::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
 }
 
 Untyped::Untyped(const Untyped& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.Untyped)
 }
 
 void Untyped::SharedCtor() {
+    _is_default_instance_ = false;
   _cached_size_ = 0;
   value_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
 Untyped::~Untyped() {
@@ -1751,19 +1972,22 @@
 
 Untyped* Untyped::default_instance_ = NULL;
 
-Untyped* Untyped::New() const {
-  return new Untyped;
+Untyped* Untyped::New(::google::protobuf::Arena* arena) const {
+  Untyped* n = new Untyped;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void Untyped::Clear() {
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.Untyped)
   value_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
 }
 
 bool Untyped::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.Untyped)
   for (;;) {
@@ -1777,7 +2001,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                  input, &value_)));
-          set_has_value();
+
         } else {
           goto handle_unusual;
         }
@@ -1792,8 +2016,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -1811,48 +2034,34 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.Untyped)
   // optional double value = 1;
-  if (has_value()) {
+  if (this->value() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->value(), output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.Untyped)
 }
 
-::google::protobuf::uint8* Untyped::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Untyped::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.Untyped)
   // optional double value = 1;
-  if (has_value()) {
+  if (this->value() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->value(), target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.Untyped)
   return target;
 }
 
 int Untyped::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.Untyped)
   int total_size = 0;
 
-  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    // optional double value = 1;
-    if (has_value()) {
-      total_size += 1 + 8;
-    }
+  // optional double value = 1;
+  if (this->value() != 0) {
+    total_size += 1 + 8;
+  }
 
-  }
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
-  }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -1860,34 +2069,41 @@
 }
 
 void Untyped::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const Untyped* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const Untyped*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.Untyped)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const Untyped* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const Untyped>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.Untyped)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.Untyped)
     MergeFrom(*source);
   }
 }
 
 void Untyped::MergeFrom(const Untyped& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    if (from.has_value()) {
-      set_value(from.value());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.Untyped)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  if (from.value() != 0) {
+    set_value(from.value());
+  }
 }
 
 void Untyped::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.Untyped)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void Untyped::CopyFrom(const Untyped& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.Untyped)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -1899,12 +2115,13 @@
 }
 
 void Untyped::Swap(Untyped* other) {
-  if (other != this) {
-    std::swap(value_, other->value_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Untyped::InternalSwap(Untyped* other) {
+  std::swap(value_, other->value_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata Untyped::GetMetadata() const {
@@ -1915,36 +2132,56 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Untyped
+
+// optional double value = 1;
+void Untyped::clear_value() {
+  value_ = 0;
+}
+ double Untyped::value() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Untyped.value)
+  return value_;
+}
+ void Untyped::set_value(double value) {
+  
+  value_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Untyped.value)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Histogram::kSampleCountFieldNumber;
 const int Histogram::kSampleSumFieldNumber;
 const int Histogram::kBucketFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Histogram::Histogram()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.Histogram)
 }
 
 void Histogram::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
 }
 
 Histogram::Histogram(const Histogram& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.Histogram)
 }
 
 void Histogram::SharedCtor() {
+    _is_default_instance_ = false;
   _cached_size_ = 0;
   sample_count_ = GOOGLE_ULONGLONG(0);
   sample_sum_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
 Histogram::~Histogram() {
@@ -1974,34 +2211,43 @@
 
 Histogram* Histogram::default_instance_ = NULL;
 
-Histogram* Histogram::New() const {
-  return new Histogram;
+Histogram* Histogram::New(::google::protobuf::Arena* arena) const {
+  Histogram* n = new Histogram;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void Histogram::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<Histogram*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.Histogram)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+  _Pragma("clang diagnostic push") \
+  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+  __builtin_offsetof(Histogram, f) \
+  _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<Histogram*>(16)->f)
+#endif
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   ZR_(sample_count_, sample_sum_);
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
   bucket_.Clear();
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
 }
 
 bool Histogram::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.Histogram)
   for (;;) {
@@ -2015,7 +2261,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                  input, &sample_count_)));
-          set_has_sample_count();
+
         } else {
           goto handle_unusual;
         }
@@ -2030,7 +2276,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                  input, &sample_sum_)));
-          set_has_sample_sum();
+
         } else {
           goto handle_unusual;
         }
@@ -2042,12 +2288,15 @@
       case 3: {
         if (tag == 26) {
          parse_bucket:
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+          DO_(input->IncrementRecursionDepth());
+         parse_loop_bucket:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
                 input, add_bucket()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(26)) goto parse_bucket;
+        if (input->ExpectTag(26)) goto parse_loop_bucket;
+        input->UnsafeDecrementRecursionDepth();
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -2059,8 +2308,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -2078,73 +2326,64 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.Histogram)
   // optional uint64 sample_count = 1;
-  if (has_sample_count()) {
+  if (this->sample_count() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->sample_count(), output);
   }
 
   // optional double sample_sum = 2;
-  if (has_sample_sum()) {
+  if (this->sample_sum() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->sample_sum(), output);
   }
 
   // repeated .io.prometheus.client.Bucket bucket = 3;
-  for (int i = 0; i < this->bucket_size(); i++) {
+  for (unsigned int i = 0, n = this->bucket_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       3, this->bucket(i), output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.Histogram)
 }
 
-::google::protobuf::uint8* Histogram::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Histogram::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.Histogram)
   // optional uint64 sample_count = 1;
-  if (has_sample_count()) {
+  if (this->sample_count() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->sample_count(), target);
   }
 
   // optional double sample_sum = 2;
-  if (has_sample_sum()) {
+  if (this->sample_sum() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->sample_sum(), target);
   }
 
   // repeated .io.prometheus.client.Bucket bucket = 3;
-  for (int i = 0; i < this->bucket_size(); i++) {
+  for (unsigned int i = 0, n = this->bucket_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteMessageNoVirtualToArray(
-        3, this->bucket(i), target);
+      InternalWriteMessageNoVirtualToArray(
+        3, this->bucket(i), false, target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.Histogram)
   return target;
 }
 
 int Histogram::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.Histogram)
   int total_size = 0;
 
-  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    // optional uint64 sample_count = 1;
-    if (has_sample_count()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::UInt64Size(
-          this->sample_count());
-    }
-
-    // optional double sample_sum = 2;
-    if (has_sample_sum()) {
-      total_size += 1 + 8;
-    }
-
+  // optional uint64 sample_count = 1;
+  if (this->sample_count() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::UInt64Size(
+        this->sample_count());
   }
+
+  // optional double sample_sum = 2;
+  if (this->sample_sum() != 0) {
+    total_size += 1 + 8;
+  }
+
   // repeated .io.prometheus.client.Bucket bucket = 3;
   total_size += 1 * this->bucket_size();
   for (int i = 0; i < this->bucket_size(); i++) {
@@ -2153,11 +2392,6 @@
         this->bucket(i));
   }
 
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
-  }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -2165,38 +2399,45 @@
 }
 
 void Histogram::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const Histogram* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const Histogram*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.Histogram)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const Histogram* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const Histogram>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.Histogram)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.Histogram)
     MergeFrom(*source);
   }
 }
 
 void Histogram::MergeFrom(const Histogram& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  bucket_.MergeFrom(from.bucket_);
-  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    if (from.has_sample_count()) {
-      set_sample_count(from.sample_count());
-    }
-    if (from.has_sample_sum()) {
-      set_sample_sum(from.sample_sum());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.Histogram)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  bucket_.MergeFrom(from.bucket_);
+  if (from.sample_count() != 0) {
+    set_sample_count(from.sample_count());
+  }
+  if (from.sample_sum() != 0) {
+    set_sample_sum(from.sample_sum());
+  }
 }
 
 void Histogram::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.Histogram)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void Histogram::CopyFrom(const Histogram& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.Histogram)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -2208,14 +2449,15 @@
 }
 
 void Histogram::Swap(Histogram* other) {
-  if (other != this) {
-    std::swap(sample_count_, other->sample_count_);
-    std::swap(sample_sum_, other->sample_sum_);
-    bucket_.Swap(&other->bucket_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Histogram::InternalSwap(Histogram* other) {
+  std::swap(sample_count_, other->sample_count_);
+  std::swap(sample_sum_, other->sample_sum_);
+  bucket_.UnsafeArenaSwap(&other->bucket_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata Histogram::GetMetadata() const {
@@ -2226,35 +2468,99 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Histogram
+
+// optional uint64 sample_count = 1;
+void Histogram::clear_sample_count() {
+  sample_count_ = GOOGLE_ULONGLONG(0);
+}
+ ::google::protobuf::uint64 Histogram::sample_count() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Histogram.sample_count)
+  return sample_count_;
+}
+ void Histogram::set_sample_count(::google::protobuf::uint64 value) {
+  
+  sample_count_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Histogram.sample_count)
+}
+
+// optional double sample_sum = 2;
+void Histogram::clear_sample_sum() {
+  sample_sum_ = 0;
+}
+ double Histogram::sample_sum() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Histogram.sample_sum)
+  return sample_sum_;
+}
+ void Histogram::set_sample_sum(double value) {
+  
+  sample_sum_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Histogram.sample_sum)
+}
+
+// repeated .io.prometheus.client.Bucket bucket = 3;
+int Histogram::bucket_size() const {
+  return bucket_.size();
+}
+void Histogram::clear_bucket() {
+  bucket_.Clear();
+}
+const ::io::prometheus::client::Bucket& Histogram::bucket(int index) const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Histogram.bucket)
+  return bucket_.Get(index);
+}
+::io::prometheus::client::Bucket* Histogram::mutable_bucket(int index) {
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Histogram.bucket)
+  return bucket_.Mutable(index);
+}
+::io::prometheus::client::Bucket* Histogram::add_bucket() {
+  // @@protoc_insertion_point(field_add:io.prometheus.client.Histogram.bucket)
+  return bucket_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket >*
+Histogram::mutable_bucket() {
+  // @@protoc_insertion_point(field_mutable_list:io.prometheus.client.Histogram.bucket)
+  return &bucket_;
+}
+const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket >&
+Histogram::bucket() const {
+  // @@protoc_insertion_point(field_list:io.prometheus.client.Histogram.bucket)
+  return bucket_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Bucket::kCumulativeCountFieldNumber;
 const int Bucket::kUpperBoundFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Bucket::Bucket()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.Bucket)
 }
 
 void Bucket::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
 }
 
 Bucket::Bucket(const Bucket& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.Bucket)
 }
 
 void Bucket::SharedCtor() {
+    _is_default_instance_ = false;
   _cached_size_ = 0;
   cumulative_count_ = GOOGLE_ULONGLONG(0);
   upper_bound_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
 Bucket::~Bucket() {
@@ -2284,33 +2590,42 @@
 
 Bucket* Bucket::default_instance_ = NULL;
 
-Bucket* Bucket::New() const {
-  return new Bucket;
+Bucket* Bucket::New(::google::protobuf::Arena* arena) const {
+  Bucket* n = new Bucket;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void Bucket::Clear() {
-#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
-  &reinterpret_cast<Bucket*>(16)->f) - \
-   reinterpret_cast<char*>(16))
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.Bucket)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+  _Pragma("clang diagnostic push") \
+  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+  __builtin_offsetof(Bucket, f) \
+  _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<Bucket*>(16)->f)
+#endif
 
-#define ZR_(first, last) do {                              \
-    size_t f = OFFSET_OF_FIELD_(first);                    \
-    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
-    ::memset(&first, 0, n);                                \
-  } while (0)
+#define ZR_(first, last) do {\
+  ::memset(&first, 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
 
   ZR_(cumulative_count_, upper_bound_);
 
-#undef OFFSET_OF_FIELD_
+#undef ZR_HELPER_
 #undef ZR_
 
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
 }
 
 bool Bucket::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.Bucket)
   for (;;) {
@@ -2324,7 +2639,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                  input, &cumulative_count_)));
-          set_has_cumulative_count();
+
         } else {
           goto handle_unusual;
         }
@@ -2339,7 +2654,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                  input, &upper_bound_)));
-          set_has_upper_bound();
+
         } else {
           goto handle_unusual;
         }
@@ -2354,8 +2669,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -2373,65 +2687,51 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.Bucket)
   // optional uint64 cumulative_count = 1;
-  if (has_cumulative_count()) {
+  if (this->cumulative_count() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->cumulative_count(), output);
   }
 
   // optional double upper_bound = 2;
-  if (has_upper_bound()) {
+  if (this->upper_bound() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->upper_bound(), output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.Bucket)
 }
 
-::google::protobuf::uint8* Bucket::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Bucket::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.Bucket)
   // optional uint64 cumulative_count = 1;
-  if (has_cumulative_count()) {
+  if (this->cumulative_count() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->cumulative_count(), target);
   }
 
   // optional double upper_bound = 2;
-  if (has_upper_bound()) {
+  if (this->upper_bound() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->upper_bound(), target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.Bucket)
   return target;
 }
 
 int Bucket::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.Bucket)
   int total_size = 0;
 
-  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    // optional uint64 cumulative_count = 1;
-    if (has_cumulative_count()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::UInt64Size(
-          this->cumulative_count());
-    }
-
-    // optional double upper_bound = 2;
-    if (has_upper_bound()) {
-      total_size += 1 + 8;
-    }
-
+  // optional uint64 cumulative_count = 1;
+  if (this->cumulative_count() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::UInt64Size(
+        this->cumulative_count());
   }
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
+
+  // optional double upper_bound = 2;
+  if (this->upper_bound() != 0) {
+    total_size += 1 + 8;
   }
+
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -2439,37 +2739,44 @@
 }
 
 void Bucket::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const Bucket* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const Bucket*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.Bucket)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const Bucket* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const Bucket>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.Bucket)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.Bucket)
     MergeFrom(*source);
   }
 }
 
 void Bucket::MergeFrom(const Bucket& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    if (from.has_cumulative_count()) {
-      set_cumulative_count(from.cumulative_count());
-    }
-    if (from.has_upper_bound()) {
-      set_upper_bound(from.upper_bound());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.Bucket)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  if (from.cumulative_count() != 0) {
+    set_cumulative_count(from.cumulative_count());
+  }
+  if (from.upper_bound() != 0) {
+    set_upper_bound(from.upper_bound());
+  }
 }
 
 void Bucket::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.Bucket)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void Bucket::CopyFrom(const Bucket& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.Bucket)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -2481,13 +2788,14 @@
 }
 
 void Bucket::Swap(Bucket* other) {
-  if (other != this) {
-    std::swap(cumulative_count_, other->cumulative_count_);
-    std::swap(upper_bound_, other->upper_bound_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Bucket::InternalSwap(Bucket* other) {
+  std::swap(cumulative_count_, other->cumulative_count_);
+  std::swap(upper_bound_, other->upper_bound_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata Bucket::GetMetadata() const {
@@ -2498,10 +2806,42 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Bucket
+
+// optional uint64 cumulative_count = 1;
+void Bucket::clear_cumulative_count() {
+  cumulative_count_ = GOOGLE_ULONGLONG(0);
+}
+ ::google::protobuf::uint64 Bucket::cumulative_count() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Bucket.cumulative_count)
+  return cumulative_count_;
+}
+ void Bucket::set_cumulative_count(::google::protobuf::uint64 value) {
+  
+  cumulative_count_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Bucket.cumulative_count)
+}
+
+// optional double upper_bound = 2;
+void Bucket::clear_upper_bound() {
+  upper_bound_ = 0;
+}
+ double Bucket::upper_bound() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Bucket.upper_bound)
+  return upper_bound_;
+}
+ void Bucket::set_upper_bound(double value) {
+  
+  upper_bound_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Bucket.upper_bound)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int Metric::kLabelFieldNumber;
 const int Metric::kGaugeFieldNumber;
 const int Metric::kCounterFieldNumber;
@@ -2509,15 +2849,16 @@
 const int Metric::kUntypedFieldNumber;
 const int Metric::kHistogramFieldNumber;
 const int Metric::kTimestampMsFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Metric::Metric()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.Metric)
 }
 
 void Metric::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
   gauge_ = const_cast< ::io::prometheus::client::Gauge*>(&::io::prometheus::client::Gauge::default_instance());
   counter_ = const_cast< ::io::prometheus::client::Counter*>(&::io::prometheus::client::Counter::default_instance());
   summary_ = const_cast< ::io::prometheus::client::Summary*>(&::io::prometheus::client::Summary::default_instance());
@@ -2526,13 +2867,15 @@
 }
 
 Metric::Metric(const Metric& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.Metric)
 }
 
 void Metric::SharedCtor() {
+    _is_default_instance_ = false;
   _cached_size_ = 0;
   gauge_ = NULL;
   counter_ = NULL;
@@ -2540,7 +2883,6 @@
   untyped_ = NULL;
   histogram_ = NULL;
   timestamp_ms_ = GOOGLE_LONGLONG(0);
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
 Metric::~Metric() {
@@ -2575,37 +2917,33 @@
 
 Metric* Metric::default_instance_ = NULL;
 
-Metric* Metric::New() const {
-  return new Metric;
+Metric* Metric::New(::google::protobuf::Arena* arena) const {
+  Metric* n = new Metric;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void Metric::Clear() {
-  if (_has_bits_[0 / 32] & 126) {
-    if (has_gauge()) {
-      if (gauge_ != NULL) gauge_->::io::prometheus::client::Gauge::Clear();
-    }
-    if (has_counter()) {
-      if (counter_ != NULL) counter_->::io::prometheus::client::Counter::Clear();
-    }
-    if (has_summary()) {
-      if (summary_ != NULL) summary_->::io::prometheus::client::Summary::Clear();
-    }
-    if (has_untyped()) {
-      if (untyped_ != NULL) untyped_->::io::prometheus::client::Untyped::Clear();
-    }
-    if (has_histogram()) {
-      if (histogram_ != NULL) histogram_->::io::prometheus::client::Histogram::Clear();
-    }
-    timestamp_ms_ = GOOGLE_LONGLONG(0);
-  }
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.Metric)
+  if (GetArenaNoVirtual() == NULL && gauge_ != NULL) delete gauge_;
+  gauge_ = NULL;
+  if (GetArenaNoVirtual() == NULL && counter_ != NULL) delete counter_;
+  counter_ = NULL;
+  if (GetArenaNoVirtual() == NULL && summary_ != NULL) delete summary_;
+  summary_ = NULL;
+  if (GetArenaNoVirtual() == NULL && untyped_ != NULL) delete untyped_;
+  untyped_ = NULL;
+  if (GetArenaNoVirtual() == NULL && histogram_ != NULL) delete histogram_;
+  histogram_ = NULL;
+  timestamp_ms_ = GOOGLE_LONGLONG(0);
   label_.Clear();
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
 }
 
 bool Metric::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.Metric)
   for (;;) {
@@ -2616,13 +2954,15 @@
       // repeated .io.prometheus.client.LabelPair label = 1;
       case 1: {
         if (tag == 10) {
-         parse_label:
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+          DO_(input->IncrementRecursionDepth());
+         parse_loop_label:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
                 input, add_label()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(10)) goto parse_label;
+        if (input->ExpectTag(10)) goto parse_loop_label;
+        input->UnsafeDecrementRecursionDepth();
         if (input->ExpectTag(18)) goto parse_gauge;
         break;
       }
@@ -2686,7 +3026,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                  input, &timestamp_ms_)));
-          set_has_timestamp_ms();
+
         } else {
           goto handle_unusual;
         }
@@ -2714,8 +3054,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -2733,158 +3072,149 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.Metric)
   // repeated .io.prometheus.client.LabelPair label = 1;
-  for (int i = 0; i < this->label_size(); i++) {
+  for (unsigned int i = 0, n = this->label_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       1, this->label(i), output);
   }
 
   // optional .io.prometheus.client.Gauge gauge = 2;
-  if (has_gauge()) {
+  if (this->has_gauge()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      2, this->gauge(), output);
+      2, *this->gauge_, output);
   }
 
   // optional .io.prometheus.client.Counter counter = 3;
-  if (has_counter()) {
+  if (this->has_counter()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      3, this->counter(), output);
+      3, *this->counter_, output);
   }
 
   // optional .io.prometheus.client.Summary summary = 4;
-  if (has_summary()) {
+  if (this->has_summary()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      4, this->summary(), output);
+      4, *this->summary_, output);
   }
 
   // optional .io.prometheus.client.Untyped untyped = 5;
-  if (has_untyped()) {
+  if (this->has_untyped()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      5, this->untyped(), output);
+      5, *this->untyped_, output);
   }
 
   // optional int64 timestamp_ms = 6;
-  if (has_timestamp_ms()) {
+  if (this->timestamp_ms() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteInt64(6, this->timestamp_ms(), output);
   }
 
   // optional .io.prometheus.client.Histogram histogram = 7;
-  if (has_histogram()) {
+  if (this->has_histogram()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
-      7, this->histogram(), output);
+      7, *this->histogram_, output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.Metric)
 }
 
-::google::protobuf::uint8* Metric::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Metric::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.Metric)
   // repeated .io.prometheus.client.LabelPair label = 1;
-  for (int i = 0; i < this->label_size(); i++) {
+  for (unsigned int i = 0, n = this->label_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteMessageNoVirtualToArray(
-        1, this->label(i), target);
+      InternalWriteMessageNoVirtualToArray(
+        1, this->label(i), false, target);
   }
 
   // optional .io.prometheus.client.Gauge gauge = 2;
-  if (has_gauge()) {
+  if (this->has_gauge()) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteMessageNoVirtualToArray(
-        2, this->gauge(), target);
+      InternalWriteMessageNoVirtualToArray(
+        2, *this->gauge_, false, target);
   }
 
   // optional .io.prometheus.client.Counter counter = 3;
-  if (has_counter()) {
+  if (this->has_counter()) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteMessageNoVirtualToArray(
-        3, this->counter(), target);
+      InternalWriteMessageNoVirtualToArray(
+        3, *this->counter_, false, target);
   }
 
   // optional .io.prometheus.client.Summary summary = 4;
-  if (has_summary()) {
+  if (this->has_summary()) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteMessageNoVirtualToArray(
-        4, this->summary(), target);
+      InternalWriteMessageNoVirtualToArray(
+        4, *this->summary_, false, target);
   }
 
   // optional .io.prometheus.client.Untyped untyped = 5;
-  if (has_untyped()) {
+  if (this->has_untyped()) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteMessageNoVirtualToArray(
-        5, this->untyped(), target);
+      InternalWriteMessageNoVirtualToArray(
+        5, *this->untyped_, false, target);
   }
 
   // optional int64 timestamp_ms = 6;
-  if (has_timestamp_ms()) {
+  if (this->timestamp_ms() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(6, this->timestamp_ms(), target);
   }
 
   // optional .io.prometheus.client.Histogram histogram = 7;
-  if (has_histogram()) {
+  if (this->has_histogram()) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteMessageNoVirtualToArray(
-        7, this->histogram(), target);
+      InternalWriteMessageNoVirtualToArray(
+        7, *this->histogram_, false, target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.Metric)
   return target;
 }
 
 int Metric::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.Metric)
   int total_size = 0;
 
-  if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
-    // optional .io.prometheus.client.Gauge gauge = 2;
-    if (has_gauge()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->gauge());
-    }
-
-    // optional .io.prometheus.client.Counter counter = 3;
-    if (has_counter()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->counter());
-    }
-
-    // optional .io.prometheus.client.Summary summary = 4;
-    if (has_summary()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->summary());
-    }
-
-    // optional .io.prometheus.client.Untyped untyped = 5;
-    if (has_untyped()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->untyped());
-    }
-
-    // optional .io.prometheus.client.Histogram histogram = 7;
-    if (has_histogram()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          this->histogram());
-    }
-
-    // optional int64 timestamp_ms = 6;
-    if (has_timestamp_ms()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::Int64Size(
-          this->timestamp_ms());
-    }
-
+  // optional .io.prometheus.client.Gauge gauge = 2;
+  if (this->has_gauge()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        *this->gauge_);
   }
+
+  // optional .io.prometheus.client.Counter counter = 3;
+  if (this->has_counter()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        *this->counter_);
+  }
+
+  // optional .io.prometheus.client.Summary summary = 4;
+  if (this->has_summary()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        *this->summary_);
+  }
+
+  // optional .io.prometheus.client.Untyped untyped = 5;
+  if (this->has_untyped()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        *this->untyped_);
+  }
+
+  // optional .io.prometheus.client.Histogram histogram = 7;
+  if (this->has_histogram()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        *this->histogram_);
+  }
+
+  // optional int64 timestamp_ms = 6;
+  if (this->timestamp_ms() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int64Size(
+        this->timestamp_ms());
+  }
+
   // repeated .io.prometheus.client.LabelPair label = 1;
   total_size += 1 * this->label_size();
   for (int i = 0; i < this->label_size(); i++) {
@@ -2893,11 +3223,6 @@
         this->label(i));
   }
 
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
-  }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -2905,50 +3230,57 @@
 }
 
 void Metric::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const Metric* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const Metric*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.Metric)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const Metric* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const Metric>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.Metric)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.Metric)
     MergeFrom(*source);
   }
 }
 
 void Metric::MergeFrom(const Metric& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  label_.MergeFrom(from.label_);
-  if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
-    if (from.has_gauge()) {
-      mutable_gauge()->::io::prometheus::client::Gauge::MergeFrom(from.gauge());
-    }
-    if (from.has_counter()) {
-      mutable_counter()->::io::prometheus::client::Counter::MergeFrom(from.counter());
-    }
-    if (from.has_summary()) {
-      mutable_summary()->::io::prometheus::client::Summary::MergeFrom(from.summary());
-    }
-    if (from.has_untyped()) {
-      mutable_untyped()->::io::prometheus::client::Untyped::MergeFrom(from.untyped());
-    }
-    if (from.has_histogram()) {
-      mutable_histogram()->::io::prometheus::client::Histogram::MergeFrom(from.histogram());
-    }
-    if (from.has_timestamp_ms()) {
-      set_timestamp_ms(from.timestamp_ms());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.Metric)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  label_.MergeFrom(from.label_);
+  if (from.has_gauge()) {
+    mutable_gauge()->::io::prometheus::client::Gauge::MergeFrom(from.gauge());
+  }
+  if (from.has_counter()) {
+    mutable_counter()->::io::prometheus::client::Counter::MergeFrom(from.counter());
+  }
+  if (from.has_summary()) {
+    mutable_summary()->::io::prometheus::client::Summary::MergeFrom(from.summary());
+  }
+  if (from.has_untyped()) {
+    mutable_untyped()->::io::prometheus::client::Untyped::MergeFrom(from.untyped());
+  }
+  if (from.has_histogram()) {
+    mutable_histogram()->::io::prometheus::client::Histogram::MergeFrom(from.histogram());
+  }
+  if (from.timestamp_ms() != 0) {
+    set_timestamp_ms(from.timestamp_ms());
+  }
 }
 
 void Metric::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.Metric)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void Metric::CopyFrom(const Metric& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.Metric)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -2960,18 +3292,19 @@
 }
 
 void Metric::Swap(Metric* other) {
-  if (other != this) {
-    label_.Swap(&other->label_);
-    std::swap(gauge_, other->gauge_);
-    std::swap(counter_, other->counter_);
-    std::swap(summary_, other->summary_);
-    std::swap(untyped_, other->untyped_);
-    std::swap(histogram_, other->histogram_);
-    std::swap(timestamp_ms_, other->timestamp_ms_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Metric::InternalSwap(Metric* other) {
+  label_.UnsafeArenaSwap(&other->label_);
+  std::swap(gauge_, other->gauge_);
+  std::swap(counter_, other->counter_);
+  std::swap(summary_, other->summary_);
+  std::swap(untyped_, other->untyped_);
+  std::swap(histogram_, other->histogram_);
+  std::swap(timestamp_ms_, other->timestamp_ms_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata Metric::GetMetadata() const {
@@ -2982,39 +3315,279 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Metric
+
+// repeated .io.prometheus.client.LabelPair label = 1;
+int Metric::label_size() const {
+  return label_.size();
+}
+void Metric::clear_label() {
+  label_.Clear();
+}
+const ::io::prometheus::client::LabelPair& Metric::label(int index) const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Metric.label)
+  return label_.Get(index);
+}
+::io::prometheus::client::LabelPair* Metric::mutable_label(int index) {
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.label)
+  return label_.Mutable(index);
+}
+::io::prometheus::client::LabelPair* Metric::add_label() {
+  // @@protoc_insertion_point(field_add:io.prometheus.client.Metric.label)
+  return label_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair >*
+Metric::mutable_label() {
+  // @@protoc_insertion_point(field_mutable_list:io.prometheus.client.Metric.label)
+  return &label_;
+}
+const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair >&
+Metric::label() const {
+  // @@protoc_insertion_point(field_list:io.prometheus.client.Metric.label)
+  return label_;
+}
+
+// optional .io.prometheus.client.Gauge gauge = 2;
+bool Metric::has_gauge() const {
+  return !_is_default_instance_ && gauge_ != NULL;
+}
+void Metric::clear_gauge() {
+  if (GetArenaNoVirtual() == NULL && gauge_ != NULL) delete gauge_;
+  gauge_ = NULL;
+}
+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_;
+}
+::io::prometheus::client::Gauge* Metric::mutable_gauge() {
+  
+  if (gauge_ == NULL) {
+    gauge_ = new ::io::prometheus::client::Gauge;
+  }
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.gauge)
+  return gauge_;
+}
+::io::prometheus::client::Gauge* Metric::release_gauge() {
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.gauge)
+  
+  ::io::prometheus::client::Gauge* temp = gauge_;
+  gauge_ = NULL;
+  return temp;
+}
+void Metric::set_allocated_gauge(::io::prometheus::client::Gauge* gauge) {
+  delete gauge_;
+  gauge_ = gauge;
+  if (gauge) {
+    
+  } else {
+    
+  }
+  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.gauge)
+}
+
+// optional .io.prometheus.client.Counter counter = 3;
+bool Metric::has_counter() const {
+  return !_is_default_instance_ && counter_ != NULL;
+}
+void Metric::clear_counter() {
+  if (GetArenaNoVirtual() == NULL && counter_ != NULL) delete counter_;
+  counter_ = NULL;
+}
+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_;
+}
+::io::prometheus::client::Counter* Metric::mutable_counter() {
+  
+  if (counter_ == NULL) {
+    counter_ = new ::io::prometheus::client::Counter;
+  }
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.counter)
+  return counter_;
+}
+::io::prometheus::client::Counter* Metric::release_counter() {
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.counter)
+  
+  ::io::prometheus::client::Counter* temp = counter_;
+  counter_ = NULL;
+  return temp;
+}
+void Metric::set_allocated_counter(::io::prometheus::client::Counter* counter) {
+  delete counter_;
+  counter_ = counter;
+  if (counter) {
+    
+  } else {
+    
+  }
+  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.counter)
+}
+
+// optional .io.prometheus.client.Summary summary = 4;
+bool Metric::has_summary() const {
+  return !_is_default_instance_ && summary_ != NULL;
+}
+void Metric::clear_summary() {
+  if (GetArenaNoVirtual() == NULL && summary_ != NULL) delete summary_;
+  summary_ = NULL;
+}
+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_;
+}
+::io::prometheus::client::Summary* Metric::mutable_summary() {
+  
+  if (summary_ == NULL) {
+    summary_ = new ::io::prometheus::client::Summary;
+  }
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.summary)
+  return summary_;
+}
+::io::prometheus::client::Summary* Metric::release_summary() {
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.summary)
+  
+  ::io::prometheus::client::Summary* temp = summary_;
+  summary_ = NULL;
+  return temp;
+}
+void Metric::set_allocated_summary(::io::prometheus::client::Summary* summary) {
+  delete summary_;
+  summary_ = summary;
+  if (summary) {
+    
+  } else {
+    
+  }
+  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.summary)
+}
+
+// optional .io.prometheus.client.Untyped untyped = 5;
+bool Metric::has_untyped() const {
+  return !_is_default_instance_ && untyped_ != NULL;
+}
+void Metric::clear_untyped() {
+  if (GetArenaNoVirtual() == NULL && untyped_ != NULL) delete untyped_;
+  untyped_ = NULL;
+}
+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_;
+}
+::io::prometheus::client::Untyped* Metric::mutable_untyped() {
+  
+  if (untyped_ == NULL) {
+    untyped_ = new ::io::prometheus::client::Untyped;
+  }
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.untyped)
+  return untyped_;
+}
+::io::prometheus::client::Untyped* Metric::release_untyped() {
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.untyped)
+  
+  ::io::prometheus::client::Untyped* temp = untyped_;
+  untyped_ = NULL;
+  return temp;
+}
+void Metric::set_allocated_untyped(::io::prometheus::client::Untyped* untyped) {
+  delete untyped_;
+  untyped_ = untyped;
+  if (untyped) {
+    
+  } else {
+    
+  }
+  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.untyped)
+}
+
+// optional .io.prometheus.client.Histogram histogram = 7;
+bool Metric::has_histogram() const {
+  return !_is_default_instance_ && histogram_ != NULL;
+}
+void Metric::clear_histogram() {
+  if (GetArenaNoVirtual() == NULL && histogram_ != NULL) delete histogram_;
+  histogram_ = NULL;
+}
+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_;
+}
+::io::prometheus::client::Histogram* Metric::mutable_histogram() {
+  
+  if (histogram_ == NULL) {
+    histogram_ = new ::io::prometheus::client::Histogram;
+  }
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.Metric.histogram)
+  return histogram_;
+}
+::io::prometheus::client::Histogram* Metric::release_histogram() {
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.histogram)
+  
+  ::io::prometheus::client::Histogram* temp = histogram_;
+  histogram_ = NULL;
+  return temp;
+}
+void Metric::set_allocated_histogram(::io::prometheus::client::Histogram* histogram) {
+  delete histogram_;
+  histogram_ = histogram;
+  if (histogram) {
+    
+  } else {
+    
+  }
+  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.Metric.histogram)
+}
+
+// optional int64 timestamp_ms = 6;
+void Metric::clear_timestamp_ms() {
+  timestamp_ms_ = GOOGLE_LONGLONG(0);
+}
+ ::google::protobuf::int64 Metric::timestamp_ms() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.Metric.timestamp_ms)
+  return timestamp_ms_;
+}
+ void Metric::set_timestamp_ms(::google::protobuf::int64 value) {
+  
+  timestamp_ms_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.Metric.timestamp_ms)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
 
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int MetricFamily::kNameFieldNumber;
 const int MetricFamily::kHelpFieldNumber;
 const int MetricFamily::kTypeFieldNumber;
 const int MetricFamily::kMetricFieldNumber;
-#endif  // !_MSC_VER
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 MetricFamily::MetricFamily()
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
   SharedCtor();
   // @@protoc_insertion_point(constructor:io.prometheus.client.MetricFamily)
 }
 
 void MetricFamily::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
 }
 
 MetricFamily::MetricFamily(const MetricFamily& from)
-  : ::google::protobuf::Message() {
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
   SharedCtor();
   MergeFrom(from);
   // @@protoc_insertion_point(copy_constructor:io.prometheus.client.MetricFamily)
 }
 
 void MetricFamily::SharedCtor() {
+    _is_default_instance_ = false;
   ::google::protobuf::internal::GetEmptyString();
   _cached_size_ = 0;
-  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
-  help_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  help_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   type_ = 0;
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
 MetricFamily::~MetricFamily() {
@@ -3023,12 +3596,8 @@
 }
 
 void MetricFamily::SharedDtor() {
-  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete name_;
-  }
-  if (help_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete help_;
-  }
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  help_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (this != default_instance_) {
   }
 }
@@ -3050,32 +3619,25 @@
 
 MetricFamily* MetricFamily::default_instance_ = NULL;
 
-MetricFamily* MetricFamily::New() const {
-  return new MetricFamily;
+MetricFamily* MetricFamily::New(::google::protobuf::Arena* arena) const {
+  MetricFamily* n = new MetricFamily;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
 }
 
 void MetricFamily::Clear() {
-  if (_has_bits_[0 / 32] & 7) {
-    if (has_name()) {
-      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-        name_->clear();
-      }
-    }
-    if (has_help()) {
-      if (help_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-        help_->clear();
-      }
-    }
-    type_ = 0;
-  }
+// @@protoc_insertion_point(message_clear_start:io.prometheus.client.MetricFamily)
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  help_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  type_ = 0;
   metric_.Clear();
-  ::memset(_has_bits_, 0, sizeof(_has_bits_));
-  mutable_unknown_fields()->Clear();
 }
 
 bool MetricFamily::MergePartialFromCodedStream(
     ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
   ::google::protobuf::uint32 tag;
   // @@protoc_insertion_point(parse_start:io.prometheus.client.MetricFamily)
   for (;;) {
@@ -3088,10 +3650,10 @@
         if (tag == 10) {
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_name()));
-          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
             this->name().data(), this->name().length(),
-            ::google::protobuf::internal::WireFormat::PARSE,
-            "name");
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "io.prometheus.client.MetricFamily.name"));
         } else {
           goto handle_unusual;
         }
@@ -3105,10 +3667,10 @@
          parse_help:
           DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                 input, this->mutable_help()));
-          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
             this->help().data(), this->help().length(),
-            ::google::protobuf::internal::WireFormat::PARSE,
-            "help");
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "io.prometheus.client.MetricFamily.help"));
         } else {
           goto handle_unusual;
         }
@@ -3124,11 +3686,7 @@
           DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                    int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                  input, &value)));
-          if (::io::prometheus::client::MetricType_IsValid(value)) {
-            set_type(static_cast< ::io::prometheus::client::MetricType >(value));
-          } else {
-            mutable_unknown_fields()->AddVarint(3, value);
-          }
+          set_type(static_cast< ::io::prometheus::client::MetricType >(value));
         } else {
           goto handle_unusual;
         }
@@ -3140,12 +3698,15 @@
       case 4: {
         if (tag == 34) {
          parse_metric:
-          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+          DO_(input->IncrementRecursionDepth());
+         parse_loop_metric:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
                 input, add_metric()));
         } else {
           goto handle_unusual;
         }
-        if (input->ExpectTag(34)) goto parse_metric;
+        if (input->ExpectTag(34)) goto parse_loop_metric;
+        input->UnsafeDecrementRecursionDepth();
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -3157,8 +3718,7 @@
             ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
           goto success;
         }
-        DO_(::google::protobuf::internal::WireFormat::SkipField(
-              input, tag, mutable_unknown_fields()));
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
         break;
       }
     }
@@ -3176,115 +3736,106 @@
     ::google::protobuf::io::CodedOutputStream* output) const {
   // @@protoc_insertion_point(serialize_start:io.prometheus.client.MetricFamily)
   // optional string name = 1;
-  if (has_name()) {
-    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
       this->name().data(), this->name().length(),
-      ::google::protobuf::internal::WireFormat::SERIALIZE,
-      "name");
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "io.prometheus.client.MetricFamily.name");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
       1, this->name(), output);
   }
 
   // optional string help = 2;
-  if (has_help()) {
-    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+  if (this->help().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
       this->help().data(), this->help().length(),
-      ::google::protobuf::internal::WireFormat::SERIALIZE,
-      "help");
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "io.prometheus.client.MetricFamily.help");
     ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
       2, this->help(), output);
   }
 
   // optional .io.prometheus.client.MetricType type = 3;
-  if (has_type()) {
+  if (this->type() != 0) {
     ::google::protobuf::internal::WireFormatLite::WriteEnum(
       3, this->type(), output);
   }
 
   // repeated .io.prometheus.client.Metric metric = 4;
-  for (int i = 0; i < this->metric_size(); i++) {
+  for (unsigned int i = 0, n = this->metric_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
       4, this->metric(i), output);
   }
 
-  if (!unknown_fields().empty()) {
-    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
-        unknown_fields(), output);
-  }
   // @@protoc_insertion_point(serialize_end:io.prometheus.client.MetricFamily)
 }
 
-::google::protobuf::uint8* MetricFamily::SerializeWithCachedSizesToArray(
-    ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* MetricFamily::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
   // @@protoc_insertion_point(serialize_to_array_start:io.prometheus.client.MetricFamily)
   // optional string name = 1;
-  if (has_name()) {
-    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
       this->name().data(), this->name().length(),
-      ::google::protobuf::internal::WireFormat::SERIALIZE,
-      "name");
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "io.prometheus.client.MetricFamily.name");
     target =
       ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
         1, this->name(), target);
   }
 
   // optional string help = 2;
-  if (has_help()) {
-    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+  if (this->help().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
       this->help().data(), this->help().length(),
-      ::google::protobuf::internal::WireFormat::SERIALIZE,
-      "help");
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "io.prometheus.client.MetricFamily.help");
     target =
       ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
         2, this->help(), target);
   }
 
   // optional .io.prometheus.client.MetricType type = 3;
-  if (has_type()) {
+  if (this->type() != 0) {
     target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
       3, this->type(), target);
   }
 
   // repeated .io.prometheus.client.Metric metric = 4;
-  for (int i = 0; i < this->metric_size(); i++) {
+  for (unsigned int i = 0, n = this->metric_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
-      WriteMessageNoVirtualToArray(
-        4, this->metric(i), target);
+      InternalWriteMessageNoVirtualToArray(
+        4, this->metric(i), false, target);
   }
 
-  if (!unknown_fields().empty()) {
-    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
-        unknown_fields(), target);
-  }
   // @@protoc_insertion_point(serialize_to_array_end:io.prometheus.client.MetricFamily)
   return target;
 }
 
 int MetricFamily::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:io.prometheus.client.MetricFamily)
   int total_size = 0;
 
-  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    // optional string name = 1;
-    if (has_name()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::StringSize(
-          this->name());
-    }
-
-    // optional string help = 2;
-    if (has_help()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::StringSize(
-          this->help());
-    }
-
-    // optional .io.prometheus.client.MetricType type = 3;
-    if (has_type()) {
-      total_size += 1 +
-        ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
-    }
-
+  // optional string name = 1;
+  if (this->name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->name());
   }
+
+  // optional string help = 2;
+  if (this->help().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->help());
+  }
+
+  // optional .io.prometheus.client.MetricType type = 3;
+  if (this->type() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
+  }
+
   // repeated .io.prometheus.client.Metric metric = 4;
   total_size += 1 * this->metric_size();
   for (int i = 0; i < this->metric_size(); i++) {
@@ -3293,11 +3844,6 @@
         this->metric(i));
   }
 
-  if (!unknown_fields().empty()) {
-    total_size +=
-      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
-        unknown_fields());
-  }
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = total_size;
   GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -3305,41 +3851,50 @@
 }
 
 void MetricFamily::MergeFrom(const ::google::protobuf::Message& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  const MetricFamily* source =
-    ::google::protobuf::internal::dynamic_cast_if_available<const MetricFamily*>(
-      &from);
+// @@protoc_insertion_point(generalized_merge_from_start:io.prometheus.client.MetricFamily)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+  }
+  const MetricFamily* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const MetricFamily>(
+          &from);
   if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:io.prometheus.client.MetricFamily)
     ::google::protobuf::internal::ReflectionOps::Merge(from, this);
   } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:io.prometheus.client.MetricFamily)
     MergeFrom(*source);
   }
 }
 
 void MetricFamily::MergeFrom(const MetricFamily& from) {
-  GOOGLE_CHECK_NE(&from, this);
-  metric_.MergeFrom(from.metric_);
-  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
-    if (from.has_name()) {
-      set_name(from.name());
-    }
-    if (from.has_help()) {
-      set_help(from.help());
-    }
-    if (from.has_type()) {
-      set_type(from.type());
-    }
+// @@protoc_insertion_point(class_specific_merge_from_start:io.prometheus.client.MetricFamily)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) {
+    ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
   }
-  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+  metric_.MergeFrom(from.metric_);
+  if (from.name().size() > 0) {
+
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+  if (from.help().size() > 0) {
+
+    help_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.help_);
+  }
+  if (from.type() != 0) {
+    set_type(from.type());
+  }
 }
 
 void MetricFamily::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:io.prometheus.client.MetricFamily)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
 }
 
 void MetricFamily::CopyFrom(const MetricFamily& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:io.prometheus.client.MetricFamily)
   if (&from == this) return;
   Clear();
   MergeFrom(from);
@@ -3351,15 +3906,16 @@
 }
 
 void MetricFamily::Swap(MetricFamily* other) {
-  if (other != this) {
-    std::swap(name_, other->name_);
-    std::swap(help_, other->help_);
-    std::swap(type_, other->type_);
-    metric_.Swap(&other->metric_);
-    std::swap(_has_bits_[0], other->_has_bits_[0]);
-    _unknown_fields_.Swap(&other->_unknown_fields_);
-    std::swap(_cached_size_, other->_cached_size_);
-  }
+  if (other == this) return;
+  InternalSwap(other);
+}
+void MetricFamily::InternalSwap(MetricFamily* other) {
+  name_.Swap(&other->name_);
+  help_.Swap(&other->help_);
+  std::swap(type_, other->type_);
+  metric_.UnsafeArenaSwap(&other->metric_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
 }
 
 ::google::protobuf::Metadata MetricFamily::GetMetadata() const {
@@ -3370,6 +3926,142 @@
   return metadata;
 }
 
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// MetricFamily
+
+// optional string name = 1;
+void MetricFamily::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& MetricFamily::name() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.MetricFamily.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MetricFamily::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:io.prometheus.client.MetricFamily.name)
+}
+ void MetricFamily::set_name(const char* value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:io.prometheus.client.MetricFamily.name)
+}
+ void MetricFamily::set_name(const char* value, size_t size) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:io.prometheus.client.MetricFamily.name)
+}
+ ::std::string* MetricFamily::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.MetricFamily.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* MetricFamily::release_name() {
+  // @@protoc_insertion_point(field_release:io.prometheus.client.MetricFamily.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MetricFamily::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.MetricFamily.name)
+}
+
+// optional string help = 2;
+void MetricFamily::clear_help() {
+  help_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& MetricFamily::help() const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.MetricFamily.help)
+  return help_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MetricFamily::set_help(const ::std::string& value) {
+  
+  help_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:io.prometheus.client.MetricFamily.help)
+}
+ void MetricFamily::set_help(const char* value) {
+  
+  help_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:io.prometheus.client.MetricFamily.help)
+}
+ void MetricFamily::set_help(const char* value, size_t size) {
+  
+  help_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:io.prometheus.client.MetricFamily.help)
+}
+ ::std::string* MetricFamily::mutable_help() {
+  
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.MetricFamily.help)
+  return help_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* MetricFamily::release_help() {
+  // @@protoc_insertion_point(field_release:io.prometheus.client.MetricFamily.help)
+  
+  return help_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void MetricFamily::set_allocated_help(::std::string* help) {
+  if (help != NULL) {
+    
+  } else {
+    
+  }
+  help_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), help);
+  // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.MetricFamily.help)
+}
+
+// optional .io.prometheus.client.MetricType type = 3;
+void MetricFamily::clear_type() {
+  type_ = 0;
+}
+ ::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_);
+}
+ void MetricFamily::set_type(::io::prometheus::client::MetricType value) {
+  
+  type_ = value;
+  // @@protoc_insertion_point(field_set:io.prometheus.client.MetricFamily.type)
+}
+
+// repeated .io.prometheus.client.Metric metric = 4;
+int MetricFamily::metric_size() const {
+  return metric_.size();
+}
+void MetricFamily::clear_metric() {
+  metric_.Clear();
+}
+const ::io::prometheus::client::Metric& MetricFamily::metric(int index) const {
+  // @@protoc_insertion_point(field_get:io.prometheus.client.MetricFamily.metric)
+  return metric_.Get(index);
+}
+::io::prometheus::client::Metric* MetricFamily::mutable_metric(int index) {
+  // @@protoc_insertion_point(field_mutable:io.prometheus.client.MetricFamily.metric)
+  return metric_.Mutable(index);
+}
+::io::prometheus::client::Metric* MetricFamily::add_metric() {
+  // @@protoc_insertion_point(field_add:io.prometheus.client.MetricFamily.metric)
+  return metric_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric >*
+MetricFamily::mutable_metric() {
+  // @@protoc_insertion_point(field_mutable_list:io.prometheus.client.MetricFamily.metric)
+  return &metric_;
+}
+const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric >&
+MetricFamily::metric() const {
+  // @@protoc_insertion_point(field_list:io.prometheus.client.MetricFamily.metric)
+  return metric_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // @@protoc_insertion_point(namespace_scope)
 
diff --git a/cpp/metrics.pb.h b/cpp/metrics.pb.h
index 206ba37..44859f4 100644
--- a/cpp/metrics.pb.h
+++ b/cpp/metrics.pb.h
@@ -8,18 +8,21 @@
 
 #include <google/protobuf/stubs/common.h>
 
-#if GOOGLE_PROTOBUF_VERSION < 2006000
+#if GOOGLE_PROTOBUF_VERSION < 3000000
 #error This file was generated by a newer version of protoc which is
 #error incompatible with your Protocol Buffer headers.  Please update
 #error your headers.
 #endif
-#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
 #error This file was generated by an older version of protoc which is
 #error incompatible with your Protocol Buffer headers.  Please
 #error regenerate this file with a newer version of protoc.
 #endif
 
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
 #include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
 #include <google/protobuf/message.h>
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/extension_set.h>
@@ -32,27 +35,29 @@
 namespace client {
 
 // Internal implementation detail -- do not call these.
-void  protobuf_AddDesc_metrics_2eproto();
+void protobuf_AddDesc_metrics_2eproto();
 void protobuf_AssignDesc_metrics_2eproto();
 void protobuf_ShutdownFile_metrics_2eproto();
 
-class LabelPair;
-class Gauge;
+class Bucket;
 class Counter;
+class Gauge;
+class Histogram;
+class LabelPair;
+class Metric;
+class MetricFamily;
 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
+  HISTOGRAM = 4,
+  MetricType_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
+  MetricType_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
 };
 bool MetricType_IsValid(int value);
 const MetricType MetricType_MIN = COUNTER;
@@ -71,7 +76,7 @@
 }
 // ===================================================================
 
-class LabelPair : public ::google::protobuf::Message {
+class LabelPair : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.LabelPair) */ {
  public:
   LabelPair();
   virtual ~LabelPair();
@@ -83,14 +88,6 @@
     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();
 
@@ -98,7 +95,9 @@
 
   // implements Message ----------------------------------------------
 
-  LabelPair* New() const;
+  inline LabelPair* New() const { return New(NULL); }
+
+  LabelPair* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const LabelPair& from);
@@ -111,13 +110,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(LabelPair* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -125,42 +137,35 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  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);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  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 string value = 2;
-  inline bool has_value() const;
-  inline void clear_value();
+  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);
+  const ::std::string& value() const;
+  void set_value(const ::std::string& value);
+  void set_value(const char* value);
+  void set_value(const char* value, size_t size);
+  ::std::string* mutable_value();
+  ::std::string* release_value();
+  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];
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  ::google::protobuf::internal::ArenaStringPtr value_;
   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();
@@ -170,7 +175,7 @@
 };
 // -------------------------------------------------------------------
 
-class Gauge : public ::google::protobuf::Message {
+class Gauge : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.Gauge) */ {
  public:
   Gauge();
   virtual ~Gauge();
@@ -182,14 +187,6 @@
     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();
 
@@ -197,7 +194,9 @@
 
   // implements Message ----------------------------------------------
 
-  Gauge* New() const;
+  inline Gauge* New() const { return New(NULL); }
+
+  Gauge* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Gauge& from);
@@ -210,13 +209,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(Gauge* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -224,22 +236,18 @@
   // accessors -------------------------------------------------------
 
   // optional double value = 1;
-  inline bool has_value() const;
-  inline void clear_value();
+  void clear_value();
   static const int kValueFieldNumber = 1;
-  inline double value() const;
-  inline void set_value(double value);
+  double value() const;
+  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_;
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
   double value_;
+  mutable int _cached_size_;
   friend void  protobuf_AddDesc_metrics_2eproto();
   friend void protobuf_AssignDesc_metrics_2eproto();
   friend void protobuf_ShutdownFile_metrics_2eproto();
@@ -249,7 +257,7 @@
 };
 // -------------------------------------------------------------------
 
-class Counter : public ::google::protobuf::Message {
+class Counter : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.Counter) */ {
  public:
   Counter();
   virtual ~Counter();
@@ -261,14 +269,6 @@
     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();
 
@@ -276,7 +276,9 @@
 
   // implements Message ----------------------------------------------
 
-  Counter* New() const;
+  inline Counter* New() const { return New(NULL); }
+
+  Counter* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Counter& from);
@@ -289,13 +291,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(Counter* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -303,22 +318,18 @@
   // accessors -------------------------------------------------------
 
   // optional double value = 1;
-  inline bool has_value() const;
-  inline void clear_value();
+  void clear_value();
   static const int kValueFieldNumber = 1;
-  inline double value() const;
-  inline void set_value(double value);
+  double value() const;
+  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_;
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
   double value_;
+  mutable int _cached_size_;
   friend void  protobuf_AddDesc_metrics_2eproto();
   friend void protobuf_AssignDesc_metrics_2eproto();
   friend void protobuf_ShutdownFile_metrics_2eproto();
@@ -328,7 +339,7 @@
 };
 // -------------------------------------------------------------------
 
-class Quantile : public ::google::protobuf::Message {
+class Quantile : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.Quantile) */ {
  public:
   Quantile();
   virtual ~Quantile();
@@ -340,14 +351,6 @@
     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();
 
@@ -355,7 +358,9 @@
 
   // implements Message ----------------------------------------------
 
-  Quantile* New() const;
+  inline Quantile* New() const { return New(NULL); }
+
+  Quantile* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Quantile& from);
@@ -368,13 +373,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(Quantile* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -382,32 +400,25 @@
   // accessors -------------------------------------------------------
 
   // optional double quantile = 1;
-  inline bool has_quantile() const;
-  inline void clear_quantile();
+  void clear_quantile();
   static const int kQuantileFieldNumber = 1;
-  inline double quantile() const;
-  inline void set_quantile(double value);
+  double quantile() const;
+  void set_quantile(double value);
 
   // optional double value = 2;
-  inline bool has_value() const;
-  inline void clear_value();
+  void clear_value();
   static const int kValueFieldNumber = 2;
-  inline double value() const;
-  inline void set_value(double value);
+  double value() const;
+  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_;
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
   double quantile_;
   double value_;
+  mutable int _cached_size_;
   friend void  protobuf_AddDesc_metrics_2eproto();
   friend void protobuf_AssignDesc_metrics_2eproto();
   friend void protobuf_ShutdownFile_metrics_2eproto();
@@ -417,7 +428,7 @@
 };
 // -------------------------------------------------------------------
 
-class Summary : public ::google::protobuf::Message {
+class Summary : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.Summary) */ {
  public:
   Summary();
   virtual ~Summary();
@@ -429,14 +440,6 @@
     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();
 
@@ -444,7 +447,9 @@
 
   // implements Message ----------------------------------------------
 
-  Summary* New() const;
+  inline Summary* New() const { return New(NULL); }
+
+  Summary* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Summary& from);
@@ -457,13 +462,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(Summary* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -471,45 +489,38 @@
   // accessors -------------------------------------------------------
 
   // optional uint64 sample_count = 1;
-  inline bool has_sample_count() const;
-  inline void clear_sample_count();
+  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);
+  ::google::protobuf::uint64 sample_count() const;
+  void set_sample_count(::google::protobuf::uint64 value);
 
   // optional double sample_sum = 2;
-  inline bool has_sample_sum() const;
-  inline void clear_sample_sum();
+  void clear_sample_sum();
   static const int kSampleSumFieldNumber = 2;
-  inline double sample_sum() const;
-  inline void set_sample_sum(double value);
+  double sample_sum() const;
+  void set_sample_sum(double value);
 
   // repeated .io.prometheus.client.Quantile quantile = 3;
-  inline int quantile_size() const;
-  inline void clear_quantile();
+  int quantile_size() const;
+  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 >*
+  const ::io::prometheus::client::Quantile& quantile(int index) const;
+  ::io::prometheus::client::Quantile* mutable_quantile(int index);
+  ::io::prometheus::client::Quantile* add_quantile();
+  ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile >*
       mutable_quantile();
+  const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile >&
+      quantile() const;
 
   // @@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::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
   ::google::protobuf::uint64 sample_count_;
   double sample_sum_;
   ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile > quantile_;
+  mutable int _cached_size_;
   friend void  protobuf_AddDesc_metrics_2eproto();
   friend void protobuf_AssignDesc_metrics_2eproto();
   friend void protobuf_ShutdownFile_metrics_2eproto();
@@ -519,7 +530,7 @@
 };
 // -------------------------------------------------------------------
 
-class Untyped : public ::google::protobuf::Message {
+class Untyped : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.Untyped) */ {
  public:
   Untyped();
   virtual ~Untyped();
@@ -531,14 +542,6 @@
     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();
 
@@ -546,7 +549,9 @@
 
   // implements Message ----------------------------------------------
 
-  Untyped* New() const;
+  inline Untyped* New() const { return New(NULL); }
+
+  Untyped* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Untyped& from);
@@ -559,13 +564,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(Untyped* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -573,22 +591,18 @@
   // accessors -------------------------------------------------------
 
   // optional double value = 1;
-  inline bool has_value() const;
-  inline void clear_value();
+  void clear_value();
   static const int kValueFieldNumber = 1;
-  inline double value() const;
-  inline void set_value(double value);
+  double value() const;
+  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_;
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
   double value_;
+  mutable int _cached_size_;
   friend void  protobuf_AddDesc_metrics_2eproto();
   friend void protobuf_AssignDesc_metrics_2eproto();
   friend void protobuf_ShutdownFile_metrics_2eproto();
@@ -598,7 +612,7 @@
 };
 // -------------------------------------------------------------------
 
-class Histogram : public ::google::protobuf::Message {
+class Histogram : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.Histogram) */ {
  public:
   Histogram();
   virtual ~Histogram();
@@ -610,14 +624,6 @@
     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();
 
@@ -625,7 +631,9 @@
 
   // implements Message ----------------------------------------------
 
-  Histogram* New() const;
+  inline Histogram* New() const { return New(NULL); }
+
+  Histogram* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Histogram& from);
@@ -638,13 +646,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(Histogram* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -652,45 +673,38 @@
   // accessors -------------------------------------------------------
 
   // optional uint64 sample_count = 1;
-  inline bool has_sample_count() const;
-  inline void clear_sample_count();
+  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);
+  ::google::protobuf::uint64 sample_count() const;
+  void set_sample_count(::google::protobuf::uint64 value);
 
   // optional double sample_sum = 2;
-  inline bool has_sample_sum() const;
-  inline void clear_sample_sum();
+  void clear_sample_sum();
   static const int kSampleSumFieldNumber = 2;
-  inline double sample_sum() const;
-  inline void set_sample_sum(double value);
+  double sample_sum() const;
+  void set_sample_sum(double value);
 
   // repeated .io.prometheus.client.Bucket bucket = 3;
-  inline int bucket_size() const;
-  inline void clear_bucket();
+  int bucket_size() const;
+  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 >*
+  const ::io::prometheus::client::Bucket& bucket(int index) const;
+  ::io::prometheus::client::Bucket* mutable_bucket(int index);
+  ::io::prometheus::client::Bucket* add_bucket();
+  ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket >*
       mutable_bucket();
+  const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket >&
+      bucket() const;
 
   // @@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::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
   ::google::protobuf::uint64 sample_count_;
   double sample_sum_;
   ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket > bucket_;
+  mutable int _cached_size_;
   friend void  protobuf_AddDesc_metrics_2eproto();
   friend void protobuf_AssignDesc_metrics_2eproto();
   friend void protobuf_ShutdownFile_metrics_2eproto();
@@ -700,7 +714,7 @@
 };
 // -------------------------------------------------------------------
 
-class Bucket : public ::google::protobuf::Message {
+class Bucket : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.Bucket) */ {
  public:
   Bucket();
   virtual ~Bucket();
@@ -712,14 +726,6 @@
     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();
 
@@ -727,7 +733,9 @@
 
   // implements Message ----------------------------------------------
 
-  Bucket* New() const;
+  inline Bucket* New() const { return New(NULL); }
+
+  Bucket* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Bucket& from);
@@ -740,13 +748,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(Bucket* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -754,32 +775,25 @@
   // accessors -------------------------------------------------------
 
   // optional uint64 cumulative_count = 1;
-  inline bool has_cumulative_count() const;
-  inline void clear_cumulative_count();
+  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);
+  ::google::protobuf::uint64 cumulative_count() const;
+  void set_cumulative_count(::google::protobuf::uint64 value);
 
   // optional double upper_bound = 2;
-  inline bool has_upper_bound() const;
-  inline void clear_upper_bound();
+  void clear_upper_bound();
   static const int kUpperBoundFieldNumber = 2;
-  inline double upper_bound() const;
-  inline void set_upper_bound(double value);
+  double upper_bound() const;
+  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::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
   ::google::protobuf::uint64 cumulative_count_;
   double upper_bound_;
+  mutable int _cached_size_;
   friend void  protobuf_AddDesc_metrics_2eproto();
   friend void protobuf_AssignDesc_metrics_2eproto();
   friend void protobuf_ShutdownFile_metrics_2eproto();
@@ -789,7 +803,7 @@
 };
 // -------------------------------------------------------------------
 
-class Metric : public ::google::protobuf::Message {
+class Metric : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.Metric) */ {
  public:
   Metric();
   virtual ~Metric();
@@ -801,14 +815,6 @@
     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();
 
@@ -816,7 +822,9 @@
 
   // implements Message ----------------------------------------------
 
-  Metric* New() const;
+  inline Metric* New() const { return New(NULL); }
+
+  Metric* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const Metric& from);
@@ -829,13 +837,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(Metric* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -843,88 +864,73 @@
   // accessors -------------------------------------------------------
 
   // repeated .io.prometheus.client.LabelPair label = 1;
-  inline int label_size() const;
-  inline void clear_label();
+  int label_size() const;
+  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 >*
+  const ::io::prometheus::client::LabelPair& label(int index) const;
+  ::io::prometheus::client::LabelPair* mutable_label(int index);
+  ::io::prometheus::client::LabelPair* add_label();
+  ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair >*
       mutable_label();
+  const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair >&
+      label() const;
 
   // optional .io.prometheus.client.Gauge gauge = 2;
-  inline bool has_gauge() const;
-  inline void clear_gauge();
+  bool has_gauge() const;
+  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);
+  const ::io::prometheus::client::Gauge& gauge() const;
+  ::io::prometheus::client::Gauge* mutable_gauge();
+  ::io::prometheus::client::Gauge* release_gauge();
+  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();
+  bool has_counter() const;
+  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);
+  const ::io::prometheus::client::Counter& counter() const;
+  ::io::prometheus::client::Counter* mutable_counter();
+  ::io::prometheus::client::Counter* release_counter();
+  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();
+  bool has_summary() const;
+  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);
+  const ::io::prometheus::client::Summary& summary() const;
+  ::io::prometheus::client::Summary* mutable_summary();
+  ::io::prometheus::client::Summary* release_summary();
+  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();
+  bool has_untyped() const;
+  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);
+  const ::io::prometheus::client::Untyped& untyped() const;
+  ::io::prometheus::client::Untyped* mutable_untyped();
+  ::io::prometheus::client::Untyped* release_untyped();
+  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();
+  bool has_histogram() const;
+  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);
+  const ::io::prometheus::client::Histogram& histogram() const;
+  ::io::prometheus::client::Histogram* mutable_histogram();
+  ::io::prometheus::client::Histogram* release_histogram();
+  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();
+  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);
+  ::google::protobuf::int64 timestamp_ms() const;
+  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::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
   ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair > label_;
   ::io::prometheus::client::Gauge* gauge_;
   ::io::prometheus::client::Counter* counter_;
@@ -932,6 +938,7 @@
   ::io::prometheus::client::Untyped* untyped_;
   ::io::prometheus::client::Histogram* histogram_;
   ::google::protobuf::int64 timestamp_ms_;
+  mutable int _cached_size_;
   friend void  protobuf_AddDesc_metrics_2eproto();
   friend void protobuf_AssignDesc_metrics_2eproto();
   friend void protobuf_ShutdownFile_metrics_2eproto();
@@ -941,7 +948,7 @@
 };
 // -------------------------------------------------------------------
 
-class MetricFamily : public ::google::protobuf::Message {
+class MetricFamily : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:io.prometheus.client.MetricFamily) */ {
  public:
   MetricFamily();
   virtual ~MetricFamily();
@@ -953,14 +960,6 @@
     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();
 
@@ -968,7 +967,9 @@
 
   // implements Message ----------------------------------------------
 
-  MetricFamily* New() const;
+  inline MetricFamily* New() const { return New(NULL); }
+
+  MetricFamily* New(::google::protobuf::Arena* arena) const;
   void CopyFrom(const ::google::protobuf::Message& from);
   void MergeFrom(const ::google::protobuf::Message& from);
   void CopyFrom(const MetricFamily& from);
@@ -981,13 +982,26 @@
       ::google::protobuf::io::CodedInputStream* input);
   void SerializeWithCachedSizes(
       ::google::protobuf::io::CodedOutputStream* output) const;
-  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
   int GetCachedSize() const { return _cached_size_; }
   private:
   void SharedCtor();
   void SharedDtor();
   void SetCachedSize(int size) const;
+  void InternalSwap(MetricFamily* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
   public:
+
   ::google::protobuf::Metadata GetMetadata() const;
 
   // nested types ----------------------------------------------------
@@ -995,65 +1009,55 @@
   // accessors -------------------------------------------------------
 
   // optional string name = 1;
-  inline bool has_name() const;
-  inline void clear_name();
+  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);
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  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 string help = 2;
-  inline bool has_help() const;
-  inline void clear_help();
+  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);
+  const ::std::string& help() const;
+  void set_help(const ::std::string& value);
+  void set_help(const char* value);
+  void set_help(const char* value, size_t size);
+  ::std::string* mutable_help();
+  ::std::string* release_help();
+  void set_allocated_help(::std::string* help);
 
   // optional .io.prometheus.client.MetricType type = 3;
-  inline bool has_type() const;
-  inline void clear_type();
+  void clear_type();
   static const int kTypeFieldNumber = 3;
-  inline ::io::prometheus::client::MetricType type() const;
-  inline void set_type(::io::prometheus::client::MetricType value);
+  ::io::prometheus::client::MetricType type() const;
+  void set_type(::io::prometheus::client::MetricType value);
 
   // repeated .io.prometheus.client.Metric metric = 4;
-  inline int metric_size() const;
-  inline void clear_metric();
+  int metric_size() const;
+  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 >*
+  const ::io::prometheus::client::Metric& metric(int index) const;
+  ::io::prometheus::client::Metric* mutable_metric(int index);
+  ::io::prometheus::client::Metric* add_metric();
+  ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric >*
       mutable_metric();
+  const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric >&
+      metric() const;
 
   // @@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::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  ::google::protobuf::internal::ArenaStringPtr help_;
   ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric > metric_;
   int type_;
+  mutable int _cached_size_;
   friend void  protobuf_AddDesc_metrics_2eproto();
   friend void protobuf_AssignDesc_metrics_2eproto();
   friend void protobuf_ShutdownFile_metrics_2eproto();
@@ -1066,157 +1070,94 @@
 
 // ===================================================================
 
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
 // 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();
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline const ::std::string& LabelPair::name() const {
   // @@protoc_insertion_point(field_get:io.prometheus.client.LabelPair.name)
-  return *name_;
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 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);
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), 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);
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(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);
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(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_;
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 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;
-  }
+  // @@protoc_insertion_point(field_release:io.prometheus.client.LabelPair.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void LabelPair::set_allocated_name(::std::string* name) {
-  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete name_;
-  }
-  if (name) {
-    set_has_name();
-    name_ = name;
+  if (name != NULL) {
+    
   } else {
-    clear_has_name();
-    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    
   }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
   // @@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();
+  value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline const ::std::string& LabelPair::value() const {
   // @@protoc_insertion_point(field_get:io.prometheus.client.LabelPair.value)
-  return *value_;
+  return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 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);
+  
+  value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), 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);
+  
+  value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(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);
+  
+  value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(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_;
+  return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 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;
-  }
+  // @@protoc_insertion_point(field_release:io.prometheus.client.LabelPair.value)
+  
+  return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void LabelPair::set_allocated_value(::std::string* value) {
-  if (value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete value_;
-  }
-  if (value) {
-    set_has_value();
-    value_ = value;
+  if (value != NULL) {
+    
   } else {
-    clear_has_value();
-    value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    
   }
+  value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
   // @@protoc_insertion_point(field_set_allocated:io.prometheus.client.LabelPair.value)
 }
 
@@ -1225,25 +1166,15 @@
 // 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)
 }
@@ -1253,25 +1184,15 @@
 // 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)
 }
@@ -1281,49 +1202,29 @@
 // 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)
 }
@@ -1333,49 +1234,29 @@
 // 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)
 }
@@ -1399,41 +1280,31 @@
   // @@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_;
 }
+inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Quantile >&
+Summary::quantile() const {
+  // @@protoc_insertion_point(field_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)
 }
@@ -1443,49 +1314,29 @@
 // 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)
 }
@@ -1509,65 +1360,45 @@
   // @@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_;
 }
+inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Bucket >&
+Histogram::bucket() const {
+  // @@protoc_insertion_point(field_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)
 }
@@ -1595,43 +1426,40 @@
   // @@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_;
 }
+inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::LabelPair >&
+Metric::label() const {
+  // @@protoc_insertion_point(field_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;
+  return !_is_default_instance_ && gauge_ != NULL;
 }
 inline void Metric::clear_gauge() {
-  if (gauge_ != NULL) gauge_->::io::prometheus::client::Gauge::Clear();
-  clear_has_gauge();
+  if (GetArenaNoVirtual() == NULL && gauge_ != NULL) delete gauge_;
+  gauge_ = NULL;
 }
 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;
+  
+  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();
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.gauge)
+  
   ::io::prometheus::client::Gauge* temp = gauge_;
   gauge_ = NULL;
   return temp;
@@ -1640,39 +1468,36 @@
   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;
+  return !_is_default_instance_ && counter_ != NULL;
 }
 inline void Metric::clear_counter() {
-  if (counter_ != NULL) counter_->::io::prometheus::client::Counter::Clear();
-  clear_has_counter();
+  if (GetArenaNoVirtual() == NULL && counter_ != NULL) delete counter_;
+  counter_ = NULL;
 }
 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;
+  
+  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();
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.counter)
+  
   ::io::prometheus::client::Counter* temp = counter_;
   counter_ = NULL;
   return temp;
@@ -1681,39 +1506,36 @@
   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;
+  return !_is_default_instance_ && summary_ != NULL;
 }
 inline void Metric::clear_summary() {
-  if (summary_ != NULL) summary_->::io::prometheus::client::Summary::Clear();
-  clear_has_summary();
+  if (GetArenaNoVirtual() == NULL && summary_ != NULL) delete summary_;
+  summary_ = NULL;
 }
 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;
+  
+  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();
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.summary)
+  
   ::io::prometheus::client::Summary* temp = summary_;
   summary_ = NULL;
   return temp;
@@ -1722,39 +1544,36 @@
   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;
+  return !_is_default_instance_ && untyped_ != NULL;
 }
 inline void Metric::clear_untyped() {
-  if (untyped_ != NULL) untyped_->::io::prometheus::client::Untyped::Clear();
-  clear_has_untyped();
+  if (GetArenaNoVirtual() == NULL && untyped_ != NULL) delete untyped_;
+  untyped_ = NULL;
 }
 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;
+  
+  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();
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.untyped)
+  
   ::io::prometheus::client::Untyped* temp = untyped_;
   untyped_ = NULL;
   return temp;
@@ -1763,39 +1582,36 @@
   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;
+  return !_is_default_instance_ && histogram_ != NULL;
 }
 inline void Metric::clear_histogram() {
-  if (histogram_ != NULL) histogram_->::io::prometheus::client::Histogram::Clear();
-  clear_has_histogram();
+  if (GetArenaNoVirtual() == NULL && histogram_ != NULL) delete histogram_;
+  histogram_ = NULL;
 }
 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;
+  
+  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();
+  // @@protoc_insertion_point(field_release:io.prometheus.client.Metric.histogram)
+  
   ::io::prometheus::client::Histogram* temp = histogram_;
   histogram_ = NULL;
   return temp;
@@ -1804,33 +1620,23 @@
   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)
 }
@@ -1840,178 +1646,103 @@
 // 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();
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline const ::std::string& MetricFamily::name() const {
   // @@protoc_insertion_point(field_get:io.prometheus.client.MetricFamily.name)
-  return *name_;
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 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);
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), 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);
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(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);
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(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_;
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 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;
-  }
+  // @@protoc_insertion_point(field_release:io.prometheus.client.MetricFamily.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void MetricFamily::set_allocated_name(::std::string* name) {
-  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete name_;
-  }
-  if (name) {
-    set_has_name();
-    name_ = name;
+  if (name != NULL) {
+    
   } else {
-    clear_has_name();
-    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    
   }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
   // @@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();
+  help_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline const ::std::string& MetricFamily::help() const {
   // @@protoc_insertion_point(field_get:io.prometheus.client.MetricFamily.help)
-  return *help_;
+  return help_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 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);
+  
+  help_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), 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);
+  
+  help_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(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);
+  
+  help_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(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_;
+  return help_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 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;
-  }
+  // @@protoc_insertion_point(field_release:io.prometheus.client.MetricFamily.help)
+  
+  return help_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
 }
 inline void MetricFamily::set_allocated_help(::std::string* help) {
-  if (help_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
-    delete help_;
-  }
-  if (help) {
-    set_has_help();
-    help_ = help;
+  if (help != NULL) {
+    
   } else {
-    clear_has_help();
-    help_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    
   }
+  help_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), help);
   // @@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)
 }
@@ -2035,16 +1766,35 @@
   // @@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_;
 }
+inline const ::google::protobuf::RepeatedPtrField< ::io::prometheus::client::Metric >&
+MetricFamily::metric() const {
+  // @@protoc_insertion_point(field_list:io.prometheus.client.MetricFamily.metric)
+  return metric_;
+}
+
+#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
 
 
 // @@protoc_insertion_point(namespace_scope)
@@ -2063,8 +1813,8 @@
   return ::io::prometheus::client::MetricType_descriptor();
 }
 
-}  // namespace google
 }  // namespace protobuf
+}  // namespace google
 #endif  // SWIG
 
 // @@protoc_insertion_point(global_scope)
diff --git a/go/metrics.pb.go b/go/metrics.pb.go
index b065f86..575a0cf 100644
--- a/go/metrics.pb.go
+++ b/go/metrics.pb.go
@@ -23,12 +23,20 @@
 package io_prometheus_client
 
 import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
 import math "math"
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
+var _ = fmt.Errorf
 var _ = math.Inf
 
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
 type MetricType int32
 
 const (
@@ -54,127 +62,59 @@
 	"HISTOGRAM": 4,
 }
 
-func (x MetricType) Enum() *MetricType {
-	p := new(MetricType)
-	*p = x
-	return p
-}
 func (x MetricType) String() string {
 	return proto.EnumName(MetricType_name, int32(x))
 }
-func (x *MetricType) UnmarshalJSON(data []byte) error {
-	value, err := proto.UnmarshalJSONEnum(MetricType_value, data, "MetricType")
-	if err != nil {
-		return err
-	}
-	*x = MetricType(value)
-	return nil
-}
+func (MetricType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
 
 type LabelPair struct {
-	Name             *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
-	Value            *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
-	XXX_unrecognized []byte  `json:"-"`
+	Name  string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
 }
 
-func (m *LabelPair) Reset()         { *m = LabelPair{} }
-func (m *LabelPair) String() string { return proto.CompactTextString(m) }
-func (*LabelPair) ProtoMessage()    {}
-
-func (m *LabelPair) GetName() string {
-	if m != nil && m.Name != nil {
-		return *m.Name
-	}
-	return ""
-}
-
-func (m *LabelPair) GetValue() string {
-	if m != nil && m.Value != nil {
-		return *m.Value
-	}
-	return ""
-}
+func (m *LabelPair) Reset()                    { *m = LabelPair{} }
+func (m *LabelPair) String() string            { return proto.CompactTextString(m) }
+func (*LabelPair) ProtoMessage()               {}
+func (*LabelPair) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
 
 type Gauge struct {
-	Value            *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
-	XXX_unrecognized []byte   `json:"-"`
+	Value float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
 }
 
-func (m *Gauge) Reset()         { *m = Gauge{} }
-func (m *Gauge) String() string { return proto.CompactTextString(m) }
-func (*Gauge) ProtoMessage()    {}
-
-func (m *Gauge) GetValue() float64 {
-	if m != nil && m.Value != nil {
-		return *m.Value
-	}
-	return 0
-}
+func (m *Gauge) Reset()                    { *m = Gauge{} }
+func (m *Gauge) String() string            { return proto.CompactTextString(m) }
+func (*Gauge) ProtoMessage()               {}
+func (*Gauge) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
 
 type Counter struct {
-	Value            *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
-	XXX_unrecognized []byte   `json:"-"`
+	Value float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
 }
 
-func (m *Counter) Reset()         { *m = Counter{} }
-func (m *Counter) String() string { return proto.CompactTextString(m) }
-func (*Counter) ProtoMessage()    {}
-
-func (m *Counter) GetValue() float64 {
-	if m != nil && m.Value != nil {
-		return *m.Value
-	}
-	return 0
-}
+func (m *Counter) Reset()                    { *m = Counter{} }
+func (m *Counter) String() string            { return proto.CompactTextString(m) }
+func (*Counter) ProtoMessage()               {}
+func (*Counter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
 
 type Quantile struct {
-	Quantile         *float64 `protobuf:"fixed64,1,opt,name=quantile" json:"quantile,omitempty"`
-	Value            *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"`
-	XXX_unrecognized []byte   `json:"-"`
+	Quantile float64 `protobuf:"fixed64,1,opt,name=quantile" json:"quantile,omitempty"`
+	Value    float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"`
 }
 
-func (m *Quantile) Reset()         { *m = Quantile{} }
-func (m *Quantile) String() string { return proto.CompactTextString(m) }
-func (*Quantile) ProtoMessage()    {}
-
-func (m *Quantile) GetQuantile() float64 {
-	if m != nil && m.Quantile != nil {
-		return *m.Quantile
-	}
-	return 0
-}
-
-func (m *Quantile) GetValue() float64 {
-	if m != nil && m.Value != nil {
-		return *m.Value
-	}
-	return 0
-}
+func (m *Quantile) Reset()                    { *m = Quantile{} }
+func (m *Quantile) String() string            { return proto.CompactTextString(m) }
+func (*Quantile) ProtoMessage()               {}
+func (*Quantile) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
 
 type Summary struct {
-	SampleCount      *uint64     `protobuf:"varint,1,opt,name=sample_count" json:"sample_count,omitempty"`
-	SampleSum        *float64    `protobuf:"fixed64,2,opt,name=sample_sum" json:"sample_sum,omitempty"`
-	Quantile         []*Quantile `protobuf:"bytes,3,rep,name=quantile" json:"quantile,omitempty"`
-	XXX_unrecognized []byte      `json:"-"`
+	SampleCount uint64      `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"`
+	SampleSum   float64     `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"`
+	Quantile    []*Quantile `protobuf:"bytes,3,rep,name=quantile" json:"quantile,omitempty"`
 }
 
-func (m *Summary) Reset()         { *m = Summary{} }
-func (m *Summary) String() string { return proto.CompactTextString(m) }
-func (*Summary) ProtoMessage()    {}
-
-func (m *Summary) GetSampleCount() uint64 {
-	if m != nil && m.SampleCount != nil {
-		return *m.SampleCount
-	}
-	return 0
-}
-
-func (m *Summary) GetSampleSum() float64 {
-	if m != nil && m.SampleSum != nil {
-		return *m.SampleSum
-	}
-	return 0
-}
+func (m *Summary) Reset()                    { *m = Summary{} }
+func (m *Summary) String() string            { return proto.CompactTextString(m) }
+func (*Summary) ProtoMessage()               {}
+func (*Summary) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
 
 func (m *Summary) GetQuantile() []*Quantile {
 	if m != nil {
@@ -184,45 +124,24 @@
 }
 
 type Untyped struct {
-	Value            *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
-	XXX_unrecognized []byte   `json:"-"`
+	Value float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
 }
 
-func (m *Untyped) Reset()         { *m = Untyped{} }
-func (m *Untyped) String() string { return proto.CompactTextString(m) }
-func (*Untyped) ProtoMessage()    {}
-
-func (m *Untyped) GetValue() float64 {
-	if m != nil && m.Value != nil {
-		return *m.Value
-	}
-	return 0
-}
+func (m *Untyped) Reset()                    { *m = Untyped{} }
+func (m *Untyped) String() string            { return proto.CompactTextString(m) }
+func (*Untyped) ProtoMessage()               {}
+func (*Untyped) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
 
 type Histogram struct {
-	SampleCount      *uint64   `protobuf:"varint,1,opt,name=sample_count" json:"sample_count,omitempty"`
-	SampleSum        *float64  `protobuf:"fixed64,2,opt,name=sample_sum" json:"sample_sum,omitempty"`
-	Bucket           []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,omitempty"`
-	XXX_unrecognized []byte    `json:"-"`
+	SampleCount uint64    `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"`
+	SampleSum   float64   `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"`
+	Bucket      []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,omitempty"`
 }
 
-func (m *Histogram) Reset()         { *m = Histogram{} }
-func (m *Histogram) String() string { return proto.CompactTextString(m) }
-func (*Histogram) ProtoMessage()    {}
-
-func (m *Histogram) GetSampleCount() uint64 {
-	if m != nil && m.SampleCount != nil {
-		return *m.SampleCount
-	}
-	return 0
-}
-
-func (m *Histogram) GetSampleSum() float64 {
-	if m != nil && m.SampleSum != nil {
-		return *m.SampleSum
-	}
-	return 0
-}
+func (m *Histogram) Reset()                    { *m = Histogram{} }
+func (m *Histogram) String() string            { return proto.CompactTextString(m) }
+func (*Histogram) ProtoMessage()               {}
+func (*Histogram) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
 
 func (m *Histogram) GetBucket() []*Bucket {
 	if m != nil {
@@ -232,43 +151,29 @@
 }
 
 type Bucket struct {
-	CumulativeCount  *uint64  `protobuf:"varint,1,opt,name=cumulative_count" json:"cumulative_count,omitempty"`
-	UpperBound       *float64 `protobuf:"fixed64,2,opt,name=upper_bound" json:"upper_bound,omitempty"`
-	XXX_unrecognized []byte   `json:"-"`
+	CumulativeCount uint64  `protobuf:"varint,1,opt,name=cumulative_count,json=cumulativeCount" json:"cumulative_count,omitempty"`
+	UpperBound      float64 `protobuf:"fixed64,2,opt,name=upper_bound,json=upperBound" json:"upper_bound,omitempty"`
 }
 
-func (m *Bucket) Reset()         { *m = Bucket{} }
-func (m *Bucket) String() string { return proto.CompactTextString(m) }
-func (*Bucket) ProtoMessage()    {}
-
-func (m *Bucket) GetCumulativeCount() uint64 {
-	if m != nil && m.CumulativeCount != nil {
-		return *m.CumulativeCount
-	}
-	return 0
-}
-
-func (m *Bucket) GetUpperBound() float64 {
-	if m != nil && m.UpperBound != nil {
-		return *m.UpperBound
-	}
-	return 0
-}
+func (m *Bucket) Reset()                    { *m = Bucket{} }
+func (m *Bucket) String() string            { return proto.CompactTextString(m) }
+func (*Bucket) ProtoMessage()               {}
+func (*Bucket) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
 
 type Metric struct {
-	Label            []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"`
-	Gauge            *Gauge       `protobuf:"bytes,2,opt,name=gauge" json:"gauge,omitempty"`
-	Counter          *Counter     `protobuf:"bytes,3,opt,name=counter" json:"counter,omitempty"`
-	Summary          *Summary     `protobuf:"bytes,4,opt,name=summary" json:"summary,omitempty"`
-	Untyped          *Untyped     `protobuf:"bytes,5,opt,name=untyped" json:"untyped,omitempty"`
-	Histogram        *Histogram   `protobuf:"bytes,7,opt,name=histogram" json:"histogram,omitempty"`
-	TimestampMs      *int64       `protobuf:"varint,6,opt,name=timestamp_ms" json:"timestamp_ms,omitempty"`
-	XXX_unrecognized []byte       `json:"-"`
+	Label       []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"`
+	Gauge       *Gauge       `protobuf:"bytes,2,opt,name=gauge" json:"gauge,omitempty"`
+	Counter     *Counter     `protobuf:"bytes,3,opt,name=counter" json:"counter,omitempty"`
+	Summary     *Summary     `protobuf:"bytes,4,opt,name=summary" json:"summary,omitempty"`
+	Untyped     *Untyped     `protobuf:"bytes,5,opt,name=untyped" json:"untyped,omitempty"`
+	Histogram   *Histogram   `protobuf:"bytes,7,opt,name=histogram" json:"histogram,omitempty"`
+	TimestampMs int64        `protobuf:"varint,6,opt,name=timestamp_ms,json=timestampMs" json:"timestamp_ms,omitempty"`
 }
 
-func (m *Metric) Reset()         { *m = Metric{} }
-func (m *Metric) String() string { return proto.CompactTextString(m) }
-func (*Metric) ProtoMessage()    {}
+func (m *Metric) Reset()                    { *m = Metric{} }
+func (m *Metric) String() string            { return proto.CompactTextString(m) }
+func (*Metric) ProtoMessage()               {}
+func (*Metric) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
 
 func (m *Metric) GetLabel() []*LabelPair {
 	if m != nil {
@@ -312,45 +217,17 @@
 	return nil
 }
 
-func (m *Metric) GetTimestampMs() int64 {
-	if m != nil && m.TimestampMs != nil {
-		return *m.TimestampMs
-	}
-	return 0
-}
-
 type MetricFamily struct {
-	Name             *string     `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
-	Help             *string     `protobuf:"bytes,2,opt,name=help" json:"help,omitempty"`
-	Type             *MetricType `protobuf:"varint,3,opt,name=type,enum=io.prometheus.client.MetricType" json:"type,omitempty"`
-	Metric           []*Metric   `protobuf:"bytes,4,rep,name=metric" json:"metric,omitempty"`
-	XXX_unrecognized []byte      `json:"-"`
+	Name   string     `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	Help   string     `protobuf:"bytes,2,opt,name=help" json:"help,omitempty"`
+	Type   MetricType `protobuf:"varint,3,opt,name=type,enum=io.prometheus.client.MetricType" json:"type,omitempty"`
+	Metric []*Metric  `protobuf:"bytes,4,rep,name=metric" json:"metric,omitempty"`
 }
 
-func (m *MetricFamily) Reset()         { *m = MetricFamily{} }
-func (m *MetricFamily) String() string { return proto.CompactTextString(m) }
-func (*MetricFamily) ProtoMessage()    {}
-
-func (m *MetricFamily) GetName() string {
-	if m != nil && m.Name != nil {
-		return *m.Name
-	}
-	return ""
-}
-
-func (m *MetricFamily) GetHelp() string {
-	if m != nil && m.Help != nil {
-		return *m.Help
-	}
-	return ""
-}
-
-func (m *MetricFamily) GetType() MetricType {
-	if m != nil && m.Type != nil {
-		return *m.Type
-	}
-	return MetricType_COUNTER
-}
+func (m *MetricFamily) Reset()                    { *m = MetricFamily{} }
+func (m *MetricFamily) String() string            { return proto.CompactTextString(m) }
+func (*MetricFamily) ProtoMessage()               {}
+func (*MetricFamily) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
 
 func (m *MetricFamily) GetMetric() []*Metric {
 	if m != nil {
@@ -360,5 +237,57 @@
 }
 
 func init() {
+	proto.RegisterType((*LabelPair)(nil), "io.prometheus.client.LabelPair")
+	proto.RegisterType((*Gauge)(nil), "io.prometheus.client.Gauge")
+	proto.RegisterType((*Counter)(nil), "io.prometheus.client.Counter")
+	proto.RegisterType((*Quantile)(nil), "io.prometheus.client.Quantile")
+	proto.RegisterType((*Summary)(nil), "io.prometheus.client.Summary")
+	proto.RegisterType((*Untyped)(nil), "io.prometheus.client.Untyped")
+	proto.RegisterType((*Histogram)(nil), "io.prometheus.client.Histogram")
+	proto.RegisterType((*Bucket)(nil), "io.prometheus.client.Bucket")
+	proto.RegisterType((*Metric)(nil), "io.prometheus.client.Metric")
+	proto.RegisterType((*MetricFamily)(nil), "io.prometheus.client.MetricFamily")
 	proto.RegisterEnum("io.prometheus.client.MetricType", MetricType_name, MetricType_value)
 }
+
+func init() { proto.RegisterFile("metrics.proto", fileDescriptor0) }
+
+var fileDescriptor0 = []byte{
+	// 562 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x54, 0xcf, 0x6f, 0xd3, 0x30,
+	0x18, 0x25, 0xeb, 0xaf, 0xe5, 0xcb, 0x06, 0x91, 0x35, 0xa1, 0x08, 0x18, 0x2d, 0x3d, 0x0d, 0x0e,
+	0x95, 0x28, 0x4c, 0x48, 0x08, 0x0e, 0x2d, 0x94, 0x82, 0x44, 0xd8, 0x70, 0xdb, 0xc3, 0x4e, 0x95,
+	0x9b, 0x59, 0x6d, 0x44, 0xdc, 0x86, 0xc4, 0x9e, 0xd4, 0x33, 0x07, 0xfe, 0x0f, 0xfe, 0x51, 0xf0,
+	0xaf, 0xb4, 0x9b, 0x94, 0xf6, 0xc4, 0xcd, 0x7e, 0x79, 0xef, 0xf3, 0xcb, 0xe7, 0xe7, 0x0f, 0x8e,
+	0x19, 0xe5, 0x59, 0x1c, 0xe5, 0x9d, 0x34, 0x5b, 0xf1, 0x15, 0x3a, 0x89, 0x57, 0x6a, 0x25, 0xc1,
+	0x05, 0x15, 0x79, 0x27, 0x4a, 0x62, 0xba, 0xe4, 0xed, 0x73, 0x70, 0xbf, 0x92, 0x19, 0x4d, 0x2e,
+	0x49, 0x9c, 0x21, 0x04, 0xd5, 0x25, 0x61, 0x34, 0x70, 0x5a, 0xce, 0x99, 0x8b, 0xf5, 0x1a, 0x9d,
+	0x40, 0xed, 0x86, 0x24, 0x82, 0x06, 0x07, 0x1a, 0x34, 0x9b, 0xf6, 0x29, 0xd4, 0x86, 0x44, 0xcc,
+	0x6f, 0x7d, 0x56, 0x1a, 0xa7, 0xf8, 0xdc, 0x84, 0xc6, 0x87, 0x95, 0x58, 0x72, 0x9a, 0xed, 0x20,
+	0xbc, 0x83, 0xc3, 0xef, 0x82, 0x2c, 0x79, 0x9c, 0x50, 0xf4, 0x08, 0x0e, 0x7f, 0xda, 0xb5, 0x25,
+	0x6d, 0xf6, 0x77, 0x4f, 0xdf, 0xa8, 0x7f, 0x3b, 0xd0, 0x18, 0x09, 0xc6, 0x48, 0xb6, 0x46, 0xcf,
+	0xe0, 0x28, 0x27, 0x2c, 0x4d, 0xe8, 0x34, 0x52, 0x27, 0xea, 0x0a, 0x55, 0xec, 0x19, 0x4c, 0x9b,
+	0x40, 0xa7, 0x00, 0x96, 0x92, 0x0b, 0x66, 0x2b, 0xb9, 0x06, 0x91, 0x55, 0xd0, 0xdb, 0x5b, 0xe7,
+	0x57, 0x5a, 0x95, 0x33, 0xaf, 0xfb, 0xb4, 0x53, 0xd6, 0xab, 0x4e, 0xe1, 0x78, 0xeb, 0x4f, 0xfd,
+	0xe8, 0x64, 0xc9, 0xd7, 0x29, 0xbd, 0xde, 0xf1, 0xa3, 0xbf, 0x1c, 0x70, 0x3f, 0xc7, 0x39, 0x5f,
+	0xcd, 0x33, 0xc2, 0xfe, 0x83, 0xd9, 0xd7, 0x50, 0x9f, 0x89, 0xe8, 0x07, 0xe5, 0xd6, 0xea, 0x93,
+	0x72, 0xab, 0x7d, 0xcd, 0xc1, 0x96, 0xdb, 0x1e, 0x43, 0xdd, 0x20, 0xe8, 0x39, 0xf8, 0x91, 0x60,
+	0x22, 0x21, 0x3c, 0xbe, 0xb9, 0xeb, 0xe2, 0xc1, 0x16, 0x37, 0x4e, 0x9a, 0xe0, 0x89, 0x34, 0xa5,
+	0xd9, 0x74, 0x26, 0xb7, 0xd7, 0xd6, 0x0a, 0x68, 0xa8, 0xaf, 0x90, 0xf6, 0xdf, 0x03, 0xa8, 0x87,
+	0x3a, 0x63, 0xe8, 0x1c, 0x6a, 0x89, 0x8a, 0x91, 0xac, 0xa5, 0x5c, 0x35, 0xcb, 0x5d, 0x6d, 0x92,
+	0x86, 0x0d, 0x1b, 0xbd, 0x84, 0xda, 0x5c, 0xc5, 0x48, 0x17, 0xf7, 0xba, 0x8f, 0xcb, 0x65, 0x3a,
+	0x69, 0xd8, 0x30, 0xd1, 0x1b, 0x68, 0x44, 0x26, 0x5a, 0xb2, 0x03, 0x4a, 0x74, 0x5a, 0x2e, 0xb2,
+	0xf9, 0xc3, 0x05, 0x5b, 0x09, 0x73, 0x93, 0x99, 0xa0, 0xba, 0x4f, 0x68, 0x83, 0x85, 0x0b, 0xb6,
+	0x12, 0x0a, 0x73, 0xc7, 0x41, 0x6d, 0x9f, 0xd0, 0x06, 0x01, 0x17, 0x6c, 0xf4, 0x1e, 0xdc, 0x45,
+	0x71, 0xf5, 0x41, 0x43, 0x4b, 0x77, 0x34, 0x66, 0x93, 0x10, 0xbc, 0x55, 0xa8, 0xb0, 0xf0, 0x98,
+	0xd1, 0x9c, 0xcb, 0xcb, 0x9f, 0xb2, 0x3c, 0xa8, 0xcb, 0x0a, 0x15, 0xec, 0x6d, 0xb0, 0x30, 0x6f,
+	0xff, 0x71, 0xe0, 0xc8, 0xdc, 0xc0, 0x27, 0xc2, 0xe2, 0x64, 0x5d, 0xfa, 0x82, 0x25, 0xb6, 0xa0,
+	0x49, 0x6a, 0x1f, 0xb0, 0x5e, 0xcb, 0x18, 0x55, 0x95, 0x47, 0xdd, 0xc2, 0xfb, 0xdd, 0x56, 0xb9,
+	0x2b, 0x53, 0x79, 0x2c, 0x79, 0x58, 0xb3, 0x55, 0xf8, 0xcc, 0x4c, 0x91, 0x1d, 0xdc, 0x13, 0x3e,
+	0xa3, 0xc3, 0x96, 0xfb, 0x22, 0x04, 0xd8, 0x56, 0x42, 0x9e, 0x1c, 0x0d, 0x17, 0x93, 0x6f, 0xe3,
+	0x01, 0xf6, 0xef, 0x21, 0x57, 0x8e, 0x91, 0xde, 0x64, 0x38, 0xf0, 0x1d, 0x85, 0x8f, 0x26, 0x61,
+	0xd8, 0xc3, 0x57, 0xfe, 0x81, 0xda, 0x48, 0xca, 0xd5, 0xe5, 0xe0, 0xa3, 0x5f, 0x41, 0xc7, 0xf2,
+	0x05, 0x7d, 0x19, 0x8d, 0x2f, 0x86, 0xb8, 0x17, 0xfa, 0xd5, 0xfe, 0x43, 0x28, 0x9d, 0x64, 0xb3,
+	0xba, 0x1e, 0x73, 0xaf, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0xc1, 0xa0, 0x86, 0x95, 0xf7, 0x04,
+	0x00, 0x00,
+}
diff --git a/metrics.proto b/metrics.proto
index 0b84af9..2992b70 100644
--- a/metrics.proto
+++ b/metrics.proto
@@ -11,14 +11,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-syntax = "proto2";
+syntax = "proto3";
 
 package io.prometheus.client;
 option java_package = "io.prometheus.client";
 
 message LabelPair {
-  optional string name  = 1;
-  optional string value = 2;
+  string name  = 1;
+  string value = 2;
 }
 
 enum MetricType {
@@ -30,52 +30,52 @@
 }
 
 message Gauge {
-  optional double value = 1;
+  double value = 1;
 }
 
 message Counter {
-  optional double value = 1;
+  double value = 1;
 }
 
 message Quantile {
-  optional double quantile = 1;
-  optional double value    = 2;
+  double quantile = 1;
+  double value    = 2;
 }
 
 message Summary {
-  optional uint64   sample_count = 1;
-  optional double   sample_sum   = 2;
-  repeated Quantile quantile     = 3;
+  uint64 sample_count         = 1;
+  double sample_sum           = 2;
+  repeated Quantile quantile  = 3;
 }
 
 message Untyped {
-  optional double value = 1;
+  double value = 1;
 }
 
 message Histogram {
-  optional uint64 sample_count = 1;
-  optional double sample_sum   = 2;
-  repeated Bucket bucket       = 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional.
+  uint64 sample_count    = 1;
+  double sample_sum      = 2;
+  repeated Bucket bucket = 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional.
 }
 
 message Bucket {
-  optional uint64 cumulative_count = 1; // Cumulative in increasing order.
-  optional double upper_bound = 2;      // Inclusive.
+  uint64 cumulative_count = 1; // Cumulative in increasing order.
+  double upper_bound      = 2;      // Inclusive.
 }
 
 message Metric {
-  repeated LabelPair label        = 1;
-  optional Gauge     gauge        = 2;
-  optional Counter   counter      = 3;
-  optional Summary   summary      = 4;
-  optional Untyped   untyped      = 5;
-  optional Histogram histogram    = 7;
-  optional int64     timestamp_ms = 6;
+  repeated LabelPair label = 1;
+  Gauge     gauge          = 2;
+  Counter   counter        = 3;
+  Summary   summary        = 4;
+  Untyped   untyped        = 5;
+  Histogram histogram      = 7;
+  int64     timestamp_ms   = 6;
 }
 
 message MetricFamily {
-  optional string     name   = 1;
-  optional string     help   = 2;
-  optional MetricType type   = 3;
-  repeated Metric     metric = 4;
+  string     name        = 1;
+  string     help        = 2;
+  MetricType type        = 3;
+  repeated Metric metric = 4;
 }
diff --git a/pom.xml b/pom.xml
index 4d34c90..4fd5f16 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,7 +44,7 @@
       <dependency>
         <groupId>com.google.protobuf</groupId>
         <artifactId>protobuf-java</artifactId>
-        <version>2.5.0</version>
+        <version>3.0.0</version>
       </dependency>
     </dependencies>
 
diff --git a/python/prometheus/client/model/metrics_pb2.py b/python/prometheus/client/model/metrics_pb2.py
index 8c239ac..cba8936 100644
--- a/python/prometheus/client/model/metrics_pb2.py
+++ b/python/prometheus/client/model/metrics_pb2.py
@@ -19,7 +19,8 @@
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='metrics.proto',
   package='io.prometheus.client',
-  serialized_pb=_b('\n\rmetrics.proto\x12\x14io.prometheus.client\"(\n\tLabelPair\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\x16\n\x05Gauge\x12\r\n\x05value\x18\x01 \x01(\x01\"\x18\n\x07\x43ounter\x12\r\n\x05value\x18\x01 \x01(\x01\"+\n\x08Quantile\x12\x10\n\x08quantile\x18\x01 \x01(\x01\x12\r\n\x05value\x18\x02 \x01(\x01\"e\n\x07Summary\x12\x14\n\x0csample_count\x18\x01 \x01(\x04\x12\x12\n\nsample_sum\x18\x02 \x01(\x01\x12\x30\n\x08quantile\x18\x03 \x03(\x0b\x32\x1e.io.prometheus.client.Quantile\"\x18\n\x07Untyped\x12\r\n\x05value\x18\x01 \x01(\x01\"c\n\tHistogram\x12\x14\n\x0csample_count\x18\x01 \x01(\x04\x12\x12\n\nsample_sum\x18\x02 \x01(\x01\x12,\n\x06\x62ucket\x18\x03 \x03(\x0b\x32\x1c.io.prometheus.client.Bucket\"7\n\x06\x42ucket\x12\x18\n\x10\x63umulative_count\x18\x01 \x01(\x04\x12\x13\n\x0bupper_bound\x18\x02 \x01(\x01\"\xbe\x02\n\x06Metric\x12.\n\x05label\x18\x01 \x03(\x0b\x32\x1f.io.prometheus.client.LabelPair\x12*\n\x05gauge\x18\x02 \x01(\x0b\x32\x1b.io.prometheus.client.Gauge\x12.\n\x07\x63ounter\x18\x03 \x01(\x0b\x32\x1d.io.prometheus.client.Counter\x12.\n\x07summary\x18\x04 \x01(\x0b\x32\x1d.io.prometheus.client.Summary\x12.\n\x07untyped\x18\x05 \x01(\x0b\x32\x1d.io.prometheus.client.Untyped\x12\x32\n\thistogram\x18\x07 \x01(\x0b\x32\x1f.io.prometheus.client.Histogram\x12\x14\n\x0ctimestamp_ms\x18\x06 \x01(\x03\"\x88\x01\n\x0cMetricFamily\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04help\x18\x02 \x01(\t\x12.\n\x04type\x18\x03 \x01(\x0e\x32 .io.prometheus.client.MetricType\x12,\n\x06metric\x18\x04 \x03(\x0b\x32\x1c.io.prometheus.client.Metric*M\n\nMetricType\x12\x0b\n\x07\x43OUNTER\x10\x00\x12\t\n\x05GAUGE\x10\x01\x12\x0b\n\x07SUMMARY\x10\x02\x12\x0b\n\x07UNTYPED\x10\x03\x12\r\n\tHISTOGRAM\x10\x04\x42\x16\n\x14io.prometheus.client')
+  syntax='proto3',
+  serialized_pb=_b('\n\rmetrics.proto\x12\x14io.prometheus.client\"(\n\tLabelPair\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\x16\n\x05Gauge\x12\r\n\x05value\x18\x01 \x01(\x01\"\x18\n\x07\x43ounter\x12\r\n\x05value\x18\x01 \x01(\x01\"+\n\x08Quantile\x12\x10\n\x08quantile\x18\x01 \x01(\x01\x12\r\n\x05value\x18\x02 \x01(\x01\"e\n\x07Summary\x12\x14\n\x0csample_count\x18\x01 \x01(\x04\x12\x12\n\nsample_sum\x18\x02 \x01(\x01\x12\x30\n\x08quantile\x18\x03 \x03(\x0b\x32\x1e.io.prometheus.client.Quantile\"\x18\n\x07Untyped\x12\r\n\x05value\x18\x01 \x01(\x01\"c\n\tHistogram\x12\x14\n\x0csample_count\x18\x01 \x01(\x04\x12\x12\n\nsample_sum\x18\x02 \x01(\x01\x12,\n\x06\x62ucket\x18\x03 \x03(\x0b\x32\x1c.io.prometheus.client.Bucket\"7\n\x06\x42ucket\x12\x18\n\x10\x63umulative_count\x18\x01 \x01(\x04\x12\x13\n\x0bupper_bound\x18\x02 \x01(\x01\"\xbe\x02\n\x06Metric\x12.\n\x05label\x18\x01 \x03(\x0b\x32\x1f.io.prometheus.client.LabelPair\x12*\n\x05gauge\x18\x02 \x01(\x0b\x32\x1b.io.prometheus.client.Gauge\x12.\n\x07\x63ounter\x18\x03 \x01(\x0b\x32\x1d.io.prometheus.client.Counter\x12.\n\x07summary\x18\x04 \x01(\x0b\x32\x1d.io.prometheus.client.Summary\x12.\n\x07untyped\x18\x05 \x01(\x0b\x32\x1d.io.prometheus.client.Untyped\x12\x32\n\thistogram\x18\x07 \x01(\x0b\x32\x1f.io.prometheus.client.Histogram\x12\x14\n\x0ctimestamp_ms\x18\x06 \x01(\x03\"\x88\x01\n\x0cMetricFamily\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04help\x18\x02 \x01(\t\x12.\n\x04type\x18\x03 \x01(\x0e\x32 .io.prometheus.client.MetricType\x12,\n\x06metric\x18\x04 \x03(\x0b\x32\x1c.io.prometheus.client.Metric*M\n\nMetricType\x12\x0b\n\x07\x43OUNTER\x10\x00\x12\t\n\x05GAUGE\x10\x01\x12\x0b\n\x07SUMMARY\x10\x02\x12\x0b\n\x07UNTYPED\x10\x03\x12\r\n\tHISTOGRAM\x10\x04\x42\x16\n\x14io.prometheus.clientb\x06proto3')
 )
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -95,6 +96,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
@@ -113,7 +115,7 @@
     _descriptor.FieldDescriptor(
       name='value', full_name='io.prometheus.client.Gauge.value', index=0,
       number=1, type=1, cpp_type=5, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -125,6 +127,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
@@ -143,7 +146,7 @@
     _descriptor.FieldDescriptor(
       name='value', full_name='io.prometheus.client.Counter.value', index=0,
       number=1, type=1, cpp_type=5, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -155,6 +158,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
@@ -173,14 +177,14 @@
     _descriptor.FieldDescriptor(
       name='quantile', full_name='io.prometheus.client.Quantile.quantile', index=0,
       number=1, type=1, cpp_type=5, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
       name='value', full_name='io.prometheus.client.Quantile.value', index=1,
       number=2, type=1, cpp_type=5, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -192,6 +196,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
@@ -217,7 +222,7 @@
     _descriptor.FieldDescriptor(
       name='sample_sum', full_name='io.prometheus.client.Summary.sample_sum', index=1,
       number=2, type=1, cpp_type=5, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -236,6 +241,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
@@ -254,7 +260,7 @@
     _descriptor.FieldDescriptor(
       name='value', full_name='io.prometheus.client.Untyped.value', index=0,
       number=1, type=1, cpp_type=5, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -266,6 +272,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
@@ -291,7 +298,7 @@
     _descriptor.FieldDescriptor(
       name='sample_sum', full_name='io.prometheus.client.Histogram.sample_sum', index=1,
       number=2, type=1, cpp_type=5, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -310,6 +317,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
@@ -335,7 +343,7 @@
     _descriptor.FieldDescriptor(
       name='upper_bound', full_name='io.prometheus.client.Bucket.upper_bound', index=1,
       number=2, type=1, cpp_type=5, label=1,
-      has_default_value=False, default_value=0,
+      has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
@@ -347,6 +355,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
@@ -419,6 +428,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
@@ -470,6 +480,7 @@
   ],
   options=None,
   is_extendable=False,
+  syntax='proto3',
   extension_ranges=[],
   oneofs=[
   ],
diff --git a/src/main/java/io/prometheus/client/Metrics.java b/src/main/java/io/prometheus/client/Metrics.java
index fb6218e..d1356fe 100644
--- a/src/main/java/io/prometheus/client/Metrics.java
+++ b/src/main/java/io/prometheus/client/Metrics.java
@@ -6,7 +6,13 @@
 public final class Metrics {
   private Metrics() {}
   public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
       com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
   }
   /**
    * Protobuf enum {@code io.prometheus.client.MetricType}
@@ -16,23 +22,24 @@
     /**
      * <code>COUNTER = 0;</code>
      */
-    COUNTER(0, 0),
+    COUNTER(0),
     /**
      * <code>GAUGE = 1;</code>
      */
-    GAUGE(1, 1),
+    GAUGE(1),
     /**
      * <code>SUMMARY = 2;</code>
      */
-    SUMMARY(2, 2),
+    SUMMARY(2),
     /**
      * <code>UNTYPED = 3;</code>
      */
-    UNTYPED(3, 3),
+    UNTYPED(3),
     /**
      * <code>HISTOGRAM = 4;</code>
      */
-    HISTOGRAM(4, 4),
+    HISTOGRAM(4),
+    UNRECOGNIZED(-1),
     ;
 
     /**
@@ -57,9 +64,23 @@
     public static final int HISTOGRAM_VALUE = 4;
 
 
-    public final int getNumber() { return value; }
+    public final int getNumber() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
 
+    /**
+     * @deprecated Use {@link #forNumber(int)} instead.
+     */
+    @java.lang.Deprecated
     public static MetricType valueOf(int value) {
+      return forNumber(value);
+    }
+
+    public static MetricType forNumber(int value) {
       switch (value) {
         case 0: return COUNTER;
         case 1: return GAUGE;
@@ -74,17 +95,17 @@
         internalGetValueMap() {
       return internalValueMap;
     }
-    private static com.google.protobuf.Internal.EnumLiteMap<MetricType>
-        internalValueMap =
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        MetricType> internalValueMap =
           new com.google.protobuf.Internal.EnumLiteMap<MetricType>() {
             public MetricType findValueByNumber(int number) {
-              return MetricType.valueOf(number);
+              return MetricType.forNumber(number);
             }
           };
 
     public final com.google.protobuf.Descriptors.EnumValueDescriptor
         getValueDescriptor() {
-      return getDescriptor().getValues().get(index);
+      return getDescriptor().getValues().get(ordinal());
     }
     public final com.google.protobuf.Descriptors.EnumDescriptor
         getDescriptorForType() {
@@ -103,14 +124,15 @@
         throw new java.lang.IllegalArgumentException(
           "EnumValueDescriptor is not for this type.");
       }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
       return VALUES[desc.getIndex()];
     }
 
-    private final int index;
     private final int value;
 
-    private MetricType(int index, int value) {
-      this.index = index;
+    private MetricType(int value) {
       this.value = value;
     }
 
@@ -124,10 +146,6 @@
     /**
      * <code>optional string name = 1;</code>
      */
-    boolean hasName();
-    /**
-     * <code>optional string name = 1;</code>
-     */
     java.lang.String getName();
     /**
      * <code>optional string name = 1;</code>
@@ -138,10 +156,6 @@
     /**
      * <code>optional string value = 2;</code>
      */
-    boolean hasValue();
-    /**
-     * <code>optional string value = 2;</code>
-     */
     java.lang.String getValue();
     /**
      * <code>optional string value = 2;</code>
@@ -152,40 +166,30 @@
   /**
    * Protobuf type {@code io.prometheus.client.LabelPair}
    */
-  public static final class LabelPair extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class LabelPair extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.LabelPair)
       LabelPairOrBuilder {
     // Use LabelPair.newBuilder() to construct.
-    private LabelPair(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private LabelPair(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private LabelPair(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final LabelPair defaultInstance;
-    public static LabelPair getDefaultInstance() {
-      return defaultInstance;
+    private LabelPair() {
+      name_ = "";
+      value_ = "";
     }
 
-    public LabelPair getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private LabelPair(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -195,22 +199,21 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
             }
             case 10: {
-              com.google.protobuf.ByteString bs = input.readBytes();
-              bitField0_ |= 0x00000001;
-              name_ = bs;
+              java.lang.String s = input.readStringRequireUtf8();
+
+              name_ = s;
               break;
             }
             case 18: {
-              com.google.protobuf.ByteString bs = input.readBytes();
-              bitField0_ |= 0x00000002;
-              value_ = bs;
+              java.lang.String s = input.readStringRequireUtf8();
+
+              value_ = s;
               break;
             }
           }
@@ -219,9 +222,8 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -230,37 +232,15 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.LabelPair.class, io.prometheus.client.Metrics.LabelPair.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<LabelPair> PARSER =
-        new com.google.protobuf.AbstractParser<LabelPair>() {
-      public LabelPair parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new LabelPair(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<LabelPair> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
     public static final int NAME_FIELD_NUMBER = 1;
-    private java.lang.Object name_;
-    /**
-     * <code>optional string name = 1;</code>
-     */
-    public boolean hasName() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
+    private volatile java.lang.Object name_;
     /**
      * <code>optional string name = 1;</code>
      */
@@ -272,9 +252,7 @@
         com.google.protobuf.ByteString bs = 
             (com.google.protobuf.ByteString) ref;
         java.lang.String s = bs.toStringUtf8();
-        if (bs.isValidUtf8()) {
-          name_ = s;
-        }
+        name_ = s;
         return s;
       }
     }
@@ -296,13 +274,7 @@
     }
 
     public static final int VALUE_FIELD_NUMBER = 2;
-    private java.lang.Object value_;
-    /**
-     * <code>optional string value = 2;</code>
-     */
-    public boolean hasValue() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
-    }
+    private volatile java.lang.Object value_;
     /**
      * <code>optional string value = 2;</code>
      */
@@ -314,9 +286,7 @@
         com.google.protobuf.ByteString bs = 
             (com.google.protobuf.ByteString) ref;
         java.lang.String s = bs.toStringUtf8();
-        if (bs.isValidUtf8()) {
-          value_ = s;
-        }
+        value_ = s;
         return s;
       }
     }
@@ -337,10 +307,6 @@
       }
     }
 
-    private void initFields() {
-      name_ = "";
-      value_ = "";
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -353,40 +319,62 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        output.writeBytes(1, getNameBytes());
+      if (!getNameBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
-        output.writeBytes(2, getValueBytes());
+      if (!getValueBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, value_);
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBytesSize(1, getNameBytes());
+      if (!getNameBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBytesSize(2, getValueBytes());
+      if (!getValueBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, value_);
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.LabelPair)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.LabelPair other = (io.prometheus.client.Metrics.LabelPair) obj;
+
+      boolean result = true;
+      result = result && getName()
+          .equals(other.getName());
+      result = result && getValue()
+          .equals(other.getValue());
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (37 * hash) + NAME_FIELD_NUMBER;
+      hash = (53 * hash) + getName().hashCode();
+      hash = (37 * hash) + VALUE_FIELD_NUMBER;
+      hash = (53 * hash) + getValue().hashCode();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.LabelPair parseFrom(
@@ -412,46 +400,57 @@
     }
     public static io.prometheus.client.Metrics.LabelPair parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.LabelPair parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.LabelPair parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.LabelPair parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.LabelPair parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.LabelPair parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.LabelPair prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.LabelPair prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -459,7 +458,7 @@
      * Protobuf type {@code io.prometheus.client.LabelPair}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.LabelPair)
         io.prometheus.client.Metrics.LabelPairOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -467,7 +466,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_LabelPair_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_LabelPair_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -480,29 +479,22 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         name_ = "";
-        bitField0_ = (bitField0_ & ~0x00000001);
-        value_ = "";
-        bitField0_ = (bitField0_ & ~0x00000002);
-        return this;
-      }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
+        value_ = "";
+
+        return this;
       }
 
       public com.google.protobuf.Descriptors.Descriptor
@@ -524,21 +516,38 @@
 
       public io.prometheus.client.Metrics.LabelPair buildPartial() {
         io.prometheus.client.Metrics.LabelPair result = new io.prometheus.client.Metrics.LabelPair(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
         result.name_ = name_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-          to_bitField0_ |= 0x00000002;
-        }
         result.value_ = value_;
-        result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.LabelPair) {
           return mergeFrom((io.prometheus.client.Metrics.LabelPair)other);
@@ -550,17 +559,15 @@
 
       public Builder mergeFrom(io.prometheus.client.Metrics.LabelPair other) {
         if (other == io.prometheus.client.Metrics.LabelPair.getDefaultInstance()) return this;
-        if (other.hasName()) {
-          bitField0_ |= 0x00000001;
+        if (!other.getName().isEmpty()) {
           name_ = other.name_;
           onChanged();
         }
-        if (other.hasValue()) {
-          bitField0_ |= 0x00000002;
+        if (!other.getValue().isEmpty()) {
           value_ = other.value_;
           onChanged();
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -577,7 +584,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.LabelPair) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -585,27 +592,18 @@
         }
         return this;
       }
-      private int bitField0_;
 
       private java.lang.Object name_ = "";
       /**
        * <code>optional string name = 1;</code>
        */
-      public boolean hasName() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional string name = 1;</code>
-       */
       public java.lang.String getName() {
         java.lang.Object ref = name_;
         if (!(ref instanceof java.lang.String)) {
           com.google.protobuf.ByteString bs =
               (com.google.protobuf.ByteString) ref;
           java.lang.String s = bs.toStringUtf8();
-          if (bs.isValidUtf8()) {
-            name_ = s;
-          }
+          name_ = s;
           return s;
         } else {
           return (java.lang.String) ref;
@@ -635,7 +633,7 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  bitField0_ |= 0x00000001;
+  
         name_ = value;
         onChanged();
         return this;
@@ -644,7 +642,7 @@
        * <code>optional string name = 1;</code>
        */
       public Builder clearName() {
-        bitField0_ = (bitField0_ & ~0x00000001);
+        
         name_ = getDefaultInstance().getName();
         onChanged();
         return this;
@@ -657,7 +655,8 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  bitField0_ |= 0x00000001;
+  checkByteStringIsUtf8(value);
+        
         name_ = value;
         onChanged();
         return this;
@@ -667,21 +666,13 @@
       /**
        * <code>optional string value = 2;</code>
        */
-      public boolean hasValue() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
-      }
-      /**
-       * <code>optional string value = 2;</code>
-       */
       public java.lang.String getValue() {
         java.lang.Object ref = value_;
         if (!(ref instanceof java.lang.String)) {
           com.google.protobuf.ByteString bs =
               (com.google.protobuf.ByteString) ref;
           java.lang.String s = bs.toStringUtf8();
-          if (bs.isValidUtf8()) {
-            value_ = s;
-          }
+          value_ = s;
           return s;
         } else {
           return (java.lang.String) ref;
@@ -711,7 +702,7 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  bitField0_ |= 0x00000002;
+  
         value_ = value;
         onChanged();
         return this;
@@ -720,7 +711,7 @@
        * <code>optional string value = 2;</code>
        */
       public Builder clearValue() {
-        bitField0_ = (bitField0_ & ~0x00000002);
+        
         value_ = getDefaultInstance().getValue();
         onChanged();
         return this;
@@ -733,21 +724,59 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  bitField0_ |= 0x00000002;
+  checkByteStringIsUtf8(value);
+        
         value_ = value;
         onChanged();
         return this;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.LabelPair)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair)
+    private static final io.prometheus.client.Metrics.LabelPair DEFAULT_INSTANCE;
     static {
-      defaultInstance = new LabelPair(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.LabelPair();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.LabelPair)
+    public static io.prometheus.client.Metrics.LabelPair getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<LabelPair>
+        PARSER = new com.google.protobuf.AbstractParser<LabelPair>() {
+      public LabelPair parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new LabelPair(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<LabelPair> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<LabelPair> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.LabelPair getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   public interface GaugeOrBuilder extends
@@ -757,49 +786,34 @@
     /**
      * <code>optional double value = 1;</code>
      */
-    boolean hasValue();
-    /**
-     * <code>optional double value = 1;</code>
-     */
     double getValue();
   }
   /**
    * Protobuf type {@code io.prometheus.client.Gauge}
    */
-  public static final class Gauge extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class Gauge extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.Gauge)
       GaugeOrBuilder {
     // Use Gauge.newBuilder() to construct.
-    private Gauge(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private Gauge(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private Gauge(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final Gauge defaultInstance;
-    public static Gauge getDefaultInstance() {
-      return defaultInstance;
+    private Gauge() {
+      value_ = 0D;
     }
 
-    public Gauge getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private Gauge(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -809,14 +823,13 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
             }
             case 9: {
-              bitField0_ |= 0x00000001;
+
               value_ = input.readDouble();
               break;
             }
@@ -826,9 +839,8 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -837,47 +849,22 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.Gauge.class, io.prometheus.client.Metrics.Gauge.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<Gauge> PARSER =
-        new com.google.protobuf.AbstractParser<Gauge>() {
-      public Gauge parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Gauge(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<Gauge> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
     public static final int VALUE_FIELD_NUMBER = 1;
     private double value_;
     /**
      * <code>optional double value = 1;</code>
      */
-    public boolean hasValue() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>optional double value = 1;</code>
-     */
     public double getValue() {
       return value_;
     }
 
-    private void initFields() {
-      value_ = 0D;
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -890,33 +877,56 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (value_ != 0D) {
         output.writeDouble(1, value_);
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (value_ != 0D) {
         size += com.google.protobuf.CodedOutputStream
           .computeDoubleSize(1, value_);
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.Gauge)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.Gauge other = (io.prometheus.client.Metrics.Gauge) obj;
+
+      boolean result = true;
+      result = result && (
+          java.lang.Double.doubleToLongBits(getValue())
+          == java.lang.Double.doubleToLongBits(
+              other.getValue()));
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (37 * hash) + VALUE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          java.lang.Double.doubleToLongBits(getValue()));
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.Gauge parseFrom(
@@ -942,46 +952,57 @@
     }
     public static io.prometheus.client.Metrics.Gauge parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Gauge parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Gauge parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Gauge parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Gauge parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Gauge parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.Gauge prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.Gauge prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -989,7 +1010,7 @@
      * Protobuf type {@code io.prometheus.client.Gauge}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.Gauge)
         io.prometheus.client.Metrics.GaugeOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -997,7 +1018,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Gauge_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Gauge_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -1010,27 +1031,20 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         value_ = 0D;
-        bitField0_ = (bitField0_ & ~0x00000001);
-        return this;
-      }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
+        return this;
       }
 
       public com.google.protobuf.Descriptors.Descriptor
@@ -1052,17 +1066,37 @@
 
       public io.prometheus.client.Metrics.Gauge buildPartial() {
         io.prometheus.client.Metrics.Gauge result = new io.prometheus.client.Metrics.Gauge(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
         result.value_ = value_;
-        result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.Gauge) {
           return mergeFrom((io.prometheus.client.Metrics.Gauge)other);
@@ -1074,10 +1108,10 @@
 
       public Builder mergeFrom(io.prometheus.client.Metrics.Gauge other) {
         if (other == io.prometheus.client.Metrics.Gauge.getDefaultInstance()) return this;
-        if (other.hasValue()) {
+        if (other.getValue() != 0D) {
           setValue(other.getValue());
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -1094,7 +1128,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.Gauge) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -1102,18 +1136,11 @@
         }
         return this;
       }
-      private int bitField0_;
 
       private double value_ ;
       /**
        * <code>optional double value = 1;</code>
        */
-      public boolean hasValue() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional double value = 1;</code>
-       */
       public double getValue() {
         return value_;
       }
@@ -1121,7 +1148,7 @@
        * <code>optional double value = 1;</code>
        */
       public Builder setValue(double value) {
-        bitField0_ |= 0x00000001;
+        
         value_ = value;
         onChanged();
         return this;
@@ -1130,21 +1157,58 @@
        * <code>optional double value = 1;</code>
        */
       public Builder clearValue() {
-        bitField0_ = (bitField0_ & ~0x00000001);
+        
         value_ = 0D;
         onChanged();
         return this;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.Gauge)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge)
+    private static final io.prometheus.client.Metrics.Gauge DEFAULT_INSTANCE;
     static {
-      defaultInstance = new Gauge(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.Gauge();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.Gauge)
+    public static io.prometheus.client.Metrics.Gauge getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Gauge>
+        PARSER = new com.google.protobuf.AbstractParser<Gauge>() {
+      public Gauge parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new Gauge(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Gauge> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Gauge> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.Gauge getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   public interface CounterOrBuilder extends
@@ -1154,49 +1218,34 @@
     /**
      * <code>optional double value = 1;</code>
      */
-    boolean hasValue();
-    /**
-     * <code>optional double value = 1;</code>
-     */
     double getValue();
   }
   /**
    * Protobuf type {@code io.prometheus.client.Counter}
    */
-  public static final class Counter extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class Counter extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.Counter)
       CounterOrBuilder {
     // Use Counter.newBuilder() to construct.
-    private Counter(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private Counter(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private Counter(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final Counter defaultInstance;
-    public static Counter getDefaultInstance() {
-      return defaultInstance;
+    private Counter() {
+      value_ = 0D;
     }
 
-    public Counter getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private Counter(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -1206,14 +1255,13 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
             }
             case 9: {
-              bitField0_ |= 0x00000001;
+
               value_ = input.readDouble();
               break;
             }
@@ -1223,9 +1271,8 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -1234,47 +1281,22 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.Counter.class, io.prometheus.client.Metrics.Counter.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<Counter> PARSER =
-        new com.google.protobuf.AbstractParser<Counter>() {
-      public Counter parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Counter(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<Counter> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
     public static final int VALUE_FIELD_NUMBER = 1;
     private double value_;
     /**
      * <code>optional double value = 1;</code>
      */
-    public boolean hasValue() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>optional double value = 1;</code>
-     */
     public double getValue() {
       return value_;
     }
 
-    private void initFields() {
-      value_ = 0D;
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -1287,33 +1309,56 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (value_ != 0D) {
         output.writeDouble(1, value_);
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (value_ != 0D) {
         size += com.google.protobuf.CodedOutputStream
           .computeDoubleSize(1, value_);
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.Counter)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.Counter other = (io.prometheus.client.Metrics.Counter) obj;
+
+      boolean result = true;
+      result = result && (
+          java.lang.Double.doubleToLongBits(getValue())
+          == java.lang.Double.doubleToLongBits(
+              other.getValue()));
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (37 * hash) + VALUE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          java.lang.Double.doubleToLongBits(getValue()));
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.Counter parseFrom(
@@ -1339,46 +1384,57 @@
     }
     public static io.prometheus.client.Metrics.Counter parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Counter parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Counter parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Counter parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Counter parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Counter parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.Counter prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.Counter prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -1386,7 +1442,7 @@
      * Protobuf type {@code io.prometheus.client.Counter}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.Counter)
         io.prometheus.client.Metrics.CounterOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -1394,7 +1450,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Counter_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Counter_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -1407,27 +1463,20 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         value_ = 0D;
-        bitField0_ = (bitField0_ & ~0x00000001);
-        return this;
-      }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
+        return this;
       }
 
       public com.google.protobuf.Descriptors.Descriptor
@@ -1449,17 +1498,37 @@
 
       public io.prometheus.client.Metrics.Counter buildPartial() {
         io.prometheus.client.Metrics.Counter result = new io.prometheus.client.Metrics.Counter(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
         result.value_ = value_;
-        result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.Counter) {
           return mergeFrom((io.prometheus.client.Metrics.Counter)other);
@@ -1471,10 +1540,10 @@
 
       public Builder mergeFrom(io.prometheus.client.Metrics.Counter other) {
         if (other == io.prometheus.client.Metrics.Counter.getDefaultInstance()) return this;
-        if (other.hasValue()) {
+        if (other.getValue() != 0D) {
           setValue(other.getValue());
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -1491,7 +1560,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.Counter) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -1499,18 +1568,11 @@
         }
         return this;
       }
-      private int bitField0_;
 
       private double value_ ;
       /**
        * <code>optional double value = 1;</code>
        */
-      public boolean hasValue() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional double value = 1;</code>
-       */
       public double getValue() {
         return value_;
       }
@@ -1518,7 +1580,7 @@
        * <code>optional double value = 1;</code>
        */
       public Builder setValue(double value) {
-        bitField0_ |= 0x00000001;
+        
         value_ = value;
         onChanged();
         return this;
@@ -1527,21 +1589,58 @@
        * <code>optional double value = 1;</code>
        */
       public Builder clearValue() {
-        bitField0_ = (bitField0_ & ~0x00000001);
+        
         value_ = 0D;
         onChanged();
         return this;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.Counter)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter)
+    private static final io.prometheus.client.Metrics.Counter DEFAULT_INSTANCE;
     static {
-      defaultInstance = new Counter(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.Counter();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.Counter)
+    public static io.prometheus.client.Metrics.Counter getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Counter>
+        PARSER = new com.google.protobuf.AbstractParser<Counter>() {
+      public Counter parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new Counter(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Counter> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Counter> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.Counter getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   public interface QuantileOrBuilder extends
@@ -1551,58 +1650,40 @@
     /**
      * <code>optional double quantile = 1;</code>
      */
-    boolean hasQuantile();
-    /**
-     * <code>optional double quantile = 1;</code>
-     */
     double getQuantile();
 
     /**
      * <code>optional double value = 2;</code>
      */
-    boolean hasValue();
-    /**
-     * <code>optional double value = 2;</code>
-     */
     double getValue();
   }
   /**
    * Protobuf type {@code io.prometheus.client.Quantile}
    */
-  public static final class Quantile extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class Quantile extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.Quantile)
       QuantileOrBuilder {
     // Use Quantile.newBuilder() to construct.
-    private Quantile(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private Quantile(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private Quantile(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final Quantile defaultInstance;
-    public static Quantile getDefaultInstance() {
-      return defaultInstance;
+    private Quantile() {
+      quantile_ = 0D;
+      value_ = 0D;
     }
 
-    public Quantile getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private Quantile(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -1612,19 +1693,18 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
             }
             case 9: {
-              bitField0_ |= 0x00000001;
+
               quantile_ = input.readDouble();
               break;
             }
             case 17: {
-              bitField0_ |= 0x00000002;
+
               value_ = input.readDouble();
               break;
             }
@@ -1634,9 +1714,8 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -1645,40 +1724,18 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.Quantile.class, io.prometheus.client.Metrics.Quantile.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<Quantile> PARSER =
-        new com.google.protobuf.AbstractParser<Quantile>() {
-      public Quantile parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Quantile(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<Quantile> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
     public static final int QUANTILE_FIELD_NUMBER = 1;
     private double quantile_;
     /**
      * <code>optional double quantile = 1;</code>
      */
-    public boolean hasQuantile() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>optional double quantile = 1;</code>
-     */
     public double getQuantile() {
       return quantile_;
     }
@@ -1688,20 +1745,10 @@
     /**
      * <code>optional double value = 2;</code>
      */
-    public boolean hasValue() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
-    }
-    /**
-     * <code>optional double value = 2;</code>
-     */
     public double getValue() {
       return value_;
     }
 
-    private void initFields() {
-      quantile_ = 0D;
-      value_ = 0D;
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -1714,40 +1761,70 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (quantile_ != 0D) {
         output.writeDouble(1, quantile_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (value_ != 0D) {
         output.writeDouble(2, value_);
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (quantile_ != 0D) {
         size += com.google.protobuf.CodedOutputStream
           .computeDoubleSize(1, quantile_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (value_ != 0D) {
         size += com.google.protobuf.CodedOutputStream
           .computeDoubleSize(2, value_);
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.Quantile)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.Quantile other = (io.prometheus.client.Metrics.Quantile) obj;
+
+      boolean result = true;
+      result = result && (
+          java.lang.Double.doubleToLongBits(getQuantile())
+          == java.lang.Double.doubleToLongBits(
+              other.getQuantile()));
+      result = result && (
+          java.lang.Double.doubleToLongBits(getValue())
+          == java.lang.Double.doubleToLongBits(
+              other.getValue()));
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (37 * hash) + QUANTILE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          java.lang.Double.doubleToLongBits(getQuantile()));
+      hash = (37 * hash) + VALUE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          java.lang.Double.doubleToLongBits(getValue()));
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.Quantile parseFrom(
@@ -1773,46 +1850,57 @@
     }
     public static io.prometheus.client.Metrics.Quantile parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Quantile parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Quantile parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Quantile parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Quantile parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Quantile parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.Quantile prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.Quantile prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -1820,7 +1908,7 @@
      * Protobuf type {@code io.prometheus.client.Quantile}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.Quantile)
         io.prometheus.client.Metrics.QuantileOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -1828,7 +1916,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Quantile_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Quantile_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -1841,29 +1929,22 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         quantile_ = 0D;
-        bitField0_ = (bitField0_ & ~0x00000001);
-        value_ = 0D;
-        bitField0_ = (bitField0_ & ~0x00000002);
-        return this;
-      }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
+        value_ = 0D;
+
+        return this;
       }
 
       public com.google.protobuf.Descriptors.Descriptor
@@ -1885,21 +1966,38 @@
 
       public io.prometheus.client.Metrics.Quantile buildPartial() {
         io.prometheus.client.Metrics.Quantile result = new io.prometheus.client.Metrics.Quantile(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
         result.quantile_ = quantile_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-          to_bitField0_ |= 0x00000002;
-        }
         result.value_ = value_;
-        result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.Quantile) {
           return mergeFrom((io.prometheus.client.Metrics.Quantile)other);
@@ -1911,13 +2009,13 @@
 
       public Builder mergeFrom(io.prometheus.client.Metrics.Quantile other) {
         if (other == io.prometheus.client.Metrics.Quantile.getDefaultInstance()) return this;
-        if (other.hasQuantile()) {
+        if (other.getQuantile() != 0D) {
           setQuantile(other.getQuantile());
         }
-        if (other.hasValue()) {
+        if (other.getValue() != 0D) {
           setValue(other.getValue());
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -1934,7 +2032,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.Quantile) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -1942,18 +2040,11 @@
         }
         return this;
       }
-      private int bitField0_;
 
       private double quantile_ ;
       /**
        * <code>optional double quantile = 1;</code>
        */
-      public boolean hasQuantile() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional double quantile = 1;</code>
-       */
       public double getQuantile() {
         return quantile_;
       }
@@ -1961,7 +2052,7 @@
        * <code>optional double quantile = 1;</code>
        */
       public Builder setQuantile(double value) {
-        bitField0_ |= 0x00000001;
+        
         quantile_ = value;
         onChanged();
         return this;
@@ -1970,7 +2061,7 @@
        * <code>optional double quantile = 1;</code>
        */
       public Builder clearQuantile() {
-        bitField0_ = (bitField0_ & ~0x00000001);
+        
         quantile_ = 0D;
         onChanged();
         return this;
@@ -1980,12 +2071,6 @@
       /**
        * <code>optional double value = 2;</code>
        */
-      public boolean hasValue() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
-      }
-      /**
-       * <code>optional double value = 2;</code>
-       */
       public double getValue() {
         return value_;
       }
@@ -1993,7 +2078,7 @@
        * <code>optional double value = 2;</code>
        */
       public Builder setValue(double value) {
-        bitField0_ |= 0x00000002;
+        
         value_ = value;
         onChanged();
         return this;
@@ -2002,21 +2087,58 @@
        * <code>optional double value = 2;</code>
        */
       public Builder clearValue() {
-        bitField0_ = (bitField0_ & ~0x00000002);
+        
         value_ = 0D;
         onChanged();
         return this;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.Quantile)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile)
+    private static final io.prometheus.client.Metrics.Quantile DEFAULT_INSTANCE;
     static {
-      defaultInstance = new Quantile(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.Quantile();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.Quantile)
+    public static io.prometheus.client.Metrics.Quantile getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Quantile>
+        PARSER = new com.google.protobuf.AbstractParser<Quantile>() {
+      public Quantile parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new Quantile(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Quantile> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Quantile> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.Quantile getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   public interface SummaryOrBuilder extends
@@ -2026,19 +2148,11 @@
     /**
      * <code>optional uint64 sample_count = 1;</code>
      */
-    boolean hasSampleCount();
-    /**
-     * <code>optional uint64 sample_count = 1;</code>
-     */
     long getSampleCount();
 
     /**
      * <code>optional double sample_sum = 2;</code>
      */
-    boolean hasSampleSum();
-    /**
-     * <code>optional double sample_sum = 2;</code>
-     */
     double getSampleSum();
 
     /**
@@ -2068,40 +2182,31 @@
   /**
    * Protobuf type {@code io.prometheus.client.Summary}
    */
-  public static final class Summary extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class Summary extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.Summary)
       SummaryOrBuilder {
     // Use Summary.newBuilder() to construct.
-    private Summary(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private Summary(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private Summary(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final Summary defaultInstance;
-    public static Summary getDefaultInstance() {
-      return defaultInstance;
+    private Summary() {
+      sampleCount_ = 0L;
+      sampleSum_ = 0D;
+      quantile_ = java.util.Collections.emptyList();
     }
 
-    public Summary getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private Summary(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -2111,19 +2216,18 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
             }
             case 8: {
-              bitField0_ |= 0x00000001;
+
               sampleCount_ = input.readUInt64();
               break;
             }
             case 17: {
-              bitField0_ |= 0x00000002;
+
               sampleSum_ = input.readDouble();
               break;
             }
@@ -2132,7 +2236,8 @@
                 quantile_ = new java.util.ArrayList<io.prometheus.client.Metrics.Quantile>();
                 mutable_bitField0_ |= 0x00000004;
               }
-              quantile_.add(input.readMessage(io.prometheus.client.Metrics.Quantile.PARSER, extensionRegistry));
+              quantile_.add(
+                  input.readMessage(io.prometheus.client.Metrics.Quantile.parser(), extensionRegistry));
               break;
             }
           }
@@ -2141,12 +2246,11 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
           quantile_ = java.util.Collections.unmodifiableList(quantile_);
         }
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -2155,40 +2259,19 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.Summary.class, io.prometheus.client.Metrics.Summary.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<Summary> PARSER =
-        new com.google.protobuf.AbstractParser<Summary>() {
-      public Summary parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Summary(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<Summary> getParserForType() {
-      return PARSER;
-    }
-
     private int bitField0_;
     public static final int SAMPLE_COUNT_FIELD_NUMBER = 1;
     private long sampleCount_;
     /**
      * <code>optional uint64 sample_count = 1;</code>
      */
-    public boolean hasSampleCount() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>optional uint64 sample_count = 1;</code>
-     */
     public long getSampleCount() {
       return sampleCount_;
     }
@@ -2198,12 +2281,6 @@
     /**
      * <code>optional double sample_sum = 2;</code>
      */
-    public boolean hasSampleSum() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
-    }
-    /**
-     * <code>optional double sample_sum = 2;</code>
-     */
     public double getSampleSum() {
       return sampleSum_;
     }
@@ -2243,11 +2320,6 @@
       return quantile_.get(index);
     }
 
-    private void initFields() {
-      sampleCount_ = 0L;
-      sampleSum_ = 0D;
-      quantile_ = java.util.Collections.emptyList();
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -2260,30 +2332,27 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (sampleCount_ != 0L) {
         output.writeUInt64(1, sampleCount_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (sampleSum_ != 0D) {
         output.writeDouble(2, sampleSum_);
       }
       for (int i = 0; i < quantile_.size(); i++) {
         output.writeMessage(3, quantile_.get(i));
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (sampleCount_ != 0L) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(1, sampleCount_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (sampleSum_ != 0D) {
         size += com.google.protobuf.CodedOutputStream
           .computeDoubleSize(2, sampleSum_);
       }
@@ -2291,16 +2360,53 @@
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, quantile_.get(i));
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.Summary)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.Summary other = (io.prometheus.client.Metrics.Summary) obj;
+
+      boolean result = true;
+      result = result && (getSampleCount()
+          == other.getSampleCount());
+      result = result && (
+          java.lang.Double.doubleToLongBits(getSampleSum())
+          == java.lang.Double.doubleToLongBits(
+              other.getSampleSum()));
+      result = result && getQuantileList()
+          .equals(other.getQuantileList());
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          getSampleCount());
+      hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          java.lang.Double.doubleToLongBits(getSampleSum()));
+      if (getQuantileCount() > 0) {
+        hash = (37 * hash) + QUANTILE_FIELD_NUMBER;
+        hash = (53 * hash) + getQuantileList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.Summary parseFrom(
@@ -2326,46 +2432,57 @@
     }
     public static io.prometheus.client.Metrics.Summary parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Summary parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Summary parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Summary parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Summary parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Summary parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.Summary prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.Summary prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -2373,7 +2490,7 @@
      * Protobuf type {@code io.prometheus.client.Summary}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.Summary)
         io.prometheus.client.Metrics.SummaryOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -2381,7 +2498,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Summary_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -2394,25 +2511,22 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
           getQuantileFieldBuilder();
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         sampleCount_ = 0L;
-        bitField0_ = (bitField0_ & ~0x00000001);
+
         sampleSum_ = 0D;
-        bitField0_ = (bitField0_ & ~0x00000002);
+
         if (quantileBuilder_ == null) {
           quantile_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000004);
@@ -2422,10 +2536,6 @@
         return this;
       }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Summary_descriptor;
@@ -2447,13 +2557,7 @@
         io.prometheus.client.Metrics.Summary result = new io.prometheus.client.Metrics.Summary(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
         result.sampleCount_ = sampleCount_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-          to_bitField0_ |= 0x00000002;
-        }
         result.sampleSum_ = sampleSum_;
         if (quantileBuilder_ == null) {
           if (((bitField0_ & 0x00000004) == 0x00000004)) {
@@ -2469,6 +2573,32 @@
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.Summary) {
           return mergeFrom((io.prometheus.client.Metrics.Summary)other);
@@ -2480,10 +2610,10 @@
 
       public Builder mergeFrom(io.prometheus.client.Metrics.Summary other) {
         if (other == io.prometheus.client.Metrics.Summary.getDefaultInstance()) return this;
-        if (other.hasSampleCount()) {
+        if (other.getSampleCount() != 0L) {
           setSampleCount(other.getSampleCount());
         }
-        if (other.hasSampleSum()) {
+        if (other.getSampleSum() != 0D) {
           setSampleSum(other.getSampleSum());
         }
         if (quantileBuilder_ == null) {
@@ -2505,14 +2635,14 @@
               quantile_ = other.quantile_;
               bitField0_ = (bitField0_ & ~0x00000004);
               quantileBuilder_ = 
-                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                    getQuantileFieldBuilder() : null;
             } else {
               quantileBuilder_.addAllMessages(other.quantile_);
             }
           }
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -2529,7 +2659,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.Summary) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -2543,12 +2673,6 @@
       /**
        * <code>optional uint64 sample_count = 1;</code>
        */
-      public boolean hasSampleCount() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional uint64 sample_count = 1;</code>
-       */
       public long getSampleCount() {
         return sampleCount_;
       }
@@ -2556,7 +2680,7 @@
        * <code>optional uint64 sample_count = 1;</code>
        */
       public Builder setSampleCount(long value) {
-        bitField0_ |= 0x00000001;
+        
         sampleCount_ = value;
         onChanged();
         return this;
@@ -2565,7 +2689,7 @@
        * <code>optional uint64 sample_count = 1;</code>
        */
       public Builder clearSampleCount() {
-        bitField0_ = (bitField0_ & ~0x00000001);
+        
         sampleCount_ = 0L;
         onChanged();
         return this;
@@ -2575,12 +2699,6 @@
       /**
        * <code>optional double sample_sum = 2;</code>
        */
-      public boolean hasSampleSum() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
-      }
-      /**
-       * <code>optional double sample_sum = 2;</code>
-       */
       public double getSampleSum() {
         return sampleSum_;
       }
@@ -2588,7 +2706,7 @@
        * <code>optional double sample_sum = 2;</code>
        */
       public Builder setSampleSum(double value) {
-        bitField0_ |= 0x00000002;
+        
         sampleSum_ = value;
         onChanged();
         return this;
@@ -2597,7 +2715,7 @@
        * <code>optional double sample_sum = 2;</code>
        */
       public Builder clearSampleSum() {
-        bitField0_ = (bitField0_ & ~0x00000002);
+        
         sampleSum_ = 0D;
         onChanged();
         return this;
@@ -2612,7 +2730,7 @@
          }
       }
 
-      private com.google.protobuf.RepeatedFieldBuilder<
+      private com.google.protobuf.RepeatedFieldBuilderV3<
           io.prometheus.client.Metrics.Quantile, io.prometheus.client.Metrics.Quantile.Builder, io.prometheus.client.Metrics.QuantileOrBuilder> quantileBuilder_;
 
       /**
@@ -2828,11 +2946,11 @@
            getQuantileBuilderList() {
         return getQuantileFieldBuilder().getBuilderList();
       }
-      private com.google.protobuf.RepeatedFieldBuilder<
+      private com.google.protobuf.RepeatedFieldBuilderV3<
           io.prometheus.client.Metrics.Quantile, io.prometheus.client.Metrics.Quantile.Builder, io.prometheus.client.Metrics.QuantileOrBuilder> 
           getQuantileFieldBuilder() {
         if (quantileBuilder_ == null) {
-          quantileBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+          quantileBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               io.prometheus.client.Metrics.Quantile, io.prometheus.client.Metrics.Quantile.Builder, io.prometheus.client.Metrics.QuantileOrBuilder>(
                   quantile_,
                   ((bitField0_ & 0x00000004) == 0x00000004),
@@ -2842,16 +2960,53 @@
         }
         return quantileBuilder_;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.Summary)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary)
+    private static final io.prometheus.client.Metrics.Summary DEFAULT_INSTANCE;
     static {
-      defaultInstance = new Summary(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.Summary();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.Summary)
+    public static io.prometheus.client.Metrics.Summary getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Summary>
+        PARSER = new com.google.protobuf.AbstractParser<Summary>() {
+      public Summary parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new Summary(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Summary> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Summary> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.Summary getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   public interface UntypedOrBuilder extends
@@ -2861,49 +3016,34 @@
     /**
      * <code>optional double value = 1;</code>
      */
-    boolean hasValue();
-    /**
-     * <code>optional double value = 1;</code>
-     */
     double getValue();
   }
   /**
    * Protobuf type {@code io.prometheus.client.Untyped}
    */
-  public static final class Untyped extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class Untyped extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.Untyped)
       UntypedOrBuilder {
     // Use Untyped.newBuilder() to construct.
-    private Untyped(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private Untyped(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private Untyped(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final Untyped defaultInstance;
-    public static Untyped getDefaultInstance() {
-      return defaultInstance;
+    private Untyped() {
+      value_ = 0D;
     }
 
-    public Untyped getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private Untyped(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -2913,14 +3053,13 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
             }
             case 9: {
-              bitField0_ |= 0x00000001;
+
               value_ = input.readDouble();
               break;
             }
@@ -2930,9 +3069,8 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -2941,47 +3079,22 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.Untyped.class, io.prometheus.client.Metrics.Untyped.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<Untyped> PARSER =
-        new com.google.protobuf.AbstractParser<Untyped>() {
-      public Untyped parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Untyped(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<Untyped> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
     public static final int VALUE_FIELD_NUMBER = 1;
     private double value_;
     /**
      * <code>optional double value = 1;</code>
      */
-    public boolean hasValue() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>optional double value = 1;</code>
-     */
     public double getValue() {
       return value_;
     }
 
-    private void initFields() {
-      value_ = 0D;
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -2994,33 +3107,56 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (value_ != 0D) {
         output.writeDouble(1, value_);
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (value_ != 0D) {
         size += com.google.protobuf.CodedOutputStream
           .computeDoubleSize(1, value_);
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.Untyped)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.Untyped other = (io.prometheus.client.Metrics.Untyped) obj;
+
+      boolean result = true;
+      result = result && (
+          java.lang.Double.doubleToLongBits(getValue())
+          == java.lang.Double.doubleToLongBits(
+              other.getValue()));
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (37 * hash) + VALUE_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          java.lang.Double.doubleToLongBits(getValue()));
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.Untyped parseFrom(
@@ -3046,46 +3182,57 @@
     }
     public static io.prometheus.client.Metrics.Untyped parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Untyped parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Untyped parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Untyped parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Untyped parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Untyped parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.Untyped prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.Untyped prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -3093,7 +3240,7 @@
      * Protobuf type {@code io.prometheus.client.Untyped}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.Untyped)
         io.prometheus.client.Metrics.UntypedOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -3101,7 +3248,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Untyped_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Untyped_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -3114,27 +3261,20 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         value_ = 0D;
-        bitField0_ = (bitField0_ & ~0x00000001);
-        return this;
-      }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
+        return this;
       }
 
       public com.google.protobuf.Descriptors.Descriptor
@@ -3156,17 +3296,37 @@
 
       public io.prometheus.client.Metrics.Untyped buildPartial() {
         io.prometheus.client.Metrics.Untyped result = new io.prometheus.client.Metrics.Untyped(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
         result.value_ = value_;
-        result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.Untyped) {
           return mergeFrom((io.prometheus.client.Metrics.Untyped)other);
@@ -3178,10 +3338,10 @@
 
       public Builder mergeFrom(io.prometheus.client.Metrics.Untyped other) {
         if (other == io.prometheus.client.Metrics.Untyped.getDefaultInstance()) return this;
-        if (other.hasValue()) {
+        if (other.getValue() != 0D) {
           setValue(other.getValue());
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -3198,7 +3358,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.Untyped) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -3206,18 +3366,11 @@
         }
         return this;
       }
-      private int bitField0_;
 
       private double value_ ;
       /**
        * <code>optional double value = 1;</code>
        */
-      public boolean hasValue() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional double value = 1;</code>
-       */
       public double getValue() {
         return value_;
       }
@@ -3225,7 +3378,7 @@
        * <code>optional double value = 1;</code>
        */
       public Builder setValue(double value) {
-        bitField0_ |= 0x00000001;
+        
         value_ = value;
         onChanged();
         return this;
@@ -3234,21 +3387,58 @@
        * <code>optional double value = 1;</code>
        */
       public Builder clearValue() {
-        bitField0_ = (bitField0_ & ~0x00000001);
+        
         value_ = 0D;
         onChanged();
         return this;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.Untyped)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped)
+    private static final io.prometheus.client.Metrics.Untyped DEFAULT_INSTANCE;
     static {
-      defaultInstance = new Untyped(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.Untyped();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.Untyped)
+    public static io.prometheus.client.Metrics.Untyped getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Untyped>
+        PARSER = new com.google.protobuf.AbstractParser<Untyped>() {
+      public Untyped parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new Untyped(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Untyped> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Untyped> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.Untyped getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   public interface HistogramOrBuilder extends
@@ -3258,61 +3448,53 @@
     /**
      * <code>optional uint64 sample_count = 1;</code>
      */
-    boolean hasSampleCount();
-    /**
-     * <code>optional uint64 sample_count = 1;</code>
-     */
     long getSampleCount();
 
     /**
      * <code>optional double sample_sum = 2;</code>
      */
-    boolean hasSampleSum();
-    /**
-     * <code>optional double sample_sum = 2;</code>
-     */
     double getSampleSum();
 
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     java.util.List<io.prometheus.client.Metrics.Bucket> 
         getBucketList();
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     io.prometheus.client.Metrics.Bucket getBucket(int index);
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     int getBucketCount();
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     java.util.List<? extends io.prometheus.client.Metrics.BucketOrBuilder> 
         getBucketOrBuilderList();
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     io.prometheus.client.Metrics.BucketOrBuilder getBucketOrBuilder(
         int index);
@@ -3320,40 +3502,31 @@
   /**
    * Protobuf type {@code io.prometheus.client.Histogram}
    */
-  public static final class Histogram extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class Histogram extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.Histogram)
       HistogramOrBuilder {
     // Use Histogram.newBuilder() to construct.
-    private Histogram(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private Histogram(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private Histogram(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final Histogram defaultInstance;
-    public static Histogram getDefaultInstance() {
-      return defaultInstance;
+    private Histogram() {
+      sampleCount_ = 0L;
+      sampleSum_ = 0D;
+      bucket_ = java.util.Collections.emptyList();
     }
 
-    public Histogram getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private Histogram(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -3363,19 +3536,18 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
             }
             case 8: {
-              bitField0_ |= 0x00000001;
+
               sampleCount_ = input.readUInt64();
               break;
             }
             case 17: {
-              bitField0_ |= 0x00000002;
+
               sampleSum_ = input.readDouble();
               break;
             }
@@ -3384,7 +3556,8 @@
                 bucket_ = new java.util.ArrayList<io.prometheus.client.Metrics.Bucket>();
                 mutable_bitField0_ |= 0x00000004;
               }
-              bucket_.add(input.readMessage(io.prometheus.client.Metrics.Bucket.PARSER, extensionRegistry));
+              bucket_.add(
+                  input.readMessage(io.prometheus.client.Metrics.Bucket.parser(), extensionRegistry));
               break;
             }
           }
@@ -3393,12 +3566,11 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
           bucket_ = java.util.Collections.unmodifiableList(bucket_);
         }
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -3407,40 +3579,19 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.Histogram.class, io.prometheus.client.Metrics.Histogram.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<Histogram> PARSER =
-        new com.google.protobuf.AbstractParser<Histogram>() {
-      public Histogram parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Histogram(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<Histogram> getParserForType() {
-      return PARSER;
-    }
-
     private int bitField0_;
     public static final int SAMPLE_COUNT_FIELD_NUMBER = 1;
     private long sampleCount_;
     /**
      * <code>optional uint64 sample_count = 1;</code>
      */
-    public boolean hasSampleCount() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>optional uint64 sample_count = 1;</code>
-     */
     public long getSampleCount() {
       return sampleCount_;
     }
@@ -3450,12 +3601,6 @@
     /**
      * <code>optional double sample_sum = 2;</code>
      */
-    public boolean hasSampleSum() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
-    }
-    /**
-     * <code>optional double sample_sum = 2;</code>
-     */
     public double getSampleSum() {
       return sampleSum_;
     }
@@ -3463,63 +3608,58 @@
     public static final int BUCKET_FIELD_NUMBER = 3;
     private java.util.List<io.prometheus.client.Metrics.Bucket> bucket_;
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     public java.util.List<io.prometheus.client.Metrics.Bucket> getBucketList() {
       return bucket_;
     }
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     public java.util.List<? extends io.prometheus.client.Metrics.BucketOrBuilder> 
         getBucketOrBuilderList() {
       return bucket_;
     }
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     public int getBucketCount() {
       return bucket_.size();
     }
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     public io.prometheus.client.Metrics.Bucket getBucket(int index) {
       return bucket_.get(index);
     }
     /**
-     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-     *
      * <pre>
      * Ordered in increasing order of upper_bound, +Inf bucket is optional.
      * </pre>
+     *
+     * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
      */
     public io.prometheus.client.Metrics.BucketOrBuilder getBucketOrBuilder(
         int index) {
       return bucket_.get(index);
     }
 
-    private void initFields() {
-      sampleCount_ = 0L;
-      sampleSum_ = 0D;
-      bucket_ = java.util.Collections.emptyList();
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -3532,30 +3672,27 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (sampleCount_ != 0L) {
         output.writeUInt64(1, sampleCount_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (sampleSum_ != 0D) {
         output.writeDouble(2, sampleSum_);
       }
       for (int i = 0; i < bucket_.size(); i++) {
         output.writeMessage(3, bucket_.get(i));
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (sampleCount_ != 0L) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(1, sampleCount_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (sampleSum_ != 0D) {
         size += com.google.protobuf.CodedOutputStream
           .computeDoubleSize(2, sampleSum_);
       }
@@ -3563,16 +3700,53 @@
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(3, bucket_.get(i));
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.Histogram)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.Histogram other = (io.prometheus.client.Metrics.Histogram) obj;
+
+      boolean result = true;
+      result = result && (getSampleCount()
+          == other.getSampleCount());
+      result = result && (
+          java.lang.Double.doubleToLongBits(getSampleSum())
+          == java.lang.Double.doubleToLongBits(
+              other.getSampleSum()));
+      result = result && getBucketList()
+          .equals(other.getBucketList());
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (37 * hash) + SAMPLE_COUNT_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          getSampleCount());
+      hash = (37 * hash) + SAMPLE_SUM_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          java.lang.Double.doubleToLongBits(getSampleSum()));
+      if (getBucketCount() > 0) {
+        hash = (37 * hash) + BUCKET_FIELD_NUMBER;
+        hash = (53 * hash) + getBucketList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.Histogram parseFrom(
@@ -3598,46 +3772,57 @@
     }
     public static io.prometheus.client.Metrics.Histogram parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Histogram parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Histogram parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Histogram parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Histogram parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Histogram parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.Histogram prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.Histogram prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -3645,7 +3830,7 @@
      * Protobuf type {@code io.prometheus.client.Histogram}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.Histogram)
         io.prometheus.client.Metrics.HistogramOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -3653,7 +3838,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Histogram_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -3666,25 +3851,22 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
           getBucketFieldBuilder();
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         sampleCount_ = 0L;
-        bitField0_ = (bitField0_ & ~0x00000001);
+
         sampleSum_ = 0D;
-        bitField0_ = (bitField0_ & ~0x00000002);
+
         if (bucketBuilder_ == null) {
           bucket_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000004);
@@ -3694,10 +3876,6 @@
         return this;
       }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Histogram_descriptor;
@@ -3719,13 +3897,7 @@
         io.prometheus.client.Metrics.Histogram result = new io.prometheus.client.Metrics.Histogram(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
         result.sampleCount_ = sampleCount_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-          to_bitField0_ |= 0x00000002;
-        }
         result.sampleSum_ = sampleSum_;
         if (bucketBuilder_ == null) {
           if (((bitField0_ & 0x00000004) == 0x00000004)) {
@@ -3741,6 +3913,32 @@
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.Histogram) {
           return mergeFrom((io.prometheus.client.Metrics.Histogram)other);
@@ -3752,10 +3950,10 @@
 
       public Builder mergeFrom(io.prometheus.client.Metrics.Histogram other) {
         if (other == io.prometheus.client.Metrics.Histogram.getDefaultInstance()) return this;
-        if (other.hasSampleCount()) {
+        if (other.getSampleCount() != 0L) {
           setSampleCount(other.getSampleCount());
         }
-        if (other.hasSampleSum()) {
+        if (other.getSampleSum() != 0D) {
           setSampleSum(other.getSampleSum());
         }
         if (bucketBuilder_ == null) {
@@ -3777,14 +3975,14 @@
               bucket_ = other.bucket_;
               bitField0_ = (bitField0_ & ~0x00000004);
               bucketBuilder_ = 
-                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                    getBucketFieldBuilder() : null;
             } else {
               bucketBuilder_.addAllMessages(other.bucket_);
             }
           }
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -3801,7 +3999,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.Histogram) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -3815,12 +4013,6 @@
       /**
        * <code>optional uint64 sample_count = 1;</code>
        */
-      public boolean hasSampleCount() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional uint64 sample_count = 1;</code>
-       */
       public long getSampleCount() {
         return sampleCount_;
       }
@@ -3828,7 +4020,7 @@
        * <code>optional uint64 sample_count = 1;</code>
        */
       public Builder setSampleCount(long value) {
-        bitField0_ |= 0x00000001;
+        
         sampleCount_ = value;
         onChanged();
         return this;
@@ -3837,7 +4029,7 @@
        * <code>optional uint64 sample_count = 1;</code>
        */
       public Builder clearSampleCount() {
-        bitField0_ = (bitField0_ & ~0x00000001);
+        
         sampleCount_ = 0L;
         onChanged();
         return this;
@@ -3847,12 +4039,6 @@
       /**
        * <code>optional double sample_sum = 2;</code>
        */
-      public boolean hasSampleSum() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
-      }
-      /**
-       * <code>optional double sample_sum = 2;</code>
-       */
       public double getSampleSum() {
         return sampleSum_;
       }
@@ -3860,7 +4046,7 @@
        * <code>optional double sample_sum = 2;</code>
        */
       public Builder setSampleSum(double value) {
-        bitField0_ |= 0x00000002;
+        
         sampleSum_ = value;
         onChanged();
         return this;
@@ -3869,7 +4055,7 @@
        * <code>optional double sample_sum = 2;</code>
        */
       public Builder clearSampleSum() {
-        bitField0_ = (bitField0_ & ~0x00000002);
+        
         sampleSum_ = 0D;
         onChanged();
         return this;
@@ -3884,15 +4070,15 @@
          }
       }
 
-      private com.google.protobuf.RepeatedFieldBuilder<
+      private com.google.protobuf.RepeatedFieldBuilderV3<
           io.prometheus.client.Metrics.Bucket, io.prometheus.client.Metrics.Bucket.Builder, io.prometheus.client.Metrics.BucketOrBuilder> bucketBuilder_;
 
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public java.util.List<io.prometheus.client.Metrics.Bucket> getBucketList() {
         if (bucketBuilder_ == null) {
@@ -3902,11 +4088,11 @@
         }
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public int getBucketCount() {
         if (bucketBuilder_ == null) {
@@ -3916,11 +4102,11 @@
         }
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public io.prometheus.client.Metrics.Bucket getBucket(int index) {
         if (bucketBuilder_ == null) {
@@ -3930,11 +4116,11 @@
         }
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public Builder setBucket(
           int index, io.prometheus.client.Metrics.Bucket value) {
@@ -3951,11 +4137,11 @@
         return this;
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public Builder setBucket(
           int index, io.prometheus.client.Metrics.Bucket.Builder builderForValue) {
@@ -3969,11 +4155,11 @@
         return this;
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public Builder addBucket(io.prometheus.client.Metrics.Bucket value) {
         if (bucketBuilder_ == null) {
@@ -3989,11 +4175,11 @@
         return this;
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public Builder addBucket(
           int index, io.prometheus.client.Metrics.Bucket value) {
@@ -4010,11 +4196,11 @@
         return this;
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public Builder addBucket(
           io.prometheus.client.Metrics.Bucket.Builder builderForValue) {
@@ -4028,11 +4214,11 @@
         return this;
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public Builder addBucket(
           int index, io.prometheus.client.Metrics.Bucket.Builder builderForValue) {
@@ -4046,11 +4232,11 @@
         return this;
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public Builder addAllBucket(
           java.lang.Iterable<? extends io.prometheus.client.Metrics.Bucket> values) {
@@ -4065,11 +4251,11 @@
         return this;
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public Builder clearBucket() {
         if (bucketBuilder_ == null) {
@@ -4082,11 +4268,11 @@
         return this;
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public Builder removeBucket(int index) {
         if (bucketBuilder_ == null) {
@@ -4099,22 +4285,22 @@
         return this;
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public io.prometheus.client.Metrics.Bucket.Builder getBucketBuilder(
           int index) {
         return getBucketFieldBuilder().getBuilder(index);
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public io.prometheus.client.Metrics.BucketOrBuilder getBucketOrBuilder(
           int index) {
@@ -4124,11 +4310,11 @@
         }
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public java.util.List<? extends io.prometheus.client.Metrics.BucketOrBuilder> 
            getBucketOrBuilderList() {
@@ -4139,22 +4325,22 @@
         }
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public io.prometheus.client.Metrics.Bucket.Builder addBucketBuilder() {
         return getBucketFieldBuilder().addBuilder(
             io.prometheus.client.Metrics.Bucket.getDefaultInstance());
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public io.prometheus.client.Metrics.Bucket.Builder addBucketBuilder(
           int index) {
@@ -4162,21 +4348,21 @@
             index, io.prometheus.client.Metrics.Bucket.getDefaultInstance());
       }
       /**
-       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
-       *
        * <pre>
        * Ordered in increasing order of upper_bound, +Inf bucket is optional.
        * </pre>
+       *
+       * <code>repeated .io.prometheus.client.Bucket bucket = 3;</code>
        */
       public java.util.List<io.prometheus.client.Metrics.Bucket.Builder> 
            getBucketBuilderList() {
         return getBucketFieldBuilder().getBuilderList();
       }
-      private com.google.protobuf.RepeatedFieldBuilder<
+      private com.google.protobuf.RepeatedFieldBuilderV3<
           io.prometheus.client.Metrics.Bucket, io.prometheus.client.Metrics.Bucket.Builder, io.prometheus.client.Metrics.BucketOrBuilder> 
           getBucketFieldBuilder() {
         if (bucketBuilder_ == null) {
-          bucketBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+          bucketBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               io.prometheus.client.Metrics.Bucket, io.prometheus.client.Metrics.Bucket.Builder, io.prometheus.client.Metrics.BucketOrBuilder>(
                   bucket_,
                   ((bitField0_ & 0x00000004) == 0x00000004),
@@ -4186,16 +4372,53 @@
         }
         return bucketBuilder_;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.Histogram)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
+    private static final io.prometheus.client.Metrics.Histogram DEFAULT_INSTANCE;
     static {
-      defaultInstance = new Histogram(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.Histogram();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.Histogram)
+    public static io.prometheus.client.Metrics.Histogram getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Histogram>
+        PARSER = new com.google.protobuf.AbstractParser<Histogram>() {
+      public Histogram parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new Histogram(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Histogram> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Histogram> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.Histogram getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   public interface BucketOrBuilder extends
@@ -4203,76 +4426,50 @@
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>optional uint64 cumulative_count = 1;</code>
-     *
      * <pre>
      * Cumulative in increasing order.
      * </pre>
-     */
-    boolean hasCumulativeCount();
-    /**
-     * <code>optional uint64 cumulative_count = 1;</code>
      *
-     * <pre>
-     * Cumulative in increasing order.
-     * </pre>
+     * <code>optional uint64 cumulative_count = 1;</code>
      */
     long getCumulativeCount();
 
     /**
-     * <code>optional double upper_bound = 2;</code>
-     *
      * <pre>
      * Inclusive.
      * </pre>
-     */
-    boolean hasUpperBound();
-    /**
-     * <code>optional double upper_bound = 2;</code>
      *
-     * <pre>
-     * Inclusive.
-     * </pre>
+     * <code>optional double upper_bound = 2;</code>
      */
     double getUpperBound();
   }
   /**
    * Protobuf type {@code io.prometheus.client.Bucket}
    */
-  public static final class Bucket extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class Bucket extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.Bucket)
       BucketOrBuilder {
     // Use Bucket.newBuilder() to construct.
-    private Bucket(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private Bucket(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private Bucket(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final Bucket defaultInstance;
-    public static Bucket getDefaultInstance() {
-      return defaultInstance;
+    private Bucket() {
+      cumulativeCount_ = 0L;
+      upperBound_ = 0D;
     }
 
-    public Bucket getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private Bucket(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -4282,19 +4479,18 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
             }
             case 8: {
-              bitField0_ |= 0x00000001;
+
               cumulativeCount_ = input.readUInt64();
               break;
             }
             case 17: {
-              bitField0_ |= 0x00000002;
+
               upperBound_ = input.readDouble();
               break;
             }
@@ -4304,9 +4500,8 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -4315,47 +4510,21 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.Bucket.class, io.prometheus.client.Metrics.Bucket.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<Bucket> PARSER =
-        new com.google.protobuf.AbstractParser<Bucket>() {
-      public Bucket parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Bucket(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<Bucket> getParserForType() {
-      return PARSER;
-    }
-
-    private int bitField0_;
     public static final int CUMULATIVE_COUNT_FIELD_NUMBER = 1;
     private long cumulativeCount_;
     /**
-     * <code>optional uint64 cumulative_count = 1;</code>
-     *
      * <pre>
      * Cumulative in increasing order.
      * </pre>
-     */
-    public boolean hasCumulativeCount() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
-    /**
-     * <code>optional uint64 cumulative_count = 1;</code>
      *
-     * <pre>
-     * Cumulative in increasing order.
-     * </pre>
+     * <code>optional uint64 cumulative_count = 1;</code>
      */
     public long getCumulativeCount() {
       return cumulativeCount_;
@@ -4364,30 +4533,16 @@
     public static final int UPPER_BOUND_FIELD_NUMBER = 2;
     private double upperBound_;
     /**
-     * <code>optional double upper_bound = 2;</code>
-     *
      * <pre>
      * Inclusive.
      * </pre>
-     */
-    public boolean hasUpperBound() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
-    }
-    /**
-     * <code>optional double upper_bound = 2;</code>
      *
-     * <pre>
-     * Inclusive.
-     * </pre>
+     * <code>optional double upper_bound = 2;</code>
      */
     public double getUpperBound() {
       return upperBound_;
     }
 
-    private void initFields() {
-      cumulativeCount_ = 0L;
-      upperBound_ = 0D;
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -4400,40 +4555,68 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (cumulativeCount_ != 0L) {
         output.writeUInt64(1, cumulativeCount_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (upperBound_ != 0D) {
         output.writeDouble(2, upperBound_);
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (cumulativeCount_ != 0L) {
         size += com.google.protobuf.CodedOutputStream
           .computeUInt64Size(1, cumulativeCount_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (upperBound_ != 0D) {
         size += com.google.protobuf.CodedOutputStream
           .computeDoubleSize(2, upperBound_);
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.Bucket)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.Bucket other = (io.prometheus.client.Metrics.Bucket) obj;
+
+      boolean result = true;
+      result = result && (getCumulativeCount()
+          == other.getCumulativeCount());
+      result = result && (
+          java.lang.Double.doubleToLongBits(getUpperBound())
+          == java.lang.Double.doubleToLongBits(
+              other.getUpperBound()));
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (37 * hash) + CUMULATIVE_COUNT_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          getCumulativeCount());
+      hash = (37 * hash) + UPPER_BOUND_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          java.lang.Double.doubleToLongBits(getUpperBound()));
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.Bucket parseFrom(
@@ -4459,46 +4642,57 @@
     }
     public static io.prometheus.client.Metrics.Bucket parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Bucket parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Bucket parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Bucket parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Bucket parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Bucket parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.Bucket prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.Bucket prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -4506,7 +4700,7 @@
      * Protobuf type {@code io.prometheus.client.Bucket}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.Bucket)
         io.prometheus.client.Metrics.BucketOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -4514,7 +4708,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Bucket_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Bucket_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -4527,29 +4721,22 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         cumulativeCount_ = 0L;
-        bitField0_ = (bitField0_ & ~0x00000001);
-        upperBound_ = 0D;
-        bitField0_ = (bitField0_ & ~0x00000002);
-        return this;
-      }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
+        upperBound_ = 0D;
+
+        return this;
       }
 
       public com.google.protobuf.Descriptors.Descriptor
@@ -4571,21 +4758,38 @@
 
       public io.prometheus.client.Metrics.Bucket buildPartial() {
         io.prometheus.client.Metrics.Bucket result = new io.prometheus.client.Metrics.Bucket(this);
-        int from_bitField0_ = bitField0_;
-        int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
         result.cumulativeCount_ = cumulativeCount_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-          to_bitField0_ |= 0x00000002;
-        }
         result.upperBound_ = upperBound_;
-        result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.Bucket) {
           return mergeFrom((io.prometheus.client.Metrics.Bucket)other);
@@ -4597,13 +4801,13 @@
 
       public Builder mergeFrom(io.prometheus.client.Metrics.Bucket other) {
         if (other == io.prometheus.client.Metrics.Bucket.getDefaultInstance()) return this;
-        if (other.hasCumulativeCount()) {
+        if (other.getCumulativeCount() != 0L) {
           setCumulativeCount(other.getCumulativeCount());
         }
-        if (other.hasUpperBound()) {
+        if (other.getUpperBound() != 0D) {
           setUpperBound(other.getUpperBound());
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -4620,7 +4824,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.Bucket) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -4628,51 +4832,40 @@
         }
         return this;
       }
-      private int bitField0_;
 
       private long cumulativeCount_ ;
       /**
-       * <code>optional uint64 cumulative_count = 1;</code>
-       *
        * <pre>
        * Cumulative in increasing order.
        * </pre>
-       */
-      public boolean hasCumulativeCount() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional uint64 cumulative_count = 1;</code>
        *
-       * <pre>
-       * Cumulative in increasing order.
-       * </pre>
+       * <code>optional uint64 cumulative_count = 1;</code>
        */
       public long getCumulativeCount() {
         return cumulativeCount_;
       }
       /**
-       * <code>optional uint64 cumulative_count = 1;</code>
-       *
        * <pre>
        * Cumulative in increasing order.
        * </pre>
+       *
+       * <code>optional uint64 cumulative_count = 1;</code>
        */
       public Builder setCumulativeCount(long value) {
-        bitField0_ |= 0x00000001;
+        
         cumulativeCount_ = value;
         onChanged();
         return this;
       }
       /**
-       * <code>optional uint64 cumulative_count = 1;</code>
-       *
        * <pre>
        * Cumulative in increasing order.
        * </pre>
+       *
+       * <code>optional uint64 cumulative_count = 1;</code>
        */
       public Builder clearCumulativeCount() {
-        bitField0_ = (bitField0_ & ~0x00000001);
+        
         cumulativeCount_ = 0L;
         onChanged();
         return this;
@@ -4680,61 +4873,88 @@
 
       private double upperBound_ ;
       /**
-       * <code>optional double upper_bound = 2;</code>
-       *
        * <pre>
        * Inclusive.
        * </pre>
-       */
-      public boolean hasUpperBound() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
-      }
-      /**
-       * <code>optional double upper_bound = 2;</code>
        *
-       * <pre>
-       * Inclusive.
-       * </pre>
+       * <code>optional double upper_bound = 2;</code>
        */
       public double getUpperBound() {
         return upperBound_;
       }
       /**
-       * <code>optional double upper_bound = 2;</code>
-       *
        * <pre>
        * Inclusive.
        * </pre>
+       *
+       * <code>optional double upper_bound = 2;</code>
        */
       public Builder setUpperBound(double value) {
-        bitField0_ |= 0x00000002;
+        
         upperBound_ = value;
         onChanged();
         return this;
       }
       /**
-       * <code>optional double upper_bound = 2;</code>
-       *
        * <pre>
        * Inclusive.
        * </pre>
+       *
+       * <code>optional double upper_bound = 2;</code>
        */
       public Builder clearUpperBound() {
-        bitField0_ = (bitField0_ & ~0x00000002);
+        
         upperBound_ = 0D;
         onChanged();
         return this;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.Bucket)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
+    private static final io.prometheus.client.Metrics.Bucket DEFAULT_INSTANCE;
     static {
-      defaultInstance = new Bucket(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.Bucket();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.Bucket)
+    public static io.prometheus.client.Metrics.Bucket getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Bucket>
+        PARSER = new com.google.protobuf.AbstractParser<Bucket>() {
+      public Bucket parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new Bucket(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Bucket> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Bucket> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.Bucket getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   public interface MetricOrBuilder extends
@@ -4833,49 +5053,35 @@
     /**
      * <code>optional int64 timestamp_ms = 6;</code>
      */
-    boolean hasTimestampMs();
-    /**
-     * <code>optional int64 timestamp_ms = 6;</code>
-     */
     long getTimestampMs();
   }
   /**
    * Protobuf type {@code io.prometheus.client.Metric}
    */
-  public static final class Metric extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class Metric extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.Metric)
       MetricOrBuilder {
     // Use Metric.newBuilder() to construct.
-    private Metric(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private Metric(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private Metric(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final Metric defaultInstance;
-    public static Metric getDefaultInstance() {
-      return defaultInstance;
+    private Metric() {
+      label_ = java.util.Collections.emptyList();
+      timestampMs_ = 0L;
     }
 
-    public Metric getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private Metric(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -4885,8 +5091,7 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
@@ -4896,77 +5101,78 @@
                 label_ = new java.util.ArrayList<io.prometheus.client.Metrics.LabelPair>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              label_.add(input.readMessage(io.prometheus.client.Metrics.LabelPair.PARSER, extensionRegistry));
+              label_.add(
+                  input.readMessage(io.prometheus.client.Metrics.LabelPair.parser(), extensionRegistry));
               break;
             }
             case 18: {
               io.prometheus.client.Metrics.Gauge.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+              if (gauge_ != null) {
                 subBuilder = gauge_.toBuilder();
               }
-              gauge_ = input.readMessage(io.prometheus.client.Metrics.Gauge.PARSER, extensionRegistry);
+              gauge_ = input.readMessage(io.prometheus.client.Metrics.Gauge.parser(), extensionRegistry);
               if (subBuilder != null) {
                 subBuilder.mergeFrom(gauge_);
                 gauge_ = subBuilder.buildPartial();
               }
-              bitField0_ |= 0x00000001;
+
               break;
             }
             case 26: {
               io.prometheus.client.Metrics.Counter.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+              if (counter_ != null) {
                 subBuilder = counter_.toBuilder();
               }
-              counter_ = input.readMessage(io.prometheus.client.Metrics.Counter.PARSER, extensionRegistry);
+              counter_ = input.readMessage(io.prometheus.client.Metrics.Counter.parser(), extensionRegistry);
               if (subBuilder != null) {
                 subBuilder.mergeFrom(counter_);
                 counter_ = subBuilder.buildPartial();
               }
-              bitField0_ |= 0x00000002;
+
               break;
             }
             case 34: {
               io.prometheus.client.Metrics.Summary.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000004) == 0x00000004)) {
+              if (summary_ != null) {
                 subBuilder = summary_.toBuilder();
               }
-              summary_ = input.readMessage(io.prometheus.client.Metrics.Summary.PARSER, extensionRegistry);
+              summary_ = input.readMessage(io.prometheus.client.Metrics.Summary.parser(), extensionRegistry);
               if (subBuilder != null) {
                 subBuilder.mergeFrom(summary_);
                 summary_ = subBuilder.buildPartial();
               }
-              bitField0_ |= 0x00000004;
+
               break;
             }
             case 42: {
               io.prometheus.client.Metrics.Untyped.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000008) == 0x00000008)) {
+              if (untyped_ != null) {
                 subBuilder = untyped_.toBuilder();
               }
-              untyped_ = input.readMessage(io.prometheus.client.Metrics.Untyped.PARSER, extensionRegistry);
+              untyped_ = input.readMessage(io.prometheus.client.Metrics.Untyped.parser(), extensionRegistry);
               if (subBuilder != null) {
                 subBuilder.mergeFrom(untyped_);
                 untyped_ = subBuilder.buildPartial();
               }
-              bitField0_ |= 0x00000008;
+
               break;
             }
             case 48: {
-              bitField0_ |= 0x00000020;
+
               timestampMs_ = input.readInt64();
               break;
             }
             case 58: {
               io.prometheus.client.Metrics.Histogram.Builder subBuilder = null;
-              if (((bitField0_ & 0x00000010) == 0x00000010)) {
+              if (histogram_ != null) {
                 subBuilder = histogram_.toBuilder();
               }
-              histogram_ = input.readMessage(io.prometheus.client.Metrics.Histogram.PARSER, extensionRegistry);
+              histogram_ = input.readMessage(io.prometheus.client.Metrics.Histogram.parser(), extensionRegistry);
               if (subBuilder != null) {
                 subBuilder.mergeFrom(histogram_);
                 histogram_ = subBuilder.buildPartial();
               }
-              bitField0_ |= 0x00000010;
+
               break;
             }
           }
@@ -4975,12 +5181,11 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
           label_ = java.util.Collections.unmodifiableList(label_);
         }
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -4989,28 +5194,13 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.Metric.class, io.prometheus.client.Metrics.Metric.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<Metric> PARSER =
-        new com.google.protobuf.AbstractParser<Metric>() {
-      public Metric parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new Metric(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<Metric> getParserForType() {
-      return PARSER;
-    }
-
     private int bitField0_;
     public static final int LABEL_FIELD_NUMBER = 1;
     private java.util.List<io.prometheus.client.Metrics.LabelPair> label_;
@@ -5053,19 +5243,19 @@
      * <code>optional .io.prometheus.client.Gauge gauge = 2;</code>
      */
     public boolean hasGauge() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
+      return gauge_ != null;
     }
     /**
      * <code>optional .io.prometheus.client.Gauge gauge = 2;</code>
      */
     public io.prometheus.client.Metrics.Gauge getGauge() {
-      return gauge_;
+      return gauge_ == null ? io.prometheus.client.Metrics.Gauge.getDefaultInstance() : gauge_;
     }
     /**
      * <code>optional .io.prometheus.client.Gauge gauge = 2;</code>
      */
     public io.prometheus.client.Metrics.GaugeOrBuilder getGaugeOrBuilder() {
-      return gauge_;
+      return getGauge();
     }
 
     public static final int COUNTER_FIELD_NUMBER = 3;
@@ -5074,19 +5264,19 @@
      * <code>optional .io.prometheus.client.Counter counter = 3;</code>
      */
     public boolean hasCounter() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
+      return counter_ != null;
     }
     /**
      * <code>optional .io.prometheus.client.Counter counter = 3;</code>
      */
     public io.prometheus.client.Metrics.Counter getCounter() {
-      return counter_;
+      return counter_ == null ? io.prometheus.client.Metrics.Counter.getDefaultInstance() : counter_;
     }
     /**
      * <code>optional .io.prometheus.client.Counter counter = 3;</code>
      */
     public io.prometheus.client.Metrics.CounterOrBuilder getCounterOrBuilder() {
-      return counter_;
+      return getCounter();
     }
 
     public static final int SUMMARY_FIELD_NUMBER = 4;
@@ -5095,19 +5285,19 @@
      * <code>optional .io.prometheus.client.Summary summary = 4;</code>
      */
     public boolean hasSummary() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+      return summary_ != null;
     }
     /**
      * <code>optional .io.prometheus.client.Summary summary = 4;</code>
      */
     public io.prometheus.client.Metrics.Summary getSummary() {
-      return summary_;
+      return summary_ == null ? io.prometheus.client.Metrics.Summary.getDefaultInstance() : summary_;
     }
     /**
      * <code>optional .io.prometheus.client.Summary summary = 4;</code>
      */
     public io.prometheus.client.Metrics.SummaryOrBuilder getSummaryOrBuilder() {
-      return summary_;
+      return getSummary();
     }
 
     public static final int UNTYPED_FIELD_NUMBER = 5;
@@ -5116,19 +5306,19 @@
      * <code>optional .io.prometheus.client.Untyped untyped = 5;</code>
      */
     public boolean hasUntyped() {
-      return ((bitField0_ & 0x00000008) == 0x00000008);
+      return untyped_ != null;
     }
     /**
      * <code>optional .io.prometheus.client.Untyped untyped = 5;</code>
      */
     public io.prometheus.client.Metrics.Untyped getUntyped() {
-      return untyped_;
+      return untyped_ == null ? io.prometheus.client.Metrics.Untyped.getDefaultInstance() : untyped_;
     }
     /**
      * <code>optional .io.prometheus.client.Untyped untyped = 5;</code>
      */
     public io.prometheus.client.Metrics.UntypedOrBuilder getUntypedOrBuilder() {
-      return untyped_;
+      return getUntyped();
     }
 
     public static final int HISTOGRAM_FIELD_NUMBER = 7;
@@ -5137,19 +5327,19 @@
      * <code>optional .io.prometheus.client.Histogram histogram = 7;</code>
      */
     public boolean hasHistogram() {
-      return ((bitField0_ & 0x00000010) == 0x00000010);
+      return histogram_ != null;
     }
     /**
      * <code>optional .io.prometheus.client.Histogram histogram = 7;</code>
      */
     public io.prometheus.client.Metrics.Histogram getHistogram() {
-      return histogram_;
+      return histogram_ == null ? io.prometheus.client.Metrics.Histogram.getDefaultInstance() : histogram_;
     }
     /**
      * <code>optional .io.prometheus.client.Histogram histogram = 7;</code>
      */
     public io.prometheus.client.Metrics.HistogramOrBuilder getHistogramOrBuilder() {
-      return histogram_;
+      return getHistogram();
     }
 
     public static final int TIMESTAMP_MS_FIELD_NUMBER = 6;
@@ -5157,25 +5347,10 @@
     /**
      * <code>optional int64 timestamp_ms = 6;</code>
      */
-    public boolean hasTimestampMs() {
-      return ((bitField0_ & 0x00000020) == 0x00000020);
-    }
-    /**
-     * <code>optional int64 timestamp_ms = 6;</code>
-     */
     public long getTimestampMs() {
       return timestampMs_;
     }
 
-    private void initFields() {
-      label_ = java.util.Collections.emptyList();
-      gauge_ = io.prometheus.client.Metrics.Gauge.getDefaultInstance();
-      counter_ = io.prometheus.client.Metrics.Counter.getDefaultInstance();
-      summary_ = io.prometheus.client.Metrics.Summary.getDefaultInstance();
-      untyped_ = io.prometheus.client.Metrics.Untyped.getDefaultInstance();
-      histogram_ = io.prometheus.client.Metrics.Histogram.getDefaultInstance();
-      timestampMs_ = 0L;
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -5188,34 +5363,31 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
       for (int i = 0; i < label_.size(); i++) {
         output.writeMessage(1, label_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        output.writeMessage(2, gauge_);
+      if (gauge_ != null) {
+        output.writeMessage(2, getGauge());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
-        output.writeMessage(3, counter_);
+      if (counter_ != null) {
+        output.writeMessage(3, getCounter());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
-        output.writeMessage(4, summary_);
+      if (summary_ != null) {
+        output.writeMessage(4, getSummary());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
-        output.writeMessage(5, untyped_);
+      if (untyped_ != null) {
+        output.writeMessage(5, getUntyped());
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (timestampMs_ != 0L) {
         output.writeInt64(6, timestampMs_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
-        output.writeMessage(7, histogram_);
+      if (histogram_ != null) {
+        output.writeMessage(7, getHistogram());
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
@@ -5223,40 +5395,115 @@
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, label_.get(i));
       }
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+      if (gauge_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, gauge_);
+          .computeMessageSize(2, getGauge());
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+      if (counter_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(3, counter_);
+          .computeMessageSize(3, getCounter());
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (summary_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(4, summary_);
+          .computeMessageSize(4, getSummary());
       }
-      if (((bitField0_ & 0x00000008) == 0x00000008)) {
+      if (untyped_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, untyped_);
+          .computeMessageSize(5, getUntyped());
       }
-      if (((bitField0_ & 0x00000020) == 0x00000020)) {
+      if (timestampMs_ != 0L) {
         size += com.google.protobuf.CodedOutputStream
           .computeInt64Size(6, timestampMs_);
       }
-      if (((bitField0_ & 0x00000010) == 0x00000010)) {
+      if (histogram_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(7, histogram_);
+          .computeMessageSize(7, getHistogram());
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.Metric)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.Metric other = (io.prometheus.client.Metrics.Metric) obj;
+
+      boolean result = true;
+      result = result && getLabelList()
+          .equals(other.getLabelList());
+      result = result && (hasGauge() == other.hasGauge());
+      if (hasGauge()) {
+        result = result && getGauge()
+            .equals(other.getGauge());
+      }
+      result = result && (hasCounter() == other.hasCounter());
+      if (hasCounter()) {
+        result = result && getCounter()
+            .equals(other.getCounter());
+      }
+      result = result && (hasSummary() == other.hasSummary());
+      if (hasSummary()) {
+        result = result && getSummary()
+            .equals(other.getSummary());
+      }
+      result = result && (hasUntyped() == other.hasUntyped());
+      if (hasUntyped()) {
+        result = result && getUntyped()
+            .equals(other.getUntyped());
+      }
+      result = result && (hasHistogram() == other.hasHistogram());
+      if (hasHistogram()) {
+        result = result && getHistogram()
+            .equals(other.getHistogram());
+      }
+      result = result && (getTimestampMs()
+          == other.getTimestampMs());
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (getLabelCount() > 0) {
+        hash = (37 * hash) + LABEL_FIELD_NUMBER;
+        hash = (53 * hash) + getLabelList().hashCode();
+      }
+      if (hasGauge()) {
+        hash = (37 * hash) + GAUGE_FIELD_NUMBER;
+        hash = (53 * hash) + getGauge().hashCode();
+      }
+      if (hasCounter()) {
+        hash = (37 * hash) + COUNTER_FIELD_NUMBER;
+        hash = (53 * hash) + getCounter().hashCode();
+      }
+      if (hasSummary()) {
+        hash = (37 * hash) + SUMMARY_FIELD_NUMBER;
+        hash = (53 * hash) + getSummary().hashCode();
+      }
+      if (hasUntyped()) {
+        hash = (37 * hash) + UNTYPED_FIELD_NUMBER;
+        hash = (53 * hash) + getUntyped().hashCode();
+      }
+      if (hasHistogram()) {
+        hash = (37 * hash) + HISTOGRAM_FIELD_NUMBER;
+        hash = (53 * hash) + getHistogram().hashCode();
+      }
+      hash = (37 * hash) + TIMESTAMP_MS_FIELD_NUMBER;
+      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+          getTimestampMs());
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.Metric parseFrom(
@@ -5282,46 +5529,57 @@
     }
     public static io.prometheus.client.Metrics.Metric parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Metric parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Metric parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Metric parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.Metric parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.Metric parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.Metric prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.Metric prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -5329,7 +5587,7 @@
      * Protobuf type {@code io.prometheus.client.Metric}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.Metric)
         io.prometheus.client.Metrics.MetricOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -5337,7 +5595,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Metric_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_Metric_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -5350,24 +5608,16 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
           getLabelFieldBuilder();
-          getGaugeFieldBuilder();
-          getCounterFieldBuilder();
-          getSummaryFieldBuilder();
-          getUntypedFieldBuilder();
-          getHistogramFieldBuilder();
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         if (labelBuilder_ == null) {
@@ -5377,42 +5627,38 @@
           labelBuilder_.clear();
         }
         if (gaugeBuilder_ == null) {
-          gauge_ = io.prometheus.client.Metrics.Gauge.getDefaultInstance();
+          gauge_ = null;
         } else {
-          gaugeBuilder_.clear();
+          gauge_ = null;
+          gaugeBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000002);
         if (counterBuilder_ == null) {
-          counter_ = io.prometheus.client.Metrics.Counter.getDefaultInstance();
+          counter_ = null;
         } else {
-          counterBuilder_.clear();
+          counter_ = null;
+          counterBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000004);
         if (summaryBuilder_ == null) {
-          summary_ = io.prometheus.client.Metrics.Summary.getDefaultInstance();
+          summary_ = null;
         } else {
-          summaryBuilder_.clear();
+          summary_ = null;
+          summaryBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000008);
         if (untypedBuilder_ == null) {
-          untyped_ = io.prometheus.client.Metrics.Untyped.getDefaultInstance();
+          untyped_ = null;
         } else {
-          untypedBuilder_.clear();
+          untyped_ = null;
+          untypedBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000010);
         if (histogramBuilder_ == null) {
-          histogram_ = io.prometheus.client.Metrics.Histogram.getDefaultInstance();
+          histogram_ = null;
         } else {
-          histogramBuilder_.clear();
+          histogram_ = null;
+          histogramBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000020);
         timestampMs_ = 0L;
-        bitField0_ = (bitField0_ & ~0x00000040);
-        return this;
-      }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
+        return this;
       }
 
       public com.google.protobuf.Descriptors.Descriptor
@@ -5445,55 +5691,63 @@
         } else {
           result.label_ = labelBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-          to_bitField0_ |= 0x00000001;
-        }
         if (gaugeBuilder_ == null) {
           result.gauge_ = gauge_;
         } else {
           result.gauge_ = gaugeBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
-          to_bitField0_ |= 0x00000002;
-        }
         if (counterBuilder_ == null) {
           result.counter_ = counter_;
         } else {
           result.counter_ = counterBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
-          to_bitField0_ |= 0x00000004;
-        }
         if (summaryBuilder_ == null) {
           result.summary_ = summary_;
         } else {
           result.summary_ = summaryBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
-          to_bitField0_ |= 0x00000008;
-        }
         if (untypedBuilder_ == null) {
           result.untyped_ = untyped_;
         } else {
           result.untyped_ = untypedBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
-          to_bitField0_ |= 0x00000010;
-        }
         if (histogramBuilder_ == null) {
           result.histogram_ = histogram_;
         } else {
           result.histogram_ = histogramBuilder_.build();
         }
-        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
-          to_bitField0_ |= 0x00000020;
-        }
         result.timestampMs_ = timestampMs_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.Metric) {
           return mergeFrom((io.prometheus.client.Metrics.Metric)other);
@@ -5524,7 +5778,7 @@
               label_ = other.label_;
               bitField0_ = (bitField0_ & ~0x00000001);
               labelBuilder_ = 
-                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                    getLabelFieldBuilder() : null;
             } else {
               labelBuilder_.addAllMessages(other.label_);
@@ -5546,10 +5800,10 @@
         if (other.hasHistogram()) {
           mergeHistogram(other.getHistogram());
         }
-        if (other.hasTimestampMs()) {
+        if (other.getTimestampMs() != 0L) {
           setTimestampMs(other.getTimestampMs());
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -5566,7 +5820,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.Metric) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -5585,7 +5839,7 @@
          }
       }
 
-      private com.google.protobuf.RepeatedFieldBuilder<
+      private com.google.protobuf.RepeatedFieldBuilderV3<
           io.prometheus.client.Metrics.LabelPair, io.prometheus.client.Metrics.LabelPair.Builder, io.prometheus.client.Metrics.LabelPairOrBuilder> labelBuilder_;
 
       /**
@@ -5801,11 +6055,11 @@
            getLabelBuilderList() {
         return getLabelFieldBuilder().getBuilderList();
       }
-      private com.google.protobuf.RepeatedFieldBuilder<
+      private com.google.protobuf.RepeatedFieldBuilderV3<
           io.prometheus.client.Metrics.LabelPair, io.prometheus.client.Metrics.LabelPair.Builder, io.prometheus.client.Metrics.LabelPairOrBuilder> 
           getLabelFieldBuilder() {
         if (labelBuilder_ == null) {
-          labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+          labelBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               io.prometheus.client.Metrics.LabelPair, io.prometheus.client.Metrics.LabelPair.Builder, io.prometheus.client.Metrics.LabelPairOrBuilder>(
                   label_,
                   ((bitField0_ & 0x00000001) == 0x00000001),
@@ -5816,21 +6070,21 @@
         return labelBuilder_;
       }
 
-      private io.prometheus.client.Metrics.Gauge gauge_ = io.prometheus.client.Metrics.Gauge.getDefaultInstance();
-      private com.google.protobuf.SingleFieldBuilder<
+      private io.prometheus.client.Metrics.Gauge gauge_ = null;
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Gauge, io.prometheus.client.Metrics.Gauge.Builder, io.prometheus.client.Metrics.GaugeOrBuilder> gaugeBuilder_;
       /**
        * <code>optional .io.prometheus.client.Gauge gauge = 2;</code>
        */
       public boolean hasGauge() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
+        return gaugeBuilder_ != null || gauge_ != null;
       }
       /**
        * <code>optional .io.prometheus.client.Gauge gauge = 2;</code>
        */
       public io.prometheus.client.Metrics.Gauge getGauge() {
         if (gaugeBuilder_ == null) {
-          return gauge_;
+          return gauge_ == null ? io.prometheus.client.Metrics.Gauge.getDefaultInstance() : gauge_;
         } else {
           return gaugeBuilder_.getMessage();
         }
@@ -5848,7 +6102,7 @@
         } else {
           gaugeBuilder_.setMessage(value);
         }
-        bitField0_ |= 0x00000002;
+
         return this;
       }
       /**
@@ -5862,7 +6116,7 @@
         } else {
           gaugeBuilder_.setMessage(builderForValue.build());
         }
-        bitField0_ |= 0x00000002;
+
         return this;
       }
       /**
@@ -5870,8 +6124,7 @@
        */
       public Builder mergeGauge(io.prometheus.client.Metrics.Gauge value) {
         if (gaugeBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) == 0x00000002) &&
-              gauge_ != io.prometheus.client.Metrics.Gauge.getDefaultInstance()) {
+          if (gauge_ != null) {
             gauge_ =
               io.prometheus.client.Metrics.Gauge.newBuilder(gauge_).mergeFrom(value).buildPartial();
           } else {
@@ -5881,7 +6134,7 @@
         } else {
           gaugeBuilder_.mergeFrom(value);
         }
-        bitField0_ |= 0x00000002;
+
         return this;
       }
       /**
@@ -5889,19 +6142,20 @@
        */
       public Builder clearGauge() {
         if (gaugeBuilder_ == null) {
-          gauge_ = io.prometheus.client.Metrics.Gauge.getDefaultInstance();
+          gauge_ = null;
           onChanged();
         } else {
-          gaugeBuilder_.clear();
+          gauge_ = null;
+          gaugeBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000002);
+
         return this;
       }
       /**
        * <code>optional .io.prometheus.client.Gauge gauge = 2;</code>
        */
       public io.prometheus.client.Metrics.Gauge.Builder getGaugeBuilder() {
-        bitField0_ |= 0x00000002;
+        
         onChanged();
         return getGaugeFieldBuilder().getBuilder();
       }
@@ -5912,17 +6166,18 @@
         if (gaugeBuilder_ != null) {
           return gaugeBuilder_.getMessageOrBuilder();
         } else {
-          return gauge_;
+          return gauge_ == null ?
+              io.prometheus.client.Metrics.Gauge.getDefaultInstance() : gauge_;
         }
       }
       /**
        * <code>optional .io.prometheus.client.Gauge gauge = 2;</code>
        */
-      private com.google.protobuf.SingleFieldBuilder<
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Gauge, io.prometheus.client.Metrics.Gauge.Builder, io.prometheus.client.Metrics.GaugeOrBuilder> 
           getGaugeFieldBuilder() {
         if (gaugeBuilder_ == null) {
-          gaugeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+          gaugeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               io.prometheus.client.Metrics.Gauge, io.prometheus.client.Metrics.Gauge.Builder, io.prometheus.client.Metrics.GaugeOrBuilder>(
                   getGauge(),
                   getParentForChildren(),
@@ -5932,21 +6187,21 @@
         return gaugeBuilder_;
       }
 
-      private io.prometheus.client.Metrics.Counter counter_ = io.prometheus.client.Metrics.Counter.getDefaultInstance();
-      private com.google.protobuf.SingleFieldBuilder<
+      private io.prometheus.client.Metrics.Counter counter_ = null;
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Counter, io.prometheus.client.Metrics.Counter.Builder, io.prometheus.client.Metrics.CounterOrBuilder> counterBuilder_;
       /**
        * <code>optional .io.prometheus.client.Counter counter = 3;</code>
        */
       public boolean hasCounter() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+        return counterBuilder_ != null || counter_ != null;
       }
       /**
        * <code>optional .io.prometheus.client.Counter counter = 3;</code>
        */
       public io.prometheus.client.Metrics.Counter getCounter() {
         if (counterBuilder_ == null) {
-          return counter_;
+          return counter_ == null ? io.prometheus.client.Metrics.Counter.getDefaultInstance() : counter_;
         } else {
           return counterBuilder_.getMessage();
         }
@@ -5964,7 +6219,7 @@
         } else {
           counterBuilder_.setMessage(value);
         }
-        bitField0_ |= 0x00000004;
+
         return this;
       }
       /**
@@ -5978,7 +6233,7 @@
         } else {
           counterBuilder_.setMessage(builderForValue.build());
         }
-        bitField0_ |= 0x00000004;
+
         return this;
       }
       /**
@@ -5986,8 +6241,7 @@
        */
       public Builder mergeCounter(io.prometheus.client.Metrics.Counter value) {
         if (counterBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) == 0x00000004) &&
-              counter_ != io.prometheus.client.Metrics.Counter.getDefaultInstance()) {
+          if (counter_ != null) {
             counter_ =
               io.prometheus.client.Metrics.Counter.newBuilder(counter_).mergeFrom(value).buildPartial();
           } else {
@@ -5997,7 +6251,7 @@
         } else {
           counterBuilder_.mergeFrom(value);
         }
-        bitField0_ |= 0x00000004;
+
         return this;
       }
       /**
@@ -6005,19 +6259,20 @@
        */
       public Builder clearCounter() {
         if (counterBuilder_ == null) {
-          counter_ = io.prometheus.client.Metrics.Counter.getDefaultInstance();
+          counter_ = null;
           onChanged();
         } else {
-          counterBuilder_.clear();
+          counter_ = null;
+          counterBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000004);
+
         return this;
       }
       /**
        * <code>optional .io.prometheus.client.Counter counter = 3;</code>
        */
       public io.prometheus.client.Metrics.Counter.Builder getCounterBuilder() {
-        bitField0_ |= 0x00000004;
+        
         onChanged();
         return getCounterFieldBuilder().getBuilder();
       }
@@ -6028,17 +6283,18 @@
         if (counterBuilder_ != null) {
           return counterBuilder_.getMessageOrBuilder();
         } else {
-          return counter_;
+          return counter_ == null ?
+              io.prometheus.client.Metrics.Counter.getDefaultInstance() : counter_;
         }
       }
       /**
        * <code>optional .io.prometheus.client.Counter counter = 3;</code>
        */
-      private com.google.protobuf.SingleFieldBuilder<
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Counter, io.prometheus.client.Metrics.Counter.Builder, io.prometheus.client.Metrics.CounterOrBuilder> 
           getCounterFieldBuilder() {
         if (counterBuilder_ == null) {
-          counterBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+          counterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               io.prometheus.client.Metrics.Counter, io.prometheus.client.Metrics.Counter.Builder, io.prometheus.client.Metrics.CounterOrBuilder>(
                   getCounter(),
                   getParentForChildren(),
@@ -6048,21 +6304,21 @@
         return counterBuilder_;
       }
 
-      private io.prometheus.client.Metrics.Summary summary_ = io.prometheus.client.Metrics.Summary.getDefaultInstance();
-      private com.google.protobuf.SingleFieldBuilder<
+      private io.prometheus.client.Metrics.Summary summary_ = null;
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Summary, io.prometheus.client.Metrics.Summary.Builder, io.prometheus.client.Metrics.SummaryOrBuilder> summaryBuilder_;
       /**
        * <code>optional .io.prometheus.client.Summary summary = 4;</code>
        */
       public boolean hasSummary() {
-        return ((bitField0_ & 0x00000008) == 0x00000008);
+        return summaryBuilder_ != null || summary_ != null;
       }
       /**
        * <code>optional .io.prometheus.client.Summary summary = 4;</code>
        */
       public io.prometheus.client.Metrics.Summary getSummary() {
         if (summaryBuilder_ == null) {
-          return summary_;
+          return summary_ == null ? io.prometheus.client.Metrics.Summary.getDefaultInstance() : summary_;
         } else {
           return summaryBuilder_.getMessage();
         }
@@ -6080,7 +6336,7 @@
         } else {
           summaryBuilder_.setMessage(value);
         }
-        bitField0_ |= 0x00000008;
+
         return this;
       }
       /**
@@ -6094,7 +6350,7 @@
         } else {
           summaryBuilder_.setMessage(builderForValue.build());
         }
-        bitField0_ |= 0x00000008;
+
         return this;
       }
       /**
@@ -6102,8 +6358,7 @@
        */
       public Builder mergeSummary(io.prometheus.client.Metrics.Summary value) {
         if (summaryBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) == 0x00000008) &&
-              summary_ != io.prometheus.client.Metrics.Summary.getDefaultInstance()) {
+          if (summary_ != null) {
             summary_ =
               io.prometheus.client.Metrics.Summary.newBuilder(summary_).mergeFrom(value).buildPartial();
           } else {
@@ -6113,7 +6368,7 @@
         } else {
           summaryBuilder_.mergeFrom(value);
         }
-        bitField0_ |= 0x00000008;
+
         return this;
       }
       /**
@@ -6121,19 +6376,20 @@
        */
       public Builder clearSummary() {
         if (summaryBuilder_ == null) {
-          summary_ = io.prometheus.client.Metrics.Summary.getDefaultInstance();
+          summary_ = null;
           onChanged();
         } else {
-          summaryBuilder_.clear();
+          summary_ = null;
+          summaryBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000008);
+
         return this;
       }
       /**
        * <code>optional .io.prometheus.client.Summary summary = 4;</code>
        */
       public io.prometheus.client.Metrics.Summary.Builder getSummaryBuilder() {
-        bitField0_ |= 0x00000008;
+        
         onChanged();
         return getSummaryFieldBuilder().getBuilder();
       }
@@ -6144,17 +6400,18 @@
         if (summaryBuilder_ != null) {
           return summaryBuilder_.getMessageOrBuilder();
         } else {
-          return summary_;
+          return summary_ == null ?
+              io.prometheus.client.Metrics.Summary.getDefaultInstance() : summary_;
         }
       }
       /**
        * <code>optional .io.prometheus.client.Summary summary = 4;</code>
        */
-      private com.google.protobuf.SingleFieldBuilder<
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Summary, io.prometheus.client.Metrics.Summary.Builder, io.prometheus.client.Metrics.SummaryOrBuilder> 
           getSummaryFieldBuilder() {
         if (summaryBuilder_ == null) {
-          summaryBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+          summaryBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               io.prometheus.client.Metrics.Summary, io.prometheus.client.Metrics.Summary.Builder, io.prometheus.client.Metrics.SummaryOrBuilder>(
                   getSummary(),
                   getParentForChildren(),
@@ -6164,21 +6421,21 @@
         return summaryBuilder_;
       }
 
-      private io.prometheus.client.Metrics.Untyped untyped_ = io.prometheus.client.Metrics.Untyped.getDefaultInstance();
-      private com.google.protobuf.SingleFieldBuilder<
+      private io.prometheus.client.Metrics.Untyped untyped_ = null;
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Untyped, io.prometheus.client.Metrics.Untyped.Builder, io.prometheus.client.Metrics.UntypedOrBuilder> untypedBuilder_;
       /**
        * <code>optional .io.prometheus.client.Untyped untyped = 5;</code>
        */
       public boolean hasUntyped() {
-        return ((bitField0_ & 0x00000010) == 0x00000010);
+        return untypedBuilder_ != null || untyped_ != null;
       }
       /**
        * <code>optional .io.prometheus.client.Untyped untyped = 5;</code>
        */
       public io.prometheus.client.Metrics.Untyped getUntyped() {
         if (untypedBuilder_ == null) {
-          return untyped_;
+          return untyped_ == null ? io.prometheus.client.Metrics.Untyped.getDefaultInstance() : untyped_;
         } else {
           return untypedBuilder_.getMessage();
         }
@@ -6196,7 +6453,7 @@
         } else {
           untypedBuilder_.setMessage(value);
         }
-        bitField0_ |= 0x00000010;
+
         return this;
       }
       /**
@@ -6210,7 +6467,7 @@
         } else {
           untypedBuilder_.setMessage(builderForValue.build());
         }
-        bitField0_ |= 0x00000010;
+
         return this;
       }
       /**
@@ -6218,8 +6475,7 @@
        */
       public Builder mergeUntyped(io.prometheus.client.Metrics.Untyped value) {
         if (untypedBuilder_ == null) {
-          if (((bitField0_ & 0x00000010) == 0x00000010) &&
-              untyped_ != io.prometheus.client.Metrics.Untyped.getDefaultInstance()) {
+          if (untyped_ != null) {
             untyped_ =
               io.prometheus.client.Metrics.Untyped.newBuilder(untyped_).mergeFrom(value).buildPartial();
           } else {
@@ -6229,7 +6485,7 @@
         } else {
           untypedBuilder_.mergeFrom(value);
         }
-        bitField0_ |= 0x00000010;
+
         return this;
       }
       /**
@@ -6237,19 +6493,20 @@
        */
       public Builder clearUntyped() {
         if (untypedBuilder_ == null) {
-          untyped_ = io.prometheus.client.Metrics.Untyped.getDefaultInstance();
+          untyped_ = null;
           onChanged();
         } else {
-          untypedBuilder_.clear();
+          untyped_ = null;
+          untypedBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000010);
+
         return this;
       }
       /**
        * <code>optional .io.prometheus.client.Untyped untyped = 5;</code>
        */
       public io.prometheus.client.Metrics.Untyped.Builder getUntypedBuilder() {
-        bitField0_ |= 0x00000010;
+        
         onChanged();
         return getUntypedFieldBuilder().getBuilder();
       }
@@ -6260,17 +6517,18 @@
         if (untypedBuilder_ != null) {
           return untypedBuilder_.getMessageOrBuilder();
         } else {
-          return untyped_;
+          return untyped_ == null ?
+              io.prometheus.client.Metrics.Untyped.getDefaultInstance() : untyped_;
         }
       }
       /**
        * <code>optional .io.prometheus.client.Untyped untyped = 5;</code>
        */
-      private com.google.protobuf.SingleFieldBuilder<
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Untyped, io.prometheus.client.Metrics.Untyped.Builder, io.prometheus.client.Metrics.UntypedOrBuilder> 
           getUntypedFieldBuilder() {
         if (untypedBuilder_ == null) {
-          untypedBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+          untypedBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               io.prometheus.client.Metrics.Untyped, io.prometheus.client.Metrics.Untyped.Builder, io.prometheus.client.Metrics.UntypedOrBuilder>(
                   getUntyped(),
                   getParentForChildren(),
@@ -6280,21 +6538,21 @@
         return untypedBuilder_;
       }
 
-      private io.prometheus.client.Metrics.Histogram histogram_ = io.prometheus.client.Metrics.Histogram.getDefaultInstance();
-      private com.google.protobuf.SingleFieldBuilder<
+      private io.prometheus.client.Metrics.Histogram histogram_ = null;
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Histogram, io.prometheus.client.Metrics.Histogram.Builder, io.prometheus.client.Metrics.HistogramOrBuilder> histogramBuilder_;
       /**
        * <code>optional .io.prometheus.client.Histogram histogram = 7;</code>
        */
       public boolean hasHistogram() {
-        return ((bitField0_ & 0x00000020) == 0x00000020);
+        return histogramBuilder_ != null || histogram_ != null;
       }
       /**
        * <code>optional .io.prometheus.client.Histogram histogram = 7;</code>
        */
       public io.prometheus.client.Metrics.Histogram getHistogram() {
         if (histogramBuilder_ == null) {
-          return histogram_;
+          return histogram_ == null ? io.prometheus.client.Metrics.Histogram.getDefaultInstance() : histogram_;
         } else {
           return histogramBuilder_.getMessage();
         }
@@ -6312,7 +6570,7 @@
         } else {
           histogramBuilder_.setMessage(value);
         }
-        bitField0_ |= 0x00000020;
+
         return this;
       }
       /**
@@ -6326,7 +6584,7 @@
         } else {
           histogramBuilder_.setMessage(builderForValue.build());
         }
-        bitField0_ |= 0x00000020;
+
         return this;
       }
       /**
@@ -6334,8 +6592,7 @@
        */
       public Builder mergeHistogram(io.prometheus.client.Metrics.Histogram value) {
         if (histogramBuilder_ == null) {
-          if (((bitField0_ & 0x00000020) == 0x00000020) &&
-              histogram_ != io.prometheus.client.Metrics.Histogram.getDefaultInstance()) {
+          if (histogram_ != null) {
             histogram_ =
               io.prometheus.client.Metrics.Histogram.newBuilder(histogram_).mergeFrom(value).buildPartial();
           } else {
@@ -6345,7 +6602,7 @@
         } else {
           histogramBuilder_.mergeFrom(value);
         }
-        bitField0_ |= 0x00000020;
+
         return this;
       }
       /**
@@ -6353,19 +6610,20 @@
        */
       public Builder clearHistogram() {
         if (histogramBuilder_ == null) {
-          histogram_ = io.prometheus.client.Metrics.Histogram.getDefaultInstance();
+          histogram_ = null;
           onChanged();
         } else {
-          histogramBuilder_.clear();
+          histogram_ = null;
+          histogramBuilder_ = null;
         }
-        bitField0_ = (bitField0_ & ~0x00000020);
+
         return this;
       }
       /**
        * <code>optional .io.prometheus.client.Histogram histogram = 7;</code>
        */
       public io.prometheus.client.Metrics.Histogram.Builder getHistogramBuilder() {
-        bitField0_ |= 0x00000020;
+        
         onChanged();
         return getHistogramFieldBuilder().getBuilder();
       }
@@ -6376,17 +6634,18 @@
         if (histogramBuilder_ != null) {
           return histogramBuilder_.getMessageOrBuilder();
         } else {
-          return histogram_;
+          return histogram_ == null ?
+              io.prometheus.client.Metrics.Histogram.getDefaultInstance() : histogram_;
         }
       }
       /**
        * <code>optional .io.prometheus.client.Histogram histogram = 7;</code>
        */
-      private com.google.protobuf.SingleFieldBuilder<
+      private com.google.protobuf.SingleFieldBuilderV3<
           io.prometheus.client.Metrics.Histogram, io.prometheus.client.Metrics.Histogram.Builder, io.prometheus.client.Metrics.HistogramOrBuilder> 
           getHistogramFieldBuilder() {
         if (histogramBuilder_ == null) {
-          histogramBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+          histogramBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               io.prometheus.client.Metrics.Histogram, io.prometheus.client.Metrics.Histogram.Builder, io.prometheus.client.Metrics.HistogramOrBuilder>(
                   getHistogram(),
                   getParentForChildren(),
@@ -6400,12 +6659,6 @@
       /**
        * <code>optional int64 timestamp_ms = 6;</code>
        */
-      public boolean hasTimestampMs() {
-        return ((bitField0_ & 0x00000040) == 0x00000040);
-      }
-      /**
-       * <code>optional int64 timestamp_ms = 6;</code>
-       */
       public long getTimestampMs() {
         return timestampMs_;
       }
@@ -6413,7 +6666,7 @@
        * <code>optional int64 timestamp_ms = 6;</code>
        */
       public Builder setTimestampMs(long value) {
-        bitField0_ |= 0x00000040;
+        
         timestampMs_ = value;
         onChanged();
         return this;
@@ -6422,21 +6675,58 @@
        * <code>optional int64 timestamp_ms = 6;</code>
        */
       public Builder clearTimestampMs() {
-        bitField0_ = (bitField0_ & ~0x00000040);
+        
         timestampMs_ = 0L;
         onChanged();
         return this;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.Metric)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
+    private static final io.prometheus.client.Metrics.Metric DEFAULT_INSTANCE;
     static {
-      defaultInstance = new Metric(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.Metric();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.Metric)
+    public static io.prometheus.client.Metrics.Metric getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Metric>
+        PARSER = new com.google.protobuf.AbstractParser<Metric>() {
+      public Metric parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new Metric(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Metric> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Metric> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.Metric getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   public interface MetricFamilyOrBuilder extends
@@ -6446,10 +6736,6 @@
     /**
      * <code>optional string name = 1;</code>
      */
-    boolean hasName();
-    /**
-     * <code>optional string name = 1;</code>
-     */
     java.lang.String getName();
     /**
      * <code>optional string name = 1;</code>
@@ -6460,10 +6746,6 @@
     /**
      * <code>optional string help = 2;</code>
      */
-    boolean hasHelp();
-    /**
-     * <code>optional string help = 2;</code>
-     */
     java.lang.String getHelp();
     /**
      * <code>optional string help = 2;</code>
@@ -6474,7 +6756,7 @@
     /**
      * <code>optional .io.prometheus.client.MetricType type = 3;</code>
      */
-    boolean hasType();
+    int getTypeValue();
     /**
      * <code>optional .io.prometheus.client.MetricType type = 3;</code>
      */
@@ -6507,40 +6789,32 @@
   /**
    * Protobuf type {@code io.prometheus.client.MetricFamily}
    */
-  public static final class MetricFamily extends
-      com.google.protobuf.GeneratedMessage implements
+  public  static final class MetricFamily extends
+      com.google.protobuf.GeneratedMessageV3 implements
       // @@protoc_insertion_point(message_implements:io.prometheus.client.MetricFamily)
       MetricFamilyOrBuilder {
     // Use MetricFamily.newBuilder() to construct.
-    private MetricFamily(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+    private MetricFamily(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
-      this.unknownFields = builder.getUnknownFields();
     }
-    private MetricFamily(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-    private static final MetricFamily defaultInstance;
-    public static MetricFamily getDefaultInstance() {
-      return defaultInstance;
+    private MetricFamily() {
+      name_ = "";
+      help_ = "";
+      type_ = 0;
+      metric_ = java.util.Collections.emptyList();
     }
 
-    public MetricFamily getDefaultInstanceForType() {
-      return defaultInstance;
-    }
-
-    private final com.google.protobuf.UnknownFieldSet unknownFields;
     @java.lang.Override
     public final com.google.protobuf.UnknownFieldSet
-        getUnknownFields() {
-      return this.unknownFields;
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
     }
     private MetricFamily(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
-      initFields();
+      this();
       int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
         boolean done = false;
         while (!done) {
@@ -6550,33 +6824,27 @@
               done = true;
               break;
             default: {
-              if (!parseUnknownField(input, unknownFields,
-                                     extensionRegistry, tag)) {
+              if (!input.skipField(tag)) {
                 done = true;
               }
               break;
             }
             case 10: {
-              com.google.protobuf.ByteString bs = input.readBytes();
-              bitField0_ |= 0x00000001;
-              name_ = bs;
+              java.lang.String s = input.readStringRequireUtf8();
+
+              name_ = s;
               break;
             }
             case 18: {
-              com.google.protobuf.ByteString bs = input.readBytes();
-              bitField0_ |= 0x00000002;
-              help_ = bs;
+              java.lang.String s = input.readStringRequireUtf8();
+
+              help_ = s;
               break;
             }
             case 24: {
               int rawValue = input.readEnum();
-              io.prometheus.client.Metrics.MetricType value = io.prometheus.client.Metrics.MetricType.valueOf(rawValue);
-              if (value == null) {
-                unknownFields.mergeVarintField(3, rawValue);
-              } else {
-                bitField0_ |= 0x00000004;
-                type_ = value;
-              }
+
+              type_ = rawValue;
               break;
             }
             case 34: {
@@ -6584,7 +6852,8 @@
                 metric_ = new java.util.ArrayList<io.prometheus.client.Metrics.Metric>();
                 mutable_bitField0_ |= 0x00000008;
               }
-              metric_.add(input.readMessage(io.prometheus.client.Metrics.Metric.PARSER, extensionRegistry));
+              metric_.add(
+                  input.readMessage(io.prometheus.client.Metrics.Metric.parser(), extensionRegistry));
               break;
             }
           }
@@ -6593,12 +6862,11 @@
         throw e.setUnfinishedMessage(this);
       } catch (java.io.IOException e) {
         throw new com.google.protobuf.InvalidProtocolBufferException(
-            e.getMessage()).setUnfinishedMessage(this);
+            e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
           metric_ = java.util.Collections.unmodifiableList(metric_);
         }
-        this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
@@ -6607,37 +6875,16 @@
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
     }
 
-    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
       return io.prometheus.client.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
               io.prometheus.client.Metrics.MetricFamily.class, io.prometheus.client.Metrics.MetricFamily.Builder.class);
     }
 
-    public static com.google.protobuf.Parser<MetricFamily> PARSER =
-        new com.google.protobuf.AbstractParser<MetricFamily>() {
-      public MetricFamily parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new MetricFamily(input, extensionRegistry);
-      }
-    };
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<MetricFamily> getParserForType() {
-      return PARSER;
-    }
-
     private int bitField0_;
     public static final int NAME_FIELD_NUMBER = 1;
-    private java.lang.Object name_;
-    /**
-     * <code>optional string name = 1;</code>
-     */
-    public boolean hasName() {
-      return ((bitField0_ & 0x00000001) == 0x00000001);
-    }
+    private volatile java.lang.Object name_;
     /**
      * <code>optional string name = 1;</code>
      */
@@ -6649,9 +6896,7 @@
         com.google.protobuf.ByteString bs = 
             (com.google.protobuf.ByteString) ref;
         java.lang.String s = bs.toStringUtf8();
-        if (bs.isValidUtf8()) {
-          name_ = s;
-        }
+        name_ = s;
         return s;
       }
     }
@@ -6673,13 +6918,7 @@
     }
 
     public static final int HELP_FIELD_NUMBER = 2;
-    private java.lang.Object help_;
-    /**
-     * <code>optional string help = 2;</code>
-     */
-    public boolean hasHelp() {
-      return ((bitField0_ & 0x00000002) == 0x00000002);
-    }
+    private volatile java.lang.Object help_;
     /**
      * <code>optional string help = 2;</code>
      */
@@ -6691,9 +6930,7 @@
         com.google.protobuf.ByteString bs = 
             (com.google.protobuf.ByteString) ref;
         java.lang.String s = bs.toStringUtf8();
-        if (bs.isValidUtf8()) {
-          help_ = s;
-        }
+        help_ = s;
         return s;
       }
     }
@@ -6715,18 +6952,19 @@
     }
 
     public static final int TYPE_FIELD_NUMBER = 3;
-    private io.prometheus.client.Metrics.MetricType type_;
+    private int type_;
     /**
      * <code>optional .io.prometheus.client.MetricType type = 3;</code>
      */
-    public boolean hasType() {
-      return ((bitField0_ & 0x00000004) == 0x00000004);
+    public int getTypeValue() {
+      return type_;
     }
     /**
      * <code>optional .io.prometheus.client.MetricType type = 3;</code>
      */
     public io.prometheus.client.Metrics.MetricType getType() {
-      return type_;
+      io.prometheus.client.Metrics.MetricType result = io.prometheus.client.Metrics.MetricType.valueOf(type_);
+      return result == null ? io.prometheus.client.Metrics.MetricType.UNRECOGNIZED : result;
     }
 
     public static final int METRIC_FIELD_NUMBER = 4;
@@ -6764,12 +7002,6 @@
       return metric_.get(index);
     }
 
-    private void initFields() {
-      name_ = "";
-      help_ = "";
-      type_ = io.prometheus.client.Metrics.MetricType.COUNTER;
-      metric_ = java.util.Collections.emptyList();
-    }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
       byte isInitialized = memoizedIsInitialized;
@@ -6782,54 +7014,85 @@
 
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      getSerializedSize();
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        output.writeBytes(1, getNameBytes());
+      if (!getNameBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
-        output.writeBytes(2, getHelpBytes());
+      if (!getHelpBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, help_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
-        output.writeEnum(3, type_.getNumber());
+      if (type_ != io.prometheus.client.Metrics.MetricType.COUNTER.getNumber()) {
+        output.writeEnum(3, type_);
       }
       for (int i = 0; i < metric_.size(); i++) {
         output.writeMessage(4, metric_.get(i));
       }
-      getUnknownFields().writeTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
     public int getSerializedSize() {
-      int size = memoizedSerializedSize;
+      int size = memoizedSize;
       if (size != -1) return size;
 
       size = 0;
-      if (((bitField0_ & 0x00000001) == 0x00000001)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBytesSize(1, getNameBytes());
+      if (!getNameBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
       }
-      if (((bitField0_ & 0x00000002) == 0x00000002)) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeBytesSize(2, getHelpBytes());
+      if (!getHelpBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, help_);
       }
-      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+      if (type_ != io.prometheus.client.Metrics.MetricType.COUNTER.getNumber()) {
         size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(3, type_.getNumber());
+          .computeEnumSize(3, type_);
       }
       for (int i = 0; i < metric_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(4, metric_.get(i));
       }
-      size += getUnknownFields().getSerializedSize();
-      memoizedSerializedSize = size;
+      memoizedSize = size;
       return size;
     }
 
     private static final long serialVersionUID = 0L;
     @java.lang.Override
-    protected java.lang.Object writeReplace()
-        throws java.io.ObjectStreamException {
-      return super.writeReplace();
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.prometheus.client.Metrics.MetricFamily)) {
+        return super.equals(obj);
+      }
+      io.prometheus.client.Metrics.MetricFamily other = (io.prometheus.client.Metrics.MetricFamily) obj;
+
+      boolean result = true;
+      result = result && getName()
+          .equals(other.getName());
+      result = result && getHelp()
+          .equals(other.getHelp());
+      result = result && type_ == other.type_;
+      result = result && getMetricList()
+          .equals(other.getMetricList());
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = (37 * hash) + NAME_FIELD_NUMBER;
+      hash = (53 * hash) + getName().hashCode();
+      hash = (37 * hash) + HELP_FIELD_NUMBER;
+      hash = (53 * hash) + getHelp().hashCode();
+      hash = (37 * hash) + TYPE_FIELD_NUMBER;
+      hash = (53 * hash) + type_;
+      if (getMetricCount() > 0) {
+        hash = (37 * hash) + METRIC_FIELD_NUMBER;
+        hash = (53 * hash) + getMetricList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
     }
 
     public static io.prometheus.client.Metrics.MetricFamily parseFrom(
@@ -6855,46 +7118,57 @@
     }
     public static io.prometheus.client.Metrics.MetricFamily parseFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.MetricFamily parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.MetricFamily parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.MetricFamily parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
     public static io.prometheus.client.Metrics.MetricFamily parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
-      return PARSER.parseFrom(input);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
     }
     public static io.prometheus.client.Metrics.MetricFamily parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
-      return PARSER.parseFrom(input, extensionRegistry);
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
-    public static Builder newBuilder() { return Builder.create(); }
     public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder(io.prometheus.client.Metrics.MetricFamily prototype) {
-      return newBuilder().mergeFrom(prototype);
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
     }
-    public Builder toBuilder() { return newBuilder(this); }
+    public static Builder newBuilder(io.prometheus.client.Metrics.MetricFamily prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
 
     @java.lang.Override
     protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
       Builder builder = new Builder(parent);
       return builder;
     }
@@ -6902,7 +7176,7 @@
      * Protobuf type {@code io.prometheus.client.MetricFamily}
      */
     public static final class Builder extends
-        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
         // @@protoc_insertion_point(builder_implements:io.prometheus.client.MetricFamily)
         io.prometheus.client.Metrics.MetricFamilyOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
@@ -6910,7 +7184,7 @@
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
       }
 
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
@@ -6923,27 +7197,24 @@
       }
 
       private Builder(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
         super(parent);
         maybeForceBuilderInitialization();
       }
       private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
           getMetricFieldBuilder();
         }
       }
-      private static Builder create() {
-        return new Builder();
-      }
-
       public Builder clear() {
         super.clear();
         name_ = "";
-        bitField0_ = (bitField0_ & ~0x00000001);
+
         help_ = "";
-        bitField0_ = (bitField0_ & ~0x00000002);
-        type_ = io.prometheus.client.Metrics.MetricType.COUNTER;
-        bitField0_ = (bitField0_ & ~0x00000004);
+
+        type_ = 0;
+
         if (metricBuilder_ == null) {
           metric_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000008);
@@ -6953,10 +7224,6 @@
         return this;
       }
 
-      public Builder clone() {
-        return create().mergeFrom(buildPartial());
-      }
-
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
         return io.prometheus.client.Metrics.internal_static_io_prometheus_client_MetricFamily_descriptor;
@@ -6978,17 +7245,8 @@
         io.prometheus.client.Metrics.MetricFamily result = new io.prometheus.client.Metrics.MetricFamily(this);
         int from_bitField0_ = bitField0_;
         int to_bitField0_ = 0;
-        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-          to_bitField0_ |= 0x00000001;
-        }
         result.name_ = name_;
-        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-          to_bitField0_ |= 0x00000002;
-        }
         result.help_ = help_;
-        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
-          to_bitField0_ |= 0x00000004;
-        }
         result.type_ = type_;
         if (metricBuilder_ == null) {
           if (((bitField0_ & 0x00000008) == 0x00000008)) {
@@ -7004,6 +7262,32 @@
         return result;
       }
 
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
       public Builder mergeFrom(com.google.protobuf.Message other) {
         if (other instanceof io.prometheus.client.Metrics.MetricFamily) {
           return mergeFrom((io.prometheus.client.Metrics.MetricFamily)other);
@@ -7015,18 +7299,16 @@
 
       public Builder mergeFrom(io.prometheus.client.Metrics.MetricFamily other) {
         if (other == io.prometheus.client.Metrics.MetricFamily.getDefaultInstance()) return this;
-        if (other.hasName()) {
-          bitField0_ |= 0x00000001;
+        if (!other.getName().isEmpty()) {
           name_ = other.name_;
           onChanged();
         }
-        if (other.hasHelp()) {
-          bitField0_ |= 0x00000002;
+        if (!other.getHelp().isEmpty()) {
           help_ = other.help_;
           onChanged();
         }
-        if (other.hasType()) {
-          setType(other.getType());
+        if (other.type_ != 0) {
+          setTypeValue(other.getTypeValue());
         }
         if (metricBuilder_ == null) {
           if (!other.metric_.isEmpty()) {
@@ -7047,14 +7329,14 @@
               metric_ = other.metric_;
               bitField0_ = (bitField0_ & ~0x00000008);
               metricBuilder_ = 
-                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                    getMetricFieldBuilder() : null;
             } else {
               metricBuilder_.addAllMessages(other.metric_);
             }
           }
         }
-        this.mergeUnknownFields(other.getUnknownFields());
+        onChanged();
         return this;
       }
 
@@ -7071,7 +7353,7 @@
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
           parsedMessage = (io.prometheus.client.Metrics.MetricFamily) e.getUnfinishedMessage();
-          throw e;
+          throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
             mergeFrom(parsedMessage);
@@ -7085,21 +7367,13 @@
       /**
        * <code>optional string name = 1;</code>
        */
-      public boolean hasName() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * <code>optional string name = 1;</code>
-       */
       public java.lang.String getName() {
         java.lang.Object ref = name_;
         if (!(ref instanceof java.lang.String)) {
           com.google.protobuf.ByteString bs =
               (com.google.protobuf.ByteString) ref;
           java.lang.String s = bs.toStringUtf8();
-          if (bs.isValidUtf8()) {
-            name_ = s;
-          }
+          name_ = s;
           return s;
         } else {
           return (java.lang.String) ref;
@@ -7129,7 +7403,7 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  bitField0_ |= 0x00000001;
+  
         name_ = value;
         onChanged();
         return this;
@@ -7138,7 +7412,7 @@
        * <code>optional string name = 1;</code>
        */
       public Builder clearName() {
-        bitField0_ = (bitField0_ & ~0x00000001);
+        
         name_ = getDefaultInstance().getName();
         onChanged();
         return this;
@@ -7151,7 +7425,8 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  bitField0_ |= 0x00000001;
+  checkByteStringIsUtf8(value);
+        
         name_ = value;
         onChanged();
         return this;
@@ -7161,21 +7436,13 @@
       /**
        * <code>optional string help = 2;</code>
        */
-      public boolean hasHelp() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
-      }
-      /**
-       * <code>optional string help = 2;</code>
-       */
       public java.lang.String getHelp() {
         java.lang.Object ref = help_;
         if (!(ref instanceof java.lang.String)) {
           com.google.protobuf.ByteString bs =
               (com.google.protobuf.ByteString) ref;
           java.lang.String s = bs.toStringUtf8();
-          if (bs.isValidUtf8()) {
-            help_ = s;
-          }
+          help_ = s;
           return s;
         } else {
           return (java.lang.String) ref;
@@ -7205,7 +7472,7 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  bitField0_ |= 0x00000002;
+  
         help_ = value;
         onChanged();
         return this;
@@ -7214,7 +7481,7 @@
        * <code>optional string help = 2;</code>
        */
       public Builder clearHelp() {
-        bitField0_ = (bitField0_ & ~0x00000002);
+        
         help_ = getDefaultInstance().getHelp();
         onChanged();
         return this;
@@ -7227,24 +7494,34 @@
         if (value == null) {
     throw new NullPointerException();
   }
-  bitField0_ |= 0x00000002;
+  checkByteStringIsUtf8(value);
+        
         help_ = value;
         onChanged();
         return this;
       }
 
-      private io.prometheus.client.Metrics.MetricType type_ = io.prometheus.client.Metrics.MetricType.COUNTER;
+      private int type_ = 0;
       /**
        * <code>optional .io.prometheus.client.MetricType type = 3;</code>
        */
-      public boolean hasType() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
+      public int getTypeValue() {
+        return type_;
+      }
+      /**
+       * <code>optional .io.prometheus.client.MetricType type = 3;</code>
+       */
+      public Builder setTypeValue(int value) {
+        type_ = value;
+        onChanged();
+        return this;
       }
       /**
        * <code>optional .io.prometheus.client.MetricType type = 3;</code>
        */
       public io.prometheus.client.Metrics.MetricType getType() {
-        return type_;
+        io.prometheus.client.Metrics.MetricType result = io.prometheus.client.Metrics.MetricType.valueOf(type_);
+        return result == null ? io.prometheus.client.Metrics.MetricType.UNRECOGNIZED : result;
       }
       /**
        * <code>optional .io.prometheus.client.MetricType type = 3;</code>
@@ -7253,8 +7530,8 @@
         if (value == null) {
           throw new NullPointerException();
         }
-        bitField0_ |= 0x00000004;
-        type_ = value;
+        
+        type_ = value.getNumber();
         onChanged();
         return this;
       }
@@ -7262,8 +7539,8 @@
        * <code>optional .io.prometheus.client.MetricType type = 3;</code>
        */
       public Builder clearType() {
-        bitField0_ = (bitField0_ & ~0x00000004);
-        type_ = io.prometheus.client.Metrics.MetricType.COUNTER;
+        
+        type_ = 0;
         onChanged();
         return this;
       }
@@ -7277,7 +7554,7 @@
          }
       }
 
-      private com.google.protobuf.RepeatedFieldBuilder<
+      private com.google.protobuf.RepeatedFieldBuilderV3<
           io.prometheus.client.Metrics.Metric, io.prometheus.client.Metrics.Metric.Builder, io.prometheus.client.Metrics.MetricOrBuilder> metricBuilder_;
 
       /**
@@ -7493,11 +7770,11 @@
            getMetricBuilderList() {
         return getMetricFieldBuilder().getBuilderList();
       }
-      private com.google.protobuf.RepeatedFieldBuilder<
+      private com.google.protobuf.RepeatedFieldBuilderV3<
           io.prometheus.client.Metrics.Metric, io.prometheus.client.Metrics.Metric.Builder, io.prometheus.client.Metrics.MetricOrBuilder> 
           getMetricFieldBuilder() {
         if (metricBuilder_ == null) {
-          metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
+          metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               io.prometheus.client.Metrics.Metric, io.prometheus.client.Metrics.Metric.Builder, io.prometheus.client.Metrics.MetricOrBuilder>(
                   metric_,
                   ((bitField0_ & 0x00000008) == 0x00000008),
@@ -7507,74 +7784,111 @@
         }
         return metricBuilder_;
       }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return this;
+      }
+
 
       // @@protoc_insertion_point(builder_scope:io.prometheus.client.MetricFamily)
     }
 
+    // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
+    private static final io.prometheus.client.Metrics.MetricFamily DEFAULT_INSTANCE;
     static {
-      defaultInstance = new MetricFamily(true);
-      defaultInstance.initFields();
+      DEFAULT_INSTANCE = new io.prometheus.client.Metrics.MetricFamily();
     }
 
-    // @@protoc_insertion_point(class_scope:io.prometheus.client.MetricFamily)
+    public static io.prometheus.client.Metrics.MetricFamily getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<MetricFamily>
+        PARSER = new com.google.protobuf.AbstractParser<MetricFamily>() {
+      public MetricFamily parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+          return new MetricFamily(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<MetricFamily> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<MetricFamily> getParserForType() {
+      return PARSER;
+    }
+
+    public io.prometheus.client.Metrics.MetricFamily getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
   }
 
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_LabelPair_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_LabelPair_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_Gauge_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_Gauge_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_Counter_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_Counter_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_Quantile_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_Quantile_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_Summary_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_Summary_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_Untyped_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_Untyped_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_Histogram_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_Histogram_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_Bucket_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_Bucket_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_Metric_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_Metric_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_io_prometheus_client_MetricFamily_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable;
 
   public static com.google.protobuf.Descriptors.FileDescriptor
       getDescriptor() {
     return descriptor;
   }
-  private static com.google.protobuf.Descriptors.FileDescriptor
+  private static  com.google.protobuf.Descriptors.FileDescriptor
       descriptor;
   static {
     java.lang.String[] descriptorData = {
@@ -7603,7 +7917,7 @@
       "etric\030\004 \003(\0132\034.io.prometheus.client.Metri" +
       "c*M\n\nMetricType\022\013\n\007COUNTER\020\000\022\t\n\005GAUGE\020\001\022" +
       "\013\n\007SUMMARY\020\002\022\013\n\007UNTYPED\020\003\022\r\n\tHISTOGRAM\020\004" +
-      "B\026\n\024io.prometheus.client"
+      "B\026\n\024io.prometheus.clientb\006proto3"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
         new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
@@ -7620,61 +7934,61 @@
     internal_static_io_prometheus_client_LabelPair_descriptor =
       getDescriptor().getMessageTypes().get(0);
     internal_static_io_prometheus_client_LabelPair_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_LabelPair_descriptor,
         new java.lang.String[] { "Name", "Value", });
     internal_static_io_prometheus_client_Gauge_descriptor =
       getDescriptor().getMessageTypes().get(1);
     internal_static_io_prometheus_client_Gauge_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_Gauge_descriptor,
         new java.lang.String[] { "Value", });
     internal_static_io_prometheus_client_Counter_descriptor =
       getDescriptor().getMessageTypes().get(2);
     internal_static_io_prometheus_client_Counter_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_Counter_descriptor,
         new java.lang.String[] { "Value", });
     internal_static_io_prometheus_client_Quantile_descriptor =
       getDescriptor().getMessageTypes().get(3);
     internal_static_io_prometheus_client_Quantile_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_Quantile_descriptor,
         new java.lang.String[] { "Quantile", "Value", });
     internal_static_io_prometheus_client_Summary_descriptor =
       getDescriptor().getMessageTypes().get(4);
     internal_static_io_prometheus_client_Summary_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_Summary_descriptor,
         new java.lang.String[] { "SampleCount", "SampleSum", "Quantile", });
     internal_static_io_prometheus_client_Untyped_descriptor =
       getDescriptor().getMessageTypes().get(5);
     internal_static_io_prometheus_client_Untyped_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_Untyped_descriptor,
         new java.lang.String[] { "Value", });
     internal_static_io_prometheus_client_Histogram_descriptor =
       getDescriptor().getMessageTypes().get(6);
     internal_static_io_prometheus_client_Histogram_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_Histogram_descriptor,
         new java.lang.String[] { "SampleCount", "SampleSum", "Bucket", });
     internal_static_io_prometheus_client_Bucket_descriptor =
       getDescriptor().getMessageTypes().get(7);
     internal_static_io_prometheus_client_Bucket_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_Bucket_descriptor,
         new java.lang.String[] { "CumulativeCount", "UpperBound", });
     internal_static_io_prometheus_client_Metric_descriptor =
       getDescriptor().getMessageTypes().get(8);
     internal_static_io_prometheus_client_Metric_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_Metric_descriptor,
         new java.lang.String[] { "Label", "Gauge", "Counter", "Summary", "Untyped", "Histogram", "TimestampMs", });
     internal_static_io_prometheus_client_MetricFamily_descriptor =
       getDescriptor().getMessageTypes().get(9);
     internal_static_io_prometheus_client_MetricFamily_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_io_prometheus_client_MetricFamily_descriptor,
         new java.lang.String[] { "Name", "Help", "Type", "Metric", });
   }
