void go_validator_generator::generate_integer_field_validator()

in compiler/cpp/src/thrift/generate/go_validator_generator.cc [410:626]


void go_validator_generator::generate_integer_field_validator(std::ostream& out,
                                                              const generator_context& context) {
  auto generate_current_type = [](std::ostream& out, t_type* type) {
    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
    switch (tbase) {
    case t_base_type::TYPE_I8:
      out << "int8";
      break;
    case t_base_type::TYPE_I16:
      out << "int16";
      break;
    case t_base_type::TYPE_I32:
      out << "int32";
      break;
    case t_base_type::TYPE_I64:
      out << "int64";
      break;
    default:
      throw "validator error: unsupported integer type: " + type->get_name();
    }
  };

  for (auto it = context.rules.begin(); it != context.rules.end(); it++) {
    const std::vector<validation_value*>& values = (*it)->get_values();
    if (values.size() == 0) {
      continue;
    }

    std::map<std::string, std::string> signs{{"vt.lt", ">="},
                                             {"vt.le", ">"},
                                             {"vt.gt", "<="},
                                             {"vt.ge", "<"}};
    std::string key = (*it)->get_name();
    auto key_it = signs.find(key);
    if (key_it != signs.end()) {
      out << indent() << "if " << context.tgt << " " << key_it->second << " ";
      if (values[0]->is_field_reference()) {
        out << get_field_reference_name(values[0]->get_field_reference());
      } else if (values[0]->is_validation_function()) {
        generate_current_type(out, context.type);
        out << "(";
        validation_value::validation_function* func = values[0]->get_function();
        if (func->name == "len") {
          out << "len(";
          if (func->arguments[0]->is_field_reference()) {
            out << get_field_reference_name(func->arguments[0]->get_field_reference());
          }
          out << ")";
        }
        out << ")";
      } else {
        out << values[0]->get_int();
      }
      out << "{" << '\n';
      indent_up();
      out << indent()
          << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"" + key + "\", \""
          << context.field_symbol << "\", \"" << context.field_symbol << " not valid, rule " << key
          << " check failed\")" << '\n';
      indent_down();
      out << indent() << "}" << '\n';
    } else if (key == "vt.in") {
      if (values.size() > 1) {
        std::string exist = GenID("_exist");
        out << indent() << "var " << exist << " bool" << '\n';

        std::string src = GenID("_src");
        out << indent() << src << " := []";
        generate_current_type(out, context.type);
        out << "{";
        for (auto it = values.begin(); it != values.end(); it++) {
          if (it != values.begin()) {
            out << ", ";
          }
          if ((*it)->is_field_reference()) {
            out << get_field_reference_name((*it)->get_field_reference());
          } else if ((*it)->is_validation_function()) {
            generate_current_type(out, context.type);
            out << "(";
            validation_value::validation_function* func = (*it)->get_function();
            if (func->name == "len") {
              out << "len(";
              if (func->arguments[0]->is_field_reference()) {
                out << get_field_reference_name(func->arguments[0]->get_field_reference());
              }
              out << ")";
            }
            out << ")";
          } else {
            out << (*it)->get_int();
          }
        }
        out << "}" << '\n';

        out << indent() << "for _, src := range " << src << " {" << '\n';
        indent_up();
        out << indent() << "if " << context.tgt << " == src {" << '\n';
        indent_up();
        out << indent() << exist << " = true" << '\n';
        out << indent() << "break" << '\n';
        indent_down();
        out << indent() << "}" << '\n';
        indent_down();
        out << indent() << "}" << '\n';
        out << indent() << "if " << exist << " == false {" << '\n';
      } else {
        out << indent() << "if " << context.tgt << " != ";
        if (values[0]->is_field_reference()) {
          out << get_field_reference_name(values[0]->get_field_reference());
        } else if (values[0]->is_validation_function()) {
          generate_current_type(out, context.type);
          out << "(";
          validation_value::validation_function* func = values[0]->get_function();
          if (func->name == "len") {
            out << "len(";
            if (func->arguments[0]->is_field_reference()) {
              out << get_field_reference_name(func->arguments[0]->get_field_reference());
            }
            out << ")";
          }
          out << ")";
        } else {
          out << values[0]->get_int();
        }
        out << "{" << '\n';
      }
      indent_up();
      out << indent()
          << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.in\", \""
          << context.field_symbol << "\", \"" << context.field_symbol
          << " not valid, rule vt.in check failed\")" << '\n';
      indent_down();
      out << indent() << "}" << '\n';
    } else if (key == "vt.not_in") {
      if (values.size() > 1) {
        std::string src = GenID("_src");
        out << indent() << src << " := []";
        t_base_type::t_base tbase = ((t_base_type*)context.type)->get_base();
        switch (tbase) {
        case t_base_type::TYPE_I8:
          out << "int8";
          break;
        case t_base_type::TYPE_I16:
          out << "int16";
          break;
        case t_base_type::TYPE_I32:
          out << "int32";
          break;
        case t_base_type::TYPE_I64:
          out << "int64";
          break;
        default:
          throw "validator error: unsupported integer type: " + context.type->get_name();
        }
        out << "{";
        for (auto it = values.begin(); it != values.end(); it++) {
          if (it != values.begin()) {
            out << ", ";
          }
          if ((*it)->is_field_reference()) {
            out << get_field_reference_name((*it)->get_field_reference());
          } else if ((*it)->is_validation_function()) {
            generate_current_type(out, context.type);
            out << "(";
            validation_value::validation_function* func = (*it)->get_function();
            if (func->name == "len") {
              out << "len(";
              if (func->arguments[0]->is_field_reference()) {
                out << get_field_reference_name(func->arguments[0]->get_field_reference());
              }
              out << ")";
            }
            out << ")";
          } else {
            out << (*it)->get_int();
          }
        }
        out << "}" << '\n';

        out << indent() << "for _, src := range " << src << " {" << '\n';
        indent_up();
        out << indent() << "if " << context.tgt << " == src {" << '\n';
      } else {
        out << indent() << "if " << context.tgt << " == ";
        if (values[0]->is_field_reference()) {
          out << get_field_reference_name(values[0]->get_field_reference());
        } else if (values[0]->is_validation_function()) {
          generate_current_type(out, context.type);
          out << "(";
          validation_value::validation_function* func = values[0]->get_function();
          if (func->name == "len") {
            out << "len(";
            if (func->arguments[0]->is_field_reference()) {
              out << get_field_reference_name(func->arguments[0]->get_field_reference());
            }
            out << ")";
          }
          out << ")";
        } else {
          out << values[0]->get_int();
        }
        out << "{" << '\n';
      }
      indent_up();
      out << indent()
          << "return thrift.NewValidationException(thrift.VALIDATION_FAILED, \"vt.not_in\", \""
          << context.field_symbol << "\", \"" << context.field_symbol
          << " not valid, rule vt.not_in check failed\")" << '\n';
      indent_down();
      out << indent() << "}" << '\n';
      if (values.size() > 1) {
        indent_down();
        out << indent() << "}" << '\n';
      }
    }
  }
}