Use the id of PendingStream & perspective of Session to set the type of QuicStream. This change will make it easier to support bidirectional PendingStream later.

No behavior change as every PendingStream is read unidirectional and so is every QuicStream created from a PendingStream.

PiperOrigin-RevId: 397320262
diff --git a/quic/core/http/quic_receive_control_stream.cc b/quic/core/http/quic_receive_control_stream.cc
index 9c164d0..3c6546f 100644
--- a/quic/core/http/quic_receive_control_stream.cc
+++ b/quic/core/http/quic_receive_control_stream.cc
@@ -24,7 +24,6 @@
     QuicSpdySession* spdy_session)
     : QuicStream(pending,
                  spdy_session,
-                 READ_UNIDIRECTIONAL,
                  /*is_static=*/true),
       settings_frame_received_(false),
       decoder_(this),
diff --git a/quic/core/http/quic_server_session_base_test.cc b/quic/core/http/quic_server_session_base_test.cc
index 60d616e..279ff60 100644
--- a/quic/core/http/quic_server_session_base_test.cc
+++ b/quic/core/http/quic_server_session_base_test.cc
@@ -94,8 +94,8 @@
   }
 
   QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override {
-    QuicSpdyStream* stream = new QuicSimpleServerStream(
-        pending, this, READ_UNIDIRECTIONAL, quic_simple_server_backend_);
+    QuicSpdyStream* stream =
+        new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
     ActivateStream(absl::WrapUnique(stream));
     return stream;
   }
diff --git a/quic/core/http/quic_spdy_client_session.cc b/quic/core/http/quic_spdy_client_session.cc
index 45bdd1d..898398f 100644
--- a/quic/core/http/quic_spdy_client_session.cc
+++ b/quic/core/http/quic_spdy_client_session.cc
@@ -185,8 +185,7 @@
 
 QuicSpdyStream* QuicSpdyClientSession::CreateIncomingStream(
     PendingStream* pending) {
-  QuicSpdyStream* stream =
-      new QuicSpdyClientStream(pending, this, READ_UNIDIRECTIONAL);
+  QuicSpdyStream* stream = new QuicSpdyClientStream(pending, this);
   ActivateStream(absl::WrapUnique(stream));
   return stream;
 }
diff --git a/quic/core/http/quic_spdy_client_stream.cc b/quic/core/http/quic_spdy_client_stream.cc
index d264ba6..7f55fef 100644
--- a/quic/core/http/quic_spdy_client_stream.cc
+++ b/quic/core/http/quic_spdy_client_stream.cc
@@ -31,9 +31,8 @@
       has_preliminary_headers_(false) {}
 
 QuicSpdyClientStream::QuicSpdyClientStream(PendingStream* pending,
-                                           QuicSpdyClientSession* session,
-                                           StreamType type)
-    : QuicSpdyStream(pending, session, type),
+                                           QuicSpdyClientSession* session)
+    : QuicSpdyStream(pending, session),
       content_length_(-1),
       response_code_(0),
       header_bytes_read_(0),
diff --git a/quic/core/http/quic_spdy_client_stream.h b/quic/core/http/quic_spdy_client_stream.h
index 2318465..8637d11 100644
--- a/quic/core/http/quic_spdy_client_stream.h
+++ b/quic/core/http/quic_spdy_client_stream.h
@@ -25,8 +25,7 @@
                        QuicSpdyClientSession* session,
                        StreamType type);
   QuicSpdyClientStream(PendingStream* pending,
-                       QuicSpdyClientSession* spdy_session,
-                       StreamType type);
+                       QuicSpdyClientSession* spdy_session);
   QuicSpdyClientStream(const QuicSpdyClientStream&) = delete;
   QuicSpdyClientStream& operator=(const QuicSpdyClientStream&) = delete;
   ~QuicSpdyClientStream() override;
