// Copyright 2019 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.

#include "src/lib/fidl_codec/wire_types.h"

#include <zircon/fidl.h>

#include <rapidjson/error/en.h>

#include "src/lib/fidl_codec/library_loader.h"
#include "src/lib/fidl_codec/type_visitor.h"
#include "src/lib/fidl_codec/wire_object.h"
#include "src/lib/fxl/logging.h"

// See wire_types.h for details.

namespace fidl_codec {
namespace {

class ToStringVisitor : public TypeVisitor {
 public:
  enum ExpandLevels {
    kNone,
    kOne,
    kAll,
  };

  explicit ToStringVisitor(const std::string& indent, ExpandLevels levels, std::string* result)
      : indent_(indent), levels_(levels), result_(result) {}
  ~ToStringVisitor() = default;

 private:
  ExpandLevels NextExpandLevels() {
    if (levels_ == ExpandLevels::kAll) {
      return ExpandLevels::kAll;
    }

    return ExpandLevels::kNone;
  }

  template <typename T>
  void VisitTypeWithMembers(const Type* type, const std::string& name,
                            const std::vector<T>& members, fit::function<bool(const T&)> body) {
    *result_ += name + " ";
    VisitType(type);

    if (levels_ == ExpandLevels::kNone) {
      return;
    }

    *result_ += " {";

    if (members.empty()) {
      *result_ += "}";
      return;
    }

    *result_ += "\n";

    for (const auto& member : members) {
      if (body(member)) {
        *result_ += ";\n";
      }
    }

    *result_ += indent_ + "}";
  }

  void VisitType(const Type* type) override { *result_ += type->Name(); }

  void VisitEnumType(const EnumType* type) override {
    VisitTypeWithMembers<EnumOrBitsMember>(type, "enum", type->enum_definition().members(),
                                           [this](const EnumOrBitsMember& member) {
                                             *result_ += indent_ + "  " + member.name() + " = ";
                                             if (member.negative()) {
                                               *result_ += "-";
                                             }
                                             *result_ += std::to_string(member.absolute_value());
                                             return true;
                                           });
  }

  void VisitBitsType(const BitsType* type) override {
    VisitTypeWithMembers<EnumOrBitsMember>(
        type, "bits", type->bits_definition().members(), [this](const EnumOrBitsMember& member) {
          *result_ +=
              indent_ + "  " + member.name() + " = " + std::to_string(member.absolute_value());
          return true;
        });
  }

  void VisitUnionType(const UnionType* type) override {
    VisitTypeWithMembers<std::unique_ptr<UnionMember>>(
        type, "union", type->union_definition().members(),
        [this](const std::unique_ptr<UnionMember>& member) {
          *result_ += indent_ + "  " + std::to_string(member->ordinal()) + ": ";
          if (member->reserved()) {
            *result_ += "reserved";
            return true;
          }

          ToStringVisitor visitor(indent_ + "  ", NextExpandLevels(), result_);
          member->type()->Visit(&visitor);

          *result_ += " " + std::string(member->name());
          return true;
        });
  }

  void VisitStructType(const StructType* type) override {
    VisitTypeWithMembers<std::unique_ptr<StructMember>>(
        type, "struct", type->struct_definition().members(),
        [this](const std::unique_ptr<StructMember>& member) {
          *result_ += indent_ + "  ";
          ToStringVisitor visitor(indent_ + "  ", NextExpandLevels(), result_);
          member->type()->Visit(&visitor);
          *result_ += " " + std::string(member->name());
          return true;
        });
  }

  void VisitArrayType(const ArrayType* type) override {
    *result_ += "array<";
    type->component_type()->Visit(this);
    *result_ += ">";
  }

  void VisitVectorType(const VectorType* type) override {
    *result_ += "vector<";
    type->component_type()->Visit(this);
    *result_ += ">";
  }

  void VisitTableType(const TableType* type) override {
    VisitTypeWithMembers<std::unique_ptr<TableMember>>(
        type, "table", type->table_definition().members(),
        [this](const std::unique_ptr<TableMember>& member) {
          if (!member) {
            return false;
          }
          *result_ += indent_ + "  ";
          *result_ += std::to_string(member->ordinal()) + ": ";
          if (member->reserved()) {
            *result_ += "reserved";
            return true;
          }
          ToStringVisitor visitor(indent_ + "  ", NextExpandLevels(), result_);
          member->type()->Visit(&visitor);
          *result_ += " " + std::string(member->name());
          return true;
        });
  }

