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

#ifndef LIB_FIDL_WALKER_H_
#define LIB_FIDL_WALKER_H_

#include <lib/fidl/coding.h>
#include <lib/fidl/internal.h>
#include <lib/fidl/visitor.h>
#include <stdalign.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>

#include <cstdint>
#include <cstdlib>
#include <limits>
#include <type_traits>

namespace fidl {

namespace internal {

// The MSB is an ownership bit in the count field of vectors.
constexpr uint64_t kVectorOwnershipMask = uint64_t(1) << 63;
// The LSB is an ownership bit in tracking_ptr of non-array type.
constexpr uint64_t kNonArrayTrackingPtrOwnershipMask = uint64_t(1) << 0;

// Some assumptions about data type layout.
static_assert(offsetof(fidl_string_t, size) == 0u, "fidl_string_t layout");
static_assert(offsetof(fidl_string_t, data) == 8u, "fidl_string_t layout");
static_assert(sizeof(fidl_string_t) == 16u, "fidl_string_t layout");

static_assert(offsetof(fidl_vector_t, count) == 0u, "fidl_vector_t layout");
static_assert(offsetof(fidl_vector_t, data) == 8u, "fidl_vector_t layout");
static_assert(sizeof(fidl_vector_t) == 16u, "fidl_vector_t layout");

static_assert(offsetof(fidl_envelope_t, num_bytes) == 0u, "fidl_envelope_t layout");
static_assert(offsetof(fidl_envelope_t, num_handles) == 4u, "fidl_envelope_t layout");
static_assert(offsetof(fidl_envelope_t, data) == 8u, "fidl_envelope_t layout");
static_assert(sizeof(fidl_envelope_t) == 16u, "fidl_envelope_t layout");

static_assert(ZX_HANDLE_INVALID == FIDL_HANDLE_ABSENT, "invalid handle equals absence marker");

constexpr uint32_t PrimitiveSize(const FidlCodedPrimitive primitive) {
  switch (primitive) {
    case kFidlCodedPrimitive_Bool:
    case kFidlCodedPrimitive_Int8:
    case kFidlCodedPrimitive_Uint8:
      return 1;
    case kFidlCodedPrimitive_Int16:
    case kFidlCodedPrimitive_Uint16:
      return 2;
    case kFidlCodedPrimitive_Int32:
    case kFidlCodedPrimitive_Uint32:
    case kFidlCodedPrimitive_Float32:
      return 4;
    case kFidlCodedPrimitive_Int64:
    case kFidlCodedPrimitive_Uint64:
    case kFidlCodedPrimitive_Float64:
      return 8;
  }
  __builtin_unreachable();
}

constexpr uint32_t TypeSize(const fidl_type_t* type) {
  switch (type->type_tag) {
    case kFidlTypePrimitive:
      return PrimitiveSize(type->coded_primitive);
    case kFidlTypeEnum:
      return PrimitiveSize(type->coded_enum.underlying_type);
    case kFidlTypeBits:
      return PrimitiveSize(type->coded_bits.underlying_type);
    case kFidlTypeStructPointer:
    case kFidlTypeUnionPointer:
      return sizeof(uint64_t);
    case kFidlTypeHandle:
      return sizeof(zx_handle_t);
    case kFidlTypeStruct:
      return type->coded_struct.size;
    case kFidlTypeTable:
      return sizeof(fidl_vector_t);
    case kFidlTypeUnion:
      return type->coded_union.size;
    case kFidlTypeXUnion:
      return sizeof(fidl_xunion_t);
    case kFidlTypeString:
      return sizeof(fidl_string_t);
    case kFidlTypeArray:
      return type->coded_array.array_size;
    case kFidlTypeVector:
      return sizeof(fidl_vector_t);
  }
  __builtin_unreachable();
}

constexpr bool IsPrimitive(const fidl_type_t* type) {
  switch (type->type_tag) {
    case kFidlTypePrimitive:
      return true;
    default:
      return false;
  }
}

// The Walker class traverses through a FIDL message by following its coding table and
// calling the visitor implementation. VisitorImpl must be a concrete implementation of the
// fidl::Visitor interface. The concrete type is used to eliminate dynamic dispatch.
template <typename VisitorImpl>
class Walker final {
 private:
  using MutationTrait = typename VisitorImpl::MutationTrait;

  using StartingPoint = typename VisitorImpl::StartingPoint;

  using Position = typename VisitorImpl::Position;

  using VisitorSuper = Visitor<MutationTrait, StartingPoint, Position>;

