Move RFC 9000 variable length integer encoding from QUIC to QUICHE

Since BHTTP uses these, and we're starting BHTTP in QUICHE, we need to move the read/write functions for varints to QUICHE. While I was in there, I improved some comments to refer to the published RFC, and removed a few ODR violations.

This CL is a no-op, it does not modify any existing functionality.

PiperOrigin-RevId: 467990159
diff --git a/quiche/common/quiche_data_reader.cc b/quiche/common/quiche_data_reader.cc
index 52b4af4..080431c 100644
--- a/quiche/common/quiche_data_reader.cc
+++ b/quiche/common/quiche_data_reader.cc
@@ -143,6 +143,94 @@
   return absl::SimpleAtoi(digits, result);
 }
 
+QuicheVariableLengthIntegerLength QuicheDataReader::PeekVarInt62Length() {
+  QUICHE_DCHECK_EQ(endianness(), NETWORK_BYTE_ORDER);
+  const unsigned char* next =
+      reinterpret_cast<const unsigned char*>(data() + pos());
+  if (BytesRemaining() == 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  return static_cast<QuicheVariableLengthIntegerLength>(
+      1 << ((*next & 0b11000000) >> 6));
+}
+
+// Read an RFC 9000 62-bit Variable Length Integer.
+//
+// Performance notes
+//
+// Measurements and experiments showed that unrolling the four cases
+// like this and dereferencing next_ as we do (*(next_+n) --- and then
+// doing a single pos_+=x at the end) gains about 10% over making a
+// loop and dereferencing next_ such as *(next_++)
+//
+// Using a register for pos_ was not helpful.
+//
+// Branches are ordered to increase the likelihood of the first being
+// taken.
+//
+// Low-level optimization is useful here because this function will be
+// called frequently, leading to outsize benefits.
+bool QuicheDataReader::ReadVarInt62(uint64_t* result) {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+
+  size_t remaining = BytesRemaining();
+  const unsigned char* next =
+      reinterpret_cast<const unsigned char*>(data() + pos());
+  if (remaining != 0) {
+    switch (*next & 0xc0) {
+      case 0xc0:
+        // Leading 0b11...... is 8 byte encoding
+        if (remaining >= 8) {
+          *result = (static_cast<uint64_t>((*(next)) & 0x3f) << 56) +
+                    (static_cast<uint64_t>(*(next + 1)) << 48) +
+                    (static_cast<uint64_t>(*(next + 2)) << 40) +
+                    (static_cast<uint64_t>(*(next + 3)) << 32) +
+                    (static_cast<uint64_t>(*(next + 4)) << 24) +
+                    (static_cast<uint64_t>(*(next + 5)) << 16) +
+                    (static_cast<uint64_t>(*(next + 6)) << 8) +
+                    (static_cast<uint64_t>(*(next + 7)) << 0);
+          AdvancePos(8);
+          return true;
+        }
+        return false;
+
+      case 0x80:
+        // Leading 0b10...... is 4 byte encoding
+        if (remaining >= 4) {
+          *result = (((*(next)) & 0x3f) << 24) + (((*(next + 1)) << 16)) +
+                    (((*(next + 2)) << 8)) + (((*(next + 3)) << 0));
+          AdvancePos(4);
+          return true;
+        }
+        return false;
+
+      case 0x40:
+        // Leading 0b01...... is 2 byte encoding
+        if (remaining >= 2) {
+          *result = (((*(next)) & 0x3f) << 8) + (*(next + 1));
+          AdvancePos(2);
+          return true;
+        }
+        return false;
+
+      case 0x00:
+        // Leading 0b00...... is 1 byte encoding
+        *result = (*next) & 0x3f;
+        AdvancePos(1);
+        return true;
+    }
+  }
+  return false;
+}
+
+bool QuicheDataReader::ReadStringPieceVarInt62(absl::string_view* result) {
+  uint64_t result_length;
+  if (!ReadVarInt62(&result_length)) {
+    return false;
+  }
+  return ReadStringPiece(result, result_length);
+}
+
 absl::string_view QuicheDataReader::ReadRemainingPayload() {
   absl::string_view payload = PeekRemainingPayload();
   pos_ = len_;
diff --git a/quiche/common/quiche_data_reader.h b/quiche/common/quiche_data_reader.h
index bf336f9..ed05b69 100644
--- a/quiche/common/quiche_data_reader.h
+++ b/quiche/common/quiche_data_reader.h
@@ -92,6 +92,25 @@
   // iterator on success, may forward it even in case of failure.
   bool ReadDecimal64(size_t num_digits, uint64_t* result);
 
+  // Returns the length in bytes of a variable length integer based on the next
+  // two bits available. Returns 1, 2, 4, or 8 on success, and 0 on failure.
+  QuicheVariableLengthIntegerLength PeekVarInt62Length();
+
+  // Read an RFC 9000 62-bit Variable Length Integer and place the result in
+  // |*result|. Returns false if there is not enough space in the buffer to read
+  // the number, true otherwise. If false is returned, |*result| is not altered.
+  bool ReadVarInt62(uint64_t* result);
+
+  // Reads a string prefixed with a RFC 9000 62-bit variable Length integer
+  // length into the given output parameter.
+  //
+  // NOTE: Does not copy but rather references strings in the underlying buffer.
+  // This should be kept in mind when handling memory management!
+  //
+  // Returns false if there is not enough space in the buffer to read
+  // the number and subsequent string, true otherwise.
+  bool ReadStringPieceVarInt62(absl::string_view* result);
+
   // Returns the remaining payload as a absl::string_view.
   //
   // NOTE: Does not copy but rather references strings in the underlying buffer.
diff --git a/quiche/common/quiche_data_writer.cc b/quiche/common/quiche_data_writer.cc
index 5f83e1f..5e79439 100644
--- a/quiche/common/quiche_data_writer.cc
+++ b/quiche/common/quiche_data_writer.cc
@@ -9,6 +9,7 @@
 
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_bug_tracker.h"
 #include "quiche/common/quiche_endian.h"
 
 namespace quiche {
@@ -133,6 +134,158 @@
   return WriteBytes(&tag, sizeof(tag));
 }
 
+// Converts a uint64_t into a 62-bit RFC 9000 Variable Length Integer.
+//
+// Performance notes
+//
+// Measurements and experiments showed that unrolling the four cases
+// like this and dereferencing next_ as we do (*(next_+n)) gains about
+// 10% over making a loop and dereferencing it as *(next_++)
+//
+// Using a register for next didn't help.
+//
+// Branches are ordered to increase the likelihood of the first being
+// taken.
+//
+// Low-level optimization is useful here because this function will be
+// called frequently, leading to outsize benefits.
+bool QuicheDataWriter::WriteVarInt62(uint64_t value) {
+  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
+
+  size_t remaining_bytes = remaining();
+  char* next = buffer() + length();
+
+  if ((value & kVarInt62ErrorMask) == 0) {
+    // We know the high 2 bits are 0 so |value| is legal.
+    // We can do the encoding.
+    if ((value & kVarInt62Mask8Bytes) != 0) {
+      // Someplace in the high-4 bytes is a 1-bit. Do an 8-byte
+      // encoding.
+      if (remaining_bytes >= 8) {
+        *(next + 0) = ((value >> 56) & 0x3f) + 0xc0;
+        *(next + 1) = (value >> 48) & 0xff;
+        *(next + 2) = (value >> 40) & 0xff;
+        *(next + 3) = (value >> 32) & 0xff;
+        *(next + 4) = (value >> 24) & 0xff;
+        *(next + 5) = (value >> 16) & 0xff;
+        *(next + 6) = (value >> 8) & 0xff;
+        *(next + 7) = value & 0xff;
+        IncreaseLength(8);
+        return true;
+      }
+      return false;
+    }
+    // The high-order-4 bytes are all 0, check for a 1, 2, or 4-byte
+    // encoding
+    if ((value & kVarInt62Mask4Bytes) != 0) {
+      // The encoding will not fit into 2 bytes, Do a 4-byte
+      // encoding.
+      if (remaining_bytes >= 4) {
+        *(next + 0) = ((value >> 24) & 0x3f) + 0x80;
+        *(next + 1) = (value >> 16) & 0xff;
+        *(next + 2) = (value >> 8) & 0xff;
+        *(next + 3) = value & 0xff;
+        IncreaseLength(4);
+        return true;
+      }
+      return false;
+    }
+    // The high-order bits are all 0. Check to see if the number
+    // can be encoded as one or two bytes. One byte encoding has
+    // only 6 significant bits (bits 0xffffffff ffffffc0 are all 0).
+    // Two byte encoding has more than 6, but 14 or less significant
+    // bits (bits 0xffffffff ffffc000 are 0 and 0x00000000 00003fc0
+    // are not 0)
+    if ((value & kVarInt62Mask2Bytes) != 0) {
+      // Do 2-byte encoding
+      if (remaining_bytes >= 2) {
+        *(next + 0) = ((value >> 8) & 0x3f) + 0x40;
+        *(next + 1) = (value)&0xff;
+        IncreaseLength(2);
+        return true;
+      }
+      return false;
+    }
+    if (remaining_bytes >= 1) {
+      // Do 1-byte encoding
+      *next = (value & 0x3f);
+      IncreaseLength(1);
+      return true;
+    }
+    return false;
+  }
+  // Can not encode, high 2 bits not 0
+  return false;
+}
+
+bool QuicheDataWriter::WriteStringPieceVarInt62(
+    const absl::string_view& string_piece) {
+  if (!WriteVarInt62(string_piece.size())) {
+    return false;
+  }
+  if (!string_piece.empty()) {
+    if (!WriteBytes(string_piece.data(), string_piece.size())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// static
+QuicheVariableLengthIntegerLength QuicheDataWriter::GetVarInt62Len(
+    uint64_t value) {
+  if ((value & kVarInt62ErrorMask) != 0) {
+    QUICHE_BUG(invalid_varint) << "Attempted to encode a value, " << value
+                               << ", that is too big for VarInt62";
+    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  }
+  if ((value & kVarInt62Mask8Bytes) != 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_8;
+  }
+  if ((value & kVarInt62Mask4Bytes) != 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_4;
+  }
+  if ((value & kVarInt62Mask2Bytes) != 0) {
+    return VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  }
+  return VARIABLE_LENGTH_INTEGER_LENGTH_1;
+}
+
+bool QuicheDataWriter::WriteVarInt62WithForcedLength(
+    uint64_t value, QuicheVariableLengthIntegerLength write_length) {
+  QUICHE_DCHECK_EQ(endianness(), NETWORK_BYTE_ORDER);
+
+  size_t remaining_bytes = remaining();
+  if (remaining_bytes < write_length) {
+    return false;
+  }
+
+  const QuicheVariableLengthIntegerLength min_length = GetVarInt62Len(value);
+  if (write_length < min_length) {
+    QUICHE_BUG(invalid_varint_forced) << "Cannot write value " << value
+                                      << " with write_length " << write_length;
+    return false;
+  }
+  if (write_length == min_length) {
+    return WriteVarInt62(value);
+  }
+
+  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_2) {
+    return WriteUInt8(0b01000000) && WriteUInt8(value);
+  }
+  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_4) {
+    return WriteUInt8(0b10000000) && WriteUInt8(0) && WriteUInt16(value);
+  }
+  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_8) {
+    return WriteUInt8(0b11000000) && WriteUInt8(0) && WriteUInt16(0) &&
+           WriteUInt32(value);
+  }
+
+  QUICHE_BUG(invalid_write_length)
+      << "Invalid write_length " << static_cast<int>(write_length);
+  return false;
+}
+
 bool QuicheDataWriter::Seek(size_t length) {
   if (!BeginWrite(length)) {
     return false;
diff --git a/quiche/common/quiche_data_writer.h b/quiche/common/quiche_data_writer.h
index 5f027a9..8035bb2 100644
--- a/quiche/common/quiche_data_writer.h
+++ b/quiche/common/quiche_data_writer.h
@@ -17,6 +17,24 @@
 
 namespace quiche {
 
+// Maximum value that can be properly encoded using RFC 9000 62-bit Variable
+// Length Integer encoding.
+enum : uint64_t {
+  kVarInt62MaxValue = UINT64_C(0x3fffffffffffffff),
+};
+
+// RFC 9000 62-bit Variable Length Integer encoding masks
+// If a uint64_t anded with a mask is not 0 then the value is encoded
+// using that length (or is too big, in the case of kVarInt62ErrorMask).
+// Values must be checked in order (error, 8-, 4-, and then 2- bytes)
+// and if none are non-0, the value is encoded in 1 byte.
+enum : uint64_t {
+  kVarInt62ErrorMask = UINT64_C(0xc000000000000000),
+  kVarInt62Mask8Bytes = UINT64_C(0x3fffffffc0000000),
+  kVarInt62Mask4Bytes = UINT64_C(0x000000003fffc000),
+  kVarInt62Mask2Bytes = UINT64_C(0x0000000000003fc0),
+};
+
 // This class provides facilities for packing binary data.
 //
 // The QuicheDataWriter supports appending primitive values (int, string, etc)
@@ -69,6 +87,28 @@
   // in big endian.
   bool WriteTag(uint32_t tag);
 
+  // Write a 62-bit unsigned integer using RFC 9000 Variable Length Integer
+  // encoding. Returns false if the value is out of range or if there is no room
+  // in the buffer.
+  bool WriteVarInt62(uint64_t value);
+
+  // Same as WriteVarInt62(uint64_t), but forces an encoding size to write to.
+  // This is not as optimized as WriteVarInt62(uint64_t). Returns false if the
+  // value does not fit in the specified write_length or if there is no room in
+  // the buffer.
+  bool WriteVarInt62WithForcedLength(
+      uint64_t value, QuicheVariableLengthIntegerLength write_length);
+
+  // Writes a string piece as a consecutive length/content pair. The
+  // length uses RFC 9000 Variable Length Integer encoding.
+  bool WriteStringPieceVarInt62(const absl::string_view& string_piece);
+
+  // Utility function to return the number of bytes needed to encode
+  // the given value using IETF VarInt62 encoding. Returns the number
+  // of bytes required to encode the given integer or 0 if the value
+  // is too large to encode.
+  static QuicheVariableLengthIntegerLength GetVarInt62Len(uint64_t value);
+
   // Advance the writer's position for writing by |length| bytes without writing
   // anything. This method only makes sense to be used on a buffer that has
   // already been written to (and is having certain parts rewritten).
diff --git a/quiche/common/quiche_data_writer_test.cc b/quiche/common/quiche_data_writer_test.cc
index 7ae15d2..eb14350 100644
--- a/quiche/common/quiche_data_writer_test.cc
+++ b/quiche/common/quiche_data_writer_test.cc
@@ -337,6 +337,416 @@
   }
 }
 
+const int kVarIntBufferLength = 1024;
+
+// Encodes and then decodes a specified value, checks that the
+// value that was encoded is the same as the decoded value, the length
+// is correct, and that after decoding, all data in the buffer has
+// been consumed..
+// Returns true if everything works, false if not.
+bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
+  // Init the buffer to all 0, just for cleanliness. Makes for better
+  // output if, in debugging, we need to dump out the buffer.
+  memset(buffer, 0, size_of_buffer);
+  // make a writer. Note that for IETF encoding
+  // we do not care about endianness... It's always big-endian,
+  // but the c'tor expects to be told what endianness is in force...
+  QuicheDataWriter writer(size_of_buffer, buffer,
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+
+  // Try to write the value.
+  if (writer.WriteVarInt62(value_in) != true) {
+    return false;
+  }
+  // Look at the value we encoded. Determine how much should have been
+  // used based on the value, and then check the state of the writer
+  // to see that it matches.
+  size_t expected_length = 0;
+  if (value_in <= 0x3f) {
+    expected_length = 1;
+  } else if (value_in <= 0x3fff) {
+    expected_length = 2;
+  } else if (value_in <= 0x3fffffff) {
+    expected_length = 4;
+  } else {
+    expected_length = 8;
+  }
+  if (writer.length() != expected_length) {
+    return false;
+  }
+
+  // set up a reader, just the length we've used, no more, no less.
+  QuicheDataReader reader(buffer, expected_length,
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  uint64_t value_out;
+
+  if (reader.ReadVarInt62(&value_out) == false) {
+    return false;
+  }
+  if (value_in != value_out) {
+    return false;
+  }
+  // We only write one value so there had better be nothing left to read
+  return reader.IsDoneReading();
+}
+
+// Test that 8-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicheDataWriterTest, VarInt8Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x31 + 0xc0));  // 0xc0 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
+}
+
+// Test that 4-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicheDataWriterTest, VarInt4Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x32 + 0x80));  // 0x80 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
+}
+
+// Test that 2-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicheDataWriterTest, VarInt2Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer is correct. Bytes
+  // are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3647));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
+            (0x36 + 0x40));  // 0x40 for encoding
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
+}
+
+// Test that 1-byte-encoded Variable Length Integers are properly laid
+// out in the buffer.
+TEST_P(QuicheDataWriterTest, VarInt1Layout) {
+  char buffer[1024];
+
+  // Check that the layout of bytes in the buffer
+  // is correct. Bytes are always encoded big endian...
+  memset(buffer, 0, sizeof(buffer));
+  QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  EXPECT_TRUE(writer.WriteVarInt62(0x3f));
+  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
+}
+
+// Test certain, targeted, values that are expected to succeed:
+// 0, 1,
+// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
+// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
+// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
+//                          transition)
+// 0x3ffffffffffffffe, 0x3fffffffffffffff,  (the highest valid values)
+// 0xfe, 0xff, 0x100, 0x101,
+// 0xfffe, 0xffff, 0x10000, 0x10001,
+// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
+// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
+// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
+// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
+// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
+TEST_P(QuicheDataWriterTest, VarIntGoodTargetedValues) {
+  char buffer[kVarIntBufferLength];
+  uint64_t passing_values[] = {
+      0,
+      1,
+      0x3e,
+      0x3f,
+      0x40,
+      0x41,
+      0x3ffe,
+      0x3fff,
+      0x4000,
+      0x4001,
+      0x3ffffffe,
+      0x3fffffff,
+      0x40000000,
+      0x40000001,
+      0x3ffffffffffffffe,
+      0x3fffffffffffffff,
+      0xfe,
+      0xff,
+      0x100,
+      0x101,
+      0xfffe,
+      0xffff,
+      0x10000,
+      0x10001,
+      0xfffffe,
+      0xffffff,
+      0x1000000,
+      0x1000001,
+      0xfffffffe,
+      0xffffffff,
+      0x100000000,
+      0x100000001,
+      0xfffffffffe,
+      0xffffffffff,
+      0x10000000000,
+      0x10000000001,
+      0xfffffffffffe,
+      0xffffffffffff,
+      0x1000000000000,
+      0x1000000000001,
+      0xfffffffffffffe,
+      0xffffffffffffff,
+      0x100000000000000,
+      0x100000000000001,
+  };
+  for (uint64_t test_val : passing_values) {
+    EXPECT_TRUE(
+        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
+        << " encode/decode of " << test_val << " failed";
+  }
+}
+//
+// Test certain, targeted, values where failure is expected (the
+// values are invalid w.r.t. IETF VarInt encoding):
+// 0x4000000000000000, 0x4000000000000001,  ( Just above max allowed value)
+// 0xfffffffffffffffe, 0xffffffffffffffff,  (should fail)
+TEST_P(QuicheDataWriterTest, VarIntBadTargetedValues) {
+  char buffer[kVarIntBufferLength];
+  uint64_t failing_values[] = {
+      0x4000000000000000,
+      0x4000000000000001,
+      0xfffffffffffffffe,
+      0xffffffffffffffff,
+  };
+  for (uint64_t test_val : failing_values) {
+    EXPECT_FALSE(
+        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
+        << " encode/decode of " << test_val << " succeeded, but was an "
+        << "invalid value";
+  }
+}
+// Test writing varints with a forced length.
+TEST_P(QuicheDataWriterTest, WriteVarInt62WithForcedLength) {
+  char buffer[90];
+  memset(buffer, 0, sizeof(buffer));
+  QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer));
+
+  writer.WriteVarInt62WithForcedLength(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
+  writer.WriteVarInt62WithForcedLength(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62WithForcedLength(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62WithForcedLength(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62WithForcedLength(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
+  writer.WriteVarInt62WithForcedLength(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62WithForcedLength(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62WithForcedLength(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62WithForcedLength(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62WithForcedLength(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62WithForcedLength(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62WithForcedLength(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
+  writer.WriteVarInt62WithForcedLength(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62WithForcedLength(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62WithForcedLength(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62WithForcedLength(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62WithForcedLength(1073741823,
+                                       VARIABLE_LENGTH_INTEGER_LENGTH_4);
+  writer.WriteVarInt62WithForcedLength(1073741823,
+                                       VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  writer.WriteVarInt62WithForcedLength(1073741824,
+                                       VARIABLE_LENGTH_INTEGER_LENGTH_8);
+
+  QuicheDataReader reader(buffer, sizeof(buffer));
+
+  uint64_t test_val = 0;
+  for (int i = 0; i < 4; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 1u);
+  }
+  for (int i = 0; i < 4; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 63u);
+  }
+
+  for (int i = 0; i < 3; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 64u);
+  }
+  for (int i = 0; i < 3; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 16383u);
+  }
+
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 16384u);
+  }
+  for (int i = 0; i < 2; ++i) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, 1073741823u);
+  }
+
+  EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+  EXPECT_EQ(test_val, 1073741824u);
+
+  // We are at the end of the buffer so this should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Following tests all try to fill the buffer with multiple values,
+// go one value more than the buffer can accommodate, then read
+// the successfully encoded values, and try to read the unsuccessfully
+// encoded value. The following is the number of values to encode.
+const int kMultiVarCount = 1000;
+
+// Test writing & reading multiple 8-byte-encoded varints
+TEST_P(QuicheDataWriterTest, MultiVarInt8) {
+  uint64_t test_val;
+  char buffer[8 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
+  }
+  EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicheDataReader reader(buffer, sizeof(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 4-byte-encoded varints
+TEST_P(QuicheDataWriterTest, MultiVarInt4) {
+  uint64_t test_val;
+  char buffer[4 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
+  }
+  EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicheDataReader reader(buffer, sizeof(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 2-byte-encoded varints
+TEST_P(QuicheDataWriterTest, MultiVarInt2) {
+  uint64_t test_val;
+  char buffer[2 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
+  }
+  EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicheDataReader reader(buffer, sizeof(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
+// Test writing & reading multiple 1-byte-encoded varints
+TEST_P(QuicheDataWriterTest, MultiVarInt1) {
+  uint64_t test_val;
+  char buffer[1 * kMultiVarCount];
+  memset(buffer, 0, sizeof(buffer));
+  QuicheDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  // Put N values into the buffer. Adding i to the value ensures that
+  // each value is different so we can detect if we overwrite values,
+  // or read the same value over and over. &0xf ensures we do not
+  // overflow the max value for single-byte encoding.
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
+  }
+  EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
+
+  // N+1st should fail, the buffer is full.
+  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
+
+  // Now we should be able to read out the N values that were
+  // successfully encoded.
+  QuicheDataReader reader(buffer, sizeof(buffer),
+                          quiche::Endianness::NETWORK_BYTE_ORDER);
+  for (int i = 0; i < kMultiVarCount; i++) {
+    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
+    EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
+  }
+  // And the N+1st should fail.
+  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
+}
+
 TEST_P(QuicheDataWriterTest, Seek) {
   char buffer[3] = {};
   QuicheDataWriter writer(ABSL_ARRAYSIZE(buffer), buffer,
diff --git a/quiche/common/quiche_endian.h b/quiche/common/quiche_endian.h
index 30639cc..834f743 100644
--- a/quiche/common/quiche_endian.h
+++ b/quiche/common/quiche_endian.h
@@ -54,6 +54,20 @@
   }
 };
 
+enum QuicheVariableLengthIntegerLength : uint8_t {
+  // Length zero means the variable length integer is not present.
+  VARIABLE_LENGTH_INTEGER_LENGTH_0 = 0,
+  VARIABLE_LENGTH_INTEGER_LENGTH_1 = 1,
+  VARIABLE_LENGTH_INTEGER_LENGTH_2 = 2,
+  VARIABLE_LENGTH_INTEGER_LENGTH_4 = 4,
+  VARIABLE_LENGTH_INTEGER_LENGTH_8 = 8,
+
+  // By default we write the IETF long header length using the 2-byte encoding
+  // of variable length integers, even when the length is below 64, which allows
+  // us to fill in the length before knowing what the length actually is.
+  kQuicheDefaultLongHeaderLengthLength = VARIABLE_LENGTH_INTEGER_LENGTH_2,
+};
+
 }  // namespace quiche
 
 #endif  // QUICHE_COMMON_QUICHE_ENDIAN_H_
diff --git a/quiche/quic/core/chlo_extractor_test.cc b/quiche/quic/core/chlo_extractor_test.cc
index 3852469..6b49fdc 100644
--- a/quiche/quic/core/chlo_extractor_test.cc
+++ b/quiche/quic/core/chlo_extractor_test.cc
@@ -65,8 +65,9 @@
     header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
     header.packet_number = QuicPacketNumber(1);
     if (version_.HasLongHeaderLengths()) {
-      header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-      header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+      header.retry_token_length_length =
+          quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
+      header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
     }
     QuicFrames frames;
     size_t offset = 0;
diff --git a/quiche/quic/core/crypto/transport_parameters.cc b/quiche/quic/core/crypto/transport_parameters.cc
index 635d159..140c16a 100644
--- a/quiche/quic/core/crypto/transport_parameters.cc
+++ b/quiche/quic/core/crypto/transport_parameters.cc
@@ -177,13 +177,13 @@
       has_been_read_(false) {
   QUICHE_DCHECK_LE(min_value, default_value);
   QUICHE_DCHECK_LE(default_value, max_value);
-  QUICHE_DCHECK_LE(max_value, kVarInt62MaxValue);
+  QUICHE_DCHECK_LE(max_value, quiche::kVarInt62MaxValue);
 }
 
 TransportParameters::IntegerParameter::IntegerParameter(
     TransportParameters::TransportParameterId param_id)
     : TransportParameters::IntegerParameter::IntegerParameter(
-          param_id, 0, 0, kVarInt62MaxValue) {}
+          param_id, 0, 0, quiche::kVarInt62MaxValue) {}
 
 void TransportParameters::IntegerParameter::set_value(uint64_t value) {
   value_ = value;
@@ -206,13 +206,13 @@
     QUIC_BUG(quic_bug_10743_1) << "Failed to write param_id for " << *this;
     return false;
   }
-  const QuicVariableLengthIntegerLength value_length =
+  const quiche::QuicheVariableLengthIntegerLength value_length =
       QuicDataWriter::GetVarInt62Len(value_);
   if (!writer->WriteVarInt62(value_length)) {
     QUIC_BUG(quic_bug_10743_2) << "Failed to write value_length for " << *this;
     return false;
   }
-  if (!writer->WriteVarInt62(value_, value_length)) {
+  if (!writer->WriteVarInt62WithForcedLength(value_, value_length)) {
     QUIC_BUG(quic_bug_10743_3) << "Failed to write value for " << *this;
     return false;
   }
@@ -451,7 +451,8 @@
 TransportParameters::TransportParameters()
     : max_idle_timeout_ms(kMaxIdleTimeout),
       max_udp_payload_size(kMaxPacketSize, kDefaultMaxPacketSizeTransportParam,
-                           kMinMaxPacketSizeTransportParam, kVarInt62MaxValue),
+                           kMinMaxPacketSizeTransportParam,
+                           quiche::kVarInt62MaxValue),
       initial_max_data(kInitialMaxData),
       initial_max_stream_data_bidi_local(kInitialMaxStreamDataBidiLocal),
       initial_max_stream_data_bidi_remote(kInitialMaxStreamDataBidiRemote),
@@ -469,7 +470,7 @@
       active_connection_id_limit(kActiveConnectionIdLimit,
                                  kDefaultActiveConnectionIdLimitTransportParam,
                                  kMinActiveConnectionIdLimitTransportParam,
-                                 kVarInt62MaxValue),
+                                 quiche::kVarInt62MaxValue),
       max_datagram_frame_size(kMaxDatagramFrameSize),
       initial_round_trip_time_us(kInitialRoundTripTime)
 // Important note: any new transport parameters must be added
diff --git a/quiche/quic/core/crypto/transport_parameters.h b/quiche/quic/core/crypto/transport_parameters.h
index e1f349b..14ae6e9 100644
--- a/quiche/quic/core/crypto/transport_parameters.h
+++ b/quiche/quic/core/crypto/transport_parameters.h
@@ -61,7 +61,7 @@
     friend struct TransportParameters;
     // Constructors for initial setup used by TransportParameters only.
     // This constructor sets |default_value| and |min_value| to 0, and
-    // |max_value| to kVarInt62MaxValue.
+    // |max_value| to quiche::kVarInt62MaxValue.
     explicit IntegerParameter(TransportParameterId param_id);
     IntegerParameter(TransportParameterId param_id, uint64_t default_value,
                      uint64_t min_value, uint64_t max_value);
diff --git a/quiche/quic/core/http/http_decoder.cc b/quiche/quic/core/http/http_decoder.cc
index 5845a37..2bdce8e 100644
--- a/quiche/quic/core/http/http_decoder.cc
+++ b/quiche/quic/core/http/http_decoder.cc
@@ -657,9 +657,9 @@
     case static_cast<uint64_t>(HttpFrameType::SETTINGS):
       return kPayloadLengthLimit;
     case static_cast<uint64_t>(HttpFrameType::GOAWAY):
-      return VARIABLE_LENGTH_INTEGER_LENGTH_8;
+      return quiche::VARIABLE_LENGTH_INTEGER_LENGTH_8;
     case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID):
-      return VARIABLE_LENGTH_INTEGER_LENGTH_8;
+      return quiche::VARIABLE_LENGTH_INTEGER_LENGTH_8;
     case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM):
       return kPayloadLengthLimit;
     case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
diff --git a/quiche/quic/core/http/http_decoder_test.cc b/quiche/quic/core/http/http_decoder_test.cc
index 3ea97ca..c0a18ee 100644
--- a/quiche/quic/core/http/http_decoder_test.cc
+++ b/quiche/quic/core/http/http_decoder_test.cc
@@ -569,7 +569,8 @@
     HttpDecoder decoder(&visitor);
     QuicDataWriter writer(max_input_length, input);
     ASSERT_TRUE(writer.WriteVarInt62(frame_type));         // frame type.
-    ASSERT_TRUE(writer.WriteVarInt62(kVarInt62MaxValue));  // frame length.
+    ASSERT_TRUE(
+        writer.WriteVarInt62(quiche::kVarInt62MaxValue));  // frame length.
     ASSERT_TRUE(writer.WriteUInt8(0x00));  // one byte of payload.
     EXPECT_NE(decoder.ProcessInput(input, writer.length()), 0u) << frame_type;
   }
diff --git a/quiche/quic/core/quic_chaos_protector_test.cc b/quiche/quic/core/quic_chaos_protector_test.cc
index 95c073a..92d3af9 100644
--- a/quiche/quic/core/quic_chaos_protector_test.cc
+++ b/quiche/quic/core/quic_chaos_protector_test.cc
@@ -87,8 +87,9 @@
     header_.packet_number = QuicPacketNumber(1);
     header_.form = IETF_QUIC_LONG_HEADER_PACKET;
     header_.long_packet_type = INITIAL;
-    header_.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header_.length_length = kQuicDefaultLongHeaderLengthLength;
+    header_.retry_token_length_length =
+        quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header_.length_length = quiche::kQuicheDefaultLongHeaderLengthLength;
     // Setup validation framer.
     validation_framer_.framer()->SetInitialObfuscators(
         header_.destination_connection_id);
diff --git a/quiche/quic/core/quic_config.cc b/quiche/quic/core/quic_config.cc
index c48001a..04aa196 100644
--- a/quiche/quic/core/quic_config.cc
+++ b/quiche/quic/core/quic_config.cc
@@ -147,9 +147,9 @@
 }
 
 void QuicFixedUint62::SetSendValue(uint64_t value) {
-  if (value > kVarInt62MaxValue) {
+  if (value > quiche::kVarInt62MaxValue) {
     QUIC_BUG(quic_bug_10575_3) << "QuicFixedUint62 invalid value " << value;
-    value = kVarInt62MaxValue;
+    value = quiche::kVarInt62MaxValue;
   }
   has_send_value_ = true;
   send_value_ = value;
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 21a4bbf..dca0520 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -1119,9 +1119,10 @@
       header.long_packet_type = EncryptionlevelToLongHeaderType(level);
       if (QuicVersionHasLongHeaderLengths(
               peer_framer_.version().transport_version)) {
-        header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+        header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
         if (header.long_packet_type == INITIAL) {
-          header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+          header.retry_token_length_length =
+              quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
         }
       }
     }
@@ -2893,8 +2894,8 @@
   if (QuicVersionHasLongHeaderLengths(
           peer_framer_.version().transport_version)) {
     header.long_packet_type = INITIAL;
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    header.retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   }
 
   QuicFrames frames;
@@ -2941,8 +2942,8 @@
   if (QuicVersionHasLongHeaderLengths(
           peer_framer_.version().transport_version)) {
     header.long_packet_type = INITIAL;
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    header.retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   }
 
   QuicFrames frames;
diff --git a/quiche/quic/core/quic_crypto_stream.cc b/quiche/quic/core/quic_crypto_stream.cc
index 904557b..45f5351 100644
--- a/quiche/quic/core/quic_crypto_stream.cc
+++ b/quiche/quic/core/quic_crypto_stream.cc
@@ -49,13 +49,13 @@
     QuicTransportVersion version, QuicConnectionId connection_id) {
   QUICHE_DCHECK(
       QuicUtils::IsConnectionIdValidForVersion(connection_id, version));
-  QuicVariableLengthIntegerLength retry_token_length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_1;
-  QuicVariableLengthIntegerLength length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  quiche::QuicheVariableLengthIntegerLength retry_token_length_length =
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
+  quiche::QuicheVariableLengthIntegerLength length_length =
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   if (!QuicVersionHasLongHeaderLengths(version)) {
-    retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
-    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+    retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
+    length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
   }
   return QuicPacketCreator::StreamFramePacketOverhead(
       version, static_cast<QuicConnectionIdLength>(connection_id.length()),
diff --git a/quiche/quic/core/quic_data_reader.cc b/quiche/quic/core/quic_data_reader.cc
index 1a06057..aa8b278 100644
--- a/quiche/quic/core/quic_data_reader.cc
+++ b/quiche/quic/core/quic_data_reader.cc
@@ -83,93 +83,5 @@
   return ReadConnectionId(connection_id, connection_id_length);
 }
 
-QuicVariableLengthIntegerLength QuicDataReader::PeekVarInt62Length() {
-  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-  const unsigned char* next =
-      reinterpret_cast<const unsigned char*>(data() + pos());
-  if (BytesRemaining() == 0) {
-    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  }
-  return static_cast<QuicVariableLengthIntegerLength>(
-      1 << ((*next & 0b11000000) >> 6));
-}
-
-// Read an IETF/QUIC formatted 62-bit Variable Length Integer.
-//
-// Performance notes
-//
-// Measurements and experiments showed that unrolling the four cases
-// like this and dereferencing next_ as we do (*(next_+n) --- and then
-// doing a single pos_+=x at the end) gains about 10% over making a
-// loop and dereferencing next_ such as *(next_++)
-//
-// Using a register for pos_ was not helpful.
-//
-// Branches are ordered to increase the likelihood of the first being
-// taken.
-//
-// Low-level optimization is useful here because this function will be
-// called frequently, leading to outsize benefits.
-bool QuicDataReader::ReadVarInt62(uint64_t* result) {
-  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-
-  size_t remaining = BytesRemaining();
-  const unsigned char* next =
-      reinterpret_cast<const unsigned char*>(data() + pos());
-  if (remaining != 0) {
-    switch (*next & 0xc0) {
-      case 0xc0:
-        // Leading 0b11...... is 8 byte encoding
-        if (remaining >= 8) {
-          *result = (static_cast<uint64_t>((*(next)) & 0x3f) << 56) +
-                    (static_cast<uint64_t>(*(next + 1)) << 48) +
-                    (static_cast<uint64_t>(*(next + 2)) << 40) +
-                    (static_cast<uint64_t>(*(next + 3)) << 32) +
-                    (static_cast<uint64_t>(*(next + 4)) << 24) +
-                    (static_cast<uint64_t>(*(next + 5)) << 16) +
-                    (static_cast<uint64_t>(*(next + 6)) << 8) +
-                    (static_cast<uint64_t>(*(next + 7)) << 0);
-          AdvancePos(8);
-          return true;
-        }
-        return false;
-
-      case 0x80:
-        // Leading 0b10...... is 4 byte encoding
-        if (remaining >= 4) {
-          *result = (((*(next)) & 0x3f) << 24) + (((*(next + 1)) << 16)) +
-                    (((*(next + 2)) << 8)) + (((*(next + 3)) << 0));
-          AdvancePos(4);
-          return true;
-        }
-        return false;
-
-      case 0x40:
-        // Leading 0b01...... is 2 byte encoding
-        if (remaining >= 2) {
-          *result = (((*(next)) & 0x3f) << 8) + (*(next + 1));
-          AdvancePos(2);
-          return true;
-        }
-        return false;
-
-      case 0x00:
-        // Leading 0b00...... is 1 byte encoding
-        *result = (*next) & 0x3f;
-        AdvancePos(1);
-        return true;
-    }
-  }
-  return false;
-}
-
-bool QuicDataReader::ReadStringPieceVarInt62(absl::string_view* result) {
-  uint64_t result_length;
-  if (!ReadVarInt62(&result_length)) {
-    return false;
-  }
-  return ReadStringPiece(result, result_length);
-}
-
 #undef ENDPOINT  // undef for jumbo builds
 }  // namespace quic
diff --git a/quiche/quic/core/quic_data_reader.h b/quiche/quic/core/quic_data_reader.h
index 0a67df8..0a907e0 100644
--- a/quiche/quic/core/quic_data_reader.h
+++ b/quiche/quic/core/quic_data_reader.h
@@ -62,29 +62,6 @@
   // Forwards the internal iterator on success.
   // Returns true on success, false otherwise.
   bool ReadLengthPrefixedConnectionId(QuicConnectionId* connection_id);
-
-  // Returns the length in bytes of a variable length integer based on the next
-  // two bits available. Returns 1, 2, 4, or 8 on success, and 0 on failure.
-  QuicVariableLengthIntegerLength PeekVarInt62Length();
-
-  // Read an IETF-encoded Variable Length Integer and place the result
-  // in |*result|.
-  // Returns true if it works, false if not. The only error is that
-  // there is not enough in the buffer to read the number.
-  // If there is an error, |*result| is not altered.
-  // Numbers are encoded per the rules in draft-ietf-quic-transport-10.txt
-  // and that the integers in the range 0 ... (2^62)-1.
-  bool ReadVarInt62(uint64_t* result);
-
-  // Reads a string prefixed with a Variable Length integer length into the
-  // given output parameter.
-  //
-  // NOTE: Does not copy but rather references strings in the underlying buffer.
-  // This should be kept in mind when handling memory management!
-  //
-  // Forwards the internal iterator on success.
-  // Returns true on success, false otherwise.
-  bool ReadStringPieceVarInt62(absl::string_view* result);
 };
 
 }  // namespace quic
diff --git a/quiche/quic/core/quic_data_writer.cc b/quiche/quic/core/quic_data_writer.cc
index 4fbd3b6..09f1923 100644
--- a/quiche/quic/core/quic_data_writer.cc
+++ b/quiche/quic/core/quic_data_writer.cc
@@ -102,157 +102,4 @@
   return true;
 }
 
-// Converts a uint64_t into an IETF/Quic formatted Variable Length
-// Integer. IETF Variable Length Integers have 62 significant bits, so
-// the value to write must be in the range of 0..(2^62)-1.
-//
-// Performance notes
-//
-// Measurements and experiments showed that unrolling the four cases
-// like this and dereferencing next_ as we do (*(next_+n)) gains about
-// 10% over making a loop and dereferencing it as *(next_++)
-//
-// Using a register for next didn't help.
-//
-// Branches are ordered to increase the likelihood of the first being
-// taken.
-//
-// Low-level optimization is useful here because this function will be
-// called frequently, leading to outsize benefits.
-bool QuicDataWriter::WriteVarInt62(uint64_t value) {
-  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-
-  size_t remaining_bytes = remaining();
-  char* next = buffer() + length();
-
-  if ((value & kVarInt62ErrorMask) == 0) {
-    // We know the high 2 bits are 0 so |value| is legal.
-    // We can do the encoding.
-    if ((value & kVarInt62Mask8Bytes) != 0) {
-      // Someplace in the high-4 bytes is a 1-bit. Do an 8-byte
-      // encoding.
-      if (remaining_bytes >= 8) {
-        *(next + 0) = ((value >> 56) & 0x3f) + 0xc0;
-        *(next + 1) = (value >> 48) & 0xff;
-        *(next + 2) = (value >> 40) & 0xff;
-        *(next + 3) = (value >> 32) & 0xff;
-        *(next + 4) = (value >> 24) & 0xff;
-        *(next + 5) = (value >> 16) & 0xff;
-        *(next + 6) = (value >> 8) & 0xff;
-        *(next + 7) = value & 0xff;
-        IncreaseLength(8);
-        return true;
-      }
-      return false;
-    }
-    // The high-order-4 bytes are all 0, check for a 1, 2, or 4-byte
-    // encoding
-    if ((value & kVarInt62Mask4Bytes) != 0) {
-      // The encoding will not fit into 2 bytes, Do a 4-byte
-      // encoding.
-      if (remaining_bytes >= 4) {
-        *(next + 0) = ((value >> 24) & 0x3f) + 0x80;
-        *(next + 1) = (value >> 16) & 0xff;
-        *(next + 2) = (value >> 8) & 0xff;
-        *(next + 3) = value & 0xff;
-        IncreaseLength(4);
-        return true;
-      }
-      return false;
-    }
-    // The high-order bits are all 0. Check to see if the number
-    // can be encoded as one or two bytes. One byte encoding has
-    // only 6 significant bits (bits 0xffffffff ffffffc0 are all 0).
-    // Two byte encoding has more than 6, but 14 or less significant
-    // bits (bits 0xffffffff ffffc000 are 0 and 0x00000000 00003fc0
-    // are not 0)
-    if ((value & kVarInt62Mask2Bytes) != 0) {
-      // Do 2-byte encoding
-      if (remaining_bytes >= 2) {
-        *(next + 0) = ((value >> 8) & 0x3f) + 0x40;
-        *(next + 1) = (value)&0xff;
-        IncreaseLength(2);
-        return true;
-      }
-      return false;
-    }
-    if (remaining_bytes >= 1) {
-      // Do 1-byte encoding
-      *next = (value & 0x3f);
-      IncreaseLength(1);
-      return true;
-    }
-    return false;
-  }
-  // Can not encode, high 2 bits not 0
-  return false;
-}
-
-bool QuicDataWriter::WriteVarInt62(
-    uint64_t value, QuicVariableLengthIntegerLength write_length) {
-  QUICHE_DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER);
-
-  size_t remaining_bytes = remaining();
-  if (remaining_bytes < write_length) {
-    return false;
-  }
-
-  const QuicVariableLengthIntegerLength min_length = GetVarInt62Len(value);
-  if (write_length < min_length) {
-    QUIC_BUG(quic_bug_10347_1) << "Cannot write value " << value
-                               << " with write_length " << write_length;
-    return false;
-  }
-  if (write_length == min_length) {
-    return WriteVarInt62(value);
-  }
-
-  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_2) {
-    return WriteUInt8(0b01000000) && WriteUInt8(value);
-  }
-  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_4) {
-    return WriteUInt8(0b10000000) && WriteUInt8(0) && WriteUInt16(value);
-  }
-  if (write_length == VARIABLE_LENGTH_INTEGER_LENGTH_8) {
-    return WriteUInt8(0b11000000) && WriteUInt8(0) && WriteUInt16(0) &&
-           WriteUInt32(value);
-  }
-
-  QUIC_BUG(quic_bug_10347_2)
-      << "Invalid write_length " << static_cast<int>(write_length);
-  return false;
-}
-
-// static
-QuicVariableLengthIntegerLength QuicDataWriter::GetVarInt62Len(uint64_t value) {
-  if ((value & kVarInt62ErrorMask) != 0) {
-    QUIC_BUG(quic_bug_10347_3) << "Attempted to encode a value, " << value
-                               << ", that is too big for VarInt62";
-    return VARIABLE_LENGTH_INTEGER_LENGTH_0;
-  }
-  if ((value & kVarInt62Mask8Bytes) != 0) {
-    return VARIABLE_LENGTH_INTEGER_LENGTH_8;
-  }
-  if ((value & kVarInt62Mask4Bytes) != 0) {
-    return VARIABLE_LENGTH_INTEGER_LENGTH_4;
-  }
-  if ((value & kVarInt62Mask2Bytes) != 0) {
-    return VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-  return VARIABLE_LENGTH_INTEGER_LENGTH_1;
-}
-
-bool QuicDataWriter::WriteStringPieceVarInt62(
-    const absl::string_view& string_piece) {
-  if (!WriteVarInt62(string_piece.size())) {
-    return false;
-  }
-  if (!string_piece.empty()) {
-    if (!WriteBytes(string_piece.data(), string_piece.size())) {
-      return false;
-    }
-  }
-  return true;
-}
-
 }  // namespace quic
diff --git a/quiche/quic/core/quic_data_writer.h b/quiche/quic/core/quic_data_writer.h
index b1cd198..c96b3b7 100644
--- a/quiche/quic/core/quic_data_writer.h
+++ b/quiche/quic/core/quic_data_writer.h
@@ -18,19 +18,6 @@
 
 class QuicRandom;
 
-// Maximum value that can be properly encoded using VarInt62 coding.
-const uint64_t kVarInt62MaxValue = UINT64_C(0x3fffffffffffffff);
-
-// VarInt62 encoding masks
-// If a uint64_t anded with a mask is not 0 then the value is encoded
-// using that length (or is too big, in the case of kVarInt62ErrorMask).
-// Values must be checked in order (error, 8-, 4-, and then 2- bytes)
-// and if none are non-0, the value is encoded in 1 byte.
-const uint64_t kVarInt62ErrorMask = UINT64_C(0xc000000000000000);
-const uint64_t kVarInt62Mask8Bytes = UINT64_C(0x3fffffffc0000000);
-const uint64_t kVarInt62Mask4Bytes = UINT64_C(0x000000003fffc000);
-const uint64_t kVarInt62Mask2Bytes = UINT64_C(0x0000000000003fc0);
-
 // This class provides facilities for packing QUIC data.
 //
 // The QuicDataWriter supports appending primitive values (int, string, etc)
@@ -52,31 +39,6 @@
   // Methods for adding to the payload.  These values are appended to the end
   // of the QuicDataWriter payload.
 
-  // Write an unsigned-integer value per the IETF QUIC/Variable Length
-  // Integer encoding rules (see draft-ietf-quic-transport-08.txt).
-  // IETF Variable Length Integers have 62 significant bits, so the
-  // value to write must be in the range of 0...(2^62)-1. Returns
-  // false if the value is out of range or if there is no room in the
-  // buffer.
-  bool WriteVarInt62(uint64_t value);
-
-  // Same as WriteVarInt62(uint64_t), but forces an encoding size to write to.
-  // This is not as optimized as WriteVarInt62(uint64_t).
-  // Returns false if the value does not fit in the specified write_length or if
-  // there is no room in the buffer.
-  bool WriteVarInt62(uint64_t value,
-                     QuicVariableLengthIntegerLength write_length);
-
-  // Writes a string piece as a consecutive length/content pair. The
-  // length is VarInt62 encoded.
-  bool WriteStringPieceVarInt62(const absl::string_view& string_piece);
-
-  // Utility function to return the number of bytes needed to encode
-  // the given value using IETF VarInt62 encoding. Returns the number
-  // of bytes required to encode the given integer or 0 if the value
-  // is too large to encode.
-  static QuicVariableLengthIntegerLength GetVarInt62Len(uint64_t value);
-
   // Write unsigned floating point corresponding to the value. Large values are
   // clamped to the maximum representable (kUFloat16MaxValue). Values that can
   // not be represented directly are rounded down.
diff --git a/quiche/quic/core/quic_data_writer_test.cc b/quiche/quic/core/quic_data_writer_test.cc
index 5d20c84..9d454e9 100644
--- a/quiche/quic/core/quic_data_writer_test.cc
+++ b/quiche/quic/core/quic_data_writer_test.cc
@@ -666,416 +666,12 @@
   }
 }
 
-const int kVarIntBufferLength = 1024;
-
-// Encodes and then decodes a specified value, checks that the
-// value that was encoded is the same as the decoded value, the length
-// is correct, and that after decoding, all data in the buffer has
-// been consumed..
-// Returns true if everything works, false if not.
-bool EncodeDecodeValue(uint64_t value_in, char* buffer, size_t size_of_buffer) {
-  // Init the buffer to all 0, just for cleanliness. Makes for better
-  // output if, in debugging, we need to dump out the buffer.
-  memset(buffer, 0, size_of_buffer);
-  // make a writer. Note that for IETF encoding
-  // we do not care about endianness... It's always big-endian,
-  // but the c'tor expects to be told what endianness is in force...
-  QuicDataWriter writer(size_of_buffer, buffer,
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-
-  // Try to write the value.
-  if (writer.WriteVarInt62(value_in) != true) {
-    return false;
-  }
-  // Look at the value we encoded. Determine how much should have been
-  // used based on the value, and then check the state of the writer
-  // to see that it matches.
-  size_t expected_length = 0;
-  if (value_in <= 0x3f) {
-    expected_length = 1;
-  } else if (value_in <= 0x3fff) {
-    expected_length = 2;
-  } else if (value_in <= 0x3fffffff) {
-    expected_length = 4;
-  } else {
-    expected_length = 8;
-  }
-  if (writer.length() != expected_length) {
-    return false;
-  }
-
-  // set up a reader, just the length we've used, no more, no less.
-  QuicDataReader reader(buffer, expected_length,
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  uint64_t value_out;
-
-  if (reader.ReadVarInt62(&value_out) == false) {
-    return false;
-  }
-  if (value_in != value_out) {
-    return false;
-  }
-  // We only write one value so there had better be nothing left to read
-  return reader.IsDoneReading();
-}
-
-// Test that 8-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt8Layout) {
-  char buffer[1024];
-
-  // Check that the layout of bytes in the buffer is correct. Bytes
-  // are always encoded big endian...
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
-            (0x31 + 0xc0));  // 0xc0 for encoding
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x42);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf3);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe4);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 4)), 0xd5);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 5)), 0xc6);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 6)), 0xb7);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 7)), 0xa8);
-}
-
-// Test that 4-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt4Layout) {
-  char buffer[1024];
-
-  // Check that the layout of bytes in the buffer is correct. Bytes
-  // are always encoded big endian...
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(0x3243f4e5));
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
-            (0x32 + 0x80));  // 0x80 for encoding
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x43);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 2)), 0xf4);
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 3)), 0xe5);
-}
-
-// Test that 2-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt2Layout) {
-  char buffer[1024];
-
-  // Check that the layout of bytes in the buffer is correct. Bytes
-  // are always encoded big endian...
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(0x3647));
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)),
-            (0x36 + 0x40));  // 0x40 for encoding
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 1)), 0x47);
-}
-
-// Test that 1-byte-encoded Variable Length Integers are properly laid
-// out in the buffer.
-TEST_P(QuicDataWriterTest, VarInt1Layout) {
-  char buffer[1024];
-
-  // Check that the layout of bytes in the buffer
-  // is correct. Bytes are always encoded big endian...
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  EXPECT_TRUE(writer.WriteVarInt62(0x3f));
-  EXPECT_EQ(static_cast<unsigned char>(*(writer.data() + 0)), 0x3f);
-}
-
-// Test certain, targeted, values that are expected to succeed:
-// 0, 1,
-// 0x3e, 0x3f, 0x40, 0x41 (around the 1-2 byte transitions)
-// 0x3ffe, 0x3fff, 0x4000, 0x4001 (the 2-4 byte transition)
-// 0x3ffffffe, 0x3fffffff, 0x40000000, 0x40000001 (the 4-8 byte
-//                          transition)
-// 0x3ffffffffffffffe, 0x3fffffffffffffff,  (the highest valid values)
-// 0xfe, 0xff, 0x100, 0x101,
-// 0xfffe, 0xffff, 0x10000, 0x10001,
-// 0xfffffe, 0xffffff, 0x1000000, 0x1000001,
-// 0xfffffffe, 0xffffffff, 0x100000000, 0x100000001,
-// 0xfffffffffe, 0xffffffffff, 0x10000000000, 0x10000000001,
-// 0xfffffffffffe, 0xffffffffffff, 0x1000000000000, 0x1000000000001,
-// 0xfffffffffffffe, 0xffffffffffffff, 0x100000000000000, 0x100000000000001,
-TEST_P(QuicDataWriterTest, VarIntGoodTargetedValues) {
-  char buffer[kVarIntBufferLength];
-  uint64_t passing_values[] = {
-      0,
-      1,
-      0x3e,
-      0x3f,
-      0x40,
-      0x41,
-      0x3ffe,
-      0x3fff,
-      0x4000,
-      0x4001,
-      0x3ffffffe,
-      0x3fffffff,
-      0x40000000,
-      0x40000001,
-      0x3ffffffffffffffe,
-      0x3fffffffffffffff,
-      0xfe,
-      0xff,
-      0x100,
-      0x101,
-      0xfffe,
-      0xffff,
-      0x10000,
-      0x10001,
-      0xfffffe,
-      0xffffff,
-      0x1000000,
-      0x1000001,
-      0xfffffffe,
-      0xffffffff,
-      0x100000000,
-      0x100000001,
-      0xfffffffffe,
-      0xffffffffff,
-      0x10000000000,
-      0x10000000001,
-      0xfffffffffffe,
-      0xffffffffffff,
-      0x1000000000000,
-      0x1000000000001,
-      0xfffffffffffffe,
-      0xffffffffffffff,
-      0x100000000000000,
-      0x100000000000001,
-  };
-  for (uint64_t test_val : passing_values) {
-    EXPECT_TRUE(
-        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
-        << " encode/decode of " << test_val << " failed";
-  }
-}
-//
-// Test certain, targeted, values where failure is expected (the
-// values are invalid w.r.t. IETF VarInt encoding):
-// 0x4000000000000000, 0x4000000000000001,  ( Just above max allowed value)
-// 0xfffffffffffffffe, 0xffffffffffffffff,  (should fail)
-TEST_P(QuicDataWriterTest, VarIntBadTargetedValues) {
-  char buffer[kVarIntBufferLength];
-  uint64_t failing_values[] = {
-      0x4000000000000000,
-      0x4000000000000001,
-      0xfffffffffffffffe,
-      0xffffffffffffffff,
-  };
-  for (uint64_t test_val : failing_values) {
-    EXPECT_FALSE(
-        EncodeDecodeValue(test_val, static_cast<char*>(buffer), sizeof(buffer)))
-        << " encode/decode of " << test_val << " succeeded, but was an "
-        << "invalid value";
-  }
-}
-
 // Following tests all try to fill the buffer with multiple values,
 // go one value more than the buffer can accommodate, then read
 // the successfully encoded values, and try to read the unsuccessfully
 // encoded value. The following is the number of values to encode.
 const int kMultiVarCount = 1000;
 
-// Test writing & reading multiple 8-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt8) {
-  uint64_t test_val;
-  char buffer[8 * kMultiVarCount];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  // Put N values into the buffer. Adding i to the value ensures that
-  // each value is different so we can detect if we overwrite values,
-  // or read the same value over and over.
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8) + i));
-  }
-  EXPECT_EQ(writer.length(), 8u * kMultiVarCount);
-
-  // N+1st should fail, the buffer is full.
-  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4d5c6b7a8)));
-
-  // Now we should be able to read out the N values that were
-  // successfully encoded.
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4d5c6b7a8) + i));
-  }
-  // And the N+1st should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing & reading multiple 4-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt4) {
-  uint64_t test_val;
-  char buffer[4 * kMultiVarCount];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  // Put N values into the buffer. Adding i to the value ensures that
-  // each value is different so we can detect if we overwrite values,
-  // or read the same value over and over.
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142f3e4) + i));
-  }
-  EXPECT_EQ(writer.length(), 4u * kMultiVarCount);
-
-  // N+1st should fail, the buffer is full.
-  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142f3e4)));
-
-  // Now we should be able to read out the N values that were
-  // successfully encoded.
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, (UINT64_C(0x3142f3e4) + i));
-  }
-  // And the N+1st should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing & reading multiple 2-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt2) {
-  uint64_t test_val;
-  char buffer[2 * kMultiVarCount];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  // Put N values into the buffer. Adding i to the value ensures that
-  // each value is different so we can detect if we overwrite values,
-  // or read the same value over and over.
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x3142) + i));
-  }
-  EXPECT_EQ(writer.length(), 2u * kMultiVarCount);
-
-  // N+1st should fail, the buffer is full.
-  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x3142)));
-
-  // Now we should be able to read out the N values that were
-  // successfully encoded.
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, (UINT64_C(0x3142) + i));
-  }
-  // And the N+1st should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing & reading multiple 1-byte-encoded varints
-TEST_P(QuicDataWriterTest, MultiVarInt1) {
-  uint64_t test_val;
-  char buffer[1 * kMultiVarCount];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  // Put N values into the buffer. Adding i to the value ensures that
-  // each value is different so we can detect if we overwrite values,
-  // or read the same value over and over. &0xf ensures we do not
-  // overflow the max value for single-byte encoding.
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(writer.WriteVarInt62(UINT64_C(0x30) + (i & 0xf)));
-  }
-  EXPECT_EQ(writer.length(), 1u * kMultiVarCount);
-
-  // N+1st should fail, the buffer is full.
-  EXPECT_FALSE(writer.WriteVarInt62(UINT64_C(0x31)));
-
-  // Now we should be able to read out the N values that were
-  // successfully encoded.
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-  for (int i = 0; i < kMultiVarCount; i++) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, (UINT64_C(0x30) + (i & 0xf)));
-  }
-  // And the N+1st should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
-// Test writing varints with a forced length.
-TEST_P(QuicDataWriterTest, VarIntFixedLength) {
-  char buffer[90];
-  memset(buffer, 0, sizeof(buffer));
-  QuicDataWriter writer(sizeof(buffer), static_cast<char*>(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-
-  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_1);
-  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_2);
-  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(1, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_1);
-  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_2);
-  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(63, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_2);
-  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(64, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_2);
-  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(16383, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(16384, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_4);
-  writer.WriteVarInt62(1073741823, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  writer.WriteVarInt62(1073741824, VARIABLE_LENGTH_INTEGER_LENGTH_8);
-
-  QuicDataReader reader(buffer, sizeof(buffer),
-                        quiche::Endianness::NETWORK_BYTE_ORDER);
-
-  uint64_t test_val = 0;
-  for (int i = 0; i < 4; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 1u);
-  }
-  for (int i = 0; i < 4; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 63u);
-  }
-
-  for (int i = 0; i < 3; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 64u);
-  }
-  for (int i = 0; i < 3; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 16383u);
-  }
-
-  for (int i = 0; i < 2; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 16384u);
-  }
-  for (int i = 0; i < 2; ++i) {
-    EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-    EXPECT_EQ(test_val, 1073741823u);
-  }
-
-  EXPECT_TRUE(reader.ReadVarInt62(&test_val));
-  EXPECT_EQ(test_val, 1073741824u);
-
-  // We are at the end of the buffer so this should fail.
-  EXPECT_FALSE(reader.ReadVarInt62(&test_val));
-}
-
 // Test encoding/decoding stream-id values.
 void EncodeDecodeStreamId(uint64_t value_in) {
   char buffer[1 * kMultiVarCount];
diff --git a/quiche/quic/core/quic_framer.cc b/quiche/quic/core/quic_framer.cc
index b6b0c5b..1630a2c 100644
--- a/quiche/quic/core/quic_framer.cc
+++ b/quiche/quic/core/quic_framer.cc
@@ -860,20 +860,20 @@
   }
   if (writer->length() < length_field_offset ||
       writer->length() - length_field_offset <
-          kQuicDefaultLongHeaderLengthLength) {
+          quiche::kQuicheDefaultLongHeaderLengthLength) {
     set_detailed_error("Invalid length_field_offset.");
     QUIC_BUG(quic_bug_10850_14) << "Invalid length_field_offset.";
     return false;
   }
   size_t length_to_write = writer->length() - length_field_offset -
