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

#include <cstdint>

// TODO(fxbug.dev/8032): 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 {
  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;

  // TODO(fxbug.dev/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; }
};

// |FieldShape| describes the offset and padding information for members that are contained within
// an aggregate type (e.g. struct/union).
// TODO(fxbug.dev/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;

// Returns depth according to the "old" wire format (with static unions). This is currently only
// supported to calculate the Layout=Simple/ForDeprecatedCBindings attribute constraint.
uint32_t OldWireFormatDepth(const flat::Object& object);
uint32_t OldWireFormatDepth(const flat::Object* object);

}  // namespace fidl

#endif  // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_TYPE_SHAPE_H_
