/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <grpc/support/port_platform.h>

#include "src/core/ext/transport/chttp2/transport/internal.h"

#include <string.h>

#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>

#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/http2_errors.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/status_conversion.h"
#include "src/core/lib/transport/timeout_encoding.h"

static grpc_error* init_frame_parser(grpc_chttp2_transport* t);
static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t,
                                            int is_continuation);
static grpc_error* init_data_frame_parser(grpc_chttp2_transport* t);
static grpc_error* init_rst_stream_parser(grpc_chttp2_transport* t);
static grpc_error* init_settings_frame_parser(grpc_chttp2_transport* t);
static grpc_error* init_window_update_frame_parser(grpc_chttp2_transport* t);
static grpc_error* init_ping_parser(grpc_chttp2_transport* t);
static grpc_error* init_goaway_parser(grpc_chttp2_transport* t);
static grpc_error* init_skip_frame_parser(grpc_chttp2_transport* t,
                                          int is_header);

static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice,
                                     int is_last);

grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t,
                                     grpc_slice slice) {
  uint8_t* beg = GRPC_SLICE_START_PTR(slice);
  uint8_t* end = GRPC_SLICE_END_PTR(slice);
  uint8_t* cur = beg;
  grpc_error* err;

  if (cur == end) return GRPC_ERROR_NONE;

  switch (t->deframe_state) {
    case GRPC_DTS_CLIENT_PREFIX_0:
    case GRPC_DTS_CLIENT_PREFIX_1:
    case GRPC_DTS_CLIENT_PREFIX_2:
    case GRPC_DTS_CLIENT_PREFIX_3:
    case GRPC_DTS_CLIENT_PREFIX_4:
    case GRPC_DTS_CLIENT_PREFIX_5:
    case GRPC_DTS_CLIENT_PREFIX_6:
    case GRPC_DTS_CLIENT_PREFIX_7:
    case GRPC_DTS_CLIENT_PREFIX_8:
    case GRPC_DTS_CLIENT_PREFIX_9:
    case GRPC_DTS_CLIENT_PREFIX_10:
    case GRPC_DTS_CLIENT_PREFIX_11:
    case GRPC_DTS_CLIENT_PREFIX_12:
    case GRPC_DTS_CLIENT_PREFIX_13:
    case GRPC_DTS_CLIENT_PREFIX_14:
    case GRPC_DTS_CLIENT_PREFIX_15:
    case GRPC_DTS_CLIENT_PREFIX_16:
    case GRPC_DTS_CLIENT_PREFIX_17:
    case GRPC_DTS_CLIENT_PREFIX_18:
    case GRPC_DTS_CLIENT_PREFIX_19:
    case GRPC_DTS_CLIENT_PREFIX_20:
    case GRPC_DTS_CLIENT_PREFIX_21:
    case GRPC_DTS_CLIENT_PREFIX_22:
    case GRPC_DTS_CLIENT_PREFIX_23:
      while (cur != end && t->deframe_state != GRPC_DTS_FH_0) {
        if (*cur != GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state]) {
          char* msg;
          gpr_asprintf(
              &msg,
              "Connect string mismatch: expected '%c' (%d) got '%c' (%d) "
              "at byte %d",
              GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state],
              static_cast<int>(static_cast<uint8_t>(
                  GRPC_CHTTP2_CLIENT_CONNECT_STRING[t->deframe_state])),
              *cur, static_cast<int>(*cur), t->deframe_state);
          err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
          gpr_free(msg);
          return err;
        }
        ++cur;
        t->deframe_state = static_cast<grpc_chttp2_deframe_transport_state>(
            1 + static_cast<int>(t->deframe_state));
      }
      if (cur == end) {
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    dts_fh_0:
    case GRPC_DTS_FH_0:
      GPR_ASSERT(cur < end);
      t->incoming_frame_size = (static_cast<uint32_t>(*cur)) << 16;
      if (++cur == end) {
        t->deframe_state = GRPC_DTS_FH_1;
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    case GRPC_DTS_FH_1:
      GPR_ASSERT(cur < end);
      t->incoming_frame_size |= (static_cast<uint32_t>(*cur)) << 8;
      if (++cur == end) {
        t->deframe_state = GRPC_DTS_FH_2;
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    case GRPC_DTS_FH_2:
      GPR_ASSERT(cur < end);
      t->incoming_frame_size |= *cur;
      if (++cur == end) {
        t->deframe_state = GRPC_DTS_FH_3;
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    case GRPC_DTS_FH_3:
      GPR_ASSERT(cur < end);
      t->incoming_frame_type = *cur;
      if (++cur == end) {
        t->deframe_state = GRPC_DTS_FH_4;
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    case GRPC_DTS_FH_4:
      GPR_ASSERT(cur < end);
      t->incoming_frame_flags = *cur;
      if (++cur == end) {
        t->deframe_state = GRPC_DTS_FH_5;
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    case GRPC_DTS_FH_5:
      GPR_ASSERT(cur < end);
      t->incoming_stream_id = ((static_cast<uint32_t>(*cur)) & 0x7f) << 24;
      if (++cur == end) {
        t->deframe_state = GRPC_DTS_FH_6;
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    case GRPC_DTS_FH_6:
      GPR_ASSERT(cur < end);
      t->incoming_stream_id |= (static_cast<uint32_t>(*cur)) << 16;
      if (++cur == end) {
        t->deframe_state = GRPC_DTS_FH_7;
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    case GRPC_DTS_FH_7:
      GPR_ASSERT(cur < end);
      t->incoming_stream_id |= (static_cast<uint32_t>(*cur)) << 8;
      if (++cur == end) {
        t->deframe_state = GRPC_DTS_FH_8;
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    case GRPC_DTS_FH_8:
      GPR_ASSERT(cur < end);
      t->incoming_stream_id |= (static_cast<uint32_t>(*cur));
      t->deframe_state = GRPC_DTS_FRAME;
      err = init_frame_parser(t);
      if (err != GRPC_ERROR_NONE) {
        return err;
      }
      if (t->incoming_frame_size == 0) {
        err = parse_frame_slice(t, grpc_empty_slice(), 1);
        if (err != GRPC_ERROR_NONE) {
          return err;
        }
        t->incoming_stream = nullptr;
        if (++cur == end) {
          t->deframe_state = GRPC_DTS_FH_0;
          return GRPC_ERROR_NONE;
        }
        goto dts_fh_0; /* loop */
      } else if (t->flow_control->flow_control_enabled() &&
                 t->incoming_frame_size >
                     t->settings[GRPC_ACKED_SETTINGS]
                                [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]) {
        char* msg;
        gpr_asprintf(&msg, "Frame size %d is larger than max frame size %d",
                     t->incoming_frame_size,
                     t->settings[GRPC_ACKED_SETTINGS]
                                [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]);
        err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
        gpr_free(msg);
        return err;
      }
      if (++cur == end) {
        return GRPC_ERROR_NONE;
      }
    /* fallthrough */
    case GRPC_DTS_FRAME:
      GPR_ASSERT(cur < end);
      if (static_cast<uint32_t>(end - cur) == t->incoming_frame_size) {
        err = parse_frame_slice(
            t,
            grpc_slice_sub_no_ref(slice, static_cast<size_t>(cur - beg),
                                  static_cast<size_t>(end - beg)),
            1);
        if (err != GRPC_ERROR_NONE) {
          return err;
        }
        t->deframe_state = GRPC_DTS_FH_0;
        t->incoming_stream = nullptr;
        return GRPC_ERROR_NONE;
      } else if (static_cast<uint32_t>(end - cur) > t->incoming_frame_size) {
        size_t cur_offset = static_cast<size_t>(cur - beg);
        err = parse_frame_slice(
            t,
            grpc_slice_sub_no_ref(slice, cur_offset,
                                  cur_offset + t->incoming_frame_size),
            1);
        if (err != GRPC_ERROR_NONE) {
          return err;
        }
        cur += t->incoming_frame_size;
        t->incoming_stream = nullptr;
        goto dts_fh_0; /* loop */
      } else {
        err = parse_frame_slice(
            t,
            grpc_slice_sub_no_ref(slice, static_cast<size_t>(cur - beg),
                                  static_cast<size_t>(end - beg)),
            0);
        if (err != GRPC_ERROR_NONE) {
          return err;
        }
        t->incoming_frame_size -= static_cast<uint32_t>(end - cur);
        return GRPC_ERROR_NONE;
      }
      GPR_UNREACHABLE_CODE(return nullptr);
  }

  GPR_UNREACHABLE_CODE(return nullptr);
}

static grpc_error* init_frame_parser(grpc_chttp2_transport* t) {
  if (t->is_first_frame &&
      t->incoming_frame_type != GRPC_CHTTP2_FRAME_SETTINGS) {
    char* msg;
    gpr_asprintf(
        &msg, "Expected SETTINGS frame as the first frame, got frame type %d",
        t->incoming_frame_type);
    grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
    gpr_free(msg);
    return err;
  }
  t->is_first_frame = false;
  if (t->expect_continuation_stream_id != 0) {
    if (t->incoming_frame_type != GRPC_CHTTP2_FRAME_CONTINUATION) {
      char* msg;
      gpr_asprintf(&msg, "Expected CONTINUATION frame, got frame type %02x",
                   t->incoming_frame_type);
      grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
      gpr_free(msg);
      return err;
    }
    if (t->expect_continuation_stream_id != t->incoming_stream_id) {
      char* msg;
      gpr_asprintf(
          &msg,
          "Expected CONTINUATION frame for grpc_chttp2_stream %08x, got "
          "grpc_chttp2_stream %08x",
          t->expect_continuation_stream_id, t->incoming_stream_id);
      grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
      gpr_free(msg);
      return err;
    }
    return init_header_frame_parser(t, 1);
  }
  switch (t->incoming_frame_type) {
    case GRPC_CHTTP2_FRAME_DATA:
      return init_data_frame_parser(t);
    case GRPC_CHTTP2_FRAME_HEADER:
      return init_header_frame_parser(t, 0);
    case GRPC_CHTTP2_FRAME_CONTINUATION:
      return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
          "Unexpected CONTINUATION frame");
    case GRPC_CHTTP2_FRAME_RST_STREAM:
      return init_rst_stream_parser(t);
    case GRPC_CHTTP2_FRAME_SETTINGS:
      return init_settings_frame_parser(t);
    case GRPC_CHTTP2_FRAME_WINDOW_UPDATE:
      return init_window_update_frame_parser(t);
    case GRPC_CHTTP2_FRAME_PING:
      return init_ping_parser(t);
    case GRPC_CHTTP2_FRAME_GOAWAY:
      return init_goaway_parser(t);
    default:
      if (grpc_http_trace.enabled()) {
        gpr_log(GPR_ERROR, "Unknown frame type %02x", t->incoming_frame_type);
      }
      return init_skip_frame_parser(t, 0);
  }
}

static grpc_error* skip_parser(void* parser, grpc_chttp2_transport* t,
                               grpc_chttp2_stream* s, grpc_slice slice,
                               int is_last) {
  return GRPC_ERROR_NONE;
}

static void skip_header(void* tp, grpc_mdelem md) { GRPC_MDELEM_UNREF(md); }

static grpc_error* init_skip_frame_parser(grpc_chttp2_transport* t,
                                          int is_header) {
  if (is_header) {
    uint8_t is_eoh = t->expect_continuation_stream_id != 0;
    t->parser = grpc_chttp2_header_parser_parse;
    t->parser_data = &t->hpack_parser;
    t->hpack_parser.on_header = skip_header;
    t->hpack_parser.on_header_user_data = nullptr;
    t->hpack_parser.is_boundary = is_eoh;
    t->hpack_parser.is_eof = static_cast<uint8_t>(is_eoh ? t->header_eof : 0);
  } else {
    t->parser = skip_parser;
  }
  return GRPC_ERROR_NONE;
}

void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport* t) {
  init_skip_frame_parser(t, t->parser == grpc_chttp2_header_parser_parse);
}

static grpc_error* init_data_frame_parser(grpc_chttp2_transport* t) {
  grpc_chttp2_stream* s =
      grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id);
  grpc_error* err = GRPC_ERROR_NONE;
  grpc_core::chttp2::FlowControlAction action;
  if (s == nullptr) {
    err = t->flow_control->RecvData(t->incoming_frame_size);
    action = t->flow_control->MakeAction();
  } else {
    err = s->flow_control->RecvData(t->incoming_frame_size);
    action = s->flow_control->MakeAction();
  }
  grpc_chttp2_act_on_flowctl_action(action, t, s);
  if (err != GRPC_ERROR_NONE) {
    goto error_handler;
  }
  if (s == nullptr) {
    return init_skip_frame_parser(t, 0);
  }
  s->received_bytes += t->incoming_frame_size;
  s->stats.incoming.framing_bytes += 9;
  if (err == GRPC_ERROR_NONE && s->read_closed) {
    return init_skip_frame_parser(t, 0);
  }
  if (err == GRPC_ERROR_NONE) {
    err = grpc_chttp2_data_parser_begin_frame(
        &s->data_parser, t->incoming_frame_flags, s->id, s);
  }
error_handler:
  intptr_t unused;
  if (err == GRPC_ERROR_NONE) {
    t->incoming_stream = s;
    /* t->parser = grpc_chttp2_data_parser_parse;*/
    t->parser = grpc_chttp2_data_parser_parse;
    t->parser_data = &s->data_parser;
    t->ping_state.last_ping_sent_time = GRPC_MILLIS_INF_PAST;
    return GRPC_ERROR_NONE;
  } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, &unused)) {
    /* handle stream errors by closing the stream */
    if (s != nullptr) {
      grpc_chttp2_mark_stream_closed(t, s, true, false, err);
    }
    grpc_slice_buffer_add(
        &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id,
                                                GRPC_HTTP2_PROTOCOL_ERROR,
                                                &s->stats.outgoing));
    return init_skip_frame_parser(t, 0);
  } else {
    return err;
  }
}

static void free_timeout(void* p) { gpr_free(p); }

static void on_initial_header(void* tp, grpc_mdelem md) {
  GPR_TIMER_SCOPE("on_initial_header", 0);

  grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp);
  grpc_chttp2_stream* s = t->incoming_stream;
  GPR_ASSERT(s != nullptr);

  if (grpc_http_trace.enabled()) {
    char* key = grpc_slice_to_c_string(GRPC_MDKEY(md));
    char* value =
        grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII);
    gpr_log(GPR_INFO, "HTTP:%d:HDR:%s: %s: %s", s->id,
            t->is_client ? "CLI" : "SVR", key, value);
    gpr_free(key);
    gpr_free(value);
  }

  if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
    // We don't use grpc_mdelem_eq here to avoid executing additional
    // instructions. The reasoning is if the payload is not equal, we already
    // know that the metadata elements are not equal because the md is
    // confirmed to be static. If we had used grpc_mdelem_eq here, then if the
    // payloads are not equal, grpc_mdelem_eq executes more instructions to
    // determine if they're equal or not.
    if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload ||
        md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) {
      s->seen_error = true;
    }
  } else {
    if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
        !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
      /* TODO(ctiller): check for a status like " 0" */
      s->seen_error = true;
    }

    if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
      grpc_millis* cached_timeout = static_cast<grpc_millis*>(
          grpc_mdelem_get_user_data(md, free_timeout));
      grpc_millis timeout;
      if (cached_timeout != nullptr) {
        timeout = *cached_timeout;
      } else {
        if (GPR_UNLIKELY(
                !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) {
          char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
          gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
          gpr_free(val);
          timeout = GRPC_MILLIS_INF_FUTURE;
        }
        if (GRPC_MDELEM_IS_INTERNED(md)) {
          /* store the result */
          cached_timeout =
              static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis)));
          *cached_timeout = timeout;
          grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
        }
      }
      if (timeout != GRPC_MILLIS_INF_FUTURE) {
        grpc_chttp2_incoming_metadata_buffer_set_deadline(
            &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout);
      }
      GRPC_MDELEM_UNREF(md);
      return;
    }
  }

  const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
  const size_t metadata_size_limit =
      t->settings[GRPC_ACKED_SETTINGS]
                 [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
  if (new_size > metadata_size_limit) {
    gpr_log(GPR_DEBUG,
            "received initial metadata size exceeds limit (%" PRIuPTR
            " vs. %" PRIuPTR ")",
            new_size, metadata_size_limit);
    grpc_chttp2_cancel_stream(
        t, s,
        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                               "received initial metadata size exceeds limit"),
                           GRPC_ERROR_INT_GRPC_STATUS,
                           GRPC_STATUS_RESOURCE_EXHAUSTED));
    grpc_chttp2_parsing_become_skip_parser(t);
    s->seen_error = true;
    GRPC_MDELEM_UNREF(md);
  } else {
    grpc_error* error =
        grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md);
    if (error != GRPC_ERROR_NONE) {
      grpc_chttp2_cancel_stream(t, s, error);
      grpc_chttp2_parsing_become_skip_parser(t);
      s->seen_error = true;
      GRPC_MDELEM_UNREF(md);
    }
  }
}

