string t_go_generator::render_const_value()

in compiler/cpp/src/thrift/generate/t_go_generator.cc [950:1191]


string t_go_generator::render_const_value(t_type* type, t_const_value* value, const string& name, bool opt) {
  string typedef_opt_ptr;
  string typedef_opt;
  if (type->is_typedef()) {
    typedef_opt = publicize(type_name(type));
    typedef_opt_ptr = typedef_opt + "Ptr";
  }
  type = get_true_type(type);
  std::ostringstream out;

  if (type->is_base_type()) {
    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();

    if (opt) {
      switch (tbase) {
        case t_base_type::TYPE_BOOL:
          if (typedef_opt_ptr != "") {
            out << typedef_opt_ptr;
          } else {
            out << "thrift.BoolPtr";
          }
          out << "(";
          out << (value->get_integer() > 0 ? "true" : "false");
          break;

        case t_base_type::TYPE_I8:
          if (typedef_opt_ptr != "") {
            out << typedef_opt_ptr;
          } else {
            out << "thrift.Int8Ptr";
          }
          out << "(";
          out << value->get_integer();
          break;
        case t_base_type::TYPE_I16:
          if (typedef_opt_ptr != "") {
            out << typedef_opt_ptr;
          } else {
            out << "thrift.Int16Ptr";
          }
          out << "(";
          out << value->get_integer();
          break;
        case t_base_type::TYPE_I32:
          if (typedef_opt_ptr != "") {
            out << typedef_opt_ptr;
          } else {
            out << "thrift.Int32Ptr";
          }
          out << "(";
          out << value->get_integer();
          break;
        case t_base_type::TYPE_I64:
          if (typedef_opt_ptr != "") {
            out << typedef_opt_ptr;
          } else {
            out << "thrift.Int64Ptr";
          }
          out << "(";
          out << value->get_integer();
          break;

        case t_base_type::TYPE_DOUBLE:
          if (typedef_opt_ptr != "") {
            out << typedef_opt_ptr;
          } else {
            out << "thrift.Float64Ptr";
          }
          out << "(";
          if (value->get_type() == t_const_value::CV_INTEGER) {
            out << value->get_integer();
          } else {
            out << value->get_double();
          }
          break;

        case t_base_type::TYPE_STRING:
          if (typedef_opt_ptr != "") {
            out << typedef_opt_ptr;
          } else {
            out << "thrift.StringPtr";
          }
          out << "(";
          out << '"' + get_escaped_string(value) + '"';
          break;

        case t_base_type::TYPE_UUID:
          if (typedef_opt_ptr != "") {
            out << typedef_opt_ptr << "(" << typedef_opt;
          } else {
            out << "thrift.TuuidPtr";
          }
          out << "(";
          out << "thrift.Must(thrift.ParseTuuid(\"" + get_escaped_string(value) + "\"))";
          if (typedef_opt_ptr != "") {
            out << ")";
          }
          break;

        default:
          throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
      }
      out << ")";
    } else {
      switch (tbase) {
        case t_base_type::TYPE_STRING:
          if (type->is_binary()) {
            out << "[]byte(\"" << get_escaped_string(value) << "\")";
          } else {
            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_I8:
        case t_base_type::TYPE_I16:
        case t_base_type::TYPE_I32:
        case t_base_type::TYPE_I64:
          if (opt) {
            out << "&(&struct{x int}{";
          }
          out << value->get_integer();
          if (opt) {
            out << "}).x";
          }
          break;

        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;

        case t_base_type::TYPE_UUID:
          if (typedef_opt != "") {
            out << typedef_opt << "(";
          }
          out << "thrift.Must(thrift.ParseTuuid(\"" + get_escaped_string(value) + "\"))";
          if (typedef_opt != "") {
            out << ")";
          }

          break;

        default:
          throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
      }
    }
  } else if (type->is_enum()) {
    if (opt) {
      if (typedef_opt_ptr != "") {
        out << typedef_opt_ptr << "(";
      } else {
        out << type_name(type) << "Ptr(";
      }
    }
    out << value->get_integer();
    if (opt) {
      out << ")";
    }
  } else if (type->is_struct() || type->is_xception()) {
    out << "&" << publicize(type_name(type)) << "{";
    indent_up();
    const vector<t_field*>& fields = ((t_struct*)type)->get_members();
    vector<t_field*>::const_iterator f_iter;
    const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
    map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;

    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
      t_type* field_type = nullptr;
      bool is_optional = false;
      for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
        if ((*f_iter)->get_name() == v_iter->first->get_string()) {
          field_type = (*f_iter)->get_type();
          is_optional = is_pointer_field(*f_iter);
        }
      }

      if (field_type == nullptr) {
        throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
      }
      out << '\n' << indent() << publicize(v_iter->first->get_string()) << ": "
          << render_const_value(field_type, v_iter->second, name, is_optional) << "," << '\n';
    }

    indent_down();
    out << "}";

  } else if (type->is_map()) {
    t_type* ktype = ((t_map*)type)->get_key_type();
    t_type* vtype = ((t_map*)type)->get_val_type();
    const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
    out << "map[" << type_to_go_key_type(ktype) << "]" << type_to_go_type(vtype) << "{" << '\n';
    indent_up();
    map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;

    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
      out << indent() << render_const_value(ktype, v_iter->first, name) << ": "
          << render_const_value(vtype, v_iter->second, name) << "," << '\n';
    }

    indent_down();
    out << indent() << "}";
  } else if (type->is_list()) {
    t_type* etype = ((t_list*)type)->get_elem_type();
    const vector<t_const_value*>& val = value->get_list();
    out << "[]" << type_to_go_type(etype) << "{" << '\n';
    indent_up();
    vector<t_const_value*>::const_iterator v_iter;

    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
      out << indent() << render_const_value(etype, *v_iter, name) << ", ";
    }

    indent_down();
    out << indent() << "}";
  } else if (type->is_set()) {
    t_type* etype = ((t_set*)type)->get_elem_type();
    const vector<t_const_value*>& val = value->get_list();
    out << "[]" << type_to_go_type(etype) << "{" << '\n';
    indent_up();
    vector<t_const_value*>::const_iterator v_iter;

    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
      out << indent() << render_const_value(etype, *v_iter, name) << ", ";
    }

    indent_down();
    out << indent() << "}";
  } else {
    throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name();
  }

  return out.str();
}