  std::string indent_;
  ExpandLevels levels_;
  std::string* result_;
};

}  // namespace

std::string Type::ToString(bool expand) const {
  std::string ret;
  ToStringVisitor visitor(
      "", expand ? ToStringVisitor::ExpandLevels::kAll : ToStringVisitor::ExpandLevels::kOne, &ret);
  Visit(&visitor);
  return ret;
}

void Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  printer << Red << "invalid" << ResetColor;
}

std::string InvalidType::Name() const { return "unknown"; }

size_t InvalidType::InlineSize() const { return 0; }

std::unique_ptr<Value> InvalidType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  return std::make_unique<InvalidValue>();
}

void InvalidType::Visit(TypeVisitor* visitor) const { visitor->VisitInvalidType(this); }

size_t BoolType::InlineSize() const { return sizeof(uint8_t); }

std::unique_ptr<Value> BoolType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  auto byte = decoder->GetAddress(offset, sizeof(uint8_t));
  if (byte == nullptr) {
    return std::make_unique<InvalidValue>();
  }
  return std::make_unique<BoolValue>(*byte);
}

void BoolType::Visit(TypeVisitor* visitor) const { visitor->VisitBoolType(this); };

std::string Int8Type::Name() const { return "int8"; }

void Int8Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue;
        if (negative) {
          printer << '-';
        }
        printer << absolute << ResetColor;
        break;
    }
  }
}

void Int8Type::Visit(TypeVisitor* visitor) const { visitor->VisitInt8Type(this); }

std::string Int16Type::Name() const { return "int16"; }

void Int16Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue;
        if (negative) {
          printer << '-';
        }
        printer << absolute << ResetColor;
        break;
    }
  }
}

void Int16Type::Visit(TypeVisitor* visitor) const { visitor->VisitInt16Type(this); }

std::string Int32Type::Name() const { return "int32"; }

void Int32Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue;
        if (negative) {
          printer << '-';
        }
        printer << absolute << ResetColor;
        break;
    }
  }
}

void Int32Type::Visit(TypeVisitor* visitor) const { visitor->VisitInt32Type(this); }

std::string Int64Type::Name() const {
  switch (kind_) {
    case Kind::kDecimal:
      return "int64";
    case Kind::kTime:
      return "zx.time";
  }
}

void Int64Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue;
        if (negative) {
          printer << '-';
        }
        printer << absolute << ResetColor;
        break;
      case Kind::kTime:
        printer.DisplayTime(static_cast<zx_time_t>(absolute));
        break;
    }
  }
}

void Int64Type::Visit(TypeVisitor* visitor) const { visitor->VisitInt64Type(this); }

std::string Uint8Type::Name() const { return "uint8"; }

void Uint8Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    FX_DCHECK(!negative);
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue << absolute << ResetColor;
        break;
      case Kind::kHexaDecimal:
        printer << Blue << std::hex << absolute << std::dec << ResetColor;
        break;
    }
  }
}

void Uint8Type::Visit(TypeVisitor* visitor) const { visitor->VisitUint8Type(this); }

std::string Uint16Type::Name() const { return "uint16"; }

void Uint16Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    FX_DCHECK(!negative);
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue << absolute << ResetColor;
        break;
      case Kind::kHexaDecimal:
        printer << Blue << std::hex << absolute << std::dec << ResetColor;
        break;
    }
  }
}

void Uint16Type::Visit(TypeVisitor* visitor) const { visitor->VisitUint16Type(this); }

std::string Uint32Type::Name() const { return "uint32"; }

void Uint32Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    FX_DCHECK(!negative);
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue << absolute << ResetColor;
        break;
      case Kind::kHexaDecimal:
        printer << Blue << std::hex << absolute << std::dec << ResetColor;
        break;
    }
  }
}

void Uint32Type::Visit(TypeVisitor* visitor) const { visitor->VisitUint32Type(this); }

std::string Uint64Type::Name() const {
  switch (kind_) {
    case Kind::kDecimal:
    case Kind::kHexaDecimal:
      return "uint64";
  }
}

void Uint64Type::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    FX_DCHECK(!negative);
    switch (kind_) {
      case Kind::kDecimal:
        printer << Blue << absolute << ResetColor;
        break;
      case Kind::kHexaDecimal:
        printer << Blue << std::hex << absolute << std::dec << ResetColor;
        break;
    }
  }
}

void Uint64Type::Visit(TypeVisitor* visitor) const { visitor->VisitUint64Type(this); }

std::string Float32Type::Name() const { return "float32"; }