static void on_trailing_header(void* tp, grpc_mdelem md) {
  GPR_TIMER_SCOPE("on_trailing_header", 0);

  grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(tp);
  grpc_chttp2_stream* s = t->incoming_stream;
  GPR_ASSERT(s != nullptr);

  if (grpc_http_trace.enabled()) {
    char* key = grpc_slice_to_c_string(GRPC_MDKEY(md));
    char* value =
        grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII);
    gpr_log(GPR_INFO, "HTTP:%d:TRL:%s: %s: %s", s->id,
            t->is_client ? "CLI" : "SVR", key, value);
    gpr_free(key);
    gpr_free(value);
  }

  if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
    // We don't use grpc_mdelem_eq here to avoid executing additional
    // instructions. The reasoning is if the payload is not equal, we already
    // know that the metadata elements are not equal because the md is
    // confirmed to be static. If we had used grpc_mdelem_eq here, then if the
    // payloads are not equal, grpc_mdelem_eq executes more instructions to
    // determine if they're equal or not.
    if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload ||
        md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) {
      s->seen_error = true;
    }
  } else if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
             !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
    /* TODO(ctiller): check for a status like " 0" */
    s->seen_error = true;
  }

  const size_t new_size = s->metadata_buffer[1].size + GRPC_MDELEM_LENGTH(md);
  const size_t metadata_size_limit =
      t->settings[GRPC_ACKED_SETTINGS]
                 [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
  if (new_size > metadata_size_limit) {
    gpr_log(GPR_DEBUG,
            "received trailing metadata size exceeds limit (%" PRIuPTR
            " vs. %" PRIuPTR ")",
            new_size, metadata_size_limit);
    grpc_chttp2_cancel_stream(
        t, s,
        grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                               "received trailing metadata size exceeds limit"),
                           GRPC_ERROR_INT_GRPC_STATUS,
                           GRPC_STATUS_RESOURCE_EXHAUSTED));
    grpc_chttp2_parsing_become_skip_parser(t);
    s->seen_error = true;
    GRPC_MDELEM_UNREF(md);
  } else {
    grpc_error* error =
        grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[1], md);
    if (error != GRPC_ERROR_NONE) {
      grpc_chttp2_cancel_stream(t, s, error);
      grpc_chttp2_parsing_become_skip_parser(t);
      s->seen_error = true;
      GRPC_MDELEM_UNREF(md);
    }
  }
}

