Modernize the HTTP/3 HttpDecoder by using non-const references in place
of non-null pointers, when they do not outlive the call. Annotate
with absl::NonNull when pointer do outlive the call.

PiperOrigin-RevId: 656422493
diff --git a/quiche/quic/core/http/http_decoder.cc b/quiche/quic/core/http/http_decoder.cc
index 1df1416..00de94f 100644
--- a/quiche/quic/core/http/http_decoder.cc
+++ b/quiche/quic/core/http/http_decoder.cc
@@ -112,16 +112,16 @@
 
     switch (state_) {
       case STATE_READING_FRAME_TYPE:
-        continue_processing = ReadFrameType(&reader);
+        continue_processing = ReadFrameType(reader);
         break;
       case STATE_READING_FRAME_LENGTH:
-        continue_processing = ReadFrameLength(&reader);
+        continue_processing = ReadFrameLength(reader);
         break;
       case STATE_BUFFER_OR_PARSE_PAYLOAD:
-        continue_processing = BufferOrParsePayload(&reader);
+        continue_processing = BufferOrParsePayload(reader);
         break;
       case STATE_READING_FRAME_PAYLOAD:
-        continue_processing = ReadFramePayload(&reader);
+        continue_processing = ReadFramePayload(reader);
         break;
       case STATE_FINISH_PARSING:
         continue_processing = FinishParsing();
@@ -145,20 +145,20 @@
   return len - reader.BytesRemaining();
 }
 