-                           kQuicDefaultLongHeaderLengthLength;
+                           quiche::kQuicheDefaultLongHeaderLengthLength;
   // Add length of auth tag.
   length_to_write = GetCiphertextSize(level, length_to_write);
 
   QuicDataWriter length_writer(writer->length() - length_field_offset,
                                writer->data() + length_field_offset);
-  if (!length_writer.WriteVarInt62(length_to_write,
-                                   kQuicDefaultLongHeaderLengthLength)) {
+  if (!length_writer.WriteVarInt62WithForcedLength(
+          length_to_write, quiche::kQuicheDefaultLongHeaderLengthLength)) {
     set_detailed_error("Failed to overwrite long header length.");
     QUIC_BUG(quic_bug_10850_15) << "Failed to overwrite long header length.";
     return false;
@@ -1741,7 +1741,7 @@
                                        size_t buffer_length) {
   QUICHE_DCHECK_NE(GOOGLE_QUIC_PACKET, header->form);
   QUICHE_DCHECK(!header->has_possible_stateless_reset_token);
-  header->length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  header->length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
   header->remaining_packet_length = 0;
   if (header->form == IETF_QUIC_SHORT_HEADER_PACKET &&
       perspective_ == Perspective::IS_CLIENT) {
@@ -2274,13 +2274,13 @@
   if (QuicVersionHasLongHeaderLengths(transport_version()) &&
       header.version_flag) {
     if (header.long_packet_type == INITIAL) {
-      QUICHE_DCHECK_NE(VARIABLE_LENGTH_INTEGER_LENGTH_0,
+      QUICHE_DCHECK_NE(quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0,
                        header.retry_token_length_length)
           << ENDPOINT << ParsedQuicVersionToString(version_)
           << " bad retry token length length in header: " << header;
       // Write retry token length.
-      if (!writer->WriteVarInt62(header.retry_token.length(),
-                                 header.retry_token_length_length)) {
+      if (!writer->WriteVarInt62WithForcedLength(
+              header.retry_token.length(), header.retry_token_length_length)) {
         return false;
       }
       // Write retry token.
@@ -3963,7 +3963,8 @@
     return false;
   }
 
-  if (ack_delay_time_in_us >= (kVarInt62MaxValue >> peer_ack_delay_exponent_)) {
+  if (ack_delay_time_in_us >=
+      (quiche::kVarInt62MaxValue >> peer_ack_delay_exponent_)) {
     ack_frame->ack_delay_time = QuicTime::Delta::Infinite();
   } else {
     ack_delay_time_in_us = (ack_delay_time_in_us << peer_ack_delay_exponent_);
@@ -4358,9 +4359,9 @@
     QuicConnectionIdLength source_connection_id_length, bool includes_version,
     bool includes_diversification_nonce,
     QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
+    quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
     uint64_t retry_token_length,
-    QuicVariableLengthIntegerLength length_length) {
+    quiche::QuicheVariableLengthIntegerLength length_length) {
   // TODO(ianswett): This is identical to QuicData::AssociatedData.
   return absl::string_view(
       encrypted.data(),
@@ -6028,7 +6029,7 @@
     return false;
   }
 
-  uint64_t ack_delay_time_us = kVarInt62MaxValue;
+  uint64_t ack_delay_time_us = quiche::kVarInt62MaxValue;
   if (!frame.ack_delay_time.IsInfinite()) {
     QUICHE_DCHECK_LE(0u, frame.ack_delay_time.ToMicroseconds());
     ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
@@ -6812,7 +6813,7 @@
   }
   const bool ietf_format = QuicUtils::IsIetfPacketHeader(first_byte);
   uint8_t unused_first_byte;
-  QuicVariableLengthIntegerLength retry_token_length_length;
+  quiche::QuicheVariableLengthIntegerLength retry_token_length_length;
   absl::string_view maybe_retry_token;
   QuicErrorCode error_code = ParsePublicHeader(
       &reader, expected_destination_connection_id_length, ietf_format,
@@ -6820,7 +6821,7 @@
       version_label, parsed_version, destination_connection_id,
       source_connection_id, long_packet_type, &retry_token_length_length,
       &maybe_retry_token, detailed_error);
-  if (retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+  if (retry_token_length_length != quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0) {
     *retry_token = maybe_retry_token;
   } else {
     retry_token->reset();
@@ -6961,7 +6962,7 @@
     QuicConnectionId* destination_connection_id,
     QuicConnectionId* source_connection_id,
     QuicLongHeaderType* long_packet_type,
-    QuicVariableLengthIntegerLength* retry_token_length_length,
+    quiche::QuicheVariableLengthIntegerLength* retry_token_length_length,
     absl::string_view* retry_token, std::string* detailed_error) {
   *version_present = false;
   *has_length_prefix = false;
@@ -6969,7 +6970,7 @@
   *parsed_version = UnsupportedQuicVersion();
   *source_connection_id = EmptyQuicConnectionId();
   *long_packet_type = INVALID_PACKET_TYPE;
-  *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  *retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
   *retry_token = absl::string_view();
   *detailed_error = "";
 
@@ -7047,7 +7048,7 @@
   *retry_token_length_length = reader->PeekVarInt62Length();
   uint64_t retry_token_length;
   if (!reader->ReadVarInt62(&retry_token_length)) {
-    *retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+    *retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
     *detailed_error = "Unable to read retry token length.";
     return QUIC_INVALID_PACKET_HEADER;
   }
diff --git a/quiche/quic/core/quic_framer.h b/quiche/quic/core/quic_framer.h
index f60a109..c39ee2b 100644
--- a/quiche/quic/core/quic_framer.h
+++ b/quiche/quic/core/quic_framer.h
@@ -425,9 +425,9 @@
       QuicConnectionIdLength source_connection_id_length, bool includes_version,
       bool includes_diversification_nonce,
       QuicPacketNumberLength packet_number_length,
-      QuicVariableLengthIntegerLength retry_token_length_length,
+      quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
       uint64_t retry_token_length,
-      QuicVariableLengthIntegerLength length_length);
+      quiche::QuicheVariableLengthIntegerLength length_length);
 
   // Parses the unencrypted fields in a QUIC header using |reader| as input,
   // stores the result in the other parameters.
@@ -440,7 +440,7 @@
       QuicConnectionId* destination_connection_id,
       QuicConnectionId* source_connection_id,
       QuicLongHeaderType* long_packet_type,
-      QuicVariableLengthIntegerLength* retry_token_length_length,
+      quiche::QuicheVariableLengthIntegerLength* retry_token_length_length,
       absl::string_view* retry_token, std::string* detailed_error);
 
   // Parses the unencrypted fields in |packet| and stores them in the other
diff --git a/quiche/quic/core/quic_framer_test.cc b/quiche/quic/core/quic_framer_test.cc
index 9b022a2..08b53f8 100644
--- a/quiche/quic/core/quic_framer_test.cc
+++ b/quiche/quic/core/quic_framer_test.cc
@@ -763,7 +763,8 @@
     return CheckDecryption(
         encrypted, includes_version, includes_diversification_nonce,
         destination_connection_id_length, source_connection_id_length,
-        VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+        quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0,
+        quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0);
   }
 
   bool CheckDecryption(
@@ -771,9 +772,9 @@
       bool includes_diversification_nonce,
       QuicConnectionIdLength destination_connection_id_length,
       QuicConnectionIdLength source_connection_id_length,
-      QuicVariableLengthIntegerLength retry_token_length_length,
+      quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
       size_t retry_token_length,
-      QuicVariableLengthIntegerLength length_length) {
+      quiche::QuicheVariableLengthIntegerLength length_length) {
     if (visitor_.header_->packet_number != decrypter_->packet_number_) {
       QUIC_LOG(ERROR) << "Decrypted incorrect packet number.  expected "
                       << visitor_.header_->packet_number
@@ -1081,7 +1082,8 @@
       framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
       PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
       !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0,
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0);
 
   memset(p + header_size, 0, kMaxIncomingPacketSize - header_size);
 
@@ -1395,8 +1397,8 @@
   QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
                    source_connection_id = EmptyQuicConnectionId();
   QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  QuicVariableLengthIntegerLength retry_token_length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_4;
+  quiche::QuicheVariableLengthIntegerLength retry_token_length_length =
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_4;
   absl::string_view retry_token;
   std::string detailed_error = "foobar";
 
@@ -1418,7 +1420,8 @@
   EXPECT_EQ(framer_.version(), parsed_version);
   EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
   EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-  EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
+  EXPECT_EQ(quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0,
+            retry_token_length_length);
   EXPECT_EQ(absl::string_view(), retry_token);
   if (framer_.version().HasIetfInvariantHeader()) {
     EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
@@ -1464,8 +1467,8 @@
   QuicConnectionId destination_connection_id = EmptyQuicConnectionId(),
                    source_connection_id = EmptyQuicConnectionId();
   QuicLongHeaderType long_packet_type = INVALID_PACKET_TYPE;
-  QuicVariableLengthIntegerLength retry_token_length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_4;
+  quiche::QuicheVariableLengthIntegerLength retry_token_length_length =
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_4;
   absl::string_view retry_token;
   std::string detailed_error = "foobar";
 
@@ -1485,7 +1488,8 @@
   EXPECT_EQ(UnsupportedQuicVersion(), parsed_version);
   EXPECT_EQ(FramerTestConnectionId(), destination_connection_id);
   EXPECT_EQ(EmptyQuicConnectionId(), source_connection_id);
-  EXPECT_EQ(VARIABLE_LENGTH_INTEGER_LENGTH_0, retry_token_length_length);
+  EXPECT_EQ(quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0,
+            retry_token_length_length);
   EXPECT_EQ(absl::string_view(), retry_token);
   EXPECT_EQ(IETF_QUIC_LONG_HEADER_PACKET, format);
 }
@@ -2964,13 +2968,13 @@
   };
   // clang-format on
 
-  QuicVariableLengthIntegerLength retry_token_length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  quiche::QuicheVariableLengthIntegerLength retry_token_length_length =
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
   size_t retry_token_length = 0;
-  QuicVariableLengthIntegerLength length_length =
+  quiche::QuicheVariableLengthIntegerLength length_length =
       QuicVersionHasLongHeaderLengths(framer_.transport_version())
-          ? VARIABLE_LENGTH_INTEGER_LENGTH_1
-          : VARIABLE_LENGTH_INTEGER_LENGTH_0;
+          ? quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1
+          : quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
 
   ReviseFirstByteByVersion(packet_ietf);
   PacketFragments& fragments =
@@ -6551,7 +6555,8 @@
       framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
       PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
       !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0,
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0);
   memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
 
   std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -6740,7 +6745,8 @@
       framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
       PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
       !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0,
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0);
   memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
 
   std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -6815,7 +6821,8 @@
       framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
       PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
       !kIncludeDiversificationNonce, PACKET_2BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0,
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0);
   memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
 
   std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -6890,7 +6897,8 @@
       framer_.transport_version(), PACKET_8BYTE_CONNECTION_ID,
       PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
       !kIncludeDiversificationNonce, PACKET_1BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0,
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0);
   memset(p + header_size + 1, 0x00, kMaxOutgoingPacketSize - header_size - 1);
 
   std::unique_ptr<QuicPacket> data(BuildDataPacket(header, frames));
@@ -6910,7 +6918,7 @@
   header.version_flag = false;
   header.packet_number = kPacketNumber;
   if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   }
 
   QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
@@ -7009,7 +7017,7 @@
   }
   header.packet_number = kPacketNumber;
   if (QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   }
 
   QuicStreamFrame stream_frame(kStreamId, true, kStreamOffset,
@@ -10422,11 +10430,12 @@
     p = packet46;
   }
 
