If these walls could talk...

PiperOrigin-RevId: 458711847
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 7503d7d..f8e0c4e 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -427,11 +427,12 @@
 
 uint8_t* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
     const MessageLite* extendee, uint8_t* target) const {
+  // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
   io::EpsCopyOutputStream stream(
       target, MessageSetByteSize(),
       io::CodedOutputStream::IsDefaultSerializationDeterministic());
-  return InternalSerializeMessageSetWithCachedSizesToArray(extendee, target,
-                                                           &stream);
+  return stream.Finalize(InternalSerializeMessageSetWithCachedSizesToArray(
+      extendee, target, &stream));
 }
 
 }  // namespace internal
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index ef623ea..1f7b951 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -62,6 +62,37 @@
 // Must be included last.
 #include "google/protobuf/port_def.inc"
 
+int max_count = 0;
+
+void set_max_count(int count) { max_count = count; }
+
+bool jdcoff = false;
+bool jdcon(int count) { return !jdcoff && (count < max_count); }
+
+void TurningOff1() {
+  // std::cerr << "TURNINGOFF" << std::endl;
+  // std::cerr << "TURNINGOFF" << std::endl;
+  // std::cerr << "TURNINGOFF" << std::endl;
+  // std::cerr << "TURNINGOFF" << std::endl;
+  // std::cerr << "TURNINGOFF" << std::endl;
+  // std::cerr << "TURNINGOFF" << std::endl;
+  // std::cerr << "TURNINGOFF" << std::endl;
+  // std::cerr << "TURNINGOFF" << std::endl;
+  // std::cerr << "TURNINGOFF" << std::endl;
+  jdcoff = !jdcoff;
+}
+
+google::protobuf::io::EpsCopyOutputStream::EpsCopyOutputStream(void* data, int size,
+                                                     bool deterministic)
+    : array_end_(static_cast<uint8_t*>(data) + size),
+      buffer_end_(nullptr),
+      stream_(nullptr),
+      is_serialization_deterministic_(deterministic) {
+  // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
+  // Added by jdcollin@
+  end_ = static_cast<uint8_t*>(data) + size - kSlopBytes;
+}
+
 namespace google {
 namespace protobuf {
 namespace io {
@@ -757,6 +788,45 @@
   return s;
 }
 
+uint8_t* EpsCopyOutputStream::FlushArray(uint8_t* ptr) {
+  // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
+  DCHECK(stream_ == nullptr);
+  if (PROTOBUF_PREDICT_FALSE(had_error_)) return ptr;
+  if (buffer_end_ != nullptr) {
+    const ptrdiff_t bytes = ptr - buffer_;
+    DCHECK_GE(bytes, 0);
+    DCHECK_LE(bytes, array_end_ - buffer_end_);
+    memcpy(buffer_end_, buffer_, static_cast<size_t>(bytes));
+    ptr = buffer_end_ + bytes;
+    buffer_end_ = nullptr;
+  }
+  return ptr;
+}
+
+std::pair<uint8_t*, uint8_t*> EpsCopyOutputStream::ConsumeArray(uint8_t* ptr,
+                                                                int size) {
+  // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
+  DCHECK(array_end_ != nullptr);
+
+  if (buffer_end_ == nullptr) {
+    int avail = array_end_ - ptr;
+    if (size > avail) return {nullptr, nullptr};
+    return {ptr, ptr + size};
+  }
+  DCHECK(ptr >= buffer_ && ptr <= buffer_ + kSlopBytes);
+
+  int bytes = ptr - buffer_;
+  int avail = array_end_ - buffer_end_ - bytes;
+  if (size > avail) return {nullptr, nullptr};
+
+  memcpy(buffer_end_, buffer_, bytes);
+  ptr = buffer_end_ + bytes;
+  buffer_end_ += bytes + size;
+  end_ = buffer_ + kSlopBytes;
+
+  return {ptr, buffer_};
+}
+
 uint8_t* EpsCopyOutputStream::Trim(uint8_t* ptr) {
   if (had_error_) return ptr;
   int s = Flush(ptr);
@@ -879,6 +949,21 @@
 }
 
 uint8_t* EpsCopyOutputStream::EnsureSpaceFallback(uint8_t* ptr) {
+  // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
+  // if (!jdcoff && array_end_) {
+  if (array_end_) {
+    if (PROTOBUF_PREDICT_FALSE(had_error_)) return buffer_;
+    if (buffer_end_ == nullptr) {
+      buffer_end_ = ptr;
+    } else {
+      DCHECK(ptr >= buffer_ && ptr <= buffer_ + kSlopBytes);
+      int bytes = ptr - buffer_;
+      memcpy(buffer_end_, buffer_, bytes);
+      buffer_end_ += bytes;
+    }
+    end_ = buffer_ + kSlopBytes;
+    return buffer_;
+  }
   do {
     if (PROTOBUF_PREDICT_FALSE(had_error_)) return buffer_;
     int overrun = ptr - end_;
@@ -892,6 +977,15 @@
 
 uint8_t* EpsCopyOutputStream::WriteRawFallback(const void* data, int size,
                                              uint8_t* ptr) {
+  // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
+  if (array_end_) {
+    // if (!jdcoff && array_end_) {
+    auto ptrs = ConsumeArray(ptr, size);
+    if (PROTOBUF_PREDICT_FALSE(ptrs.first == nullptr)) return Error();
+    memcpy(ptrs.first, data, size);
+    return ptrs.second;
+  }
+
   int s = GetSize(ptr);
   while (s < size) {
     std::memcpy(ptr, data, s);
@@ -965,18 +1059,19 @@
 #endif
 
 uint8_t* EpsCopyOutputStream::WriteCord(const absl::Cord& cord, uint8_t* ptr) {
-  int s = GetSize(ptr);
+  // std::cerr << __FUNCTION__ << std::endl;
   if (stream_ == nullptr) {
-    if (static_cast<int64_t>(cord.size()) <= s) {
-      // Just copy it to the current buffer.
-      return CopyCordToArray(cord, ptr);
-    } else {
-      return Error();
-    }
-  } else if (static_cast<int64_t>(cord.size()) <= s &&
-             static_cast<int64_t>(cord.size()) < kMaxCordBytesToCopy) {
+    auto ptrs = ConsumeArray(ptr, static_cast<int>(cord.size()));
+    if (PROTOBUF_PREDICT_FALSE(ptrs.first == nullptr)) return Error();
+    cord.CopyToArray(reinterpret_cast<char*>(ptrs.first));
+    return ptrs.second;
+  }
+  int s = GetSize(ptr);
+  if (static_cast<int64_t>(cord.size()) <= s &&
+      static_cast<int64_t>(cord.size()) < kMaxCordBytesToCopy) {
     // Just copy it to the current buffer.
-    return CopyCordToArray(cord, ptr);
+    cord.CopyToArray(reinterpret_cast<char*>(ptr));
+    return ptr + cord.size();
   } else {
     // Back up to the position where the Cord should start.
     ptr = Trim(ptr);
@@ -1034,6 +1129,22 @@
   return WriteStringToArray(str, target);
 }
 
+uint8_t* JDCUnsafeVarint(uint64_t value, uint8_t* ptr) {
+  static int counter = 0;
+  bool jdconval = jdcon(counter);
+  if (jdconval) {
+    // std::cerr << jdconval << " JDC" << " " << counter++ << std::endl;
+    *(uint64_t*)ptr = 0;
+  }
+  while (PROTOBUF_PREDICT_FALSE(value >= 0x80)) {
+    *ptr = static_cast<uint8_t>(value | 0x80);
+    value >>= 7;
+    ++ptr;
+  }
+  *ptr++ = static_cast<uint8_t>(value);
+  return ptr;
+}
+
 }  // namespace io
 }  // namespace protobuf
 }  // namespace google
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index 98ff721..32d2f09 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -1,3 +1,4 @@
+bool jdcon(int);
 // Protocol Buffers - Google's data interchange format
 // Copyright 2008 Google Inc.  All rights reserved.
 // https://developers.google.com/protocol-buffers/
@@ -111,6 +112,7 @@
 
 #include <assert.h>
 
+#include <algorithm>
 #include <atomic>
 #include <climits>
 #include <cstddef>
@@ -160,6 +162,7 @@
 // Defined in other files.
 class ZeroCopyInputStream;   // zero_copy_stream.h
 class ZeroCopyOutputStream;  // zero_copy_stream.h
+uint8_t* JDCUnsafeVarint(uint64_t value, uint8_t* ptr);
 
 // Class which reads and decodes binary data which is composed of varint-
 // encoded integers and fixed-width pieces.  Wraps a ZeroCopyInputStream.
@@ -654,12 +657,7 @@
   // Only for array serialization. No overflow protection, end_ will be the
   // pointed to the end of the array. When using this the total size is already
   // known, so no need to maintain the slop region.
-  EpsCopyOutputStream(void* data, int size, bool deterministic)
-      : end_(static_cast<uint8_t*>(data) + size),
-        buffer_end_(nullptr),
-        stream_(nullptr),
-        is_serialization_deterministic_(deterministic) {}
-
+  EpsCopyOutputStream(void* data, int size, bool deterministic);
   // Initialize from stream but with the first buffer already given (eager).
   EpsCopyOutputStream(void* data, int size, ZeroCopyOutputStream* stream,
                       bool deterministic, uint8_t** pp)
@@ -667,10 +665,21 @@
     *pp = SetInitialBuffer(data, size);
   }
 
+  // Finlizes this instance. Invokes `Trim()` for stream bound instances and
+  // `FlushArray()` for array bound instances.
+  uint8_t* Finalize(uint8_t* ptr) {
+    // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
+    return stream_ ? Trim(ptr) : FlushArray(ptr);
+  }
+
   // Flush everything that's written into the underlying ZeroCopyOutputStream
   // and trims the underlying stream to the location of ptr.
   uint8_t* Trim(uint8_t* ptr);
 
+  // Flushes any yet unwritten data into the array provided at construction.
+  // Returns a pointer directly beyond the last byte written into the array.
+  uint8_t* FlushArray(uint8_t* ptr);
+
   // After this it's guaranteed you can safely write kSlopBytes to ptr. This
   // will never fail! The underlying stream can produce an error. Use HadError
   // to check for errors.
@@ -831,6 +840,7 @@
 
 
  private:
+  uint8_t* array_end_ = nullptr;
   uint8_t* end_;
   uint8_t* buffer_end_ = buffer_;
   uint8_t buffer_[2 * kSlopBytes];
@@ -840,6 +850,8 @@
   bool is_serialization_deterministic_;
   bool skip_check_consistency = false;
 
+  std::pair<uint8_t*, uint8_t*> ConsumeArray(uint8_t* ptr, int size);
+
   uint8_t* EnsureSpaceFallback(uint8_t* ptr);
   inline uint8_t* Next();
   int Flush(uint8_t* ptr);
@@ -911,8 +923,19 @@
 
   template <typename T>
   PROTOBUF_ALWAYS_INLINE static uint8_t* UnsafeVarint(T value, uint8_t* ptr) {
+    if (std::is_same<T, uint64_t>::value) {
+      return JDCUnsafeVarint(value, ptr);
+    }
+
     static_assert(std::is_unsigned<T>::value,
                   "Varint serialization must be unsigned");
+    static int counter = 0;
+    bool jdconval = jdcon(counter);
+    if (jdconval) {
+      // std::cerr << jdconval << " JDC" << sizeof(T) << " " << counter++ <<
+      // std::endl;
+      *(T*)ptr = 0;
+    }
     while (PROTOBUF_PREDICT_FALSE(value >= 0x80)) {
       *ptr = static_cast<uint8_t>(value | 0x80);
       value >>= 7;
@@ -1789,6 +1812,8 @@
 }  // namespace protobuf
 }  // namespace google
 
+extern void TurningOff1();
+
 #if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
 #pragma runtime_checks("c", restore)
 #endif  // _MSC_VER && !defined(__INTEL_COMPILER)
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index fc0f56a..cc7bf29 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -382,7 +382,10 @@
     io::EpsCopyOutputStream out(
         target, size,
         io::CodedOutputStream::IsDefaultSerializationDeterministic());
-    uint8_t* res = msg._InternalSerialize(target, &out);
+    // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
+    // std::cerr << msg.DebugString() << std::endl;
+    auto serialized = msg._InternalSerialize(target, &out);
+    auto res = out.Finalize(serialized);
     GOOGLE_ABSL_DCHECK(target + size == res);
     return res;
   }
@@ -548,6 +551,7 @@
 }
 
 bool MessageLite::AppendPartialToCord(absl::Cord* output) const {
+  // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
   // For efficiency, we'd like to pass a size hint to CordOutputStream with
   // the exact total size expected.
   const size_t size = ByteSizeLong();
@@ -568,7 +572,7 @@
     io::EpsCopyOutputStream out(
         target, static_cast<int>(available.size()),
         io::CodedOutputStream::IsDefaultSerializationDeterministic());
-    auto res = _InternalSerialize(target, &out);
+    uint8_t* res = out.Finalize(_InternalSerialize(target, &out));
     GOOGLE_ABSL_DCHECK_EQ(res, target + size);
     buffer.IncreaseLengthBy(size);
     output->Append(std::move(buffer));
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
index 5abd813..f45fffc 100644
--- a/src/google/protobuf/wire_format.h
+++ b/src/google/protobuf/wire_format.h
@@ -181,11 +181,13 @@
   // Returns a pointer past the last written byte.
   static uint8_t* SerializeUnknownFieldsToArray(
       const UnknownFieldSet& unknown_fields, uint8_t* target) {
+    // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
     io::EpsCopyOutputStream stream(
         target, static_cast<int>(ComputeUnknownFieldsSize(unknown_fields)),
         io::CodedOutputStream::IsDefaultSerializationDeterministic());
-    return InternalSerializeUnknownFieldsToArray(unknown_fields, target,
-                                                 &stream);
+    target =
+        InternalSerializeUnknownFieldsToArray(unknown_fields, target, &stream);
+    return stream.Finalize(target);
   }
   static uint8_t* InternalSerializeUnknownFieldsToArray(
       const UnknownFieldSet& unknown_fields, uint8_t* target,
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index b95098e..ca1e890 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -652,16 +652,19 @@
   // that are non-deterministic always.
   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteGroupToArray(
       int field_number, const MessageLite& value, uint8_t* target) {
+    // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
     io::EpsCopyOutputStream stream(
         target,
         value.GetCachedSize() +
             static_cast<int>(2 * io::CodedOutputStream::VarintSize32(
                                      static_cast<uint32_t>(field_number) << 3)),
         io::CodedOutputStream::IsDefaultSerializationDeterministic());
-    return InternalWriteGroup(field_number, value, target, &stream);
+    target = InternalWriteGroup(field_number, value, target, &stream);
+    return stream.Finalize(target);
   }
   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteMessageToArray(
       int field_number, const MessageLite& value, uint8_t* target) {
+    // std::cerr << __FUNCTION__ << " " << __LINE__ << std::endl;
     int size = value.GetCachedSize();
     io::EpsCopyOutputStream stream(
         target,
@@ -669,8 +672,9 @@
                                     static_cast<uint32_t>(field_number) << 3) +
                                 io::CodedOutputStream::VarintSize32(size)),
         io::CodedOutputStream::IsDefaultSerializationDeterministic());
-    return InternalWriteMessage(field_number, value, value.GetCachedSize(),
-                                target, &stream);
+    target = InternalWriteMessage(field_number, value, value.GetCachedSize(),
+                                  target, &stream);
+    return stream.Finalize(target);
   }
 
   // Compute the byte size of a field.  The XxSize() functions do NOT include