-bool HttpDecoder::ReadFrameType(QuicDataReader* reader) {
-  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
+bool HttpDecoder::ReadFrameType(QuicDataReader& reader) {
+  QUICHE_DCHECK_NE(0u, reader.BytesRemaining());
   if (current_type_field_length_ == 0) {
     // A new frame is coming.
-    current_type_field_length_ = reader->PeekVarInt62Length();
+    current_type_field_length_ = reader.PeekVarInt62Length();
     QUICHE_DCHECK_NE(0u, current_type_field_length_);
-    if (current_type_field_length_ > reader->BytesRemaining()) {
+    if (current_type_field_length_ > reader.BytesRemaining()) {
       // Buffer a new type field.
       remaining_type_field_length_ = current_type_field_length_;
       BufferFrameType(reader);
       return true;
     }
     // The reader has all type data needed, so no need to buffer.
-    bool success = reader->ReadVarInt62(&current_frame_type_);
+    bool success = reader.ReadVarInt62(&current_frame_type_);
     QUICHE_DCHECK(success);
   } else {
     // Buffer the existing type field.
@@ -203,20 +203,20 @@
   return true;
 }
 
-bool HttpDecoder::ReadFrameLength(QuicDataReader* reader) {
-  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
+bool HttpDecoder::ReadFrameLength(QuicDataReader& reader) {
+  QUICHE_DCHECK_NE(0u, reader.BytesRemaining());
   if (current_length_field_length_ == 0) {
     // A new frame is coming.
-    current_length_field_length_ = reader->PeekVarInt62Length();
+    current_length_field_length_ = reader.PeekVarInt62Length();
     QUICHE_DCHECK_NE(0u, current_length_field_length_);
-    if (current_length_field_length_ > reader->BytesRemaining()) {
+    if (current_length_field_length_ > reader.BytesRemaining()) {
       // Buffer a new length field.
       remaining_length_field_length_ = current_length_field_length_;
       BufferFrameLength(reader);
       return true;
     }
     // The reader has all length data needed, so no need to buffer.
-    bool success = reader->ReadVarInt62(&current_frame_length_);
+    bool success = reader.ReadVarInt62(&current_frame_length_);
     QUICHE_DCHECK(success);
   } else {
     // Buffer the existing length field.
@@ -284,13 +284,11 @@
     case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH):
       continue_processing = visitor_->OnAcceptChFrameStart(header_length);
       break;
+    case static_cast<uint64_t>(HttpFrameType::METADATA):
+      continue_processing =
+          visitor_->OnMetadataFrameStart(header_length, current_frame_length_);
+      break;
     default:
-      if (current_frame_type_ ==
-          static_cast<uint64_t>(HttpFrameType::METADATA)) {
-        continue_processing = visitor_->OnMetadataFrameStart(
-            header_length, current_frame_length_);
-        break;
-      }
       continue_processing = visitor_->OnUnknownFrameStart(
           current_frame_type_, header_length, current_frame_length_);
       break;
@@ -326,9 +324,9 @@
   return false;
 }
 
-bool HttpDecoder::ReadFramePayload(QuicDataReader* reader) {
+bool HttpDecoder::ReadFramePayload(QuicDataReader& reader) {
   QUICHE_DCHECK(!IsFrameBuffered());
-  QUICHE_DCHECK_NE(0u, reader->BytesRemaining());
+  QUICHE_DCHECK_NE(0u, reader.BytesRemaining());
   QUICHE_DCHECK_NE(0u, remaining_frame_length_);
 
   bool continue_processing = true;
@@ -336,9 +334,9 @@
   switch (current_frame_type_) {
     case static_cast<uint64_t>(HttpFrameType::DATA): {
       QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-          remaining_frame_length_, reader->BytesRemaining());
+          remaining_frame_length_, reader.BytesRemaining());
       absl::string_view payload;
-      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
+      bool success = reader.ReadStringPiece(&payload, bytes_to_read);
       QUICHE_DCHECK(success);
       QUICHE_DCHECK(!payload.empty());
       continue_processing = visitor_->OnDataFramePayload(payload);
@@ -347,9 +345,9 @@
     }
     case static_cast<uint64_t>(HttpFrameType::HEADERS): {
       QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-          remaining_frame_length_, reader->BytesRemaining());
+          remaining_frame_length_, reader.BytesRemaining());
       absl::string_view payload;
-      bool success = reader->ReadStringPiece(&payload, bytes_to_read);
+      bool success = reader.ReadStringPiece(&payload, bytes_to_read);
       QUICHE_DCHECK(success);
       QUICHE_DCHECK(!payload.empty());
       continue_processing = visitor_->OnHeadersFramePayload(payload);
@@ -384,19 +382,18 @@
       QUICHE_NOTREACHED();
       break;
     }
+    case static_cast<uint64_t>(HttpFrameType::METADATA): {
+      QuicByteCount bytes_to_read = std::min<QuicByteCount>(
+          remaining_frame_length_, reader.BytesRemaining());
+      absl::string_view payload;
+      bool success = reader.ReadStringPiece(&payload, bytes_to_read);
+      QUICHE_DCHECK(success);
+      QUICHE_DCHECK(!payload.empty());
+      continue_processing = visitor_->OnMetadataFramePayload(payload);
+      remaining_frame_length_ -= payload.length();
+      break;
+    }
     default: {
-      if (current_frame_type_ ==
-          static_cast<uint64_t>(HttpFrameType::METADATA)) {
-        QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-            remaining_frame_length_, reader->BytesRemaining());
-        absl::string_view payload;
-        bool success = reader->ReadStringPiece(&payload, bytes_to_read);
-        QUICHE_DCHECK(success);
-        QUICHE_DCHECK(!payload.empty());
-        continue_processing = visitor_->OnMetadataFramePayload(payload);
-        remaining_frame_length_ -= payload.length();
-        break;
-      }
       continue_processing = HandleUnknownFramePayload(reader);
       break;
     }
@@ -452,12 +449,11 @@
       QUICHE_NOTREACHED();
       break;
     }
+    case static_cast<uint64_t>(HttpFrameType::METADATA): {
+      continue_processing = visitor_->OnMetadataFrameEnd();
+      break;
+    }
     default:
-      if (current_frame_type_ ==
-          static_cast<uint64_t>(HttpFrameType::METADATA)) {
-        continue_processing = visitor_->OnMetadataFrameEnd();
-        break;
-      }
       continue_processing = visitor_->OnUnknownFrameEnd();
   }
 
@@ -471,61 +467,61 @@
   state_ = STATE_READING_FRAME_TYPE;
 }
 
