// 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 ZIRCON_SYSTEM_ULIB_FIDL_WALKER_H_
#define ZIRCON_SYSTEM_ULIB_FIDL_WALKER_H_

#include <cstdint>
#include <cstdlib>
#include <limits>
#include <stdalign.h>
#include <type_traits>

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

namespace fidl {

namespace internal {

// 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 TypeSize(const fidl_type_t* type) {
    switch (type->type_tag) {
    case fidl::kFidlTypePrimitive:
        switch (type->coded_primitive) {
        case FidlCodedPrimitive::kBool:
        case FidlCodedPrimitive::kInt8:
        case FidlCodedPrimitive::kUint8:
            return 1;
        case FidlCodedPrimitive::kInt16:
        case FidlCodedPrimitive::kUint16:
            return 2;
        case FidlCodedPrimitive::kInt32:
        case FidlCodedPrimitive::kUint32:
        case FidlCodedPrimitive::kFloat32:
            return 4;
        case FidlCodedPrimitive::kInt64:
        case FidlCodedPrimitive::kUint64:
        case FidlCodedPrimitive::kFloat64:
            return 8;
        }
        __builtin_unreachable();
    case fidl::kFidlTypeStructPointer:
    case fidl::kFidlTypeUnionPointer:
        return sizeof(uint64_t);
    case fidl::kFidlTypeHandle:
        return sizeof(zx_handle_t);
    case fidl::kFidlTypeStruct:
        return type->coded_struct.size;
    case fidl::kFidlTypeTable:
        return sizeof(fidl_vector_t);
    case fidl::kFidlTypeUnion:
        return type->coded_union.size;
    case fidl::kFidlTypeXUnion:
        return sizeof(fidl_xunion_t);
    case fidl::kFidlTypeString:
        return sizeof(fidl_string_t);
    case fidl::kFidlTypeArray:
        return type->coded_array.array_size;
    case fidl::kFidlTypeVector:
        return sizeof(fidl_vector_t);
    }
    __builtin_unreachable();
}

constexpr bool IsPrimitive(const fidl_type_t* type) {
    switch (type->type_tag) {
    case fidl::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 fidl::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;
                break;
            case fidl::kFidlTypeStructPointer:
                state = kStateStructPointer;
                struct_pointer_state.struct_type = fidl_type->coded_struct_pointer.struct_type;
                break;
            case fidl::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 fidl::kFidlTypeUnion:
                state = kStateUnion;
                union_state.types = fidl_type->coded_union.types;
                union_state.type_count = fidl_type->coded_union.type_count;
                union_state.data_offset = fidl_type->coded_union.data_offset;
                break;
            case fidl::kFidlTypeUnionPointer:
                state = kStateUnionPointer;
                union_pointer_state.union_type = fidl_type->coded_union_pointer.union_type;
                break;
            case fidl::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;
                break;
            case fidl::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 fidl::kFidlTypeString:
                state = kStateString;
                string_state.max_size = fidl_type->coded_string.max_size;
                string_state.nullable = fidl_type->coded_string.nullable;
                break;
            case fidl::kFidlTypeHandle:
                state = kStateHandle;
                handle_state.nullable = fidl_type->coded_handle.nullable;
                break;
            case fidl::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 fidl::kFidlTypePrimitive:
                // Walker will never recurse into a primitive. Note: this branch must be
                // implemented should we decide to support table-driven ToString in the future.
                __builtin_unreachable();
            }
        }

        Frame(const fidl::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;
        }

        Frame(const fidl::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 fidl::FidlCodedUnion* coded_union, Position position)
            : position(position) {
            state = kStateUnion;
            union_state.types = coded_union->types;
            union_state.type_count = coded_union->type_count;
            union_state.data_offset = coded_union->data_offset;
        }

