// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// The base class for client/server QUIC streams.

// It does not contain the entire interface needed by an application to interact
// with a QUIC stream.  Some parts of the interface must be obtained by
// accessing the owning session object.  A subclass of QuicStream
// connects the object and the application that generates and consumes the data
// of the stream.

// The QuicStream object has a dependent QuicStreamSequencer object,
// which is given the stream frames as they arrive, and provides stream data in
// order by invoking ProcessRawData().

#ifndef QUICHE_QUIC_CORE_QUIC_STREAM_H_
#define QUICHE_QUIC_CORE_QUIC_STREAM_H_

#include <cstddef>
#include <cstdint>
#include <list>
#include <memory>
#include <optional>
#include <string>

#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/http2/core/spdy_protocol.h"
#include "quiche/quic/core/frames/quic_connection_close_frame.h"
#include "quiche/quic/core/frames/quic_reset_stream_at_frame.h"
#include "quiche/quic/core/frames/quic_rst_stream_frame.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_flow_controller.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_stream_priority.h"
#include "quiche/quic/core/quic_stream_send_buffer.h"
#include "quiche/quic/core/quic_stream_send_buffer_base.h"
#include "quiche/quic/core/quic_stream_sequencer.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/session_notifier_interface.h"
#include "quiche/quic/core/stream_delegate_interface.h"
#include "quiche/quic/platform/api/quic_export.h"
#include "quiche/common/platform/api/quiche_reference_counted.h"
#include "quiche/common/quiche_mem_slice.h"

namespace quic {

namespace test {
class QuicStreamPeer;
}  // namespace test

class QuicSession;
class QuicStream;

// Buffers frames for a stream until the first byte of that frame arrives.
class QUICHE_EXPORT PendingStream
    : public QuicStreamSequencer::StreamInterface {
 public:
  PendingStream(QuicStreamId id, QuicSession* session);
  PendingStream(const PendingStream&) = delete;
  PendingStream(PendingStream&&) = default;
  ~PendingStream() override = default;

  // QuicStreamSequencer::StreamInterface
  void OnDataAvailable() override;
  void OnFinRead() override;
  void AddBytesConsumed(QuicByteCount bytes) override;
  void ResetWithError(QuicResetStreamError error) override;
  void OnUnrecoverableError(QuicErrorCode error,
                            const std::string& details) override;
  void OnUnrecoverableError(QuicErrorCode error,
                            QuicIetfTransportErrorCodes ietf_error,
                            const std::string& details) override;
  QuicStreamId id() const override;
  ParsedQuicVersion version() const override;

  // Buffers the contents of |frame|. Frame must have a non-zero offset.
  // If the data violates flow control, the connection will be closed.
  void OnStreamFrame(const QuicStreamFrame& frame);

  bool is_bidirectional() const { return is_bidirectional_; }

  // Stores the final byte offset from |frame|.
  // If the final offset violates flow control, the connection will be closed.
  void OnRstStreamFrame(const QuicRstStreamFrame& frame);

  void OnResetStreamAtFrame(const QuicResetStreamAtFrame& frame);

  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);

  void OnStopSending(QuicResetStreamError stop_sending_error_code);

  // The error code received from QuicStopSendingFrame (if any).
  const std::optional<QuicResetStreamError>& GetStopSendingErrorCode() const {
    return stop_sending_error_code_;
  }

  // Returns the number of bytes read on this stream.
  uint64_t stream_bytes_read() { return stream_bytes_read_; }

  const QuicStreamSequencer* sequencer() const { return &sequencer_; }

  void MarkConsumed(QuicByteCount num_bytes);

  // Tells the sequencer to ignore all incoming data itself and not call
  // OnDataAvailable().
  void StopReading();

  QuicTime creation_time() const { return creation_time_; }

  std::optional<QuicResetStreamAtFrame> buffered_reset_stream_at() const {
    return buffered_reset_stream_at_;
  }

 private:
  friend class QuicStream;

  bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);

  // ID of this stream.
  QuicStreamId id_;

  // QUIC version being used by this stream.
  ParsedQuicVersion version_;

  // |stream_delegate_| must outlive this stream.
  StreamDelegateInterface* stream_delegate_;

  // Bytes read refers to payload bytes only: they do not include framing,
  // encryption overhead etc.
  uint64_t stream_bytes_read_;

  // True if a frame containing a fin has been received.
  bool fin_received_;

  // True if this pending stream is backing a bidirectional stream.
  bool is_bidirectional_;

  // Connection-level flow controller. Owned by the session.
  QuicFlowController* connection_flow_controller_;
  // Stream-level flow controller.
  QuicFlowController flow_controller_;
  // Stores the buffered frames.
  QuicStreamSequencer sequencer_;
  // The error code received from QuicStopSendingFrame (if any).
  std::optional<QuicResetStreamError> stop_sending_error_code_;
  // The time when this pending stream is created.
  const QuicTime creation_time_;

  // When RESET_STREAM_AT arrives,buffer it for when reliable_size is consumed.
  std::optional<QuicResetStreamAtFrame> buffered_reset_stream_at_;
};

class QUICHE_EXPORT QuicStream : public QuicStreamSequencer::StreamInterface {
 public:
  // Creates a new stream with stream_id |id| associated with |session|. If
  // |is_static| is true, then the stream will be given precedence
  // over other streams when determing what streams should write next.
  // |type| indicates whether the stream is bidirectional, read unidirectional
  // or write unidirectional.
  // 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, bool is_static);
  QuicStream(const QuicStream&) = delete;
  QuicStream& operator=(const QuicStream&) = delete;

  virtual ~QuicStream();

  // QuicStreamSequencer::StreamInterface implementation.
  QuicStreamId id() const override { return id_; }
  ParsedQuicVersion version() const override;
  // Called by the stream subclass after it has consumed the final incoming
  // data.
  void OnFinRead() override;

  // Called by the subclass or the sequencer to reset the stream from this
  // end.
  void ResetWithError(QuicResetStreamError error) override;
  // Convenience wrapper for the method above.
  // TODO(b/200606367): switch all calls to using QuicResetStreamError
  // interface.
  void Reset(QuicRstStreamErrorCode error);

  // Record the current offset as the reliable size to be delivered if a partial
  // reset is called. Returns false if a RST_STREAM or RESET_STREAM_AT has
  // already been sent, the stream is receive-only, or the connection does not
  // support RESET_STREAM_AT.
  bool SetReliableSize();

  // Send a RESET_STREAM_AT with a reliable size that had earlier been set by
  // SetReliableSize(). Does not send STOP_SENDING and does not close the read
  // side. Will trigger QUIC_BUG if reliable_size_ is zero.
  void PartialResetWriteSide(QuicResetStreamError error);
  // TODO(rch): Delete this function once Envoy has migrated to
  // PartialResetWriteSide.
  void ResetWriteSide(QuicResetStreamError error);
  // Reset() sends both RESET_STREAM and STOP_SENDING; this allows the caller to
  // send only STOP_SENDING.
  void SendStopSending(QuicResetStreamError error);

  // Called by the subclass or the sequencer to close the entire connection from
  // this end.
  void OnUnrecoverableError(QuicErrorCode error,
                            const std::string& details) override;
  void OnUnrecoverableError(QuicErrorCode error,
                            QuicIetfTransportErrorCodes ietf_error,
                            const std::string& details) override;

  // Called by the session when a (potentially duplicate) stream frame has been
  // received for this stream.
  virtual void OnStreamFrame(const QuicStreamFrame& frame);

  // Called by the session when the connection becomes writeable to allow the
  // stream to write any pending data.
  virtual void OnCanWrite();

  // Called by the session when the endpoint receives a RST_STREAM from the
  // peer.
  virtual void OnStreamReset(const QuicRstStreamFrame& frame);
  // Called by the session when the endpoint receives a RESET_STREAM_AT from the
  // peer.
  virtual void OnResetStreamAtFrame(const QuicResetStreamAtFrame& frame);

  // Called by the session when the endpoint receives or sends a connection
  // close, and should immediately close the stream.
  virtual void OnConnectionClosed(const QuicConnectionCloseFrame& frame,
                                  ConnectionCloseSource source);

  const QuicStreamPriority& priority() const;

  // Send PRIORITY_UPDATE frame if application protocol supports it.
  virtual void MaybeSendPriorityUpdateFrame() {}

  // Sets |priority_| to priority.  This should only be called before bytes are
  // written to the server.  For a server stream, this is called when a
  // PRIORITY_UPDATE frame is received.  This calls
  // MaybeSendPriorityUpdateFrame(), which for a client stream might send a
  // PRIORITY_UPDATE frame.
  void SetPriority(const QuicStreamPriority& priority);