-  std::unique_ptr<QuicPacket> raw(new QuicPacket(
-      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
-      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
+  std::unique_ptr<QuicPacket> raw(
+      new QuicPacket(AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
+                     PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
+                     !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+                     quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0,
+                     quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0));
   char buffer[kMaxOutgoingPacketSize];
   size_t encrypted_length = framer_.EncryptPayload(
       ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
@@ -10442,8 +10451,8 @@
       PACKET_0BYTE_CONNECTION_ID,
       /*includes_version=*/true,
       /*includes_diversification_nonce=*/true, PACKET_1BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0,
-      /*retry_token_length=*/0, VARIABLE_LENGTH_INTEGER_LENGTH_0);
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0,
+      /*retry_token_length=*/0, quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0);
   char buffer[kMaxOutgoingPacketSize];
   size_t encrypted_length = 1;
   EXPECT_QUIC_BUG(
@@ -10530,11 +10539,12 @@
     p_size = ABSL_ARRAYSIZE(packet46);
   }
 
-  std::unique_ptr<QuicPacket> raw(new QuicPacket(
-      AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
-      PACKET_0BYTE_CONNECTION_ID, kIncludeVersion,
-      !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0));
+  std::unique_ptr<QuicPacket> raw(
+      new QuicPacket(AsChars(p), p_size, false, PACKET_8BYTE_CONNECTION_ID,
+                     PACKET_0BYTE_CONNECTION_ID, kIncludeVersion,
+                     !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
+                     quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0,
+                     quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0));
   char buffer[kMaxOutgoingPacketSize];
   size_t encrypted_length = framer_.EncryptPayload(
       ENCRYPTION_INITIAL, packet_number, *raw, buffer, kMaxOutgoingPacketSize);
@@ -14741,8 +14751,8 @@
   header.packet_number = kPacketNumber;
   header.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
   header.long_packet_type = INITIAL;
-  header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+  header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
+  header.retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
   QuicFrames frames = {QuicFrame(QuicPingFrame()),
                        QuicFrame(QuicPaddingFrame(3))};
 
diff --git a/quiche/quic/core/quic_packet_creator.cc b/quiche/quic/core/quic_packet_creator.cc
index 6d39ae3..3be9c40 100644
--- a/quiche/quic/core/quic_packet_creator.cc
+++ b/quiche/quic/core/quic_packet_creator.cc
@@ -384,8 +384,9 @@
     QuicConnectionIdLength source_connection_id_length, bool include_version,
     bool include_diversification_nonce,
     QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
-    QuicVariableLengthIntegerLength length_length, QuicStreamOffset offset) {
+    quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
+    quiche::QuicheVariableLengthIntegerLength length_length,
+    QuicStreamOffset offset) {
   return GetPacketHeaderSize(version, destination_connection_id_length,
                              source_connection_id_length, include_version,
                              include_diversification_nonce,
@@ -1243,14 +1244,14 @@
       GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
 }
 
-QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
-    const {
+quiche::QuicheVariableLengthIntegerLength
+QuicPacketCreator::GetRetryTokenLengthLength() const {
   if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
       HasIetfLongHeader() &&
       EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
     return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
   }
-  return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  return quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
 }
 
 absl::string_view QuicPacketCreator::GetRetryToken() const {
@@ -1629,17 +1630,18 @@
   return MESSAGE_STATUS_SUCCESS;
 }
 
-QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
+quiche::QuicheVariableLengthIntegerLength QuicPacketCreator::GetLengthLength()
+    const {
   if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
       HasIetfLongHeader()) {
     QuicLongHeaderType long_header_type =
         EncryptionlevelToLongHeaderType(packet_.encryption_level);
     if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
         long_header_type == HANDSHAKE) {
-      return VARIABLE_LENGTH_INTEGER_LENGTH_2;
+      return quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
     }
   }
