// 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 "tools/kazoo/syscall_library.h"

#include <stdio.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>

#include <algorithm>

#include "tools/kazoo/alias_workaround.h"
#include "tools/kazoo/output_util.h"
#include "tools/kazoo/string_util.h"

namespace {

bool ValidateTransport(const rapidjson::Value& interface) {
  if (!interface.HasMember("maybe_attributes")) {
    return false;
  }
  for (const auto& attrib : interface["maybe_attributes"].GetArray()) {
    if (attrib.GetObject()["name"].Get<std::string>() == "Transport") {
      if (attrib.GetObject()["value"].Get<std::string>() == "Syscall") {
        return true;
      }
    }
  }
  return false;
}

std::string StripLibraryName(const std::string& full_name) {
  auto prefix_pos = full_name.find_first_of('/');
  ZX_ASSERT_MSG(prefix_pos != full_name.npos, "%s has no library prefix", full_name.c_str());
  size_t prefix_len = prefix_pos + 1;
  return full_name.substr(prefix_len, full_name.size() - prefix_len);
}

std::string GetCategory(const rapidjson::Value& interface, const std::string& interface_name) {
  if (interface.HasMember("maybe_attributes")) {
    for (const auto& attrib : interface["maybe_attributes"].GetArray()) {
      if (attrib.GetObject()["name"].Get<std::string>() == "NoProtocolPrefix") {
        return std::string();
      }
    }
  }

  return ToLowerAscii(StripLibraryName(interface_name));
}

std::string GetDocAttribute(const rapidjson::Value& method) {
  if (!method.HasMember("maybe_attributes")) {
    return std::string();
  }
  for (const auto& attrib : method["maybe_attributes"].GetArray()) {
    if (attrib.GetObject()["name"].Get<std::string>() == "Doc") {
      return attrib.GetObject()["value"].GetString();
    }
  }
  return std::string();
}

Required GetRequiredAttribute(const rapidjson::Value& field) {
  if (!field.HasMember("maybe_attributes")) {
    return Required::kNo;
  }
  for (const auto& attrib : field["maybe_attributes"].GetArray()) {
    if (attrib.GetObject()["name"].Get<std::string>() == "Required") {
      ZX_ASSERT(attrib.GetObject()["value"].Get<std::string>() == "");
      return Required::kYes;
    }
  }
  return Required::kNo;
}

constexpr char kRightsPrefix[] = " Rights: ";

std::string GetShortDescriptionFromDocAttribute(const std::string& full_doc_attribute) {
  auto lines = SplitString(full_doc_attribute, '\n', kKeepWhitespace);
  if (lines.size() < 1 || lines[0].substr(0, strlen(kRightsPrefix)) == kRightsPrefix) {
    return std::string();
  }
  return TrimString(lines[0], " \t\n");
}

std::vector<std::string> GetCleanDocAttribute(const std::string& full_doc_attribute) {
  auto lines = SplitString(full_doc_attribute, '\n', kTrimWhitespace);
  if (!lines.empty() && lines[lines.size() - 1].empty()) {
    lines.pop_back();
  }
  std::for_each(lines.begin(), lines.end(),
                [](std::string& line) { return TrimString(line, " \t\n"); });
  return lines;
}

std::vector<std::string> GetRightsSpecsFromDocAttribute(const std::string& full_doc_attribute) {
  auto lines = SplitString(full_doc_attribute, '\n', kKeepWhitespace);
  std::vector<std::string> ret;
  for (const auto& line : lines) {
    if (line.substr(0, strlen(kRightsPrefix)) == kRightsPrefix) {
      ret.push_back(line.substr(strlen(kRightsPrefix)));
    }
  }

  return ret;
}

std::optional<Type> PrimitiveTypeFromName(std::string subtype) {
  if (subtype == "uint8") {
    return Type(TypeUint8{});
  } else if (subtype == "uint16") {
    return Type(TypeUint16{});
  } else if (subtype == "int32") {
    return Type(TypeInt32{});
  } else if (subtype == "uint32") {
    return Type(TypeUint32{});
  } else if (subtype == "int64") {
    return Type(TypeInt64{});
  } else if (subtype == "uint64") {
    return Type(TypeUint64{});
  } else if (subtype == "bool") {
    return Type(TypeBool{});
  }

  return std::nullopt;
}

Type TypeFromJson(const SyscallLibrary& library, const rapidjson::Value& type,
                  const rapidjson::Value* type_alias) {
  if (type_alias) {
    // If the "experimental_maybe_from_type_alias" field is non-null, then the source-level has used
    // a type that's declared as "using x = y;". Here, treat various "x"s as special types. This
    // is likely mostly (?) temporary until there's 1) a more nailed down alias implementation in
    // the front end (fidlc) and 2) we move various parts of zx.fidl from being built-in to fidlc to
    // actual source level fidl and shared between the syscall definitions and normal FIDL.
    const std::string full_name((*type_alias)["name"].GetString());
    if (full_name.substr(0, 3) == "zx/" || full_name.substr(0, 3) == "zz/") {
      const std::string name = full_name.substr(3);
      if (name == "duration" || name == "Futex" || name == "koid" || name == "paddr" ||
          name == "rights" || name == "signals" || name == "status" || name == "time" ||
          name == "ticks" || name == "vaddr" || name == "VmOption") {
        return Type(TypeZxBasicAlias(CamelToSnake(name)));
      }
    }

    const std::string name = StripLibraryName(full_name);
    if (name == "uintptr") {
      return Type(TypeUintptrT{});
    }

    if (name == "usize") {
      return Type(TypeSizeT{});
    }

    Type workaround_type;
    if (AliasWorkaround(name, library, &workaround_type)) {
      return workaround_type;
    }

    return library.TypeFromIdentifier(full_name);
  }

  if (!type.HasMember("kind")) {
    fprintf(stderr, "type has no 'kind'\n");
    return Type();
  }

  std::string kind = type["kind"].GetString();
  if (kind == "primitive") {
    const rapidjson::Value& subtype_value = type["subtype"];
    ZX_ASSERT(subtype_value.IsString());
    std::string subtype = subtype_value.GetString();
    return PrimitiveTypeFromName(subtype).value();
  } else if (kind == "identifier") {
    std::string id = type["identifier"].GetString();
    return library.TypeFromIdentifier(type["identifier"].GetString());
  } else if (kind == "handle") {
    return Type(TypeHandle(type["subtype"].GetString()));
  } else if (kind == "vector") {
    Type contained_type = TypeFromJson(library, type["element_type"], nullptr);
    return Type(TypeVector(contained_type));
  } else if (kind == "string") {
    return Type(TypeString{});
  }

  ZX_ASSERT_MSG(false, "TODO: kind=%s", kind.c_str());
  return Type();
}

}  // namespace