diff --git a/quic/core/http/quic_spdy_server_stream_base.cc b/quic/core/http/quic_spdy_server_stream_base.cc
index c2e7845..93f1c2b 100644
--- a/quic/core/http/quic_spdy_server_stream_base.cc
+++ b/quic/core/http/quic_spdy_server_stream_base.cc
@@ -16,9 +16,8 @@
     : QuicSpdyStream(id, session, type) {}
 
 QuicSpdyServerStreamBase::QuicSpdyServerStreamBase(PendingStream* pending,
-                                                   QuicSpdySession* session,
-                                                   StreamType type)
-    : QuicSpdyStream(pending, session, type) {}
+                                                   QuicSpdySession* session)
+    : QuicSpdyStream(pending, session) {}
 
 void QuicSpdyServerStreamBase::CloseWriteSide() {
   if (!fin_received() && !rst_received() && sequencer()->ignore_read_data() &&
diff --git a/quic/core/http/quic_spdy_server_stream_base.h b/quic/core/http/quic_spdy_server_stream_base.h
index 252addf..21ecc0b 100644
--- a/quic/core/http/quic_spdy_server_stream_base.h
+++ b/quic/core/http/quic_spdy_server_stream_base.h
@@ -14,9 +14,7 @@
   QuicSpdyServerStreamBase(QuicStreamId id,
                            QuicSpdySession* session,
                            StreamType type);
-  QuicSpdyServerStreamBase(PendingStream* pending,
-                           QuicSpdySession* session,
-                           StreamType type);
+  QuicSpdyServerStreamBase(PendingStream* pending, QuicSpdySession* session);
   QuicSpdyServerStreamBase(const QuicSpdyServerStreamBase&) = delete;
   QuicSpdyServerStreamBase& operator=(const QuicSpdyServerStreamBase&) = delete;
 
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index 3734301..2719735 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -208,8 +208,8 @@
   TestStream(QuicStreamId id, QuicSpdySession* session, StreamType type)
       : QuicSpdyStream(id, session, type) {}
 
-  TestStream(PendingStream* pending, QuicSpdySession* session, StreamType type)
-      : QuicSpdyStream(pending, session, type) {}
+  TestStream(PendingStream* pending, QuicSpdySession* session)
+      : QuicSpdyStream(pending, session) {}
 
   using QuicStream::CloseWriteSide;
 
@@ -286,11 +286,7 @@
   }
 
   TestStream* CreateIncomingStream(PendingStream* pending) override {
-    QuicStreamId id = pending->id();
-    TestStream* stream = new TestStream(
-        pending, this,
-        DetermineStreamType(id, connection()->version(), perspective(),
-                            /*is_incoming=*/true, BIDIRECTIONAL));
+    TestStream* stream = new TestStream(pending, this);
     ActivateStream(absl::WrapUnique(stream));
     return stream;
   }
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc
index f2b8f82..2ff3b3a 100644
--- a/quic/core/http/quic_spdy_stream.cc
+++ b/quic/core/http/quic_spdy_stream.cc
@@ -213,9 +213,8 @@
 }
 
 QuicSpdyStream::QuicSpdyStream(PendingStream* pending,
-                               QuicSpdySession* spdy_session,
-                               StreamType type)
-    : QuicStream(pending, spdy_session, type, /*is_static=*/false),
+                               QuicSpdySession* spdy_session)
+    : QuicStream(pending, spdy_session, /*is_static=*/false),
       spdy_session_(spdy_session),
       on_body_available_called_because_sequencer_is_closed_(false),
       visitor_(nullptr),
diff --git a/quic/core/http/quic_spdy_stream.h b/quic/core/http/quic_spdy_stream.h
index 9042698..7a019e0 100644
--- a/quic/core/http/quic_spdy_stream.h
+++ b/quic/core/http/quic_spdy_stream.h
@@ -74,9 +74,7 @@
   QuicSpdyStream(QuicStreamId id,
                  QuicSpdySession* spdy_session,
                  StreamType type);
-  QuicSpdyStream(PendingStream* pending,
-                 QuicSpdySession* spdy_session,
-                 StreamType type);
+  QuicSpdyStream(PendingStream* pending, QuicSpdySession* spdy_session);
   QuicSpdyStream(const QuicSpdyStream&) = delete;
   QuicSpdyStream& operator=(const QuicSpdyStream&) = delete;
   ~QuicSpdyStream() override;