void Float32Type::Visit(TypeVisitor* visitor) const { visitor->VisitFloat32Type(this); }

std::string Float64Type::Name() const { return "float64"; }

void Float64Type::Visit(TypeVisitor* visitor) const { visitor->VisitFloat64Type(this); }

std::string StringType::Name() const { return "string"; }

size_t StringType::InlineSize() const { return sizeof(uint64_t) + sizeof(uint64_t); }

bool StringType::Nullable() const { return true; }

std::unique_ptr<Value> StringType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  uint64_t string_length = 0;
  if (!decoder->GetValueAt(offset, &string_length)) {
    return std::make_unique<InvalidValue>();
  }
  offset += sizeof(string_length);

  bool is_null;
  uint64_t nullable_offset;
  if (!decoder->DecodeNullableHeader(offset, string_length, &is_null, &nullable_offset)) {
    return std::make_unique<InvalidValue>();
  }
  if (is_null) {
    return std::make_unique<NullValue>();
  }
  auto data = reinterpret_cast<const char*>(decoder->GetAddress(nullable_offset, string_length));
  if (data == nullptr) {
    return std::make_unique<InvalidValue>();
  }
  return std::make_unique<StringValue>(std::string_view(data, string_length));
}

void StringType::Visit(TypeVisitor* visitor) const { visitor->VisitStringType(this); }

std::string HandleType::Name() const { return "handle"; }

size_t HandleType::InlineSize() const { return sizeof(zx_handle_t); }

std::unique_ptr<Value> HandleType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  zx_handle_t handle = FIDL_HANDLE_ABSENT;
  decoder->GetValueAt(offset, &handle);
  if ((handle != FIDL_HANDLE_ABSENT) && (handle != FIDL_HANDLE_PRESENT)) {
    decoder->AddError() << std::hex << (decoder->absolute_offset() + offset) << std::dec
                        << ": Invalid value <" << std::hex << handle << std::dec
                        << "> for handle\n";
    handle = FIDL_HANDLE_ABSENT;
  }
  zx_handle_info_t handle_info;
  if (handle == FIDL_HANDLE_ABSENT) {
    handle_info.handle = FIDL_HANDLE_ABSENT;
    handle_info.type = ZX_OBJ_TYPE_NONE;
    handle_info.rights = 0;
  } else {
    handle_info = decoder->GetNextHandle();
  }
  return std::make_unique<HandleValue>(handle_info);
}

void HandleType::Visit(TypeVisitor* visitor) const { visitor->VisitHandleType(this); }

std::string EnumType::Name() const { return enum_definition_.name(); }

size_t EnumType::InlineSize() const { return enum_definition_.size(); }

std::unique_ptr<Value> EnumType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  return enum_definition_.type()->Decode(decoder, offset);
}

void EnumType::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    printer << Blue << enum_definition_.GetName(absolute, negative) << ResetColor;
  }
}

void EnumType::Visit(TypeVisitor* visitor) const { visitor->VisitEnumType(this); }

std::string BitsType::Name() const { return bits_definition_.name(); }

size_t BitsType::InlineSize() const { return bits_definition_.size(); }

std::unique_ptr<Value> BitsType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  return bits_definition_.type()->Decode(decoder, offset);
}

void BitsType::PrettyPrint(const Value* value, PrettyPrinter& printer) const {
  uint64_t absolute;
  bool negative;
  if (!value->GetIntegerValue(&absolute, &negative)) {
    printer << Red << "invalid" << ResetColor;
  } else {
    printer << Blue << bits_definition_.GetName(absolute, negative) << ResetColor;
  }
}

void BitsType::Visit(TypeVisitor* visitor) const { visitor->VisitBitsType(this); }

std::string UnionType::Name() const { return union_definition_.name(); }

size_t UnionType::InlineSize() const {
  // In v1, unions are encoded as xunion. The inline size is the size of an envelope which
  // is always 24 bytes.
  return 24;
}

bool UnionType::Nullable() const { return nullable_; }

std::unique_ptr<Value> UnionType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  Ordinal32 ordinal = 0;
  if (decoder->GetValueAt(offset, &ordinal)) {
    if ((ordinal == 0) && !nullable_) {
      decoder->AddError() << std::hex << (decoder->absolute_offset() + offset) << std::dec
                          << ": Null envelope for a non nullable extensible union\n";
      return std::make_unique<InvalidValue>();
    }
  }

  offset += sizeof(uint64_t);  // Skips ordinal + padding.

  if (ordinal == 0) {
    if (!decoder->CheckNullEnvelope(offset)) {
      return std::make_unique<InvalidValue>();
    }
    return std::make_unique<NullValue>();
  }

  const UnionMember* member = union_definition_.MemberWithOrdinal(ordinal);
  if (member == nullptr) {
    return std::make_unique<InvalidValue>();
  }
  return std::make_unique<UnionValue>(*member, decoder->DecodeEnvelope(offset, member->type()));
}

