std::optional CanonicalName::instantiate()

in source/CanonicalName.cpp [42:99]


std::optional<CanonicalName> CanonicalName::instantiate(
    const Method* method,
    const std::vector<const Feature*>& via_type_ofs) const {
  auto value = template_value();
  mt_assert(value);
  auto canonical_name = *value;

  if (canonical_name.find(k_leaf_name_marker) != std::string::npos) {
    auto callee_name = method->signature();
    boost::algorithm::replace_all(
        canonical_name, k_leaf_name_marker, callee_name);
  }

  // Converts Lcom/SomeMutationData;.setPhoneField:.* to
  // some_mutation:phone_field which follows the graphql notation
  if (canonical_name.find(k_graphql_root_marker) != std::string::npos) {
    auto class_signature = method->get_class()->get_name()->str();
    auto pos = class_signature.find_last_of("/");
    if (pos != std::string::npos && class_signature.size() > (pos + 2)) {
      std::string class_name =
          class_signature.substr(pos + 1, class_signature.size() - pos - 2);
      boost::replace_last(class_name, "Data", "");
      convert_to_lower_underscore(class_name);
      std::string method_name = method->get_name();
      boost::replace_first(method_name, "set", "");
      convert_to_lower_underscore(method_name);
      boost::algorithm::replace_all(
          canonical_name,
          k_graphql_root_marker,
          class_name + ":" + method_name);
    }
  }

  if (canonical_name.find(k_via_type_of_marker) != std::string::npos) {
    if (via_type_ofs.size() == 0) {
      WARNING(
          2,
          "Could not instantiate canonical name template '{}'. Via-type-of feature not available.",
          *value);
      return std::nullopt;
    } else if (via_type_ofs.size() > 1) {
      ERROR(
          1,
          "Could not instantiate canonical name template '{}'. Unable to disambiguate between {} via-type-of features.",
          *value,
          via_type_ofs.size());
      // Should have been verified when parsing models during model-generation.
      mt_assert(false);
      return std::nullopt;
    }

    auto via_type_of = *via_type_ofs.begin();
    boost::algorithm::replace_all(
        canonical_name, k_via_type_of_marker, via_type_of->name());
  }

  return CanonicalName(CanonicalName::InstantiatedValue{canonical_name});
}