diff --git a/quic/core/http/web_transport_http3.cc b/quic/core/http/web_transport_http3.cc
index 679cb2b..48dccfc 100644
--- a/quic/core/http/web_transport_http3.cc
+++ b/quic/core/http/web_transport_http3.cc
@@ -259,7 +259,7 @@
 
 WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(
     PendingStream* pending, QuicSpdySession* session)
-    : QuicStream(pending, session, READ_UNIDIRECTIONAL, /*is_static=*/false),
+    : QuicStream(pending, session, /*is_static=*/false),
       session_(session),
       adapter_(session, this, sequencer()),
       needs_to_send_preamble_(false) {}
diff --git a/quic/core/qpack/qpack_receive_stream.cc b/quic/core/qpack/qpack_receive_stream.cc
index 65e290f..1f75919 100644
--- a/quic/core/qpack/qpack_receive_stream.cc
+++ b/quic/core/qpack/qpack_receive_stream.cc
@@ -11,8 +11,7 @@
 QpackReceiveStream::QpackReceiveStream(PendingStream* pending,
                                        QuicSession* session,
                                        QpackStreamReceiver* receiver)
-    : QuicStream(pending, session, READ_UNIDIRECTIONAL, /*is_static=*/true),
-      receiver_(receiver) {}
+    : QuicStream(pending, session, /*is_static=*/true), receiver_(receiver) {}
 
 void QpackReceiveStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
   stream_delegate()->OnStreamError(
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
index 10d57c3..11b3e99 100644
--- a/quic/core/quic_session_test.cc
+++ b/quic/core/quic_session_test.cc
@@ -186,8 +186,8 @@
              StreamType type)
       : QuicStream(id, session, is_static, type) {}
 
-  TestStream(PendingStream* pending, QuicSession* session, StreamType type)
-      : QuicStream(pending, session, type, /*is_static=*/false) {}
+  TestStream(PendingStream* pending, QuicSession* session)
+      : QuicStream(pending, session, /*is_static=*/false) {}
 
   using QuicStream::CloseWriteSide;
   using QuicStream::WriteMemSlices;
@@ -278,11 +278,7 @@
   }
 
   TestStream* CreateIncomingStream(PendingStream* pending) override {
-    QuicStreamId id = pending->id();
-    TestStream* stream = new TestStream(
-        pending, this,
-        DetermineStreamType(id, connection()->version(), perspective(),
-                            /*is_incoming=*/true, BIDIRECTIONAL));
+    TestStream* stream = new TestStream(pending, this);
     ActivateStream(absl::WrapUnique(stream));
     ++num_incoming_streams_created_;
     return stream;
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc
index b50f7d0..e87bc01 100644
--- a/quic/core/quic_stream.cc
+++ b/quic/core/quic_stream.cc
@@ -20,6 +20,7 @@
 #include "quic/platform/api/quic_flags.h"
 #include "quic/platform/api/quic_logging.h"
 #include "quic/platform/api/quic_mem_slice.h"
+#include "common/platform/api/quiche_logging.h"
 
 using spdy::SpdyPriority;
 
@@ -271,11 +272,19 @@
 }
 
 QuicStream::QuicStream(PendingStream* pending, QuicSession* session,
-                       StreamType type, bool is_static)
+                       bool is_static)
     : QuicStream(pending->id_, session, std::move(pending->sequencer_),
-                 is_static, type, pending->stream_bytes_read_,
-                 pending->fin_received_, std::move(pending->flow_controller_),
+                 is_static,
+                 QuicUtils::GetStreamType(pending->id_, session->perspective(),
+                                          /*peer_initiated = */ true,
+                                          session->version()),
+                 pending->stream_bytes_read_, pending->fin_received_,
+                 std::move(pending->flow_controller_),
                  pending->connection_flow_controller_) {
+  QUICHE_DCHECK(session->version().HasIetfQuicFrames());
+  // TODO(haoyuewang) Remove this check once bidirectional pending stream is
+  // supported.
+  QUICHE_DCHECK(type_ == READ_UNIDIRECTIONAL);
   sequencer_.set_stream(this);
 }
 
