// Copyright 2017 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_INTERNAL_H_
#define LIB_FIDL_INTERNAL_H_

#include <assert.h>
#include <cstdint>

#include <lib/fidl/coding.h>
#include <zircon/syscalls/object.h>
#include <zircon/types.h>

// All sizes here are given as uint32_t. Fidl message sizes are bounded to well below UINT32_MAX.
// This also applies to arrays and vectors. For arrays, element_count * element_size will always fit
// with 32 bits. For vectors, max_count * element_size will always fit within 32 bits.

// Pointers to other type tables within a type are always nonnull, with the exception of vectors.
// In that case, a null pointer indicates that the element type of the vector has no interesting
// information to be decoded (i.e. no pointers or handles). The vector type still needs to be
// emitted as it contains the information about the size of its secondary object. Contrast this with
// arrays: being inline, ones with no interesting coding information can be elided, just like a
// uint32 field in a struct is elided.

namespace fidl {

enum FidlNullability : bool {
    kNonnullable = false,
    kNullable = true,
};

constexpr inline uint64_t FidlAlign(uint32_t offset) {
    constexpr uint64_t alignment_mask = FIDL_ALIGNMENT - 1;
    return (offset + alignment_mask) & ~alignment_mask;
}

// Determine if the pointer is aligned to |FIDL_ALIGNMENT|.
inline bool IsAligned(uint8_t* ptr) {
    auto uintptr = reinterpret_cast<std::uintptr_t>(ptr);
    constexpr uintptr_t kAlignment = FIDL_ALIGNMENT;
    return uintptr % kAlignment == 0;
}

// Add |size| to out-of-line |offset|, maintaining alignment. For example, a pointer to a struct
// that is 4 bytes still needs to advance the next out-of-line offset by 8 to maintain
// the aligned-to-FIDL_ALIGNMENT property.
// Returns false on overflow. Otherwise, resulting offset is stored in |out_offset|.
inline bool AddOutOfLine(uint32_t offset, uint32_t size, uint32_t* out_offset) {
    constexpr uint32_t kMask = FIDL_ALIGNMENT - 1;
    uint32_t new_offset = offset;
    if (add_overflow(new_offset, size, &new_offset)
        || add_overflow(new_offset, kMask, &new_offset)) {
        return false;
    }
    new_offset &= ~kMask;
    *out_offset = new_offset;
    return true;
}

struct FidlStructField {
    const fidl_type* type;
    // If |type| is not nullptr, |offset| stores the offset of the struct member.
    // Otherwise, |offset| stores the offset of the padding.
    uint32_t offset;
    uint8_t padding;

    constexpr FidlStructField(const fidl_type* type, uint32_t offset, uint8_t padding)
        : type(type), offset(offset), padding(padding) {}
};

struct FidlUnionField {
    const fidl_type* type;
    uint32_t padding;

    constexpr FidlUnionField(const fidl_type* type, uint32_t padding)
        : type(type), padding(padding) {}
};

struct FidlTableField {
    const fidl_type* type;
    uint32_t ordinal;

    constexpr FidlTableField(const fidl_type* type, uint32_t ordinal)
        : type(type), ordinal(ordinal) {}
};

struct FidlXUnionField {
    const fidl_type* type;
    uint32_t ordinal;

    constexpr FidlXUnionField(const fidl_type* type, uint32_t ordinal)
        : type(type), ordinal(ordinal) {}
};

enum FidlTypeTag : uint32_t {
    kFidlTypePrimitive,
    kFidlTypeEnum,
    kFidlTypeBits,
    kFidlTypeStruct,
    kFidlTypeStructPointer,
    kFidlTypeUnion,
    kFidlTypeUnionPointer,
    kFidlTypeArray,
    kFidlTypeString,
    kFidlTypeHandle,
    kFidlTypeVector,
    kFidlTypeTable,
    kFidlTypeXUnion,
};

enum struct FidlCodedPrimitive : uint32_t {
    kBool,
    kInt8,
    kInt16,
    kInt32,
    kInt64,
    kUint8,
    kUint16,
    kUint32,
    kUint64,
    kFloat32,
    kFloat64,
};

struct FidlCodedEnum {
    const FidlCodedPrimitive underlying_type;

    constexpr explicit FidlCodedEnum(FidlCodedPrimitive underlying_type)
        : underlying_type(underlying_type) {}
};

struct FidlCodedBits {
    const FidlCodedPrimitive underlying_type;

    constexpr explicit FidlCodedBits(FidlCodedPrimitive underlying_type)
        : underlying_type(underlying_type) {}
};

// Though the |size| is implied by the fields, computing that information is not the purview of this
// library. It's easier for the compiler to stash it.
struct FidlCodedStruct {
    const FidlStructField* const fields;
    const uint32_t field_count;
    const uint32_t size;
    const char* name; // may be nullptr if omitted at compile time