bool Syscall::HasAttribute(const char* attrib_name) const {
  return attributes_.find(attrib_name) != attributes_.end();
}

std::string Syscall::GetAttribute(const char* attrib_name) const {
  ZX_ASSERT(HasAttribute(attrib_name));
  return attributes_.find(attrib_name)->second;
}

// Converts from FIDL style to C/Kernel style:
// - string to pointer+size
// - vector to pointer+size
// - structs become pointer-to-struct (const on input, mutable on output)
// - etc.
bool Syscall::MapRequestResponseToKernelAbi() {
  ZX_ASSERT(kernel_arguments_.empty());

  // Used for input arguments, which default to const unless alread specified mutable.
  auto default_to_const = [](Constness constness) {
    if (constness == Constness::kUnspecified) {
      return Constness::kConst;
    }
    return constness;
  };

  auto output_optionality = [](Optionality optionality) {
    // If explicitly made optional then leave it alone, otherwise mark non-optional.
    if (optionality == Optionality::kOutputOptional) {
      return optionality;
    }
    return Optionality::kOutputNonOptional;
  };

  auto get_vector_size_name = [](const StructMember& member) {
    std::string prefix, suffix;
    // If it's a char* or void*, blah_size seems more natural, otherwise, num_blahs is moreso.
    if ((member.type().DataAsVector().contained_type().IsChar() ||
         member.type().DataAsVector().contained_type().IsVoid()) &&
        (member.name() != "bytes")) {
      suffix = "_size";
    } else {
      prefix = "num_";
    }
    return std::tuple<std::string, bool>(prefix + member.name() + suffix,
                                         member.type().DataAsVector().uint32_size());
  };

  // Map inputs first, converting vectors, strings, and structs to their corresponding input types
  // as we go.
  for (const auto& m : request_.members()) {
    const Type& type = m.type();
    if (type.IsVector()) {
      Type pointer_to_subtype(
          TypePointer(type.DataAsVector().contained_type(), IsDecayedVectorTag{}),
          default_to_const(type.constness()), Optionality::kInputArgument);
      kernel_arguments_.emplace_back(m.name(), pointer_to_subtype, m.attributes());
      auto [size_name, is_u32] = get_vector_size_name(m);
      kernel_arguments_.emplace_back(size_name, is_u32 ? Type(TypeUint32{}) : Type(TypeSizeT{}),
                                     std::map<std::string, std::string>{});
    } else if (type.IsString()) {
      // char*, using the same constness as the string was specified as.
      kernel_arguments_.emplace_back(
          m.name(), Type(TypePointer(Type(TypeChar{})), default_to_const(type.constness()),
                         Optionality::kInputArgument), m.attributes());
      kernel_arguments_.emplace_back(m.name() + "_size", Type(TypeSizeT{}),
                                     std::map<std::string, std::string>{});
    } else if (type.IsStruct()) {
      // If it's a struct, map to struct*, const unless otherwise specified. The pointer takes the
      // constness of the struct.
      kernel_arguments_.emplace_back(
          m.name(),
          Type(TypePointer(type), default_to_const(type.constness()), Optionality::kInputArgument),
          m.attributes());
    } else {
      // Otherwise, copy it over, unchanged other than to tag it as input.
      kernel_arguments_.emplace_back(m.name(),
                                     Type(type.type_data(), default_to_const(m.type().constness()),
                                          Optionality::kInputArgument),
                                     m.attributes());
    }
  }

  // Similarly for the outputs, but turning buffers into outparams, and with special handling for
  // the C return value.
  size_t start_at;
  if (response_.members().size() == 0 || !response_.members()[0].type().IsSimpleType()) {
    kernel_return_type_ = Type(TypeVoid{});
    start_at = 0;
  } else {
    kernel_return_type_ = response_.members()[0].type();
    start_at = 1;
  }
  for (size_t i = start_at; i < response_.members().size(); ++i) {
    const StructMember& m = response_.members()[i];
    const Type& type = m.type();
    if (type.IsVector()) {
      // TODO(syscall-fidl-transition): These vector types aren't marked as non-optional in
      // abigen, but generally they probably are.
      Type pointer_to_subtype(
          TypePointer(type.DataAsVector().contained_type(), IsDecayedVectorTag{}),
          Constness::kMutable, Optionality::kOutputOptional);
      kernel_arguments_.emplace_back(m.name(), pointer_to_subtype, m.attributes());
      auto [size_name, is_u32] = get_vector_size_name(m);
      kernel_arguments_.emplace_back(size_name, is_u32 ? Type(TypeUint32{}) : Type(TypeSizeT{}),
                                     std::map<std::string, std::string>{});
    } else if (type.IsString()) {
      kernel_arguments_.emplace_back(
          m.name(),
          Type(TypePointer(Type(TypeChar{})), Constness::kMutable, Optionality::kOutputOptional),
          m.attributes());
      kernel_arguments_.emplace_back(m.name() + "_size", Type(TypeSizeT{}),
                                     std::map<std::string, std::string>{});
    } else if (type.IsPointer()) {
      kernel_arguments_.emplace_back(
          m.name(), Type(type.type_data(), Constness::kMutable, Optionality::kOutputOptional),
          m.attributes());
    } else {
      // Everything else becomes a T* (to make it an out parameter).
      kernel_arguments_.emplace_back(m.name(), Type(TypePointer(type), Constness::kMutable,
                                                    output_optionality(type.optionality())),
                                     m.attributes());
    }
  }

  // Now that we've got all the arguments in their natural order, honor the
  // "ArgReorder" attribute, which reorders arguments arbitrarily to match
  // existing declaration order.
  return HandleArgReorder();
}