  // Returns true if this stream is still waiting for acks of sent data.
  // This will return false if all data has been acked, or if the stream
  // is no longer interested in data being acked (which happens when
  // a stream is reset because of an error).
  bool IsWaitingForAcks() const;

  QuicRstStreamErrorCode stream_error() const {
    return stream_error_.internal_code();
  }
  // Application error code of RESET_STREAM.
  uint64_t ietf_application_error() const {
    return stream_error_.ietf_application_code();
  }
  QuicErrorCode connection_error() const { return connection_error_; }

  bool reading_stopped() const {
    return sequencer_.ignore_read_data() || read_side_closed_;
  }
  bool write_side_closed() const { return write_side_closed_; }
  bool read_side_closed() const { return read_side_closed_; }

  bool IsZombie() const {
    return read_side_closed_ && write_side_closed_ && IsWaitingForAcks();
  }

  bool rst_received() const { return rst_received_; }
  bool rst_sent() const { return rst_sent_; }
  bool fin_received() const { return fin_received_; }
  bool fin_sent() const { return fin_sent_; }
  bool fin_outstanding() const { return fin_outstanding_; }
  bool fin_lost() const { return fin_lost_; }

  uint64_t BufferedDataBytes() const;

  uint64_t stream_bytes_read() const { return stream_bytes_read_; }
  uint64_t stream_bytes_written() const;

  size_t busy_counter() const { return busy_counter_; }
  void set_busy_counter(size_t busy_counter) { busy_counter_ = busy_counter; }