  using Status = typename VisitorSuper::Status;

  static_assert(CheckVisitorInterface<VisitorSuper, VisitorImpl>(), "");

 public:
  Walker(const fidl_type_t* type, StartingPoint start) : type_(type), start_(start) {}

  // Walk the object/buffer located at |start_|.
  void Walk(VisitorImpl& visitor);

 private:
  // Optionally uses non-const pointers depending on if the visitor
  // is declared as mutating or not.
  template <typename T>
  using Ptr = typename VisitorImpl::template Ptr<T>;

  // Wrapper around Position::Get with friendlier syntax.
  template <typename T>
  Ptr<T> PtrTo(Position position) {
    return position.template Get<T>(start_);
  }

  // Functions that manipulate the coding stack frames.
  struct Frame {
    Frame(const fidl_type_t* fidl_type, Position position) : position(position) {
      switch (fidl_type->type_tag) {
        case kFidlTypeEnum:
          state = kStateEnum;
          enum_state.underlying_type = fidl_type->coded_enum.underlying_type;
          enum_state.validate = fidl_type->coded_enum.validate;
          break;
        case kFidlTypeBits:
          state = kStateBits;
          bits_state.underlying_type = fidl_type->coded_bits.underlying_type;
          bits_state.mask = fidl_type->coded_bits.mask;
          break;
        case kFidlTypeStruct:
          state = kStateStruct;
          struct_state.fields = fidl_type->coded_struct.fields;
          struct_state.field_count = fidl_type->coded_struct.field_count;
          struct_state.field = 0;
          struct_state.struct_size = fidl_type->coded_struct.size;
          break;
        case kFidlTypeStructPointer:
          state = kStateStructPointer;
          struct_pointer_state.struct_type = fidl_type->coded_struct_pointer.struct_type;
          break;
        case kFidlTypeTable:
          state = kStateTable;
          table_state.field = fidl_type->coded_table.fields;
          table_state.remaining_fields = fidl_type->coded_table.field_count;
          table_state.present_count = 0;
          table_state.ordinal = 0;
          break;
        case kFidlTypeUnion:
          state = kStateUnion;
          union_state.fields = fidl_type->coded_union.fields;
          union_state.field_count = fidl_type->coded_union.field_count;
          union_state.data_offset = fidl_type->coded_union.data_offset;
          union_state.union_size = fidl_type->coded_union.size;
          break;
        case kFidlTypeUnionPointer:
          state = kStateUnionPointer;
          union_pointer_state.union_type = fidl_type->coded_union_pointer.union_type;
          break;
        case kFidlTypeXUnion:
          state = kStateXUnion;
          xunion_state.fields = fidl_type->coded_xunion.fields;
          xunion_state.field_count = fidl_type->coded_xunion.field_count;
          xunion_state.inside_envelope = false;
          xunion_state.nullable = fidl_type->coded_xunion.nullable;
          xunion_state.strictness = fidl_type->coded_xunion.strictness;
          break;
        case kFidlTypeArray:
          state = kStateArray;
          array_state.element = fidl_type->coded_array.element;
          array_state.array_size = fidl_type->coded_array.array_size;
          array_state.element_size = fidl_type->coded_array.element_size;
          array_state.element_offset = 0;
          break;
        case kFidlTypeString:
          state = kStateString;
          string_state.max_size = fidl_type->coded_string.max_size;
          string_state.nullable = fidl_type->coded_string.nullable;
          break;
        case kFidlTypeHandle:
          state = kStateHandle;
          handle_state.handle_rights = fidl_type->coded_handle.handle_rights;
          handle_state.handle_subtype = fidl_type->coded_handle.handle_subtype;
          handle_state.nullable = fidl_type->coded_handle.nullable;
          break;
        case kFidlTypeVector:
          state = kStateVector;
          vector_state.element = fidl_type->coded_vector.element;
          vector_state.max_count = fidl_type->coded_vector.max_count;
          vector_state.element_size = fidl_type->coded_vector.element_size;
          vector_state.nullable = fidl_type->coded_vector.nullable;
          break;
        case kFidlTypePrimitive:
          state = kStatePrimitive;
          break;
      }
    }

    Frame(const FidlCodedStruct* coded_struct, Position position) : position(position) {
      state = kStateStruct;
      struct_state.fields = coded_struct->fields;
      struct_state.field_count = coded_struct->field_count;
      struct_state.field = 0;
      struct_state.struct_size = coded_struct->size;
    }