static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t,
                                            int is_continuation) {
  uint8_t is_eoh =
      (t->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_HEADERS) != 0;
  grpc_chttp2_stream* s;

  /* TODO(ctiller): when to increment header_frames_received? */

  if (is_eoh) {
    t->expect_continuation_stream_id = 0;
  } else {
    t->expect_continuation_stream_id = t->incoming_stream_id;
  }

  if (!is_continuation) {
    t->header_eof =
        (t->incoming_frame_flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) != 0;
  }

  t->ping_state.last_ping_sent_time = GRPC_MILLIS_INF_PAST;

  /* could be a new grpc_chttp2_stream or an existing grpc_chttp2_stream */
  s = grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id);
  if (s == nullptr) {
    if (GPR_UNLIKELY(is_continuation)) {
      GRPC_CHTTP2_IF_TRACING(
          gpr_log(GPR_ERROR,
                  "grpc_chttp2_stream disbanded before CONTINUATION received"));
      return init_skip_frame_parser(t, 1);
    }
    if (t->is_client) {
      if (GPR_LIKELY((t->incoming_stream_id & 1) &&
                     t->incoming_stream_id < t->next_stream_id)) {
        /* this is an old (probably cancelled) grpc_chttp2_stream */
      } else {
        GRPC_CHTTP2_IF_TRACING(gpr_log(
            GPR_ERROR, "ignoring new grpc_chttp2_stream creation on client"));
      }
      grpc_error* err = init_skip_frame_parser(t, 1);
      if (t->incoming_frame_flags & GRPC_CHTTP2_FLAG_HAS_PRIORITY) {
        grpc_chttp2_hpack_parser_set_has_priority(&t->hpack_parser);
      }
      return err;
    } else if (GPR_UNLIKELY(t->last_new_stream_id >= t->incoming_stream_id)) {
      GRPC_CHTTP2_IF_TRACING(gpr_log(
          GPR_ERROR,
          "ignoring out of order new grpc_chttp2_stream request on server; "
          "last grpc_chttp2_stream "
          "id=%d, new grpc_chttp2_stream id=%d",
          t->last_new_stream_id, t->incoming_stream_id));
      return init_skip_frame_parser(t, 1);
    } else if (GPR_UNLIKELY((t->incoming_stream_id & 1) == 0)) {
      GRPC_CHTTP2_IF_TRACING(gpr_log(
          GPR_ERROR,
          "ignoring grpc_chttp2_stream with non-client generated index %d",
          t->incoming_stream_id));
      return init_skip_frame_parser(t, 1);
    } else if (GPR_UNLIKELY(
                   grpc_chttp2_stream_map_size(&t->stream_map) >=
                   t->settings[GRPC_ACKED_SETTINGS]
                              [GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS])) {
      return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Max stream count exceeded");
    }
    t->last_new_stream_id = t->incoming_stream_id;
    s = t->incoming_stream =
        grpc_chttp2_parsing_accept_stream(t, t->incoming_stream_id);
    if (GPR_UNLIKELY(s == nullptr)) {
      GRPC_CHTTP2_IF_TRACING(
          gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted"));
      return init_skip_frame_parser(t, 1);
    }
    if (t->channelz_socket != nullptr) {
      t->channelz_socket->RecordStreamStartedFromRemote();
    }
  } else {
    t->incoming_stream = s;
  }
  GPR_ASSERT(s != nullptr);
  s->stats.incoming.framing_bytes += 9;
  if (GPR_UNLIKELY(s->read_closed)) {
    GRPC_CHTTP2_IF_TRACING(gpr_log(
        GPR_ERROR, "skipping already closed grpc_chttp2_stream header"));
    t->incoming_stream = nullptr;
    return init_skip_frame_parser(t, 1);
  }
  t->parser = grpc_chttp2_header_parser_parse;
  t->parser_data = &t->hpack_parser;
  if (t->header_eof) {
    s->eos_received = true;
  }
  switch (s->header_frames_received) {
    case 0:
      if (t->is_client && t->header_eof) {
        GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "parsing Trailers-Only"));
        if (s->trailing_metadata_available != nullptr) {
          *s->trailing_metadata_available = true;
        }
        t->hpack_parser.on_header = on_trailing_header;
        s->received_trailing_metadata = true;
      } else {
        GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "parsing initial_metadata"));
        t->hpack_parser.on_header = on_initial_header;
      }
      break;
    case 1:
      GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "parsing trailing_metadata"));
      t->hpack_parser.on_header = on_trailing_header;
      s->received_trailing_metadata = true;
      break;
    case 2:
      gpr_log(GPR_ERROR, "too many header frames received");
      return init_skip_frame_parser(t, 1);
  }
  t->hpack_parser.on_header_user_data = t;
  t->hpack_parser.is_boundary = is_eoh;
  t->hpack_parser.is_eof = static_cast<uint8_t>(is_eoh ? t->header_eof : 0);
  if (!is_continuation &&
      (t->incoming_frame_flags & GRPC_CHTTP2_FLAG_HAS_PRIORITY)) {
    grpc_chttp2_hpack_parser_set_has_priority(&t->hpack_parser);
  }
  return GRPC_ERROR_NONE;
}