-bool HttpDecoder::HandleUnknownFramePayload(QuicDataReader* reader) {
-  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-      remaining_frame_length_, reader->BytesRemaining());
+bool HttpDecoder::HandleUnknownFramePayload(QuicDataReader& reader) {
+  QuicByteCount bytes_to_read =
+      std::min<QuicByteCount>(remaining_frame_length_, reader.BytesRemaining());
   absl::string_view payload;
-  bool success = reader->ReadStringPiece(&payload, bytes_to_read);
+  bool success = reader.ReadStringPiece(&payload, bytes_to_read);
   QUICHE_DCHECK(success);
   QUICHE_DCHECK(!payload.empty());
   remaining_frame_length_ -= payload.length();
   return visitor_->OnUnknownFramePayload(payload);
 }
 
-bool HttpDecoder::BufferOrParsePayload(QuicDataReader* reader) {
+bool HttpDecoder::BufferOrParsePayload(QuicDataReader& reader) {
   QUICHE_DCHECK(IsFrameBuffered());
   QUICHE_DCHECK_EQ(current_frame_length_,
                    buffer_.size() + remaining_frame_length_);
 
-  if (buffer_.empty() && reader->BytesRemaining() >= current_frame_length_) {
+  if (buffer_.empty() && reader.BytesRemaining() >= current_frame_length_) {
     // |*reader| contains entire payload, which might be empty.
     remaining_frame_length_ = 0;
-    QuicDataReader current_payload_reader(reader->PeekRemainingPayload().data(),
+    QuicDataReader current_payload_reader(reader.PeekRemainingPayload().data(),
                                           current_frame_length_);
-    bool continue_processing = ParseEntirePayload(&current_payload_reader);
+    bool continue_processing = ParseEntirePayload(current_payload_reader);
 
-    reader->Seek(current_frame_length_);
+    reader.Seek(current_frame_length_);
     ResetForNextFrame();
     return continue_processing;
   }
 
   // Buffer as much of the payload as |*reader| contains.
-  QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-      remaining_frame_length_, reader->BytesRemaining());
-  absl::StrAppend(&buffer_, reader->PeekRemainingPayload().substr(
+  QuicByteCount bytes_to_read =
+      std::min<QuicByteCount>(remaining_frame_length_, reader.BytesRemaining());
+  absl::StrAppend(&buffer_, reader.PeekRemainingPayload().substr(
                                 /* pos = */ 0, bytes_to_read));
-  reader->Seek(bytes_to_read);
+  reader.Seek(bytes_to_read);
   remaining_frame_length_ -= bytes_to_read;
 
   QUICHE_DCHECK_EQ(current_frame_length_,
                    buffer_.size() + remaining_frame_length_);
 
   if (remaining_frame_length_ > 0) {
-    QUICHE_DCHECK(reader->IsDoneReading());
+    QUICHE_DCHECK(reader.IsDoneReading());
     return false;
   }
 
   QuicDataReader buffer_reader(buffer_);
-  bool continue_processing = ParseEntirePayload(&buffer_reader);
+  bool continue_processing = ParseEntirePayload(buffer_reader);
   buffer_.clear();
 
   ResetForNextFrame();
   return continue_processing;
 }
 
-bool HttpDecoder::ParseEntirePayload(QuicDataReader* reader) {
+bool HttpDecoder::ParseEntirePayload(QuicDataReader& reader) {
   QUICHE_DCHECK(IsFrameBuffered());
-  QUICHE_DCHECK_EQ(current_frame_length_, reader->BytesRemaining());
+  QUICHE_DCHECK_EQ(current_frame_length_, reader.BytesRemaining());
   QUICHE_DCHECK_EQ(0u, remaining_frame_length_);
 
   switch (current_frame_type_) {
@@ -535,18 +531,18 @@
     }
     case static_cast<uint64_t>(HttpFrameType::SETTINGS): {
       SettingsFrame frame;
-      if (!ParseSettingsFrame(reader, &frame)) {
+      if (!ParseSettingsFrame(reader, frame)) {
         return false;
       }
       return visitor_->OnSettingsFrame(frame);
     }
     case static_cast<uint64_t>(HttpFrameType::GOAWAY): {
       GoAwayFrame frame;
-      if (!reader->ReadVarInt62(&frame.id)) {
+      if (!reader.ReadVarInt62(&frame.id)) {
         RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read GOAWAY ID.");
         return false;
       }
-      if (!reader->IsDoneReading()) {
+      if (!reader.IsDoneReading()) {
         RaiseError(QUIC_HTTP_FRAME_ERROR, "Superfluous data in GOAWAY frame.");
         return false;
       }
@@ -554,12 +550,12 @@
     }
     case static_cast<uint64_t>(HttpFrameType::MAX_PUSH_ID): {
       uint64_t unused;
-      if (!reader->ReadVarInt62(&unused)) {
+      if (!reader.ReadVarInt62(&unused)) {
         RaiseError(QUIC_HTTP_FRAME_ERROR,
                    "Unable to read MAX_PUSH_ID push_id.");
         return false;
       }
-      if (!reader->IsDoneReading()) {
+      if (!reader.IsDoneReading()) {
         RaiseError(QUIC_HTTP_FRAME_ERROR,
                    "Superfluous data in MAX_PUSH_ID frame.");
         return false;
@@ -568,14 +564,14 @@
     }
     case static_cast<uint64_t>(HttpFrameType::PRIORITY_UPDATE_REQUEST_STREAM): {
       PriorityUpdateFrame frame;
-      if (!ParsePriorityUpdateFrame(reader, &frame)) {
+      if (!ParsePriorityUpdateFrame(reader, frame)) {
         return false;
       }
       return visitor_->OnPriorityUpdateFrame(frame);
     }
     case static_cast<uint64_t>(HttpFrameType::ACCEPT_CH): {
       AcceptChFrame frame;
-      if (!ParseAcceptChFrame(reader, &frame)) {
+      if (!ParseAcceptChFrame(reader, frame)) {
         return false;
       }
       return visitor_->OnAcceptChFrame(frame);
@@ -587,24 +583,24 @@
   }
 }
 
-void HttpDecoder::BufferFrameLength(QuicDataReader* reader) {
+void HttpDecoder::BufferFrameLength(QuicDataReader& reader) {
   QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-      remaining_length_field_length_, reader->BytesRemaining());
+      remaining_length_field_length_, reader.BytesRemaining());
   bool success =
-      reader->ReadBytes(length_buffer_.data() + current_length_field_length_ -
-                            remaining_length_field_length_,
-                        bytes_to_read);
+      reader.ReadBytes(length_buffer_.data() + current_length_field_length_ -
+                           remaining_length_field_length_,
+                       bytes_to_read);
   QUICHE_DCHECK(success);
   remaining_length_field_length_ -= bytes_to_read;
 }
 
-void HttpDecoder::BufferFrameType(QuicDataReader* reader) {
+void HttpDecoder::BufferFrameType(QuicDataReader& reader) {
   QuicByteCount bytes_to_read = std::min<QuicByteCount>(
-      remaining_type_field_length_, reader->BytesRemaining());
+      remaining_type_field_length_, reader.BytesRemaining());
   bool success =
-      reader->ReadBytes(type_buffer_.data() + current_type_field_length_ -
-                            remaining_type_field_length_,
-                        bytes_to_read);
+      reader.ReadBytes(type_buffer_.data() + current_type_field_length_ -
+                           remaining_type_field_length_,
+                       bytes_to_read);
   QUICHE_DCHECK(success);
   remaining_type_field_length_ -= bytes_to_read;
 }
@@ -616,20 +612,20 @@
   visitor_->OnError(this);
 }
 
-bool HttpDecoder::ParseSettingsFrame(QuicDataReader* reader,
-                                     SettingsFrame* frame) {
-  while (!reader->IsDoneReading()) {
+bool HttpDecoder::ParseSettingsFrame(QuicDataReader& reader,
+                                     SettingsFrame& frame) {
+  while (!reader.IsDoneReading()) {
     uint64_t id;
-    if (!reader->ReadVarInt62(&id)) {
+    if (!reader.ReadVarInt62(&id)) {
       RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting identifier.");
       return false;
     }
     uint64_t content;
-    if (!reader->ReadVarInt62(&content)) {
+    if (!reader.ReadVarInt62(&content)) {
       RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read setting value.");
       return false;
     }
-    auto result = frame->values.insert({id, content});
+    auto result = frame.values.insert({id, content});
     if (!result.second) {
       RaiseError(QUIC_HTTP_DUPLICATE_SETTING_IDENTIFIER,
                  "Duplicate setting identifier.");
@@ -639,36 +635,36 @@
   return true;
 }
 
-bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader* reader,
-                                           PriorityUpdateFrame* frame) {
-  if (!reader->ReadVarInt62(&frame->prioritized_element_id)) {
+bool HttpDecoder::ParsePriorityUpdateFrame(QuicDataReader& reader,
+                                           PriorityUpdateFrame& frame) {
+  if (!reader.ReadVarInt62(&frame.prioritized_element_id)) {
     RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read prioritized element id.");
     return false;
   }
 
-  absl::string_view priority_field_value = reader->ReadRemainingPayload();
-  frame->priority_field_value =
+  absl::string_view priority_field_value = reader.ReadRemainingPayload();
+  frame.priority_field_value =
       std::string(priority_field_value.data(), priority_field_value.size());
 
   return true;
 }
 
-bool HttpDecoder::ParseAcceptChFrame(QuicDataReader* reader,
-                                     AcceptChFrame* frame) {
+bool HttpDecoder::ParseAcceptChFrame(QuicDataReader& reader,
+                                     AcceptChFrame& frame) {
   absl::string_view origin;
   absl::string_view value;
-  while (!reader->IsDoneReading()) {
-    if (!reader->ReadStringPieceVarInt62(&origin)) {
+  while (!reader.IsDoneReading()) {
+    if (!reader.ReadStringPieceVarInt62(&origin)) {
       RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH origin.");
       return false;
     }
-    if (!reader->ReadStringPieceVarInt62(&value)) {
+    if (!reader.ReadStringPieceVarInt62(&value)) {
       RaiseError(QUIC_HTTP_FRAME_ERROR, "Unable to read ACCEPT_CH value.");
       return false;
     }
     // Copy data.
-    frame->entries.push_back({std::string(origin.data(), origin.size()),
-                              std::string(value.data(), value.size())});
+    frame.entries.push_back({std::string(origin.data(), origin.size()),
+                             std::string(value.data(), value.size())});
   }
   return true;
 }
diff --git a/quiche/quic/core/http/http_decoder.h b/quiche/quic/core/http/http_decoder.h
index 6d305e4..e959807 100644
--- a/quiche/quic/core/http/http_decoder.h
+++ b/quiche/quic/core/http/http_decoder.h
@@ -7,6 +7,7 @@
 
 #include <cstdint>
 
+#include "absl/base/nullability.h"
 #include "absl/strings/string_view.h"
 #include "quiche/quic/core/http/http_frames.h"
 #include "quiche/quic/core/quic_error_codes.h"
@@ -127,7 +128,7 @@
   };
 
   // |visitor| must be non-null, and must outlive HttpDecoder.
-  explicit HttpDecoder(Visitor* visitor);
+  explicit HttpDecoder(absl::Nonnull<Visitor*> visitor);
 
   ~HttpDecoder();
 
@@ -182,11 +183,11 @@
   // if there are any errors.  Also calls OnDataFrameStart() or
   // OnHeadersFrameStart() for appropriate frame types. Returns whether the
   // processing should continue.
-  bool ReadFrameType(QuicDataReader* reader);
+  bool ReadFrameType(QuicDataReader& reader);
 
   // Reads the length of a frame from |reader|. Sets error_ and error_detail_
   // if there are any errors.  Returns whether processing should continue.
-  bool ReadFrameLength(QuicDataReader* reader);
+  bool ReadFrameLength(QuicDataReader& reader);
 
   // Returns whether the current frame is of a buffered type.
   // The payload of buffered frames is buffered by HttpDecoder, and parsed by
@@ -199,7 +200,7 @@
   // For buffered frame types, calls BufferOrParsePayload().  For other frame
   // types, reads the payload of the current frame from |reader| and calls
   // visitor methods.  Returns whether processing should continue.
-  bool ReadFramePayload(QuicDataReader* reader);
+  bool ReadFramePayload(QuicDataReader& reader);
 
   // For buffered frame types, this method is only called if frame payload is
   // empty, and it calls BufferOrParsePayload().  For other frame types, this
@@ -213,41 +214,41 @@
   // Read payload of unknown frame from |reader| and call
   // Visitor::OnUnknownFramePayload().  Returns true decoding should continue,
   // false if it should be paused.
-  bool HandleUnknownFramePayload(QuicDataReader* reader);
+  bool HandleUnknownFramePayload(QuicDataReader& reader);
 
   // Buffers any remaining frame payload from |*reader| into |buffer_| if
   // necessary.  Parses the frame payload if complete.  Parses out of |*reader|
   // without unnecessary copy if |*reader| contains entire payload.
   // Returns whether processing should continue.
   // Must only be called when current frame type is buffered.
-  bool BufferOrParsePayload(QuicDataReader* reader);
+  bool BufferOrParsePayload(QuicDataReader& reader);
 
   // Parses the entire payload of certain kinds of frames that are parsed in a
   // single pass.  |reader| must have at least |current_frame_length_| bytes.
   // Returns whether processing should continue.
   // Must only be called when current frame type is buffered.
-  bool ParseEntirePayload(QuicDataReader* reader);
+  bool ParseEntirePayload(QuicDataReader& reader);
 
   // Buffers any remaining frame length field from |reader| into
   // |length_buffer_|.
-  void BufferFrameLength(QuicDataReader* reader);
+  void BufferFrameLength(QuicDataReader& reader);
 
   // Buffers any remaining frame type field from |reader| into |type_buffer_|.
-  void BufferFrameType(QuicDataReader* reader);
+  void BufferFrameType(QuicDataReader& reader);
 
   // Sets |error_| and |error_detail_| accordingly.
   void RaiseError(QuicErrorCode error, std::string error_detail);
 
   // Parses the payload of a SETTINGS frame from |reader| into |frame|.
-  bool ParseSettingsFrame(QuicDataReader* reader, SettingsFrame* frame);
+  bool ParseSettingsFrame(QuicDataReader& reader, SettingsFrame& frame);
 
   // Parses the payload of a PRIORITY_UPDATE frame (draft-02, type 0xf0700)
   // from |reader| into |frame|.
-  bool ParsePriorityUpdateFrame(QuicDataReader* reader,
-                                PriorityUpdateFrame* frame);
+  bool ParsePriorityUpdateFrame(QuicDataReader& reader,
+                                PriorityUpdateFrame& frame);
 
   // Parses the payload of an ACCEPT_CH frame from |reader| into |frame|.
-  bool ParseAcceptChFrame(QuicDataReader* reader, AcceptChFrame* frame);
+  bool ParseAcceptChFrame(QuicDataReader& reader, AcceptChFrame& frame);
 
   // Returns the max frame size of a given |frame_type|.
   QuicByteCount MaxFrameLength(uint64_t frame_type);