void UnionType::Visit(TypeVisitor* visitor) const { visitor->VisitUnionType(this); }

std::string StructType::Name() const { return struct_definition_.name(); }

size_t StructType::InlineSize() const {
  return nullable_ ? sizeof(uintptr_t) : struct_definition_.size();
}

bool StructType::Nullable() const { return nullable_; }

std::unique_ptr<Value> StructType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  if (nullable_) {
    bool is_null;
    uint64_t nullable_offset;
    if (!decoder->DecodeNullableHeader(offset, struct_definition_.size(), &is_null,
                                       &nullable_offset)) {
      return std::make_unique<InvalidValue>();
    }
    if (is_null) {
      return std::make_unique<NullValue>();
    }
    offset = nullable_offset;
  }
  return decoder->DecodeStruct(struct_definition_, offset);
}

void StructType::Visit(TypeVisitor* visitor) const { visitor->VisitStructType(this); }

const Type* ElementSequenceType::GetComponentType() const { return component_type_.get(); }

void ElementSequenceType::Visit(TypeVisitor* visitor) const {
  visitor->VisitElementSequenceType(this);
}

bool ArrayType::IsArray() const { return true; }

std::string ArrayType::Name() const {
  return std::string("array<") + component_type_->Name() + ">";
}

size_t ArrayType::InlineSize() const { return component_type_->InlineSize() * count_; }

std::unique_ptr<Value> ArrayType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  auto result = std::make_unique<VectorValue>();
  for (uint64_t i = 0; i < count_; ++i) {
    result->AddValue(component_type_->Decode(decoder, offset));
    offset += component_type_->InlineSize();
  }
  return result;
}

void ArrayType::Visit(TypeVisitor* visitor) const { visitor->VisitArrayType(this); }

std::string VectorType::Name() const {
  return std::string("vector<") + component_type_->Name() + ">";
}

size_t VectorType::InlineSize() const { return sizeof(uint64_t) + sizeof(uint64_t); }

bool VectorType::Nullable() const { return true; }

std::unique_ptr<Value> VectorType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  uint64_t element_count = 0;
  decoder->GetValueAt(offset, &element_count);
  offset += sizeof(element_count);
  bool is_null;
  uint64_t nullable_offset;
  if (!decoder->DecodeNullableHeader(offset, element_count * component_type_->InlineSize(),
                                     &is_null, &nullable_offset)) {
    return std::make_unique<InvalidValue>();
  }
  if (is_null) {
    return std::make_unique<NullValue>();
  }

  size_t component_size = component_type_->InlineSize();
  auto result = std::make_unique<VectorValue>();
  for (uint64_t i = 0;
       (i < element_count) && (nullable_offset + component_size <= decoder->num_bytes()); ++i) {
    result->AddValue(component_type_->Decode(decoder, nullable_offset));
    nullable_offset += component_size;
  }
  return result;
}

void VectorType::Visit(TypeVisitor* visitor) const { visitor->VisitVectorType(this); }

std::string TableType::Name() const { return table_definition_.name(); }

size_t TableType::InlineSize() const {
  // A table is always implemented as a size + a pointer.
  return 2 * sizeof(uint64_t);
}

std::unique_ptr<Value> TableType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  uint64_t member_count = 0;
  decoder->GetValueAt(offset, &member_count);
  offset += sizeof(member_count);

  bool is_null;
  uint64_t nullable_offset;
  constexpr size_t kEnvelopeSize = 2 * sizeof(uint32_t) + sizeof(uint64_t);
  if (!decoder->DecodeNullableHeader(offset, member_count * kEnvelopeSize, &is_null,
                                     &nullable_offset)) {
    return std::make_unique<InvalidValue>();
  }
  if (is_null) {
    decoder->AddError() << "Tables are not nullable.";
    return std::make_unique<InvalidValue>();
  }
  auto result = std::make_unique<TableValue>(table_definition_);
  for (uint64_t i = 1; i <= member_count; ++i) {
    const TableMember* member = table_definition_.GetMember(i);
    if ((member == nullptr) || member->reserved()) {
      decoder->SkipEnvelope(nullable_offset);
    } else {
      std::unique_ptr<Value> value = decoder->DecodeEnvelope(nullable_offset, member->type());
      if (!value->IsNull()) {
        result->AddMember(member, std::move(value));
      }
    }
    nullable_offset += kEnvelopeSize;
  }
  return result;
}