bool Syscall::HandleArgReorder() {
  constexpr const char kReorderAttribName[] = "ArgReorder";
  if (HasAttribute(kReorderAttribName)) {
    const std::string& target_order_string = GetAttribute(kReorderAttribName);
    std::vector<std::string> target_order = SplitString(target_order_string, ',', kTrimWhitespace);
    if (kernel_arguments_.size() != target_order.size()) {
      fprintf(stderr,
              "Attempting to reorder arguments for '%s', and there's %zu kernel arguments, but %zu "
              "arguments in the reorder spec.\n",
              name().c_str(), kernel_arguments_.size(), target_order.size());
      return false;
    }

    std::vector<StructMember> new_kernel_arguments;
    for (const auto& target : target_order) {
      bool found = false;
      for (const auto& ka : kernel_arguments_) {
        if (ka.name() == target) {
          new_kernel_arguments.push_back(ka);
          found = true;
          break;
        }
      }

      if (!found) {
        fprintf(stderr,
                "Attempting to reorder arguments for '%s', but '%s' wasn't one of the kernel "
                "arguments.\n",
                name().c_str(), target.c_str());
        return false;
      }
    }

    kernel_arguments_ = std::move(new_kernel_arguments);
  }

  return true;
}

void Enum::AddMember(const std::string& member_name, EnumMember member) {
  ZX_ASSERT(!HasMember(member_name));
  members_[member_name] = std::move(member);
  insertion_order_.push_back(member_name);
}

