void ActiveStreamFilterBase::commonContinue() {
  // TODO(mattklein123): Raise an error if this is called during a callback.
  if (!canContinue()) {
    ENVOY_STREAM_LOG(trace, "cannot continue filter chain: filter={}", *this,
                     static_cast<const void*>(this));
    return;
  }

  // Set ScopeTrackerScopeState if there's no existing crash context.
  ScopeTrackedObjectStack encapsulated_object;
  absl::optional<ScopeTrackerScopeState> state;
  if (parent_.dispatcher_.trackedObjectStackIsEmpty()) {
    restoreContextOnContinue(encapsulated_object);
    state.emplace(&encapsulated_object, parent_.dispatcher_);
  }

  ENVOY_STREAM_LOG(trace, "continuing filter chain: filter={}", *this,
                   static_cast<const void*>(this));
  ASSERT(!canIterate(),
         "Attempting to continue iteration while the IterationState is already Continue");
  // If iteration has stopped for all frame types, set iterate_from_current_filter_ to true so the
  // filter iteration starts with the current filter instead of the next one.
  if (stoppedAll()) {
    iterate_from_current_filter_ = true;
  }
  allowIteration();

  // Only resume with do1xxHeaders() if we've actually seen 1xx headers.
  if (has1xxHeaders()) {
    continued_1xx_headers_ = true;
    do1xxHeaders();
    // If the response headers have not yet come in, don't continue on with
    // headers and body. doHeaders expects request headers to exist.
    if (!parent_.filter_manager_callbacks_.responseHeaders()) {
      return;
    }
  }

  // Make sure that we handle the zero byte data frame case. We make no effort to optimize this
  // case in terms of merging it into a header only request/response. This could be done in the
  // future.
  if (!headers_continued_) {
    headers_continued_ = true;
    doHeaders(complete() && !bufferedData() && !hasTrailers());
  }

  doMetadata();

  // It is possible for trailers to be added during doData(). doData() itself handles continuation
  // of trailers for the non-continuation case. Thus, we must keep track of whether we had
  // trailers prior to calling doData(). If we do, then we continue them here, otherwise we rely
  // on doData() to do so.
  const bool had_trailers_before_data = hasTrailers();
  if (bufferedData()) {
    doData(complete() && !had_trailers_before_data);
  }

  if (had_trailers_before_data) {
    doTrailers();
  }

  iterate_from_current_filter_ = false;
}
void ActiveStreamFilterBase::commonContinue() {
   
  if (!canContinue()) {
    ENVOY_STREAM_LOG(trace, "cannot continue filter chain: filter={}", *this,
                     static_cast<const void*>(this));
    return;
  }

   
  ScopeTrackedObjectStack encapsulated_object;
  absl::optional<ScopeTrackerScopeState> state;
  if (parent_.dispatcher_.trackedObjectStackIsEmpty()) {
    restoreContextOnContinue(encapsulated_object);
    state.emplace(&encapsulated_object, parent_.dispatcher_);
  }

  ENVOY_STREAM_LOG(trace, "continuing filter chain: filter={}", *this,
                   static_cast<const void*>(this));
  ASSERT(!canIterate(),
         "Attempting to continue iteration while the IterationState is already Continue");
   
   
  if (stoppedAll()) {
    iterate_from_current_filter_ = true;
  }
  allowIteration();

   
  if (has1xxHeaders()) {
    continued_1xx_headers_ = true;
    do1xxHeaders();
     
     
    if (!parent_.filter_manager_callbacks_.responseHeaders()) {
      return;
    }
  }

   
   
   
  if (!headers_continued_) {
    headers_continued_ = true;
    doHeaders(complete() && !bufferedData() && !hasTrailers());
  }

  doMetadata();

   
   
   
   
  const bool had_trailers_before_data = hasTrailers();
  if (bufferedData()) {
    doData(complete() && !had_trailers_before_data);
  }

  if (had_trailers_before_data) {
    doTrailers();
  }

  iterate_from_current_filter_ = false;
}