  // Adjust the flow control window according to new offset in |frame|.
  virtual void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame);

  int num_frames_received() const;
  int num_duplicate_frames_received() const;

  // Flow controller related methods.
  bool IsFlowControlBlocked() const;
  QuicStreamOffset highest_received_byte_offset() const;
  void UpdateReceiveWindowSize(QuicStreamOffset size);
  QuicStreamOffset NumBytesConsumed() const {
    return sequencer()->NumBytesConsumed();
  }
  QuicStreamOffset send_window_offset() const {
    return flow_controller_->send_window_offset();
  }

  // Called when endpoint receives a frame which could increase the highest
  // offset.
  // Returns true if the highest offset did increase.
  bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset);

  // Set the flow controller's send window offset from session config.
  // |was_zero_rtt_rejected| is true if this config is from a rejected IETF QUIC
  // 0-RTT attempt. Closes the connection and returns false if |new_offset| is
  // not valid.
  bool MaybeConfigSendWindowOffset(QuicStreamOffset new_offset,
                                   bool was_zero_rtt_rejected);

  // Returns true if the stream has received either a RST_STREAM or a FIN -
  // either of which gives a definitive number of bytes which the peer has
  // sent. If this is not true on deletion of the stream object, the session
  // must keep track of the stream's byte offset until a definitive final value
  // arrives.
  bool HasReceivedFinalOffset() const { return fin_received_ || rst_received_; }

  // Returns true if the stream has queued data waiting to write.
  bool HasBufferedData() const;

  // Returns the version of QUIC being used for this stream.
  QuicTransportVersion transport_version() const;

  // Returns the crypto handshake protocol that was used on this stream's
  // connection.
  HandshakeProtocol handshake_protocol() const;

  // Sets the sequencer to consume all incoming data itself and not call
  // OnDataAvailable().
  // When the FIN is received, the stream will be notified automatically (via
  // OnFinRead()) (which may happen during the call of StopReading()).
  // TODO(dworley): There should be machinery to send a RST_STREAM/NO_ERROR and
  // stop sending stream-level flow-control updates when this end sends FIN.
  virtual void StopReading();

  // Sends as much of |data| to the connection on the application encryption
  // level as the connection will consume, and then buffers any remaining data
  // in the send buffer. If fin is true: if it is immediately passed on to the
  // session, write_side_closed() becomes true, otherwise fin_buffered_ becomes
  // true.
  void WriteOrBufferData(
      absl::string_view data, bool fin,
      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
          ack_listener);

  // Sends |data| to connection with specified |level|.
  void WriteOrBufferDataAtLevel(
      absl::string_view data, bool fin, EncryptionLevel level,
      quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
          ack_listener);

  // Adds random padding after the fin is consumed for this stream.
  void AddRandomPaddingAfterFin();

  // Write |data_length| of data starts at |offset| from send buffer.
  bool WriteStreamData(QuicStreamOffset offset, QuicByteCount data_length,
                       QuicDataWriter* writer);

  // Called when data [offset, offset + data_length) is acked. |fin_acked|
  // indicates whether the fin is acked. Returns true and updates
  // |newly_acked_length| if any new stream data (including fin) gets acked.
  virtual bool OnStreamFrameAcked(QuicStreamOffset offset,
                                  QuicByteCount data_length, bool fin_acked,
                                  QuicTime::Delta ack_delay_time,
                                  QuicTime receive_timestamp,
                                  QuicByteCount* newly_acked_length,
                                  bool is_retransmission);

  // Called when data [offset, offset + data_length) was retransmitted.
  // |fin_retransmitted| indicates whether fin was retransmitted.
  virtual void OnStreamFrameRetransmitted(QuicStreamOffset offset,
                                          QuicByteCount data_length,
                                          bool fin_retransmitted);

  // Called when data [offset, offset + data_length) is considered as lost.
  // |fin_lost| indicates whether the fin is considered as lost.
  virtual void OnStreamFrameLost(QuicStreamOffset offset,
                                 QuicByteCount data_length, bool fin_lost);

  // Called to retransmit outstanding portion in data [offset, offset +
  // data_length) and |fin| with Transmission |type|.
  // Returns true if all data gets retransmitted.
  virtual bool RetransmitStreamData(QuicStreamOffset offset,
                                    QuicByteCount data_length, bool fin,
                                    TransmissionType type);

  // Sets deadline of this stream to be now + |ttl|, returns true if the setting
  // succeeds.
  bool MaybeSetTtl(QuicTime::Delta ttl);

  // Commits data into the stream write buffer, and potentially sends it over
  // the wire.  This method has all-or-nothing semantics: if the write buffer is
  // not full, all of the memslices in |span| are moved into it; otherwise,
  // nothing happens. If `buffer_unconditionally` is set to true, behaves
  // similar to `WriteOrBufferData()` in terms of buffering.
  QuicConsumedData WriteMemSlices(absl::Span<quiche::QuicheMemSlice> span,
                                  bool fin, bool buffer_uncondtionally = false);
  QuicConsumedData WriteMemSlice(quiche::QuicheMemSlice span, bool fin);

  // Returns true if any stream data is lost (including fin) and needs to be
  // retransmitted.
  virtual bool HasPendingRetransmission() const;

  // Returns true if any portion of data [offset, offset + data_length) is
  // outstanding or fin is outstanding (if |fin| is true). Returns false
  // otherwise.
  bool IsStreamFrameOutstanding(QuicStreamOffset offset,
                                QuicByteCount data_length, bool fin) const;

  StreamType type() const { return type_; }

  // Handle received StopSending frame. Returns true if the processing finishes
  // gracefully.
  virtual bool OnStopSending(QuicResetStreamError error);

  // Returns true if the stream is static.
  bool is_static() const { return is_static_; }

  bool was_draining() const { return was_draining_; }

  QuicTime creation_time() const { return creation_time_; }

  bool fin_buffered() const { return fin_buffered_; }

  // True if buffered data in send buffer is below buffered_data_threshold_.
  bool CanWriteNewData() const;

  // Called immediately after the stream is created from a pending stream,
  // indicating it can start processing data.
  void OnStreamCreatedFromPendingStream();

  // Called by the sessionwhen a closed stream is about to be destroyed.
  virtual void OnSoonToBeDestroyed();

  void DisableConnectionFlowControlForThisStream() {
    stream_contributes_to_connection_flow_control_ = false;
  }

  // Returns the min of stream level flow control window size and connection
  // level flow control window size.
  QuicByteCount CalculateSendWindowSize() const;

  const QuicTime::Delta pending_duration() const { return pending_duration_; }

 protected:
  // Called when data of [offset, offset + data_length] is buffered in send
  // buffer.
  virtual void OnDataBuffered(
      QuicStreamOffset /*offset*/, QuicByteCount /*data_length*/,
      const quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>&
      /*ack_listener*/) {}

  // Called just before the object is destroyed.
  // The object should not be accessed after OnClose is called.
  // Sends a RST_STREAM with code QUIC_RST_ACKNOWLEDGEMENT if neither a FIN nor
  // a RST_STREAM has been sent.
  virtual void OnClose();

  // True if buffered data in send buffer is still below
  // buffered_data_threshold_ even after writing |length| bytes.
  bool CanWriteNewDataAfterData(QuicByteCount length) const;

  // Called when upper layer can write new data.
  virtual void OnCanWriteNewData() {}

  // Called when |bytes_consumed| bytes has been consumed.
  virtual void OnStreamDataConsumed(QuicByteCount bytes_consumed);

  // Called by the stream sequencer as bytes are consumed from the buffer.
  // If the receive window has dropped below the threshold, then send a
  // WINDOW_UPDATE frame.
  void AddBytesConsumed(QuicByteCount bytes) override;

  // Writes pending retransmissions if any.
  virtual void WritePendingRetransmission();

  // This is called when stream tries to retransmit data after deadline_. Make
  // this virtual so that subclasses can implement their own logics.
  virtual void OnDeadlinePassed();

  // Called to set fin_sent_. This is only used by Google QUIC while body is
  // empty.
  void SetFinSent();

  // Send STOP_SENDING if it hasn't been sent yet.
  void MaybeSendStopSending(QuicResetStreamError error);

  // Send RESET_STREAM if it hasn't been sent yet.
  void MaybeSendRstStream(QuicResetStreamError error);
  // Send RESET_STREAM_AT if neither it nor RESET_STREAM has been sent yet.
  void MaybeSendResetStreamAt(QuicResetStreamError error);

  // Convenience wrappers for two methods above.
  void MaybeSendRstStream(QuicRstStreamErrorCode error) {
    MaybeSendRstStream(QuicResetStreamError::FromInternal(error));
  }
  void MaybeSendStopSending(QuicRstStreamErrorCode error) {
    MaybeSendStopSending(QuicResetStreamError::FromInternal(error));
  }

  // Close the read side of the stream.  May cause the stream to be closed.
  virtual void CloseReadSide();

  // Close the write side of the socket.  Further writes will fail.
  // Can be called by the subclass or internally.
  // Does not send a FIN.  May cause the stream to be closed.
  virtual void CloseWriteSide();

  // Called when any new data is acked.
  virtual void OnNewDataAcked(QuicStreamOffset offset,
                              QuicByteCount data_length,
                              QuicByteCount newly_acked_length,
                              QuicTime receive_timestamp,
                              QuicTime::Delta ack_delay_time,
                              bool is_retransmission);

  void set_rst_received(bool rst_received) { rst_received_ = rst_received; }
  void set_stream_error(QuicResetStreamError error) { stream_error_ = error; }

  StreamDelegateInterface* stream_delegate() { return stream_delegate_; }

  const QuicSession* session() const { return session_; }
  QuicSession* session() { return session_; }

  const QuicStreamSequencer* sequencer() const { return &sequencer_; }
  QuicStreamSequencer* sequencer() { return &sequencer_; }

  const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const;

  const QuicStreamSendBufferBase& send_buffer() const { return *send_buffer_; }

  QuicStreamSendBufferBase& send_buffer() { return *send_buffer_; }

  // Called when the write side of the stream is closed, and all of the outgoing
  // data has been acknowledged.  This corresponds to the "Data Recvd" state of
  // RFC 9000.
  virtual void OnWriteSideInDataRecvdState() {}

  // Return the current stream-level flow control send window in bytes.
  std::optional<QuicByteCount> GetSendWindow() const;
  std::optional<QuicByteCount> GetReceiveWindow() const;

  bool notify_ack_listener_earlier() const {
    return notify_ack_listener_earlier_;
  }

 private:
  friend class test::QuicStreamPeer;
  friend class QuicStreamUtils;

  QuicStream(QuicStreamId id, QuicSession* session,
             QuicStreamSequencer sequencer, bool is_static, StreamType type,
             uint64_t stream_bytes_read, bool fin_received,
             std::optional<QuicFlowController> flow_controller,
             QuicFlowController* connection_flow_controller,
             QuicTime::Delta pending_duration);

  // Calls MaybeSendBlocked on the stream's flow controller and the connection
  // level flow controller.  If the stream is flow control blocked by the
  // connection-level flow controller but not by the stream-level flow
  // controller, marks this stream as connection-level write blocked.
  void MaybeSendBlocked();

  // Write buffered data (in send buffer) at |level|.
  void WriteBufferedData(EncryptionLevel level);

  // Called when bytes are sent to the peer.
  void AddBytesSent(QuicByteCount bytes);

  // Returns true if deadline_ has passed.
  bool HasDeadlinePassed() const;

  // If we've received a RST_STREAM_AT and have processed all remaining data,
  // then process buffered_reset_stream_at_.
  void MaybeCloseStreamWithBufferedReset();

  QuicStreamSequencer sequencer_;
  QuicStreamId id_;
  // Pointer to the owning QuicSession object.
  // TODO(b/136274541): Remove session pointer from streams.
  QuicSession* session_;
  StreamDelegateInterface* stream_delegate_;
  // The priority of the stream, once parsed.
  QuicStreamPriority priority_;
  // Bytes read refers to payload bytes only: they do not include framing,
  // encryption overhead etc.
  uint64_t stream_bytes_read_;

  // Stream error code received from a RstStreamFrame or error code sent by the
  // visitor or sequencer in the RstStreamFrame.
  QuicResetStreamError stream_error_;
  // Connection error code due to which the stream was closed. |stream_error_|
  // is set to |QUIC_STREAM_CONNECTION_ERROR| when this happens and consumers
  // should check |connection_error_|.
  QuicErrorCode connection_error_;

  // True if the read side is closed and further frames should be rejected.
  bool read_side_closed_;
  // True if the write side is closed, and further writes should fail.
  bool write_side_closed_;

  // True if OnWriteSideInDataRecvdState() has already been called.
  bool write_side_data_recvd_state_notified_;

  // True if the subclass has written a FIN with WriteOrBufferData, but it was
  // buffered in queued_data_ rather than being sent to the session.
  bool fin_buffered_;
  // True if a FIN has been sent to the session.
  bool fin_sent_;
  // True if a FIN is waiting to be acked.
  bool fin_outstanding_;
  // True if a FIN is lost.
  bool fin_lost_;

  // True if this stream has received (and the sequencer has accepted) a
  // StreamFrame with the FIN set.
  bool fin_received_;

  // True if an RST_STREAM or RESET_STREAM_AT has been sent to the session.
  // In combination with fin_sent_, used to ensure that a FIN, RST_STREAM, or
  // RESET_STREAM_AT is always sent to terminate the stream.
  bool rst_sent_;
  bool rst_stream_at_sent_;

  // True if this stream has received a RST_STREAM frame.
  bool rst_received_;

  // True if the stream has sent STOP_SENDING to the session.
  bool stop_sending_sent_;

  std::optional<QuicFlowController> flow_controller_;

  // The connection level flow controller. Not owned.
  QuicFlowController* connection_flow_controller_;

  // Special streams, such as the crypto and headers streams, do not respect
  // connection level flow control limits (but are stream level flow control
  // limited).
  bool stream_contributes_to_connection_flow_control_;

  // A counter incremented when OnCanWrite() is called and no progress is made.
  // For debugging only.
  size_t busy_counter_;

  // Indicates whether paddings will be added after the fin is consumed for this
  // stream.
  bool add_random_padding_after_fin_;

  // Send buffer of this stream. Send buffer is cleaned up when data gets acked
  // or discarded.
  std::unique_ptr<QuicStreamSendBufferBase> send_buffer_;

  // Latched value of quic_buffered_data_threshold.
  const QuicByteCount buffered_data_threshold_;

  // If true, then this stream has precedence over other streams for write
  // scheduling.
  const bool is_static_;

  // If initialized, reset this stream at this deadline.
  QuicTime deadline_;

  // True if this stream has entered draining state.
  bool was_draining_;

  // Indicates whether this stream is bidirectional, read unidirectional or
  // write unidirectional.
  const StreamType type_;

  // Creation time of this stream, as reported by the QuicClock.
  const QuicTime creation_time_;

  // The duration when the data for this stream was stored in a PendingStream
  // before being moved to this QuicStream.
  const QuicTime::Delta pending_duration_;

  // When RESET_STREAM_AT arrives,buffer it for when reliable_size is consumed.
  std::optional<QuicResetStreamAtFrame> buffered_reset_stream_at_;

  Perspective perspective_;

  const bool notify_ack_listener_earlier_ =
      GetQuicReloadableFlag(quic_notify_ack_listener_earlier);

  // If the stream is reset, outgoing data up to reliable_size_will be
  // delivered (and acknowledged) before the write side of the stream is closed.
  QuicStreamOffset reliable_size_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_H_