bool Enum::HasMember(const std::string& member_name) const {
  return members_.find(member_name) != members_.end();
}

const EnumMember& Enum::ValueForMember(const std::string& member_name) const {
  ZX_ASSERT(HasMember(member_name));
  return members_.find(member_name)->second;
}

Type SyscallLibrary::TypeFromIdentifier(const std::string& id) const {
  for (const auto& bits : bits_) {
    if (bits->id() == id) {
      // TODO(scottmg): Consider if we need to separate bits from enum here.
      return Type(TypeEnum{bits.get()});
    }
  }

  for (const auto& enm : enums_) {
    if (enm->id() == id) {
      return Type(TypeEnum{enm.get()});
    }
  }

  for (const auto& alias : type_aliases_) {
    if (alias->id() == id) {
      return Type(TypeAlias(alias.get()));
    }
  }

  for (const auto& strukt : structs_) {
    if (strukt->id() == id) {
      return Type(TypeStruct(strukt.get()));
    }
  }

  // TODO: Load struct, union, usings and return one of them here!
  ZX_ASSERT_MSG(false, "unhandled TypeFromIdentifier for %s", id.c_str());
  return Type();
}

Type SyscallLibrary::TypeFromName(const std::string& name) const {
  if (auto primitive = PrimitiveTypeFromName(name); primitive.has_value()) {
    return primitive.value();
  }
  return TypeFromIdentifier(name);
}

void SyscallLibrary::FilterSyscalls(const std::set<std::string>& attributes_to_exclude) {
  std::vector<std::unique_ptr<Syscall>> filtered;
  for (auto& syscall : syscalls_) {
    if (std::any_of(
            attributes_to_exclude.begin(), attributes_to_exclude.end(),
            [&syscall](const std::string& x) { return syscall->HasAttribute(x.c_str()); })) {
      continue;
    }

    filtered.push_back(std::move(syscall));
  }

  syscalls_ = std::move(filtered);
}

// static
bool SyscallLibraryLoader::FromJson(const std::string& json_ir, SyscallLibrary* library) {
  rapidjson::Document document;
  document.Parse(json_ir);

  // Maybe do schema validation here, though we rely on fidlc for many details
  // and general sanity, so probably only in a diagnostic mode.

  if (!document.IsObject()) {
    fprintf(stderr, "Root of json wasn't object.\n");
    return false;
  }

  library->name_ = document["name"].GetString();
  if (library->name_ != "zz" && library->name_ != "zx" && library->name_ != "zxio") {
    fprintf(stderr, "Library name %s wasn't zz or zx or zxio as expected.\n",
            library->name_.c_str());
    return false;
  }

  ZX_ASSERT(library->syscalls_.empty());

  // The order of these loads is significant. For example, enums must be loaded to be able to be
  // referred to by interface methods.

  if (!LoadBits(document, library)) {
    return false;
  }

  if (!LoadEnums(document, library)) {
    return false;
  }

  if (!LoadTypeAliases(document, library)) {
    return false;
  }

  if (!LoadStructs(document, library)) {
    return false;
  }

  if (!LoadTables(document, library)) {
    return false;
  }

  if (!LoadInterfaces(document, library)) {
    return false;
  }

  return true;
}