-  return VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  return quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
 }
 
 void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
@@ -1979,7 +1981,7 @@
       GetSourceConnectionIdLength(), IncludeVersionInHeader(),
       IncludeNonceInPublicHeader(), GetPacketNumberLength(),
       // No Retry token on packets containing application data.
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
   // This is the largest possible message payload when the length field is
   // omitted.
   size_t max_plaintext_size =
@@ -2003,13 +2005,13 @@
       framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
       framer_->perspective() == Perspective::IS_SERVER;
   // IETF QUIC long headers include a length on client 0RTT packets.
-  QuicVariableLengthIntegerLength length_length =
-      VARIABLE_LENGTH_INTEGER_LENGTH_0;
+  quiche::QuicheVariableLengthIntegerLength length_length =
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
   if (framer_->perspective() == Perspective::IS_CLIENT) {
-    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   }
   if (!QuicVersionHasLongHeaderLengths(framer_->transport_version())) {
-    length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
+    length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
   }
   const size_t packet_header_size = GetPacketHeaderSize(
       framer_->transport_version(), GetDestinationConnectionIdLength(),
@@ -2017,7 +2019,7 @@
       GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
       PACKET_4BYTE_PACKET_NUMBER,
       // No Retry token on packets containing application data.
-      VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
+      quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
   // This is the largest possible message payload when the length field is
   // omitted.
   size_t max_plaintext_size =
diff --git a/quiche/quic/core/quic_packet_creator.h b/quiche/quic/core/quic_packet_creator.h
index c2c7e2c..c6b41ad 100644
--- a/quiche/quic/core/quic_packet_creator.h
+++ b/quiche/quic/core/quic_packet_creator.h
@@ -146,8 +146,9 @@
       QuicConnectionIdLength source_connection_id_length, bool include_version,
       bool include_diversification_nonce,
       QuicPacketNumberLength packet_number_length,
-      QuicVariableLengthIntegerLength retry_token_length_length,
-      QuicVariableLengthIntegerLength length_length, QuicStreamOffset offset);
+      quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
+      quiche::QuicheVariableLengthIntegerLength length_length,
+      QuicStreamOffset offset);
 
   // Returns false and flushes all pending frames if current open packet is
   // full.