static grpc_error* init_window_update_frame_parser(grpc_chttp2_transport* t) {
  grpc_error* err = grpc_chttp2_window_update_parser_begin_frame(
      &t->simple.window_update, t->incoming_frame_size,
      t->incoming_frame_flags);
  if (err != GRPC_ERROR_NONE) return err;
  if (t->incoming_stream_id != 0) {
    grpc_chttp2_stream* s = t->incoming_stream =
        grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id);
    if (s == nullptr) {
      return init_skip_frame_parser(t, 0);
    }
    s->stats.incoming.framing_bytes += 9;
  }
  t->parser = grpc_chttp2_window_update_parser_parse;
  t->parser_data = &t->simple.window_update;
  return GRPC_ERROR_NONE;
}

static grpc_error* init_ping_parser(grpc_chttp2_transport* t) {
  grpc_error* err = grpc_chttp2_ping_parser_begin_frame(
      &t->simple.ping, t->incoming_frame_size, t->incoming_frame_flags);
  if (err != GRPC_ERROR_NONE) return err;
  t->parser = grpc_chttp2_ping_parser_parse;
  t->parser_data = &t->simple.ping;
  return GRPC_ERROR_NONE;
}

static grpc_error* init_rst_stream_parser(grpc_chttp2_transport* t) {
  grpc_error* err = grpc_chttp2_rst_stream_parser_begin_frame(
      &t->simple.rst_stream, t->incoming_frame_size, t->incoming_frame_flags);
  if (err != GRPC_ERROR_NONE) return err;
  grpc_chttp2_stream* s = t->incoming_stream =
      grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id);
  if (!t->incoming_stream) {
    return init_skip_frame_parser(t, 0);
  }
  s->stats.incoming.framing_bytes += 9;
  t->parser = grpc_chttp2_rst_stream_parser_parse;
  t->parser_data = &t->simple.rst_stream;
  return GRPC_ERROR_NONE;
}