    constexpr FidlCodedStruct(const FidlStructField* fields, uint32_t field_count, uint32_t size,
                              const char* name)
        : fields(fields), field_count(field_count), size(size), name(name) {}
};

struct FidlCodedStructPointer {
    const FidlCodedStruct* const struct_type;

    constexpr explicit FidlCodedStructPointer(const FidlCodedStruct* struct_type)
        : struct_type(struct_type) {}
};

struct FidlCodedTable {
    const FidlTableField* const fields;
    const uint32_t field_count;
    const char* name; // may be nullptr if omitted at compile time

    constexpr FidlCodedTable(const FidlTableField* fields, uint32_t field_count,
                             const char* name)
        : fields(fields), field_count(field_count), name(name) {}
};

// On-the-wire unions begin with a tag which is an index into |fields|.
// |data_offset| is the offset of the data in the wire format (tag + padding).
struct FidlCodedUnion {
    const FidlUnionField* const fields;
    const uint32_t field_count;
    const uint32_t data_offset;
    const uint32_t size;
    const char* name; // may be nullptr if omitted at compile time

    constexpr FidlCodedUnion(const FidlUnionField* const fields, uint32_t field_count,
                             uint32_t data_offset, uint32_t size, const char* name)
        : fields(fields), field_count(field_count), data_offset(data_offset), size(size),
          name(name) {}
};

struct FidlCodedUnionPointer {
    const FidlCodedUnion* const union_type;

    constexpr explicit FidlCodedUnionPointer(const FidlCodedUnion* union_type)
        : union_type(union_type) {}
};

struct FidlCodedXUnion {
    const uint32_t field_count;
    const FidlXUnionField* const fields;
    const FidlNullability nullable;
    const char* name; // may be nullptr if omitted at compile time

    constexpr FidlCodedXUnion(uint32_t field_count, const FidlXUnionField* fields,
                              FidlNullability nullable, const char* name)
        : field_count(field_count), fields(fields), nullable(nullable), name(name) {}
};

// An array is essentially a struct with |array_size / element_size| of the same field, named at
// |element|.
struct FidlCodedArray {
    const fidl_type* const element;
    const uint32_t array_size;
    const uint32_t element_size;

    constexpr FidlCodedArray(const fidl_type* element, uint32_t array_size, uint32_t element_size)
        : element(element), array_size(array_size), element_size(element_size) {}
};

// Note: must keep in sync with fidlc types.h HandleSubtype.
enum FidlHandleSubtype : zx_obj_type_t {
    // special case to indicate subtype is not specified.
    kFidlHandleSubtypeHandle = ZX_OBJ_TYPE_NONE,

    kFidlHandleSubtypeProcess = ZX_OBJ_TYPE_PROCESS,
    kFidlHandleSubtypeThread = ZX_OBJ_TYPE_THREAD,
    kFidlHandleSubtypeVmo = ZX_OBJ_TYPE_VMO,
    kFidlHandleSubtypeChannel = ZX_OBJ_TYPE_CHANNEL,
    kFidlHandleSubtypeEvent = ZX_OBJ_TYPE_EVENT,
    kFidlHandleSubtypePort = ZX_OBJ_TYPE_PORT,
    kFidlHandleSubtypeInterrupt = ZX_OBJ_TYPE_INTERRUPT,
    kFidlHandleSubtypeLog = ZX_OBJ_TYPE_LOG,
    kFidlHandleSubtypeSocket = ZX_OBJ_TYPE_SOCKET,
    kFidlHandleSubtypeResource = ZX_OBJ_TYPE_RESOURCE,
    kFidlHandleSubtypeEventpair = ZX_OBJ_TYPE_EVENTPAIR,
    kFidlHandleSubtypeJob = ZX_OBJ_TYPE_JOB,
    kFidlHandleSubtypeVmar = ZX_OBJ_TYPE_VMAR,
    kFidlHandleSubtypeFifo = ZX_OBJ_TYPE_FIFO,
    kFidlHandleSubtypeGuest = ZX_OBJ_TYPE_GUEST,
    kFidlHandleSubtypeTimer = ZX_OBJ_TYPE_TIMER,
};

struct FidlCodedHandle {
    const zx_obj_type_t handle_subtype;
    const FidlNullability nullable;

    constexpr FidlCodedHandle(uint32_t handle_subtype, FidlNullability nullable)
        : handle_subtype(handle_subtype), nullable(nullable) {}