    Frame(const FidlCodedTable* coded_table, Position position) : position(position) {
      state = kStateStruct;
      table_state.field = coded_table->fields;
      table_state.remaining_fields = coded_table->field_count;
      table_state.present_count = 0;
      table_state.ordinal = 0;
    }

    Frame(const FidlCodedUnion* coded_union, Position position) : position(position) {
      state = kStateUnion;
      union_state.fields = coded_union->fields;
      union_state.field_count = coded_union->field_count;
      union_state.data_offset = coded_union->data_offset;
      union_state.union_size = coded_union->size;
    }

    Frame(const FidlCodedXUnion* coded_xunion, Position position)
        : state(kStateXUnion), position(position) {
      // This initialization is done in the ctor body instead of in an
      // initialization list since we need to set fields in unions, which
      // is much more involved in a ctor initialization list.
      xunion_state.fields = coded_xunion->fields;
      xunion_state.field_count = coded_xunion->field_count;
      xunion_state.inside_envelope = false;
      xunion_state.nullable = coded_xunion->nullable;
      xunion_state.strictness = coded_xunion->strictness;
    }

    Frame(const fidl_type_t* element, uint32_t array_size, uint32_t element_size, Position position)
        : position(position) {
      state = kStateArray;
      array_state.element = element;
      array_state.array_size = array_size;
      array_state.element_size = element_size;
      array_state.element_offset = 0;
    }

    // The default constructor does nothing when initializing the stack of frames.
    Frame() = default;

    static Frame DoneSentinel() {
      Frame frame;
      frame.state = kStateDone;
      return frame;
    }

    uint32_t NextStructField() {
      ZX_DEBUG_ASSERT(state == kStateStruct);

      uint32_t current = struct_state.field;
      struct_state.field++;
      return current;
    }

    uint32_t NextArrayOffset() {
      ZX_DEBUG_ASSERT(state == kStateArray);

      uint32_t current = array_state.element_offset;
      array_state.element_offset += array_state.element_size;
      return current;
    }

    enum : int {
      kStateEnum,
      kStateBits,
      kStateStruct,
      kStateStructPointer,
      kStateTable,
      kStateUnion,
      kStateUnionPointer,
      kStateXUnion,
      kStateArray,
      kStateString,
      kStateHandle,
      kStateVector,
      kStatePrimitive,

      kStateDone,
    } state;

    // Position into the message.
    Position position;

    // This is a subset of the information recorded in the
    // fidl_type structures needed for coding state. For
    // example, struct sizes do not need to be present here.
    union {
      struct {
        FidlCodedPrimitive underlying_type;
        EnumValidationPredicate validate;
      } enum_state;
      struct {
        FidlCodedPrimitive underlying_type;
        uint64_t mask;
      } bits_state;
      struct {
        const FidlStructField* fields;
        uint32_t field_count;
        // Index of the currently processing field.
        uint32_t field;
        // Size of the entire struct.
        uint32_t struct_size;
      } struct_state;
      struct {
        const FidlCodedStruct* struct_type;
      } struct_pointer_state;
      struct {
        // Sparse (but monotonically increasing) coding table array for fields;
        // advance the |field| pointer on every matched ordinal to save space
        const FidlTableField* field;
        // Number of unseen fields in the coding table
        uint32_t remaining_fields;
        // How many fields are stored in the message
        uint32_t present_count;
        // Current ordinal (valid ordinals start at 1)
        uint32_t ordinal;
        // When true, the walker is currently working within an envelope, or equivalently,
        // |EnterEnvelope| was successful.
        bool inside_envelope;
      } table_state;
      struct {
        // Array of coding table corresponding to each union variant.
        // The union tag counts upwards from 0 without breaks; hence it can be used to
        // index into the |fields| array.
        const FidlUnionField* fields;
        // Size of the |fields| array. Equal to the number of tags.
        uint32_t field_count;
        // Offset of the payload in the wire format (size of tag + padding).
        uint32_t data_offset;
        // Size of the entire union.
        uint32_t union_size;
      } union_state;
      struct {
        const FidlCodedUnion* union_type;
      } union_pointer_state;
      struct {
        const FidlXUnionField* fields;
        // Number of known ordinals declared in the coding table
        uint32_t field_count;
        // When true, the walker is currently working within an envelope, or equivalently,
        // |EnterEnvelope| was successful.
        bool inside_envelope;
        FidlNullability nullable;
        FidlStrictness strictness;
      } xunion_state;
      struct {
        const fidl_type_t* element;
        // Size of the entire array in bytes
        uint32_t array_size;
        // Size of a single element in bytes
        uint32_t element_size;
        // Byte offset of the current element being processed
        uint32_t element_offset;
      } array_state;
      struct {
        uint32_t max_size;
        bool nullable;
      } string_state;
      struct {
        zx_rights_t handle_rights;
        zx_obj_type_t handle_subtype;
        bool nullable;
      } handle_state;
      struct {
        const fidl_type_t* element;
        // Upperbound on number of elements.
        uint32_t max_count;
        // Size of a single element in bytes
        uint32_t element_size;
        bool nullable;
      } vector_state;
    };
  };

