// 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_TOOLS_FIDL_INCLUDE_FIDL_TYPE_SHAPE_H_
#define ZIRCON_TOOLS_FIDL_INCLUDE_FIDL_TYPE_SHAPE_H_

#include <cstdint>

// TODO(FIDL-710): We should revisit this namespace choice as part of improving code organization.
namespace fidl {

namespace flat {

struct Object;
struct StructMember;
struct TableMemberUsed;
struct UnionMemberUsed;

}  // namespace flat

enum class WireFormat {
  kOld,       // The v0 wire format, where "union" is a static union on-the-wire.
  kV1NoEe,    // The v1-no-ee wire format, where "union" is an extensible union on-the-wire,
              // but without efficient envelope support.
  kV1Header,  // The v1 wire format, except where request and response structs do not receive
              // any special treatment (e.g. having their size increased by 16 for the transactional
              // header)
};

struct TypeShape {
  explicit TypeShape(const flat::Object& object, WireFormat wire_format);
  explicit TypeShape(const flat::Object* object, WireFormat wire_format);

  // The inline size of this type, including padding for the type's minimum alignment. For example,
  // "struct S { uint32 a; uint16 b; };" will have an inline_size of 8, not 6: the "packed" size of
  // the struct is 6, but the alignment of its largest member is 4, so 6 is rounded up to 8.
  uint32_t inline_size;

  // The minimum alignment required by this type.
  uint32_t alignment;

  // These values are calculated incorporating both the current TypeShape, and recursively over
  // all child fields. A value of std::numeric_limits<uint32_t>::max() means that the value is
  // potentially unbounded, which can happen for self-recursive aggregate objects. For flexible
  // types, these values is calculated based on the currently-defined members, and does _not_ take
  // potential future members into account.
  uint32_t depth;
  uint32_t max_handles;
  uint32_t max_out_of_line;

  // |has_padding| is true if this type has _either_ inline or out-of-line padding. For flexible
  // types, |has_padding| is calculated based on the currently-defined members, and does _not_ take
  // potential future members into account. (If it did, |has_padding| would have to be true for all
  // flexible types, which doesn't make it very useful.)
  bool has_padding;

  bool has_flexible_envelope;
  // Whether this type transitively contains a union. If this is false, union transformations
  // can be avoided
  bool contains_union;

  // TODO(fxb/36337): These accessors are for backward compatibility with current code, and could be
  // removed in the future.
  uint32_t InlineSize() const { return inline_size; }
  uint32_t Alignment() const { return alignment; }
  uint32_t Depth() const { return depth; }
  uint32_t MaxHandles() const { return max_handles; }
  uint32_t MaxOutOfLine() const { return max_out_of_line; }
  bool HasPadding() const { return has_padding; }
  bool HasFlexibleEnvelope() const { return has_flexible_envelope; }
  bool ContainsUnion() const { return contains_union; }
};

// |FieldShape| describes the offset and padding information for members that are contained within
// an aggregate type (e.g. struct/union).
// TODO(fxb/36337): We can update |FieldShape| to be a simple offset+padding struct, and remove the
// getter/setter methods since they're purely for backward-compatibility with existing code.
struct FieldShape {
  explicit FieldShape(const flat::StructMember&, const WireFormat wire_format);
  explicit FieldShape(const flat::TableMemberUsed&, const WireFormat wire_format);
  explicit FieldShape(const flat::UnionMemberUsed&, const WireFormat wire_format);

  uint32_t Offset() const { return offset; }
  // Padding after this field until the next field or the end of the container.
  // See
  // https://fuchsia.dev/fuchsia-src/development/languages/fidl/reference/wire-format/README.md#size-and-alignment
  uint32_t Padding() const { return padding; }

  void SetOffset(uint32_t updated_offset) { offset = updated_offset; }
  void SetPadding(uint32_t updated_padding) { padding = updated_padding; }

  uint32_t offset = 0;
  uint32_t padding = 0;
};

constexpr uint32_t kMessageAlign = 8u;

}  // namespace fidl

#endif  // ZIRCON_TOOLS_FIDL_INCLUDE_FIDL_TYPE_SHAPE_H_
