Change QuicStopSendingFrame to an inlined quic frame.

PiperOrigin-RevId: 439323400
diff --git a/quic/core/frames/quic_frame.cc b/quic/core/frames/quic_frame.cc
index 2e63d86..5d0a675 100644
--- a/quic/core/frames/quic_frame.cc
+++ b/quic/core/frames/quic_frame.cc
@@ -69,8 +69,7 @@
 QuicFrame::QuicFrame(QuicPathChallengeFrame* frame)
     : type(PATH_CHALLENGE_FRAME), path_challenge_frame(frame) {}
 
-QuicFrame::QuicFrame(QuicStopSendingFrame* frame)
-    : type(STOP_SENDING_FRAME), stop_sending_frame(frame) {}
+QuicFrame::QuicFrame(QuicStopSendingFrame frame) : stop_sending_frame(frame) {}
 
 QuicFrame::QuicFrame(QuicMessageFrame* frame)
     : type(MESSAGE_FRAME), message_frame(frame) {}
@@ -96,7 +95,8 @@
       frame->type != STOP_WAITING_FRAME &&
       frame->type != STREAMS_BLOCKED_FRAME && frame->type != STREAM_FRAME &&
       frame->type != HANDSHAKE_DONE_FRAME &&
-      frame->type != WINDOW_UPDATE_FRAME && frame->type != BLOCKED_FRAME) {
+      frame->type != WINDOW_UPDATE_FRAME && frame->type != BLOCKED_FRAME &&
+      frame->type != STOP_SENDING_FRAME) {
     QUICHE_CHECK(!frame->delete_forbidden) << *frame;
   }
 #endif  // QUIC_FRAME_DEBUG
@@ -112,6 +112,7 @@
     case HANDSHAKE_DONE_FRAME:
     case WINDOW_UPDATE_FRAME:
     case BLOCKED_FRAME:
+    case STOP_SENDING_FRAME:
       break;
     case ACK_FRAME:
       delete frame->ack_frame;
@@ -128,9 +129,6 @@
     case PATH_CHALLENGE_FRAME:
       delete frame->path_challenge_frame;
       break;
-    case STOP_SENDING_FRAME:
-      delete frame->stop_sending_frame;
-      break;
     case NEW_CONNECTION_ID_FRAME:
       delete frame->new_connection_id_frame;
       break;
@@ -206,7 +204,7 @@
     case PING_FRAME:
       return frame.ping_frame.control_frame_id;
     case STOP_SENDING_FRAME:
-      return frame.stop_sending_frame->control_frame_id;
+      return frame.stop_sending_frame.control_frame_id;
     case NEW_CONNECTION_ID_FRAME:
       return frame.new_connection_id_frame->control_frame_id;
     case RETIRE_CONNECTION_ID_FRAME:
@@ -246,7 +244,7 @@
       frame->max_streams_frame.control_frame_id = control_frame_id;
       return;
     case STOP_SENDING_FRAME:
-      frame->stop_sending_frame->control_frame_id = control_frame_id;
+      frame->stop_sending_frame.control_frame_id = control_frame_id;
       return;
     case NEW_CONNECTION_ID_FRAME:
       frame->new_connection_id_frame->control_frame_id = control_frame_id;
@@ -288,7 +286,7 @@
       copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
       break;
     case STOP_SENDING_FRAME:
-      copy = QuicFrame(new QuicStopSendingFrame(*frame.stop_sending_frame));
+      copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
       break;
     case NEW_CONNECTION_ID_FRAME:
       copy = QuicFrame(
@@ -381,7 +379,7 @@
       copy = QuicFrame(new QuicPathChallengeFrame(*frame.path_challenge_frame));
       break;
     case STOP_SENDING_FRAME:
-      copy = QuicFrame(new QuicStopSendingFrame(*frame.stop_sending_frame));
+      copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
       break;
     case MESSAGE_FRAME:
       copy = QuicFrame(new QuicMessageFrame(frame.message_frame->message_id));
@@ -496,7 +494,7 @@
       os << "type { PATH_CHALLENGE } " << *(frame.path_challenge_frame);
       break;
     case STOP_SENDING_FRAME:
-      os << "type { STOP_SENDING } " << *(frame.stop_sending_frame);
+      os << "type { STOP_SENDING } " << frame.stop_sending_frame;
       break;
     case MESSAGE_FRAME:
       os << "type { MESSAGE_FRAME }" << *(frame.message_frame);
diff --git a/quic/core/frames/quic_frame.h b/quic/core/frames/quic_frame.h
index 06d3085..e776999 100644
--- a/quic/core/frames/quic_frame.h
+++ b/quic/core/frames/quic_frame.h
@@ -60,6 +60,7 @@
   explicit QuicFrame(QuicHandshakeDoneFrame handshake_done_frame);
   explicit QuicFrame(QuicWindowUpdateFrame frame);
   explicit QuicFrame(QuicBlockedFrame frame);
+  explicit QuicFrame(QuicStopSendingFrame frame);
 
   explicit QuicFrame(QuicAckFrame* frame);
   explicit QuicFrame(QuicRstStreamFrame* frame);
@@ -70,7 +71,6 @@
   explicit QuicFrame(QuicNewTokenFrame* frame);
   explicit QuicFrame(QuicPathResponseFrame* frame);
   explicit QuicFrame(QuicPathChallengeFrame* frame);
-  explicit QuicFrame(QuicStopSendingFrame* frame);
   explicit QuicFrame(QuicMessageFrame* message_frame);
   explicit QuicFrame(QuicCryptoFrame* crypto_frame);
   explicit QuicFrame(QuicAckFrequencyFrame* ack_frequency_frame);
@@ -93,6 +93,7 @@
     QuicHandshakeDoneFrame handshake_done_frame;
     QuicWindowUpdateFrame window_update_frame;
     QuicBlockedFrame blocked_frame;
+    QuicStopSendingFrame stop_sending_frame;
 
     // Out of line frames.
     struct {
@@ -104,8 +105,7 @@
 
       // TODO(wub): These frames can also be inlined without increasing the size
       // of QuicFrame:
-      // QuicPathResponseFrame, QuicPathChallengeFrame and
-      // QuicStopSendingFrame.
+      // QuicPathResponseFrame, QuicPathChallengeFrame.
       union {
         QuicAckFrame* ack_frame;
         QuicRstStreamFrame* rst_stream_frame;
@@ -115,7 +115,6 @@
         QuicRetireConnectionIdFrame* retire_connection_id_frame;
         QuicPathResponseFrame* path_response_frame;
         QuicPathChallengeFrame* path_challenge_frame;
-        QuicStopSendingFrame* stop_sending_frame;
         QuicMessageFrame* message_frame;
         QuicCryptoFrame* crypto_frame;
         QuicAckFrequencyFrame* ack_frequency_frame;
diff --git a/quic/core/frames/quic_frames_test.cc b/quic/core/frames/quic_frames_test.cc
index 527a510..2520964 100644
--- a/quic/core/frames/quic_frames_test.cc
+++ b/quic/core/frames/quic_frames_test.cc
@@ -92,16 +92,15 @@
 }
 
 TEST_F(QuicFramesTest, StopSendingFrameToString) {
-  QuicStopSendingFrame stop_sending;
-  QuicFrame frame(&stop_sending);
+  QuicFrame frame((QuicStopSendingFrame()));
   SetControlFrameId(1, &frame);
   EXPECT_EQ(1u, GetControlFrameId(frame));
-  stop_sending.stream_id = 321;
-  stop_sending.error_code = QUIC_STREAM_CANCELLED;
-  stop_sending.ietf_error_code =
+  frame.stop_sending_frame.stream_id = 321;
+  frame.stop_sending_frame.error_code = QUIC_STREAM_CANCELLED;
+  frame.stop_sending_frame.ietf_error_code =
       static_cast<uint64_t>(QuicHttp3ErrorCode::REQUEST_CANCELLED);
   std::ostringstream stream;
-  stream << stop_sending;
+  stream << frame.stop_sending_frame;
   EXPECT_EQ(
       "{ control_frame_id: 1, stream_id: 321, error_code: 6, ietf_error_code: "
       "268 }\n",
@@ -599,7 +598,7 @@
         frames.push_back(QuicFrame(new QuicPathChallengeFrame()));
         break;
       case STOP_SENDING_FRAME:
-        frames.push_back(QuicFrame(new QuicStopSendingFrame()));
+        frames.push_back(QuicFrame(QuicStopSendingFrame()));
         break;
       case MESSAGE_FRAME:
         frames.push_back(QuicFrame(message_frame));
diff --git a/quic/core/frames/quic_stop_sending_frame.cc b/quic/core/frames/quic_stop_sending_frame.cc
index 396288e..7923d41 100644
--- a/quic/core/frames/quic_stop_sending_frame.cc
+++ b/quic/core/frames/quic_stop_sending_frame.cc
@@ -8,6 +8,9 @@
 
 namespace quic {
 
+QuicStopSendingFrame::QuicStopSendingFrame()
+    : QuicInlinedFrame(STOP_SENDING_FRAME) {}
+
 QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
                                            QuicStreamId stream_id,
                                            QuicRstStreamErrorCode error_code)
@@ -17,7 +20,8 @@
 QuicStopSendingFrame::QuicStopSendingFrame(QuicControlFrameId control_frame_id,
                                            QuicStreamId stream_id,
                                            QuicResetStreamError error)
-    : control_frame_id(control_frame_id),
+    : QuicInlinedFrame(STOP_SENDING_FRAME),
+      control_frame_id(control_frame_id),
       stream_id(stream_id),
       error_code(error.internal_code()),
       ietf_error_code(error.ietf_application_code()) {}
diff --git a/quic/core/frames/quic_stop_sending_frame.h b/quic/core/frames/quic_stop_sending_frame.h
index b575e75..d7c92f1 100644
--- a/quic/core/frames/quic_stop_sending_frame.h
+++ b/quic/core/frames/quic_stop_sending_frame.h
@@ -7,14 +7,16 @@
 
 #include <ostream>
 
+#include "quic/core/frames/quic_inlined_frame.h"
 #include "quic/core/quic_constants.h"
 #include "quic/core/quic_error_codes.h"
 #include "quic/core/quic_types.h"
 
 namespace quic {
 
-struct QUIC_EXPORT_PRIVATE QuicStopSendingFrame {
-  QuicStopSendingFrame() = default;
+struct QUIC_EXPORT_PRIVATE QuicStopSendingFrame
+    : public QuicInlinedFrame<QuicStopSendingFrame> {
+  QuicStopSendingFrame();
   QuicStopSendingFrame(QuicControlFrameId control_frame_id,
                        QuicStreamId stream_id,
                        QuicRstStreamErrorCode error_code);
@@ -25,6 +27,8 @@
       std::ostream& os,
       const QuicStopSendingFrame& frame);
 
+  QuicFrameType type;
+
   // A unique identifier of this control frame. 0 when this frame is received,
   // and non-zero when sent.
   QuicControlFrameId control_frame_id = kInvalidControlFrameId;
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index bb27468..760d4fd 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -2355,13 +2355,12 @@
         .WillOnce(Invoke([stream_id](const QuicFrame& frame) {
           EXPECT_EQ(STOP_SENDING_FRAME, frame.type);
 
-          QuicStopSendingFrame* stop_sending = frame.stop_sending_frame;
-          EXPECT_EQ(stream_id, stop_sending->stream_id);
-          EXPECT_EQ(QUIC_STREAM_STREAM_CREATION_ERROR,
-                    stop_sending->error_code);
+          const QuicStopSendingFrame& stop_sending = frame.stop_sending_frame;
+          EXPECT_EQ(stream_id, stop_sending.stream_id);
+          EXPECT_EQ(QUIC_STREAM_STREAM_CREATION_ERROR, stop_sending.error_code);
           EXPECT_EQ(
               static_cast<uint64_t>(QuicHttp3ErrorCode::STREAM_CREATION_ERROR),
-              stop_sending->ietf_error_code);
+              stop_sending.ietf_error_code);
 
           return ClearControlFrame(frame);
         }));
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 22f5e58..6061fd5 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -15185,7 +15185,7 @@
         frame = QuicFrame(&path_challenge_frame);
         break;
       case STOP_SENDING_FRAME:
-        frame = QuicFrame(&stop_sending_frame);
+        frame = QuicFrame(stop_sending_frame);
         break;
       case NEW_CONNECTION_ID_FRAME:
         frame = QuicFrame(&new_connection_id_frame);
diff --git a/quic/core/quic_control_frame_manager.cc b/quic/core/quic_control_frame_manager.cc
index cd0695f..b41263b 100644
--- a/quic/core/quic_control_frame_manager.cc
+++ b/quic/core/quic_control_frame_manager.cc
@@ -107,7 +107,7 @@
     QuicResetStreamError error, QuicStreamId stream_id) {
   QUIC_DVLOG(1) << "Writing STOP_SENDING_FRAME";
   WriteOrBufferQuicFrame(QuicFrame(
-      new QuicStopSendingFrame(++last_control_frame_id_, stream_id, error)));
+      QuicStopSendingFrame(++last_control_frame_id_, stream_id, error)));
 }
 
 void QuicControlFrameManager::WriteOrBufferHandshakeDone() {
diff --git a/quic/core/quic_control_frame_manager_test.cc b/quic/core/quic_control_frame_manager_test.cc
index dbd0102..0fb836a 100644
--- a/quic/core/quic_control_frame_manager_test.cc
+++ b/quic/core/quic_control_frame_manager_test.cc
@@ -83,7 +83,7 @@
     EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
     EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
     EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(blocked_)));
-    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
+    EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(stop_sending_)));
 
     EXPECT_FALSE(manager_->HasPendingRetransmission());
     EXPECT_TRUE(manager_->WillingToWrite());