@@ -578,7 +579,7 @@
 
   // Returns length of the retry token variable length integer to send over the
   // wire. Is non-zero for v99 IETF Initial packets.
-  QuicVariableLengthIntegerLength GetRetryTokenLengthLength() const;
+  quiche::QuicheVariableLengthIntegerLength GetRetryTokenLengthLength() const;
 
   // Returns the retry token to send over the wire, only sent in
   // v99 IETF Initial packets.
@@ -586,7 +587,7 @@
 
   // Returns length of the length variable length integer to send over the
   // wire. Is non-zero for v99 IETF Initial, 0-RTT or Handshake packets.
-  QuicVariableLengthIntegerLength GetLengthLength() const;
+  quiche::QuicheVariableLengthIntegerLength GetLengthLength() const;
 
   // Returns true if |frame| is a ClientHello.
   bool StreamFrameIsClientHello(const QuicStreamFrame& frame) const;
diff --git a/quiche/quic/core/quic_packets.cc b/quiche/quic/core/quic_packets.cc
index 369a32a..f0b9ccd 100644
--- a/quiche/quic/core/quic_packets.cc
+++ b/quiche/quic/core/quic_packets.cc
@@ -105,9 +105,9 @@
     QuicConnectionIdLength source_connection_id_length, bool include_version,
     bool include_diversification_nonce,
     QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