// 'bits' are currently handled the same as enums, so just use Enum for now as the underlying
// data storage.
//
// static
std::unique_ptr<Enum> SyscallLibraryLoader::ConvertBitsOrEnumMember(const rapidjson::Value& json) {
  auto obj = std::make_unique<Enum>();
  std::string full_name = json["name"].GetString();
  obj->id_ = full_name;
  std::string stripped = StripLibraryName(full_name);
  obj->original_name_ = stripped;
  obj->base_name_ = CamelToSnake(stripped);
  std::string doc_attribute = GetDocAttribute(json);
  obj->description_ = GetCleanDocAttribute(doc_attribute);
  const rapidjson::Value& type = json["type"];
  if (type.IsString()) {
    // Enum
    obj->underlying_type_ = PrimitiveTypeFromName(type.GetString()).value();
  } else {
    ZX_ASSERT(type.IsObject());
    // Bits
    ZX_ASSERT_MSG(type["kind"].GetString() == std::string("primitive"),
                  "Enum %s not backed by primitive type", full_name.c_str());
    const rapidjson::Value& subtype_value = type["subtype"];
    ZX_ASSERT(subtype_value.IsString());
    std::string subtype = subtype_value.GetString();
    obj->underlying_type_ = PrimitiveTypeFromName(subtype).value();
  }
  for (const auto& member : json["members"].GetArray()) {
    ZX_ASSERT_MSG(member["value"]["kind"] == "literal", "TODO: More complex value expressions");
    uint64_t member_value;
    std::string decimal = member["value"]["literal"]["value"].GetString();
    if (obj->underlying_type().IsUnsignedInt()) {
      member_value = StringToUInt(decimal);
    } else if (obj->underlying_type().IsSignedInt()) {
      member_value = StringToInt(decimal);
    } else {
      ZX_PANIC("Unreachable");
    }
    std::string doc_attribute = GetDocAttribute(member);
    obj->AddMember(
        member["name"].GetString(),
        EnumMember{.value = member_value, .description = GetCleanDocAttribute(doc_attribute)});
  }
  return obj;
}

// static
bool SyscallLibraryLoader::LoadBits(const rapidjson::Document& document, SyscallLibrary* library) {
  for (const auto& bits_json : document["bits_declarations"].GetArray()) {
    library->bits_.push_back(ConvertBitsOrEnumMember(bits_json));
  }
  return true;
}

// static
bool SyscallLibraryLoader::LoadEnums(const rapidjson::Document& document, SyscallLibrary* library) {
  for (const auto& enum_json : document["enum_declarations"].GetArray()) {
    library->enums_.push_back(ConvertBitsOrEnumMember(enum_json));
  }
  return true;
}

// static
bool SyscallLibraryLoader::LoadInterfaces(const rapidjson::Document& document,
                                          SyscallLibrary* library) {
  for (const auto& interface : document["interface_declarations"].GetArray()) {
    if (!ValidateTransport(interface)) {
      fprintf(stderr, "Expected Transport to be Syscall.\n");
      return false;
    }

    std::string interface_name = interface["name"].GetString();
    std::string category = GetCategory(interface, interface_name);

    for (const auto& method : interface["methods"].GetArray()) {
      auto syscall = std::make_unique<Syscall>();
      syscall->id_ = interface_name;
      syscall->original_name_ = method["name"].GetString();
      syscall->category_ = category;
      std::string snake_name = CamelToSnake(method["name"].GetString());
      if (!StartsWith(snake_name, category)) {
        snake_name = category + (category.empty() ? "" : "_") + snake_name;
      }
      syscall->name_ = snake_name;
      syscall->is_noreturn_ = !method["has_response"].GetBool();
      const auto doc_attribute = GetDocAttribute(method);
      syscall->short_description_ = GetShortDescriptionFromDocAttribute(doc_attribute);
      syscall->rights_specs_ = GetRightsSpecsFromDocAttribute(doc_attribute);
      if (method.HasMember("maybe_attributes")) {
        for (const auto& attrib : method["maybe_attributes"].GetArray()) {
          syscall->attributes_[attrib["name"].GetString()] = attrib["value"].GetString();
        }
      }

      ZX_ASSERT(method["has_request"].GetBool());  // Events are not expected in syscalls.

      auto add_struct_members = [&library](Struct* strukt, const rapidjson::Value& arg) {
        const auto* type_alias = arg.HasMember("experimental_maybe_from_type_alias")
                                     ? &arg["experimental_maybe_from_type_alias"]
                                     : nullptr;
        strukt->members_.emplace_back(arg["name"].GetString(),
                                      TypeFromJson(*library, arg["type"], type_alias),
                                      std::map<std::string, std::string>{});
        if (arg.HasMember("maybe_attributes")) {
          for (const auto& attrib : arg["maybe_attributes"].GetArray()) {
            strukt->members_.back().attributes_[attrib["name"].GetString()] =
                attrib["value"].GetString();
          }
        }
      };

      Struct& req = syscall->request_;
      req.id_ = syscall->original_name_ + "#request";
      for (const auto& arg : method["maybe_request"].GetArray()) {
        add_struct_members(&req, arg);
      }

      if (method["has_response"].GetBool()) {
        Struct& resp = syscall->response_;
        resp.id_ = syscall->original_name_ + "#response";
        for (const auto& arg : method["maybe_response"].GetArray()) {
          add_struct_members(&resp, arg);
        }
      }

      if (!syscall->MapRequestResponseToKernelAbi()) {
        return false;
      }

      library->syscalls_.push_back(std::move(syscall));
    }
  }

  return true;
}