        Frame(const fidl::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;
        }

        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() {}

        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 {
            kStateStruct,
            kStateStructPointer,
            kStateTable,
            kStateUnion,
            kStateUnionPointer,
            kStateXUnion,
            kStateArray,
            kStateString,
            kStateHandle,
            kStateVector,

            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 {
                const fidl::FidlStructField* fields;
                uint32_t field_count;
                // Index of the currently processing field.
                uint32_t field;
            } struct_state;
            struct {
                const fidl::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 fidl::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 |types| array.
                const fidl_type_t* const* types;
                // Size of the |types| array. Equal to the number of tags.
                uint32_t type_count;
                // Offset of the payload in the wire format (size of tag + padding).
                uint32_t data_offset;
            } union_state;
            struct {
                const fidl::FidlCodedUnion* union_type;
            } union_pointer_state;
            struct {
                const fidl::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;
                bool nullable;
            } 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 {
                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::kStateStruct: {
            const uint32_t field_index = frame->NextStructField();
            if (field_index == frame->struct_state.field_count) {
                Pop();
                continue;
            }
            const fidl::FidlStructField& field = frame->struct_state.fields[field_index];
            const fidl_type_t* field_type = field.type;
            Position field_position = frame->position + field.offset;
            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,
                                               PtrTo<Ptr<void>>(frame->position),
                                               frame->struct_pointer_state.struct_type->size,
                                               &frame->position);
            FIDL_STATUS_GUARD(status);
            const fidl::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) {
                    visitor.OnError("Table data cannot be absent");
                    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,
                                                   &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 fidl::FidlTableField* known_field = nullptr;
            if (table_frame.remaining_fields > 0) {
                const fidl::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,
                                          // 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.type_count) {
                visitor.OnError("Bad union discriminant");
                FIDL_STATUS_GUARD(Status::kConstraintViolationError);
            }
            const fidl_type_t* member = frame->union_state.types[union_tag];
            if (!member) {
                Pop();
                continue;
            }
            frame->position += frame->union_state.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,
                                               PtrTo<Ptr<void>>(frame->position),
                                               frame->union_pointer_state.union_type->size,
                                               &frame->position);
            FIDL_STATUS_GUARD(status);
            const fidl::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;
            }
            if (xunion->padding != 0) {
                visitor.OnError("xunion padding after discriminant are non-zero");
                FIDL_STATUS_GUARD(Status::kConstraintViolationError);
            }
            // 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;
                }
            }
            // 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,
                                          &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);
            if (string_ptr->data == nullptr) {
                if (!frame->string_state.nullable) {
                    visitor.OnError("non-nullable string is absent");
                    FIDL_STATUS_GUARD(Status::kConstraintViolationError);
                }
                if (string_ptr->size != 0) {
                    visitor.OnError("string is absent but length is not zero");
                    FIDL_STATUS_GUARD(Status::kConstraintViolationError);
                }
                Pop();
                continue;
            }
            uint64_t bound = frame->string_state.max_size;
            uint64_t size = string_ptr->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;
            auto status = visitor.VisitPointer(position,
                                               &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);
            FIDL_STATUS_GUARD(status);
            Pop();
            continue;
        }
        case Frame::kStateVector: {
            auto vector_ptr = PtrTo<fidl_vector_t>(frame->position);
            if (vector_ptr->data == nullptr) {
                if (!frame->vector_state.nullable) {
                    visitor.OnError("non-nullable vector is absent");
                    FIDL_STATUS_GUARD(Status::kConstraintViolationError);
                }
                if (vector_ptr->count != 0) {
                    visitor.OnError("absent vector of non-zero elements");
                    FIDL_STATUS_GUARD(Status::kConstraintViolationError);
                }
                Pop();
                continue;
            }
            if (vector_ptr->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(vector_ptr->count, frame->vector_state.element_size, &size)) {
                visitor.OnError("integer overflow calculating vector size");
                return;
            }
            auto status = visitor.VisitPointer(frame->position,
                                               &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::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 // ZIRCON_SYSTEM_ULIB_FIDL_WALKER_H_