diff --git a/quic/core/quic_stream.h b/quic/core/quic_stream.h
index 6537dd1..10ef313 100644
--- a/quic/core/quic_stream.h
+++ b/quic/core/quic_stream.h
@@ -137,8 +137,7 @@
   // TODO(fayang): Remove |type| when IETF stream ID numbering fully kicks in.
   QuicStream(QuicStreamId id, QuicSession* session, bool is_static,
              StreamType type);
-  QuicStream(PendingStream* pending, QuicSession* session, StreamType type,
-             bool is_static);
+  QuicStream(PendingStream* pending, QuicSession* session, bool is_static);
   QuicStream(const QuicStream&) = delete;
   QuicStream& operator=(const QuicStream&) = delete;
 
diff --git a/quic/core/quic_stream_test.cc b/quic/core/quic_stream_test.cc
index 55a6f58..9d37128 100644
--- a/quic/core/quic_stream_test.cc
+++ b/quic/core/quic_stream_test.cc
@@ -58,11 +58,8 @@
     sequencer()->set_level_triggered(true);
   }
 
-  TestStream(PendingStream* pending,
-             QuicSession* session,
-             StreamType type,
-             bool is_static)
-      : QuicStream(pending, session, type, is_static) {}
+  TestStream(PendingStream* pending, QuicSession* session, bool is_static)
+      : QuicStream(pending, session, is_static) {}
 
   MOCK_METHOD(void, OnDataAvailable, (), (override));
 
@@ -87,11 +84,11 @@
       : zero_(QuicTime::Delta::Zero()),
         supported_versions_(AllSupportedVersions()) {}
 
-  void Initialize() {
+  void Initialize(Perspective perspective = Perspective::IS_SERVER) {
     ParsedQuicVersionVector version_vector;
     version_vector.push_back(GetParam());
     connection_ = new StrictMock<MockQuicConnection>(
-        &helper_, &alarm_factory_, Perspective::IS_SERVER, version_vector);
+        &helper_, &alarm_factory_, perspective, version_vector);
     connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
     session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_);
     session_->Initialize();
@@ -166,6 +163,9 @@
   QuicStreamId kTestStreamId =
       GetNthClientInitiatedBidirectionalStreamId(GetParam().transport_version,
                                                  1);
+  const QuicStreamId kTestPendingStreamId =
+      GetNthClientInitiatedUnidirectionalStreamId(GetParam().transport_version,
+                                                  1);
 };
 
 INSTANTIATE_TEST_SUITE_P(QuicStreamTests,
@@ -173,27 +173,50 @@
                          ::testing::ValuesIn(AllSupportedVersions()),
                          ::testing::PrintToStringParamName());
 