    static_assert(ZX_OBJ_TYPE_UPPER_BOUND <= UINT32_MAX, "");
};

struct FidlCodedString {
    const uint32_t max_size;
    const FidlNullability nullable;

    constexpr FidlCodedString(uint32_t max_size, FidlNullability nullable)
        : max_size(max_size), nullable(nullable) {}
};

// Note that |max_count * element_size| is guaranteed to fit into a uint32_t. Unlike other types,
// the |element| pointer may be null. This occurs when the element type contains no interesting bits
// (i.e. pointers or handles).
struct FidlCodedVector {
    const fidl_type* const element;
    const uint32_t max_count;
    const uint32_t element_size;
    const FidlNullability nullable;

    constexpr FidlCodedVector(const fidl_type* element, uint32_t max_count, uint32_t element_size,
                              FidlNullability nullable)
        : element(element), max_count(max_count), element_size(element_size), nullable(nullable) {}
};

} // namespace fidl

struct fidl_type {
    const fidl::FidlTypeTag type_tag;
    const union {
        const fidl::FidlCodedPrimitive coded_primitive;
        const fidl::FidlCodedEnum coded_enum;
        const fidl::FidlCodedBits coded_bits;
        const fidl::FidlCodedStruct coded_struct;
        const fidl::FidlCodedStructPointer coded_struct_pointer;
        const fidl::FidlCodedTable coded_table;
        const fidl::FidlCodedUnion coded_union;
        const fidl::FidlCodedUnionPointer coded_union_pointer;
        const fidl::FidlCodedXUnion coded_xunion;
        const fidl::FidlCodedHandle coded_handle;
        const fidl::FidlCodedString coded_string;
        const fidl::FidlCodedArray coded_array;
        const fidl::FidlCodedVector coded_vector;
    };

    constexpr fidl_type(fidl::FidlCodedPrimitive coded_primitive) noexcept
        : type_tag(fidl::kFidlTypePrimitive), coded_primitive(coded_primitive) {}

    constexpr fidl_type(fidl::FidlCodedEnum coded_enum) noexcept
        : type_tag(fidl::kFidlTypeEnum), coded_enum(coded_enum) {}

    constexpr fidl_type(fidl::FidlCodedBits coded_bits) noexcept
        : type_tag(fidl::kFidlTypeBits), coded_bits(coded_bits) {}

    constexpr fidl_type(fidl::FidlCodedStruct coded_struct) noexcept
        : type_tag(fidl::kFidlTypeStruct), coded_struct(coded_struct) {}

    constexpr fidl_type(fidl::FidlCodedStructPointer coded_struct_pointer) noexcept
        : type_tag(fidl::kFidlTypeStructPointer), coded_struct_pointer(coded_struct_pointer) {}

    constexpr fidl_type(fidl::FidlCodedTable coded_table) noexcept
        : type_tag(fidl::kFidlTypeTable), coded_table(coded_table) {}

    constexpr fidl_type(fidl::FidlCodedUnion coded_union) noexcept
        : type_tag(fidl::kFidlTypeUnion), coded_union(coded_union) {}

    constexpr fidl_type(fidl::FidlCodedUnionPointer coded_union_pointer) noexcept
        : type_tag(fidl::kFidlTypeUnionPointer), coded_union_pointer(coded_union_pointer) {}

    constexpr fidl_type(fidl::FidlCodedXUnion coded_xunion) noexcept
        : type_tag(fidl::kFidlTypeXUnion), coded_xunion(coded_xunion) {}

    constexpr fidl_type(fidl::FidlCodedHandle coded_handle) noexcept
        : type_tag(fidl::kFidlTypeHandle), coded_handle(coded_handle) {}

    constexpr fidl_type(fidl::FidlCodedString coded_string) noexcept
        : type_tag(fidl::kFidlTypeString), coded_string(coded_string) {}

    constexpr fidl_type(fidl::FidlCodedArray coded_array) noexcept
        : type_tag(fidl::kFidlTypeArray), coded_array(coded_array) {}

    constexpr fidl_type(fidl::FidlCodedVector coded_vector) noexcept
        : type_tag(fidl::kFidlTypeVector), coded_vector(coded_vector) {}
};

namespace fidl {

namespace internal {

extern const fidl_type kBoolTable;
extern const fidl_type kInt8Table;
extern const fidl_type kInt16Table;
extern const fidl_type kInt32Table;
extern const fidl_type kInt64Table;
extern const fidl_type kUint8Table;
extern const fidl_type kUint16Table;
extern const fidl_type kUint32Table;
extern const fidl_type kUint64Table;
extern const fidl_type kFloat32Table;
extern const fidl_type kFloat64Table;

} // namespace internal

} // namespace fidl

#endif // LIB_FIDL_INTERNAL_H_