static grpc_error* init_goaway_parser(grpc_chttp2_transport* t) {
  grpc_error* err = grpc_chttp2_goaway_parser_begin_frame(
      &t->goaway_parser, t->incoming_frame_size, t->incoming_frame_flags);
  if (err != GRPC_ERROR_NONE) return err;
  t->parser = grpc_chttp2_goaway_parser_parse;
  t->parser_data = &t->goaway_parser;
  return GRPC_ERROR_NONE;
}

static grpc_error* init_settings_frame_parser(grpc_chttp2_transport* t) {
  if (t->incoming_stream_id != 0) {
    return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
        "Settings frame received for grpc_chttp2_stream");
  }

  grpc_error* err = grpc_chttp2_settings_parser_begin_frame(
      &t->simple.settings, t->incoming_frame_size, t->incoming_frame_flags,
      t->settings[GRPC_PEER_SETTINGS]);
  if (err != GRPC_ERROR_NONE) {
    return err;
  }
  if (t->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) {
    memcpy(t->settings[GRPC_ACKED_SETTINGS], t->settings[GRPC_SENT_SETTINGS],
           GRPC_CHTTP2_NUM_SETTINGS * sizeof(uint32_t));
    grpc_chttp2_hptbl_set_max_bytes(
        &t->hpack_parser.table,
        t->settings[GRPC_ACKED_SETTINGS]
                   [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]);
    t->sent_local_settings = 0;
  }
  t->parser = grpc_chttp2_settings_parser_parse;
  t->parser_data = &t->simple.settings;
  return GRPC_ERROR_NONE;
}

static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice,
                                     int is_last) {
  grpc_chttp2_stream* s = t->incoming_stream;
  grpc_error* err = t->parser(t->parser_data, t, s, slice, is_last);
  intptr_t unused;
  if (GPR_LIKELY(err == GRPC_ERROR_NONE)) {
    return err;
  } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, &unused)) {
    if (grpc_http_trace.enabled()) {
      const char* msg = grpc_error_string(err);
      gpr_log(GPR_ERROR, "%s", msg);
    }
    grpc_chttp2_parsing_become_skip_parser(t);
    if (s) {
      s->forced_close_error = err;
      grpc_slice_buffer_add(
          &t->qbuf, grpc_chttp2_rst_stream_create(t->incoming_stream_id,
                                                  GRPC_HTTP2_PROTOCOL_ERROR,
                                                  &s->stats.outgoing));
    } else {
      GRPC_ERROR_UNREF(err);
    }
  }
  return err;
}