-TEST_P(QuicStreamTest, PendingStreamStaticness) {
+using PendingStreamTest = QuicStreamTest;
+
+INSTANTIATE_TEST_SUITE_P(PendingStreamTests, PendingStreamTest,
+                         ::testing::ValuesIn(CurrentSupportedHttp3Versions()),
+                         ::testing::PrintToStringParamName());
+
+TEST_P(PendingStreamTest, PendingStreamStaticness) {
   Initialize();
 
-  PendingStream pending(kTestStreamId + 2, session_.get());
-  TestStream stream(&pending, session_.get(), StreamType::READ_UNIDIRECTIONAL,
-                    false);
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  TestStream stream(&pending, session_.get(), false);
   EXPECT_FALSE(stream.is_static());
 
-  PendingStream pending2(kTestStreamId + 3, session_.get());
-  TestStream stream2(&pending2, session_.get(), StreamType::READ_UNIDIRECTIONAL,
-                     true);
+  PendingStream pending2(kTestPendingStreamId + 4, session_.get());
+  TestStream stream2(&pending2, session_.get(), true);
   EXPECT_TRUE(stream2.is_static());
 }
 
-TEST_P(QuicStreamTest, PendingStreamTooMuchData) {
+TEST_P(PendingStreamTest, PendingStreamType) {
   Initialize();
 
-  PendingStream pending(kTestStreamId + 2, session_.get());
+  PendingStream pending(kTestPendingStreamId, session_.get());
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
+}
+
+TEST_P(PendingStreamTest, PendingStreamTypeOnClient) {
+  Initialize(Perspective::IS_CLIENT);
+
+  QuicStreamId server_initiated_pending_stream_id =
+      GetNthServerInitiatedUnidirectionalStreamId(session_->transport_version(),
+                                                  1);
+  PendingStream pending(server_initiated_pending_stream_id, session_.get());
+  TestStream stream(&pending, session_.get(), false);
+  EXPECT_EQ(stream.type(), READ_UNIDIRECTIONAL);
+}
+
+TEST_P(PendingStreamTest, PendingStreamTooMuchData) {
+  Initialize();
+
+  PendingStream pending(kTestPendingStreamId, session_.get());
   // Receive a stream frame that violates flow control: the byte offset is
   // higher than the receive window offset.
-  QuicStreamFrame frame(kTestStreamId + 2, false,
+  QuicStreamFrame frame(kTestPendingStreamId, false,
                         kInitialSessionFlowControlWindowForTest + 1, ".");
 
   // Stream should not accept the frame, and the connection should be closed.
@@ -202,13 +225,13 @@
   pending.OnStreamFrame(frame);
 }
 
-TEST_P(QuicStreamTest, PendingStreamTooMuchDataInRstStream) {
+TEST_P(PendingStreamTest, PendingStreamTooMuchDataInRstStream) {
   Initialize();
 
-  PendingStream pending(kTestStreamId + 2, session_.get());
+  PendingStream pending(kTestPendingStreamId, session_.get());
   // Receive a rst stream frame that violates flow control: the byte offset is
   // higher than the receive window offset.
-  QuicRstStreamFrame frame(kInvalidControlFrameId, kTestStreamId + 2,
+  QuicRstStreamFrame frame(kInvalidControlFrameId, kTestPendingStreamId,
                            QUIC_STREAM_CANCELLED,
                            kInitialSessionFlowControlWindowForTest + 1);
 
@@ -219,12 +242,12 @@
   pending.OnRstStreamFrame(frame);
 }
 
-TEST_P(QuicStreamTest, PendingStreamRstStream) {
+TEST_P(PendingStreamTest, PendingStreamRstStream) {
   Initialize();
 
-  PendingStream pending(kTestStreamId + 2, session_.get());
+  PendingStream pending(kTestPendingStreamId, session_.get());
   QuicStreamOffset final_byte_offset = 7;
-  QuicRstStreamFrame frame(kInvalidControlFrameId, kTestStreamId + 2,
+  QuicRstStreamFrame frame(kInvalidControlFrameId, kTestPendingStreamId,
                            QUIC_STREAM_CANCELLED, final_byte_offset);
 
   // Pending stream should accept the frame and not close the connection.
@@ -232,19 +255,18 @@
   pending.OnRstStreamFrame(frame);
 }
 
-TEST_P(QuicStreamTest, FromPendingStream) {
+TEST_P(PendingStreamTest, FromPendingStream) {
   Initialize();
 
-  PendingStream pending(kTestStreamId + 2, session_.get());
+  PendingStream pending(kTestPendingStreamId, session_.get());
 
-  QuicStreamFrame frame(kTestStreamId + 2, false, 2, ".");
+  QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
   pending.OnStreamFrame(frame);
   pending.OnStreamFrame(frame);
-  QuicStreamFrame frame2(kTestStreamId + 2, true, 3, ".");
+  QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
   pending.OnStreamFrame(frame2);
 
-  TestStream stream(&pending, session_.get(), StreamType::READ_UNIDIRECTIONAL,
-                    false);
+  TestStream stream(&pending, session_.get(), false);
   EXPECT_EQ(3, stream.num_frames_received());
   EXPECT_EQ(3u, stream.stream_bytes_read());
   EXPECT_EQ(1, stream.num_duplicate_frames_received());
@@ -254,19 +276,18 @@
             session_->flow_controller()->highest_received_byte_offset());
 }
 
-TEST_P(QuicStreamTest, FromPendingStreamThenData) {
+TEST_P(PendingStreamTest, FromPendingStreamThenData) {
   Initialize();
 
-  PendingStream pending(kTestStreamId + 2, session_.get());
+  PendingStream pending(kTestPendingStreamId, session_.get());
 
-  QuicStreamFrame frame(kTestStreamId + 2, false, 2, ".");
+  QuicStreamFrame frame(kTestPendingStreamId, false, 2, ".");
   pending.OnStreamFrame(frame);
 
-  auto stream = new TestStream(&pending, session_.get(),
-                               StreamType::READ_UNIDIRECTIONAL, false);
+  auto stream = new TestStream(&pending, session_.get(), false);
   session_->ActivateStream(absl::WrapUnique(stream));
 
-  QuicStreamFrame frame2(kTestStreamId + 2, true, 3, ".");
+  QuicStreamFrame frame2(kTestPendingStreamId, true, 3, ".");
   stream->OnStreamFrame(frame2);
 
   EXPECT_EQ(2, stream->num_frames_received());
diff --git a/quic/core/quic_types.h b/quic/core/quic_types.h
index 80ba33e..74e7e8e 100644
--- a/quic/core/quic_types.h
+++ b/quic/core/quic_types.h
@@ -679,7 +679,7 @@
   WRITE_FAILED,    // Trying to write nonexistent data of a stream
 };
 
-enum StreamType {
+enum StreamType : uint8_t {
   // Bidirectional streams allow for data to be sent in both directions.
   BIDIRECTIONAL,
 
diff --git a/quic/tools/quic_simple_server_session.cc b/quic/tools/quic_simple_server_session.cc
index fa1e08f..1e5734d 100644
--- a/quic/tools/quic_simple_server_session.cc
+++ b/quic/tools/quic_simple_server_session.cc
@@ -67,8 +67,8 @@
 
 QuicSpdyStream* QuicSimpleServerSession::CreateIncomingStream(
     PendingStream* pending) {
-  QuicSpdyStream* stream = new QuicSimpleServerStream(
-      pending, this, READ_UNIDIRECTIONAL, quic_simple_server_backend_);
+  QuicSpdyStream* stream =
+      new QuicSimpleServerStream(pending, this, quic_simple_server_backend_);
   ActivateStream(absl::WrapUnique(stream));
   return stream;
 }
diff --git a/quic/tools/quic_simple_server_stream.cc b/quic/tools/quic_simple_server_stream.cc
index 5cd3652..d7e2a70 100644
--- a/quic/tools/quic_simple_server_stream.cc
+++ b/quic/tools/quic_simple_server_stream.cc
@@ -38,11 +38,9 @@
 }
 
 QuicSimpleServerStream::QuicSimpleServerStream(
-    PendingStream* pending,
-    QuicSpdySession* session,
-    StreamType type,
+    PendingStream* pending, QuicSpdySession* session,
     QuicSimpleServerBackend* quic_simple_server_backend)
-    : QuicSpdyServerStreamBase(pending, session, type),
+    : QuicSpdyServerStreamBase(pending, session),
       content_length_(-1),
       generate_bytes_length_(0),
       quic_simple_server_backend_(quic_simple_server_backend) {
diff --git a/quic/tools/quic_simple_server_stream.h b/quic/tools/quic_simple_server_stream.h
index 6395345..d138492 100644
--- a/quic/tools/quic_simple_server_stream.h
+++ b/quic/tools/quic_simple_server_stream.h
@@ -25,7 +25,6 @@
                          QuicSimpleServerBackend* quic_simple_server_backend);
   QuicSimpleServerStream(PendingStream* pending,
                          QuicSpdySession* session,
-                         StreamType type,
                          QuicSimpleServerBackend* quic_simple_server_backend);
   QuicSimpleServerStream(const QuicSimpleServerStream&) = delete;
   QuicSimpleServerStream& operator=(const QuicSimpleServerStream&) = delete;