+    quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
     QuicByteCount retry_token_length,
-    QuicVariableLengthIntegerLength length_length) {
+    quiche::QuicheVariableLengthIntegerLength length_length) {
   if (VersionHasIetfInvariantHeader(version)) {
     if (include_version) {
       // Long header.
@@ -153,9 +153,9 @@
     QuicConnectionIdLength source_connection_id_length, bool include_version,
     bool include_diversification_nonce,
     QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
+    quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
     QuicByteCount retry_token_length,
-    QuicVariableLengthIntegerLength length_length) {
+    quiche::QuicheVariableLengthIntegerLength length_length) {
   // Encryption starts before private flags.
   return GetPacketHeaderSize(
       version, destination_connection_id_length, source_connection_id_length,
@@ -177,9 +177,9 @@
       form(GOOGLE_QUIC_PACKET),
       long_packet_type(INITIAL),
       possible_stateless_reset_token({}),
-      retry_token_length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
+      retry_token_length_length(quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0),
       retry_token(absl::string_view()),
-      length_length(VARIABLE_LENGTH_INTEGER_LENGTH_0),
+      length_length(quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0),
       remaining_packet_length(0) {}
 
 QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
@@ -239,14 +239,15 @@
       os << ", long_packet_type: "
          << QuicUtils::QuicLongHeaderTypetoString(header.long_packet_type);
     }
-    if (header.retry_token_length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+    if (header.retry_token_length_length !=
+        quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0) {
       os << ", retry_token_length_length: "
          << static_cast<int>(header.retry_token_length_length);
     }
     if (header.retry_token.length() != 0) {
       os << ", retry_token_length: " << header.retry_token.length();
     }
-    if (header.length_length != VARIABLE_LENGTH_INTEGER_LENGTH_0) {
+    if (header.length_length != quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0) {
       os << ", length_length: " << static_cast<int>(header.length_length);
     }
     if (header.remaining_packet_length != 0) {
@@ -285,9 +286,9 @@
     QuicConnectionIdLength source_connection_id_length, bool includes_version,
     bool includes_diversification_nonce,
     QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
+    quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
     QuicByteCount retry_token_length,
-    QuicVariableLengthIntegerLength length_length)
+    quiche::QuicheVariableLengthIntegerLength length_length)
     : QuicData(buffer, length, owns_buffer),
       buffer_(buffer),
       destination_connection_id_length_(destination_connection_id_length),
diff --git a/quiche/quic/core/quic_packets.h b/quiche/quic/core/quic_packets.h
index d4f04c8..c0cc8af 100644
--- a/quiche/quic/core/quic_packets.h
+++ b/quiche/quic/core/quic_packets.h
@@ -82,15 +82,15 @@
 QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(QuicTransportVersion version,
                                                const QuicPacketHeader& header);
 
-QUIC_EXPORT_PRIVATE size_t
-GetPacketHeaderSize(QuicTransportVersion version,
-                    QuicConnectionIdLength destination_connection_id_length,
-                    QuicConnectionIdLength source_connection_id_length,
-                    bool include_version, bool include_diversification_nonce,
-                    QuicPacketNumberLength packet_number_length,
-                    QuicVariableLengthIntegerLength retry_token_length_length,
-                    QuicByteCount retry_token_length,
-                    QuicVariableLengthIntegerLength length_length);
+QUIC_EXPORT_PRIVATE size_t GetPacketHeaderSize(
+    QuicTransportVersion version,
+    QuicConnectionIdLength destination_connection_id_length,
+    QuicConnectionIdLength source_connection_id_length, bool include_version,
+    bool include_diversification_nonce,
+    QuicPacketNumberLength packet_number_length,
+    quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
+    QuicByteCount retry_token_length,
+    quiche::QuicheVariableLengthIntegerLength length_length);
 
 // Index of the first byte in a QUIC packet of encrypted data.
 QUIC_EXPORT_PRIVATE size_t GetStartOfEncryptedData(
@@ -102,9 +102,9 @@
     QuicConnectionIdLength source_connection_id_length, bool include_version,
     bool include_diversification_nonce,
     QuicPacketNumberLength packet_number_length,
-    QuicVariableLengthIntegerLength retry_token_length_length,
+    quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
     QuicByteCount retry_token_length,
-    QuicVariableLengthIntegerLength length_length);
+    quiche::QuicheVariableLengthIntegerLength length_length);
 
 struct QUIC_EXPORT_PRIVATE QuicPacketHeader {
   QuicPacketHeader();
@@ -147,12 +147,12 @@
   StatelessResetToken possible_stateless_reset_token;
   // Length of the retry token length variable length integer field,
   // carried only by v99 IETF Initial packets.
-  QuicVariableLengthIntegerLength retry_token_length_length;
+  quiche::QuicheVariableLengthIntegerLength retry_token_length_length;
   // Retry token, carried only by v99 IETF Initial packets.
   absl::string_view retry_token;
   // Length of the length variable length integer field,
   // carried only by v99 IETF Initial, 0-RTT and Handshake packets.
-  QuicVariableLengthIntegerLength length_length;
+  quiche::QuicheVariableLengthIntegerLength length_length;
   // Length of the packet number and payload, carried only by v99 IETF Initial,
   // 0-RTT and Handshake packets. Also includes the length of the
   // diversification nonce in server to client 0-RTT packets.
@@ -222,14 +222,15 @@
 
 class QUIC_EXPORT_PRIVATE QuicPacket : public QuicData {
  public:
-  QuicPacket(char* buffer, size_t length, bool owns_buffer,
-             QuicConnectionIdLength destination_connection_id_length,
-             QuicConnectionIdLength source_connection_id_length,
-             bool includes_version, bool includes_diversification_nonce,
-             QuicPacketNumberLength packet_number_length,
-             QuicVariableLengthIntegerLength retry_token_length_length,
-             QuicByteCount retry_token_length,
-             QuicVariableLengthIntegerLength length_length);
+  QuicPacket(
+      char* buffer, size_t length, bool owns_buffer,
+      QuicConnectionIdLength destination_connection_id_length,
+      QuicConnectionIdLength source_connection_id_length, bool includes_version,
+      bool includes_diversification_nonce,
+      QuicPacketNumberLength packet_number_length,
+      quiche::QuicheVariableLengthIntegerLength retry_token_length_length,
+      QuicByteCount retry_token_length,
+      quiche::QuicheVariableLengthIntegerLength length_length);
   QuicPacket(QuicTransportVersion version, char* buffer, size_t length,
              bool owns_buffer, const QuicPacketHeader& header);
   QuicPacket(const QuicPacket&) = delete;
@@ -247,9 +248,9 @@
   const bool includes_version_;
   const bool includes_diversification_nonce_;
   const QuicPacketNumberLength packet_number_length_;
-  const QuicVariableLengthIntegerLength retry_token_length_length_;
+  const quiche::QuicheVariableLengthIntegerLength retry_token_length_length_;
   const QuicByteCount retry_token_length_;
-  const QuicVariableLengthIntegerLength length_length_;
+  const quiche::QuicheVariableLengthIntegerLength length_length_;
 };
 
 class QUIC_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData {
diff --git a/quiche/quic/core/quic_stream_test.cc b/quiche/quic/core/quic_stream_test.cc
index 51b25a5..1bec69f 100644
--- a/quiche/quic/core/quic_stream_test.cc
+++ b/quiche/quic/core/quic_stream_test.cc
@@ -346,8 +346,8 @@
               connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
               PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
               !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-              VARIABLE_LENGTH_INTEGER_LENGTH_0,
-              VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
+              quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0,
+              quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
   connection_->SetMaxPacketLength(length);
 
   EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
@@ -431,8 +431,8 @@
               connection_->transport_version(), PACKET_8BYTE_CONNECTION_ID,
               PACKET_0BYTE_CONNECTION_ID, !kIncludeVersion,
               !kIncludeDiversificationNonce, PACKET_4BYTE_PACKET_NUMBER,
-              VARIABLE_LENGTH_INTEGER_LENGTH_0,
-              VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
+              quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0,
+              quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
   connection_->SetMaxPacketLength(length);
 
   EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
diff --git a/quiche/quic/core/quic_types.h b/quiche/quic/core/quic_types.h
index b0992c8..ffaf6c6 100644
--- a/quiche/quic/core/quic_types.h
+++ b/quiche/quic/core/quic_types.h
@@ -21,6 +21,7 @@
 #include "quiche/quic/core/quic_time.h"
 #include "quiche/quic/platform/api/quic_export.h"
 #include "quiche/quic/platform/api/quic_flags.h"
+#include "quiche/common/quiche_endian.h"
 
 namespace quic {
 
@@ -353,20 +354,6 @@
 #define IETF_STREAM_FRAME_LEN_BIT 0x02
 #define IETF_STREAM_FRAME_OFF_BIT 0x04
 
-enum QuicVariableLengthIntegerLength : uint8_t {
-  // Length zero means the variable length integer is not present.
-  VARIABLE_LENGTH_INTEGER_LENGTH_0 = 0,
-  VARIABLE_LENGTH_INTEGER_LENGTH_1 = 1,
-  VARIABLE_LENGTH_INTEGER_LENGTH_2 = 2,
-  VARIABLE_LENGTH_INTEGER_LENGTH_4 = 4,
-  VARIABLE_LENGTH_INTEGER_LENGTH_8 = 8,
-
-  // By default we write the IETF long header length using the 2-byte encoding
-  // of variable length integers, even when the length is below 64, which allows
-  // us to fill in the length before knowing what the length actually is.
-  kQuicDefaultLongHeaderLengthLength = VARIABLE_LENGTH_INTEGER_LENGTH_2,
-};
-
 enum QuicPacketNumberLength : uint8_t {
   PACKET_1BYTE_PACKET_NUMBER = 1,
   PACKET_2BYTE_PACKET_NUMBER = 2,
diff --git a/quiche/quic/test_tools/quic_packet_creator_peer.cc b/quiche/quic/test_tools/quic_packet_creator_peer.cc
index 507de25..2ab9fb0 100644
--- a/quiche/quic/test_tools/quic_packet_creator_peer.cc
+++ b/quiche/quic/test_tools/quic_packet_creator_peer.cc
@@ -45,14 +45,14 @@
 }
 
 // static
-QuicVariableLengthIntegerLength
+quiche::QuicheVariableLengthIntegerLength
 QuicPacketCreatorPeer::GetRetryTokenLengthLength(QuicPacketCreator* creator) {
   return creator->GetRetryTokenLengthLength();
 }
 
 // static
-QuicVariableLengthIntegerLength QuicPacketCreatorPeer::GetLengthLength(
-    QuicPacketCreator* creator) {
+quiche::QuicheVariableLengthIntegerLength
+QuicPacketCreatorPeer::GetLengthLength(QuicPacketCreator* creator) {
   return creator->GetLengthLength();
 }
 
diff --git a/quiche/quic/test_tools/quic_packet_creator_peer.h b/quiche/quic/test_tools/quic_packet_creator_peer.h
index 0c9ce77..4607bcd 100644
--- a/quiche/quic/test_tools/quic_packet_creator_peer.h
+++ b/quiche/quic/test_tools/quic_packet_creator_peer.h
@@ -26,9 +26,9 @@
       QuicPacketCreator* creator, QuicPacketNumberLength packet_number_length);
   static QuicPacketNumberLength GetPacketNumberLength(
       QuicPacketCreator* creator);
-  static QuicVariableLengthIntegerLength GetRetryTokenLengthLength(
+  static quiche::QuicheVariableLengthIntegerLength GetRetryTokenLengthLength(
       QuicPacketCreator* creator);
-  static QuicVariableLengthIntegerLength GetLengthLength(
+  static quiche::QuicheVariableLengthIntegerLength GetLengthLength(
       QuicPacketCreator* creator);
   static void SetPacketNumber(QuicPacketCreator* creator, uint64_t s);
   static void SetPacketNumber(QuicPacketCreator* creator, QuicPacketNumber num);
diff --git a/quiche/quic/test_tools/quic_test_utils.cc b/quiche/quic/test_tools/quic_test_utils.cc
index cfb947a..03948b7 100644
--- a/quiche/quic/test_tools/quic_test_utils.cc
+++ b/quiche/quic/test_tools/quic_test_utils.cc
@@ -908,8 +908,8 @@
   ParsedQuicVersion version = (*versions)[0];
   if (QuicVersionHasLongHeaderLengths(version.transport_version) &&
       version_flag) {
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    header.retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   }
 
   QuicFrames frames;
@@ -973,8 +973,8 @@
   header.packet_number = QuicPacketNumber(33);
   header.long_packet_type = ZERO_RTT_PROTECTED;
   if (version.HasLongHeaderLengths()) {
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    header.retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   }
 
   QuicFrames frames;
@@ -1027,8 +1027,8 @@
   header.packet_number = QuicPacketNumber(packet_number);
   if (QuicVersionHasLongHeaderLengths(version.transport_version) &&
       version_flag) {
-    header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+    header.retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    header.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   }
   QuicFrame frame(QuicStreamFrame(1, false, 0, absl::string_view(data)));
   QuicFrames frames;