@@ -117,7 +117,7 @@
   EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&goaway_)));
   EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
   EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(blocked_)));
-  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&stop_sending_)));
+  EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(stop_sending_)));
 
   EXPECT_TRUE(manager_->OnControlFrameAcked(QuicFrame(window_update_)));
   EXPECT_FALSE(manager_->IsControlFrameOutstanding(QuicFrame(window_update_)));
diff --git a/quic/core/quic_error_codes.h b/quic/core/quic_error_codes.h
index 0ecef01..469f3c5 100644
--- a/quic/core/quic_error_codes.h
+++ b/quic/core/quic_error_codes.h
@@ -13,7 +13,9 @@
 
 namespace quic {
 
-enum QuicRstStreamErrorCode {
+// QuicRstStreamErrorCode is encoded as a single octet on-the-wire in IETF QUIC
+// and a 32-bit integer in gQUIC.
+enum QuicRstStreamErrorCode : uint32_t {
   // Complete response has been sent, sending a RST to ask the other endpoint
   // to stop sending request data without discarding the response.
   QUIC_STREAM_NO_ERROR = 0,
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 0de2a2f..65b44d5 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -691,7 +691,7 @@
     case PATH_CHALLENGE_FRAME:
       return GetPathChallengeFrameSize(*frame.path_challenge_frame);
     case STOP_SENDING_FRAME:
-      return GetStopSendingFrameSize(*frame.stop_sending_frame);
+      return GetStopSendingFrameSize(frame.stop_sending_frame);
     case HANDSHAKE_DONE_FRAME:
       // HANDSHAKE_DONE has no payload.
       return kQuicFrameTypeSize;
@@ -1184,7 +1184,7 @@
         }
         break;
       case STOP_SENDING_FRAME:
-        if (!AppendStopSendingFrame(*frame.stop_sending_frame, writer)) {
+        if (!AppendStopSendingFrame(frame.stop_sending_frame, writer)) {
           QUIC_BUG(quic_bug_10850_46)
               << "AppendStopSendingFrame failed: " << detailed_error();
           return 0;
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index fee0bc0..9e1b866 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -12345,7 +12345,7 @@
   frame.error_code = QUIC_STREAM_ENCODER_STREAM_ERROR;
   frame.ietf_error_code =
       static_cast<uint64_t>(QuicHttpQpackErrorCode::ENCODER_STREAM_ERROR);
-  QuicFrames frames = {QuicFrame(&frame)};
+  QuicFrames frames = {QuicFrame(frame)};
 
   // clang-format off
   unsigned char packet_ietf[] = {
@@ -12612,7 +12612,7 @@
   QuicStopSendingFrame stop_sending_frame(10, 3, QUIC_STREAM_CANCELLED);
   EXPECT_EQ(QuicFramer::GetStopSendingFrameSize(stop_sending_frame),
             QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&stop_sending_frame)));
+                framer_.transport_version(), QuicFrame(stop_sending_frame)));
 }
 
 // A set of tests to ensure that bad frame-type encodings