void TableType::Visit(TypeVisitor* visitor) const { visitor->VisitTableType(this); }

std::string FidlMessageType::Name() const { return "fidl-message"; }

size_t FidlMessageType::InlineSize() const { return 0; }

std::unique_ptr<Value> FidlMessageType::Decode(MessageDecoder* decoder, uint64_t offset) const {
  return nullptr;
}

void FidlMessageType::Visit(TypeVisitor* visitor) const { visitor->VisitFidlMessageType(this); }

std::unique_ptr<Type> Type::ScalarTypeFromName(const std::string& type_name) {
  static std::map<std::string, std::function<std::unique_ptr<Type>()>> scalar_type_map_{
      {"bool", []() { return std::make_unique<BoolType>(); }},
      {"int8", []() { return std::make_unique<Int8Type>(); }},
      {"int16", []() { return std::make_unique<Int16Type>(); }},
      {"int32", []() { return std::make_unique<Int32Type>(); }},
      {"int64", []() { return std::make_unique<Int64Type>(); }},
      {"uint8", []() { return std::make_unique<Uint8Type>(); }},
      {"uint16", []() { return std::make_unique<Uint16Type>(); }},
      {"uint32", []() { return std::make_unique<Uint32Type>(); }},
      {"uint64", []() { return std::make_unique<Uint64Type>(); }},
      {"float32", []() { return std::make_unique<Float32Type>(); }},
      {"float64", []() { return std::make_unique<Float64Type>(); }},
  };
  auto it = scalar_type_map_.find(type_name);
  if (it != scalar_type_map_.end()) {
    return it->second();
  }
  return std::make_unique<InvalidType>();
}

std::unique_ptr<Type> Type::TypeFromPrimitive(const rapidjson::Value& type) {
  if (!type.HasMember("subtype")) {
    FX_LOGS(ERROR) << "Invalid type";
    return std::make_unique<InvalidType>();
  }

  std::string subtype = type["subtype"].GetString();
  return ScalarTypeFromName(subtype);
}

std::unique_ptr<Type> Type::TypeFromIdentifier(LibraryLoader* loader,
                                               const rapidjson::Value& type) {
  if (!type.HasMember("identifier")) {
    FX_LOGS(ERROR) << "Invalid type";
    return std::make_unique<InvalidType>();
  }
  std::string id = type["identifier"].GetString();
  size_t split_index = id.find('/');
  std::string library_name = id.substr(0, split_index);
  Library* library = loader->GetLibraryFromName(library_name);
  if (library == nullptr) {
    FX_LOGS(ERROR) << "Unknown type for identifier: " << library_name;
    return std::make_unique<InvalidType>();
  }

  bool is_nullable = false;
  if (type.HasMember("nullable")) {
    is_nullable = type["nullable"].GetBool();
  }
  return library->TypeFromIdentifier(is_nullable, id);
}

std::unique_ptr<Type> Type::GetType(LibraryLoader* loader, const rapidjson::Value& type) {
  if (!type.HasMember("kind")) {
    FX_LOGS(ERROR) << "Invalid type";
    return std::make_unique<InvalidType>();
  }
  std::string kind = type["kind"].GetString();
  if (kind == "string") {
    return std::make_unique<StringType>();
  }
  if (kind == "handle") {
    return std::make_unique<HandleType>();
  }
  if (kind == "array") {
    const rapidjson::Value& element_type = type["element_type"];
    uint32_t element_count = std::strtol(type["element_count"].GetString(), nullptr, kDecimalBase);
    return std::make_unique<ArrayType>(GetType(loader, element_type), element_count);
  }
  if (kind == "vector") {
    const rapidjson::Value& element_type = type["element_type"];
    return std::make_unique<VectorType>(GetType(loader, element_type));
  }
  if (kind == "request") {
    return std::make_unique<HandleType>();
  }
  if (kind == "primitive") {
    return Type::TypeFromPrimitive(type);
  }
  if (kind == "identifier") {
    return Type::TypeFromIdentifier(loader, type);
  }
  FX_LOGS(ERROR) << "Invalid type " << kind;
  return std::make_unique<InvalidType>();
}

}  // namespace fidl_codec
