string t_hs_generator::render_const_value()

in thrift/compiler/generate/t_hs_generator.cc [495:633]


string t_hs_generator::render_const_value(
    const t_type* type, const t_const_value* value) {
  if (value == nullptr)
    return type_to_default(type);

  type = type->get_true_type();
  ostringstream out;

  if (type->is_base_type()) {
    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
    switch (tbase) {
      case t_base_type::TYPE_STRING:
      case t_base_type::TYPE_BINARY:
        out << '"' << get_escaped_string(value) << '"';
        break;

      case t_base_type::TYPE_BOOL:
        out << (value->get_integer() > 0 ? "True" : "False");
        break;

      case t_base_type::TYPE_BYTE:
      case t_base_type::TYPE_I16:
      case t_base_type::TYPE_I32:
      case t_base_type::TYPE_I64:
        out << value->get_integer();
        break;

      case t_base_type::TYPE_FLOAT:
      case t_base_type::TYPE_DOUBLE:
        if (value->get_type() == t_const_value::CV_INTEGER) {
          out << value->get_integer();
        } else {
          out << value->get_double();
        }
        break;

      default:
        throw std::runtime_error(
            "compiler error: no const of base type " +
            t_base_type::t_base_name(tbase));
    }

  } else if (type->is_enum()) {
    const t_enum* tenum = (t_enum*)type;
    vector<t_enum_value*> constants = tenum->get_enum_values();
    for (auto& c_iter : constants) {
      int val = c_iter->get_value();
      if (val == value->get_integer()) {
        const t_program* prog = type->program();
        if (prog != nullptr)
          out << capitalize(prog->name()) << "_Types.";
        out << capitalize(c_iter->get_name());
        break;
      }
    }

  } else if (type->is_struct() || type->is_xception()) {
    string cname = qualified_type_name(type);
    out << module_part(cname) << "default_" << name_part(cname) << "{";

    const vector<t_field*>& fields = ((t_struct*)type)->get_members();

    const vector<pair<t_const_value*, t_const_value*>>& val = value->get_map();

    bool first = true;
    for (auto& v_iter : val) {
      const t_field* field = nullptr;

      for (auto& f_iter : fields)
        if (f_iter->get_name() == v_iter.first->get_string())
          field = f_iter;

      if (field == nullptr)
        throw std::runtime_error(
            "type error: " + cname + " has no field " +
            v_iter.first->get_string());

      string fname = v_iter.first->get_string();
      string const_value = render_const_value(field->get_type(), v_iter.second);

      out << (first ? "" : ", ");
      out << field_name(cname, fname) << " = ";
      if (field->get_req() == t_field::e_req::optional ||
          ((t_type*)field->get_type())->is_xception()) {
        out << "Just ";
      }
      out << const_value;
      first = false;
    }

    out << "}";

  } else if (type->is_map()) {
    const t_type* ktype = ((t_map*)type)->get_key_type();
    const t_type* vtype = ((t_map*)type)->get_val_type();

    const vector<pair<t_const_value*, t_const_value*>>& val = value->get_map();
    vector<pair<t_const_value*, t_const_value*>>::const_iterator v_iter;

    out << "(Map.fromList [";

    bool first = true;
    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
      string key = render_const_value(ktype, v_iter->first);
      string val = render_const_value(vtype, v_iter->second);
      out << (first ? "" : ",");
      out << "(" << key << "," << val << ")";
      first = false;
    }
    out << "])";

  } else if (type->is_list() || type->is_set()) {
    const t_type* etype = type->is_list() ? ((t_list*)type)->get_elem_type()
                                          : ((t_set*)type)->get_elem_type();

    const vector<t_const_value*>& val = value->get_list();
    vector<t_const_value*>::const_iterator v_iter;

    if (type->is_set())
      out << "(Set.fromList [";
    else
      out << "(" << (use_list_ ? "" : "Vector.fromList [");

    bool first = true;
    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
      out << (first ? "" : ",");
      out << render_const_value(etype, *v_iter);
      first = false;
    }

    out << "])";

  } else {
    throw std::runtime_error(
        "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name());
  }

  return out.str();
}