  // Returns true on success and false on recursion overflow.
  bool Push(Frame frame) {
    if (depth_ == FIDL_RECURSION_DEPTH) {
      return false;
    }
    coding_frames_[depth_] = frame;
    ++depth_;
    return true;
  }

  void Pop() {
    ZX_DEBUG_ASSERT(depth_ != 0u);
    --depth_;
  }

  Frame* Peek() {
    ZX_DEBUG_ASSERT(depth_ != 0u);
    return &coding_frames_[depth_ - 1];
  }

  const fidl_type_t* const type_;
  const StartingPoint start_;

  // Decoding stack state.
  uint32_t depth_ = 0u;
  Frame coding_frames_[FIDL_RECURSION_DEPTH];
};

template <typename VisitorImpl>
void Walker<VisitorImpl>::Walk(VisitorImpl& visitor) {
  Push(Frame::DoneSentinel());
  Push(Frame(type_, start_.ToPosition()));

// Macro to insert the relevant goop required to support two control flows here in case of error:
// one where we keep reading after error, and another where we return immediately.
#define FIDL_STATUS_GUARD_IMPL(status, pop)                 \
  switch ((status)) {                                       \
    case Status::kSuccess:                                  \
      break;                                                \
    case Status::kConstraintViolationError:                 \
      if (VisitorImpl::kContinueAfterConstraintViolation) { \
        if ((pop)) {                                        \
          Pop();                                            \
        }                                                   \
        continue;                                           \
      } else {                                              \
        return;                                             \
      }                                                     \
    case Status::kMemoryError:                              \
      return;                                               \
  }

#define FIDL_STATUS_GUARD(status) FIDL_STATUS_GUARD_IMPL(status, true)
#define FIDL_STATUS_GUARD_NO_POP(status) FIDL_STATUS_GUARD_IMPL(status, false)

  for (;;) {
    Frame* frame = Peek();

    switch (frame->state) {
      case Frame::kStateEnum: {
        uint64_t value;
        switch (frame->enum_state.underlying_type) {
          case kFidlCodedPrimitive_Uint8:
            value = *PtrTo<uint8_t>(frame->position);
            break;
          case kFidlCodedPrimitive_Uint16:
            value = *PtrTo<uint16_t>(frame->position);
            break;
          case kFidlCodedPrimitive_Uint32:
            value = *PtrTo<uint32_t>(frame->position);
            break;
          case kFidlCodedPrimitive_Uint64:
            value = *PtrTo<uint64_t>(frame->position);
            break;
          case kFidlCodedPrimitive_Int8:
            value = static_cast<uint64_t>(*PtrTo<int8_t>(frame->position));
            break;
          case kFidlCodedPrimitive_Int16:
            value = static_cast<uint64_t>(*PtrTo<int16_t>(frame->position));
            break;
          case kFidlCodedPrimitive_Int32:
            value = static_cast<uint64_t>(*PtrTo<int32_t>(frame->position));
            break;
          case kFidlCodedPrimitive_Int64:
            value = static_cast<uint64_t>(*PtrTo<int64_t>(frame->position));
            break;
          default:
            __builtin_unreachable();
        }
        if (!frame->enum_state.validate(value)) {
          // TODO(FIDL-523): Make this strictness dependent.
          visitor.OnError("not a valid enum member");
          FIDL_STATUS_GUARD(Status::kConstraintViolationError);
        }
        Pop();
        continue;
      }
      case Frame::kStateBits: {
        uint64_t value;
        switch (frame->bits_state.underlying_type) {
          case kFidlCodedPrimitive_Uint8:
            value = *PtrTo<uint8_t>(frame->position);
            break;
          case kFidlCodedPrimitive_Uint16:
            value = *PtrTo<uint16_t>(frame->position);
            break;
          case kFidlCodedPrimitive_Uint32:
            value = *PtrTo<uint32_t>(frame->position);
            break;
          case kFidlCodedPrimitive_Uint64:
            value = *PtrTo<uint64_t>(frame->position);
            break;
          default:
            __builtin_unreachable();
        }
        if (value & ~frame->bits_state.mask) {
          visitor.OnError("not a valid bits member");
          FIDL_STATUS_GUARD(Status::kConstraintViolationError);
        }
        Pop();
        continue;
      }
      case Frame::kStateStruct: {
        const uint32_t field_index = frame->NextStructField();
        if (field_index == frame->struct_state.field_count) {
          Pop();
          continue;
        }
        const FidlStructField& field = frame->struct_state.fields[field_index];
        const fidl_type_t* field_type = field.type;
        Position field_position = frame->position + field.offset;
        if (field.padding > 0) {
          Position padding_position;
          if (field_type) {
            padding_position = field_position + TypeSize(field_type);
          } else {
            // Current type does not have coding information. |field.offset| stores the
            // offset of the padding.
            padding_position = field_position;
          }
          auto status = visitor.VisitInternalPadding(padding_position, field.padding);
          FIDL_STATUS_GUARD(status);
        }
        if (!field_type) {
          // Skip fields that do not contain codable types.
          // Such fields only serve to provide padding information.
          continue;
        }
        if (!Push(Frame(field_type, field_position))) {
          visitor.OnError("recursion depth exceeded processing struct");
          FIDL_STATUS_GUARD(Status::kConstraintViolationError);
        }
        continue;
      }
      case Frame::kStateStructPointer: {
        if (*PtrTo<Ptr<void>>(frame->position) == nullptr) {
          Pop();
          continue;
        }
        auto status = visitor.VisitPointer(
            frame->position, VisitorImpl::PointeeType::kOther, PtrTo<Ptr<void>>(frame->position),
            frame->struct_pointer_state.struct_type->size, &frame->position);
        FIDL_STATUS_GUARD(status);
        const FidlCodedStruct* coded_struct = frame->struct_pointer_state.struct_type;
        *frame = Frame(coded_struct, frame->position);
        continue;
      }
      case Frame::kStateTable: {
        auto& table_frame = frame->table_state;
        // Utility to locate the position of the Nth-ordinal envelope header
        auto envelope_position = [&frame](uint32_t ordinal) -> Position {
          return frame->position + (ordinal - 1) * static_cast<uint32_t>(sizeof(fidl_envelope_t));
        };
        if (table_frame.ordinal == 0) {
          // Process the vector part of the table
          auto envelope_vector_ptr = PtrTo<fidl_vector_t>(frame->position);
          if (envelope_vector_ptr->data == nullptr) {
            // The vector of envelope headers in a table is always non-nullable.
            if (!VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
              visitor.OnError("Table data cannot be absent");
              FIDL_STATUS_GUARD(Status::kConstraintViolationError);
            }
            if (envelope_vector_ptr->count != 0) {
              visitor.OnError("Table envelope vector data absent but non-zero count");
              FIDL_STATUS_GUARD(Status::kConstraintViolationError);
            }
          }
          uint32_t size;
          if (mul_overflow(envelope_vector_ptr->count, sizeof(fidl_envelope_t), &size)) {
            visitor.OnError("integer overflow calculating table size");
            return;
          }
          auto status = visitor.VisitPointer(frame->position, VisitorImpl::PointeeType::kOther,
                                             &envelope_vector_ptr->data, size, &frame->position);
          FIDL_STATUS_GUARD(status);
          table_frame.ordinal = 1;
          table_frame.present_count = static_cast<uint32_t>(envelope_vector_ptr->count);
          table_frame.inside_envelope = false;
          continue;
        }
        if (table_frame.inside_envelope) {
          // Leave the envelope that was entered during the last iteration
          uint32_t last_ordinal = table_frame.ordinal - 1;
          ZX_DEBUG_ASSERT(last_ordinal >= 1);
          Position envelope_pos = envelope_position(last_ordinal);
          auto envelope_ptr = PtrTo<fidl_envelope_t>(envelope_pos);
          table_frame.inside_envelope = false;
          auto status = visitor.LeaveEnvelope(envelope_pos, envelope_ptr);
          FIDL_STATUS_GUARD(status);
        }
        if (table_frame.ordinal > table_frame.present_count) {
          // Processed last stored field in table. Done with this table.
          Pop();
          continue;
        }
        const FidlTableField* known_field = nullptr;
        if (table_frame.remaining_fields > 0) {
          const FidlTableField* field = table_frame.field;
          if (field->ordinal == table_frame.ordinal) {
            known_field = field;
            table_frame.field++;
            table_frame.remaining_fields--;
          }
        }
        Position envelope_pos = envelope_position(table_frame.ordinal);
        auto envelope_ptr = PtrTo<fidl_envelope_t>(envelope_pos);
        // Process the next ordinal in the following state machine iteration
        table_frame.ordinal++;
        // Make sure we don't process a malformed envelope
        const fidl_type_t* payload_type = known_field ? known_field->type : nullptr;
        auto status = visitor.EnterEnvelope(envelope_pos, envelope_ptr, payload_type);
        FIDL_STATUS_GUARD(status);
        table_frame.inside_envelope = true;
        // Skip empty envelopes
        if (envelope_ptr->data == nullptr) {
          continue;
        }
        uint32_t num_bytes =
            payload_type != nullptr ? TypeSize(payload_type) : envelope_ptr->num_bytes;
        Position position;
        status =
            visitor.VisitPointer(frame->position, VisitorImpl::PointeeType::kOther,
                                 // casting since |envelope_ptr->data| is always void*
                                 &const_cast<Ptr<void>&>(envelope_ptr->data), num_bytes, &position);
        // Do not pop the table frame, to guarantee calling |LeaveEnvelope|
        FIDL_STATUS_GUARD_NO_POP(status);
        if (payload_type != nullptr && !IsPrimitive(payload_type)) {
          if (!Push(Frame(payload_type, position))) {
            visitor.OnError("recursion depth exceeded processing table");
            FIDL_STATUS_GUARD_NO_POP(Status::kConstraintViolationError);
          }
        }
        continue;
      }
      case Frame::kStateUnion: {
        auto union_tag = *PtrTo<fidl_union_tag_t>(frame->position);
        if (union_tag >= frame->union_state.field_count) {
          visitor.OnError("Bad union discriminant");
          FIDL_STATUS_GUARD(Status::kConstraintViolationError);
        }
        auto variant = frame->union_state.fields[union_tag];
        if (variant.padding > 0) {
          Position padding_position =
              frame->position + (frame->union_state.union_size - variant.padding);
          auto status = visitor.VisitInternalPadding(padding_position, variant.padding);
          FIDL_STATUS_GUARD(status);
        }
        auto data_offset = frame->union_state.data_offset;
        ZX_DEBUG_ASSERT(data_offset == 4 || data_offset == 8);
        if (data_offset == 8) {
          // There is an additional 4 byte of padding after the tag.
          auto status = visitor.VisitInternalPadding(frame->position + 4, 4);
          FIDL_STATUS_GUARD(status);
        }
        const fidl_type_t* member = variant.type;
        if (!member) {
          Pop();
          continue;
        }
        frame->position += data_offset;
        *frame = Frame(member, frame->position);
        continue;
      }
      case Frame::kStateUnionPointer: {
        if (*PtrTo<Ptr<fidl_union_tag_t>>(frame->position) == nullptr) {
          Pop();
          continue;
        }
        auto status = visitor.VisitPointer(
            frame->position, VisitorImpl::PointeeType::kOther, PtrTo<Ptr<void>>(frame->position),
            frame->union_pointer_state.union_type->size, &frame->position);
        FIDL_STATUS_GUARD(status);
        const FidlCodedUnion* coded_union = frame->union_pointer_state.union_type;
        *frame = Frame(coded_union, frame->position);
        continue;
      }
      case Frame::kStateXUnion: {
        auto xunion = PtrTo<fidl_xunion_t>(frame->position);
        const auto envelope_pos = frame->position + offsetof(fidl_xunion_t, envelope);
        auto envelope_ptr = &xunion->envelope;
        // |inside_envelope| is always false when first encountering an xunion.
        if (frame->xunion_state.inside_envelope) {
          // Finished processing the xunion field, and is in clean-up state
          auto status = visitor.LeaveEnvelope(envelope_pos, envelope_ptr);
          FIDL_STATUS_GUARD(status);
          Pop();
          continue;
        }
        // Validate zero-ordinal invariants
        if (xunion->tag == 0) {
          if (envelope_ptr->data != nullptr || envelope_ptr->num_bytes != 0 ||
              envelope_ptr->num_handles != 0) {
            visitor.OnError("xunion with zero as ordinal must be empty");
            FIDL_STATUS_GUARD(Status::kConstraintViolationError);
          }
          if (!frame->xunion_state.nullable) {
            visitor.OnError("non-nullable xunion is absent");
            FIDL_STATUS_GUARD(Status::kConstraintViolationError);
          }
          Pop();
          continue;
        }
        // Find coding table corresponding to the ordinal via linear search
        const FidlXUnionField* known_field = nullptr;
        for (size_t i = 0; i < frame->xunion_state.field_count; i++) {
          const auto field = frame->xunion_state.fields + i;
          if (field->ordinal == xunion->tag) {
            known_field = field;
            break;
          }
        }

        if (!known_field && frame->xunion_state.strictness == kFidlStrictness_Strict) {
          visitor.OnError("strict xunion has unknown ordinal");
          FIDL_STATUS_GUARD(Status::kConstraintViolationError);
        }

        // Make sure we don't process a malformed envelope
        const fidl_type_t* payload_type = known_field ? known_field->type : nullptr;
        auto status = visitor.EnterEnvelope(envelope_pos, envelope_ptr, payload_type);
        FIDL_STATUS_GUARD(status);
        frame->xunion_state.inside_envelope = true;
        // Skip empty envelopes
        if (envelope_ptr->data == nullptr) {
          if (xunion->tag != 0) {
            visitor.OnError("empty xunion must have zero as ordinal");
            FIDL_STATUS_GUARD_NO_POP(Status::kConstraintViolationError);
          }
          continue;
        }
        uint32_t num_bytes =
            payload_type != nullptr ? TypeSize(payload_type) : envelope_ptr->num_bytes;
        Position position;
        status =
            visitor.VisitPointer(frame->position, VisitorImpl::PointeeType::kOther,
                                 &const_cast<Ptr<void>&>(envelope_ptr->data), num_bytes, &position);
        FIDL_STATUS_GUARD_NO_POP(status);
        if (payload_type != nullptr && !IsPrimitive(payload_type)) {
          if (!Push(Frame(payload_type, position))) {
            visitor.OnError("recursion depth exceeded processing xunion");
            FIDL_STATUS_GUARD_NO_POP(Status::kConstraintViolationError);
          }
        }
        continue;
      }
      case Frame::kStateArray: {
        const uint32_t element_offset = frame->NextArrayOffset();
        if (element_offset == frame->array_state.array_size) {
          Pop();
          continue;
        }
        const fidl_type_t* element_type = frame->array_state.element;
        if (element_type) {
          Position position = frame->position + element_offset;
          if (!Push(Frame(element_type, position))) {
            visitor.OnError("recursion depth exceeded processing array");
            FIDL_STATUS_GUARD(Status::kConstraintViolationError);
          }
        } else {
          // If there is no element type pointer, the array contents
          // do not need extra processing, but the array coding table
          // is present to provide size information when linearizing
          // envelopes. Just continue.
          Pop();
        }
        continue;
      }
      case Frame::kStateString: {
        auto string_ptr = PtrTo<fidl_string_t>(frame->position);
        // The MSB of the size is reserved for an ownership bit used by fidl::StringView.
        // fidl::StringView's count() would be ideally used in place of the direct bit masking
        // here, but because of build dependencies this is currently not possible.
        const uint64_t size = string_ptr->size & ~kVectorOwnershipMask;
        auto status = visitor.VisitVectorOrStringCount(&string_ptr->size);
        FIDL_STATUS_GUARD(status);
        if (string_ptr->data == nullptr) {
          if (!frame->string_state.nullable &&
              !VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
            visitor.OnError("non-nullable string is absent");
            FIDL_STATUS_GUARD(Status::kConstraintViolationError);
          }
          if (size == 0) {
            if (frame->string_state.nullable ||
                !VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
              Pop();
              continue;
            }
          } else {
            visitor.OnError("string is absent but length is not zero");
            FIDL_STATUS_GUARD(Status::kConstraintViolationError);
          }
        }
        uint64_t bound = frame->string_state.max_size;
        if (size > std::numeric_limits<uint32_t>::max()) {
          visitor.OnError("string size overflows 32 bits");
          FIDL_STATUS_GUARD(Status::kMemoryError);
        }
        if (size > bound) {
          visitor.OnError("message tried to access too large of a bounded string");
          FIDL_STATUS_GUARD(Status::kConstraintViolationError);
        }
        Position position;
        status = visitor.VisitPointer(
            position, VisitorImpl::PointeeType::kVectorOrString,
            &reinterpret_cast<Ptr<void>&>(const_cast<Ptr<char>&>(string_ptr->data)),
            static_cast<uint32_t>(size), &position);
        FIDL_STATUS_GUARD(status);
        Pop();
        continue;
      }
      case Frame::kStateHandle: {
        auto handle_ptr = PtrTo<zx_handle_t>(frame->position);
        if (*handle_ptr == ZX_HANDLE_INVALID) {
          if (!frame->handle_state.nullable) {
            visitor.OnError("message is missing a non-nullable handle");
            FIDL_STATUS_GUARD(Status::kConstraintViolationError);
          }
          Pop();
          continue;
        }
        auto status =
            visitor.VisitHandle(frame->position, handle_ptr, frame->handle_state.handle_rights,
                                frame->handle_state.handle_subtype);
        FIDL_STATUS_GUARD(status);
        Pop();
        continue;
      }
      case Frame::kStateVector: {
        auto vector_ptr = PtrTo<fidl_vector_t>(frame->position);
        // The MSB of the count is reserved for an ownership bit used by fidl::VectorView.
        // fidl::VectorView's count() would be ideally used in place of the direct bit masking
        // here, but because of build dependencies this is currently not possible.
        const uint64_t count = vector_ptr->count & ~kVectorOwnershipMask;
        auto status = visitor.VisitVectorOrStringCount(&vector_ptr->count);
        FIDL_STATUS_GUARD(status);
        if (vector_ptr->data == nullptr) {
          if (!frame->vector_state.nullable &&
              !VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
            visitor.OnError("non-nullable vector is absent");
            FIDL_STATUS_GUARD(Status::kConstraintViolationError);
          }
          if (count == 0) {
            if (frame->vector_state.nullable ||
                !VisitorImpl::kAllowNonNullableCollectionsToBeAbsent) {
              Pop();
              continue;
            }
          } else {
            visitor.OnError("absent vector of non-zero elements");
            FIDL_STATUS_GUARD(Status::kConstraintViolationError);
          }
        }
        if (count > frame->vector_state.max_count) {
          visitor.OnError("message tried to access too large of a bounded vector");
          FIDL_STATUS_GUARD(Status::kConstraintViolationError);
        }
        uint32_t size;
        if (mul_overflow(count, frame->vector_state.element_size, &size)) {
          visitor.OnError("integer overflow calculating vector size");
          return;
        }
        status = visitor.VisitPointer(frame->position, VisitorImpl::PointeeType::kVectorOrString,
                                      &vector_ptr->data, size, &frame->position);
        FIDL_STATUS_GUARD(status);
        if (frame->vector_state.element) {
          // Continue by visiting the vector elements as an array.
          *frame = Frame(frame->vector_state.element, size, frame->vector_state.element_size,
                         frame->position);
        } else {
          // If there is no element type pointer, there is
          // nothing to process in the vector secondary
          // payload. So just continue.
          Pop();
        }
        continue;
      }
      case Frame::kStatePrimitive: {
        // Nothing to do for primitives.
        Pop();
        continue;
      }
      case Frame::kStateDone: {
        return;
      }
    }
  }
}

}  // namespace internal

// Walks the FIDL message, calling hooks in the concrete VisitorImpl.
//
// |visitor|        is an implementation of the fidl::Visitor interface.
// |type|           is the coding table for the FIDL type. It cannot be null.
// |start|          is the starting point for the walk.
template <typename VisitorImpl>
void Walk(VisitorImpl& visitor, const fidl_type_t* type,
          typename VisitorImpl::StartingPoint start) {
  internal::Walker<VisitorImpl> walker(type, start);
  walker.Walk(visitor);
}

// Infer the size of the primary object, from the coding table in |type|.
// Ensures that the primary object is of one of the expected types.
//
// An error is returned if:
// - |type| is null
// - The primary object is neither a struct nor a table.
zx_status_t PrimaryObjectSize(const fidl_type_t* type, size_t* out_size, const char** out_error);

// Calculate the offset of the first out-of-line object, from the coding table in |type|.
// Ensures that the primary object is of one of the expected types, and the offset falls within the
// |buffer_size| constraints.
//
// An error is returned if:
// - |type| is null
// - The primary object is neither a struct nor a table.
// - The offset overflows, or is larger than |buffer_size|.
zx_status_t StartingOutOfLineOffset(const fidl_type_t* type, uint32_t buffer_size,
                                    uint32_t* out_first_out_of_line, const char** out_error);

}  // namespace fidl

#endif  // LIB_FIDL_WALKER_H_