// static
bool SyscallLibraryLoader::LoadTypeAliases(const rapidjson::Document& document,
                                           SyscallLibrary* library) {
  for (const auto& type_alias_json : document["type_alias_declarations"].GetArray()) {
    auto obj = std::make_unique<Alias>();
    std::string full_name = type_alias_json["name"].GetString();
    obj->id_ = full_name;
    std::string stripped = StripLibraryName(full_name);
    obj->original_name_ = stripped;
    obj->base_name_ = CamelToSnake(stripped);
    const rapidjson::Value& partial_type_ctor = type_alias_json["partial_type_ctor"];
    ZX_ASSERT(partial_type_ctor.IsObject());
    obj->partial_type_ctor_ = partial_type_ctor["name"].GetString();
    std::string doc_attribute = GetDocAttribute(type_alias_json);
    obj->description_ = GetCleanDocAttribute(doc_attribute);
    library->type_aliases_.push_back(std::move(obj));
  }
  return true;
}

// static
bool SyscallLibraryLoader::LoadStructs(const rapidjson::Document& document,
                                       SyscallLibrary* library) {
  // TODO(scottmg): In transition, we're still relying on the existing Zircon headers to define all
  // these structures. So we only load their names for the time being, which is enough for now to
  // know that there's something in the .fidl file where the struct is declared. Note also that
  // interface parsing fills out request/response "structs", so that code should likely be shared
  // when this is implemented.
  for (const auto& struct_json : document["struct_declarations"].GetArray()) {
    auto obj = std::make_unique<Struct>();
    std::string full_name = struct_json["name"].GetString();
    obj->id_ = full_name;
    std::string stripped = StripLibraryName(full_name);
    obj->original_name_ = stripped;
    obj->base_name_ = CamelToSnake(stripped);
    library->structs_.push_back(std::move(obj));
  }
  return true;
}

// static
bool SyscallLibraryLoader::LoadTables(const rapidjson::Document& document,
                                      SyscallLibrary* library) {
  for (const auto& json : document["table_declarations"].GetArray()) {
    auto obj = std::make_unique<Table>();
    std::string full_name = json["name"].GetString();
    obj->id_ = full_name;
    std::string stripped = StripLibraryName(full_name);
    obj->original_name_ = stripped;
    obj->base_name_ = CamelToSnake(stripped);
    std::string doc_attribute = GetDocAttribute(json);
    obj->description_ = GetCleanDocAttribute(doc_attribute);
    std::vector<TableMember> members;
    for (const auto& member : json["members"].GetArray()) {
      std::string name = member["name"].GetString();
      const auto* type_alias = member.HasMember("experimental_maybe_from_type_alias")
                                    ? &member["experimental_maybe_from_type_alias"]
                                    : nullptr;
      Type type = TypeFromJson(*library, member["type"], type_alias);
      Required required = GetRequiredAttribute(member);
      std::string doc_attribute = GetDocAttribute(member);
      std::vector<std::string> description = GetCleanDocAttribute(doc_attribute);
      members.emplace_back(std::move(name), std::move(type), std::move(description), required);
    }
    obj->members_ = std::move(members);
    library->tables_.push_back(std::move(obj));
  }
  return true;
}
