in mcrouter/lib/config/ConfigPreprocessor.cpp [375:431]
void initParams(const vector<dynamic>& params) {
maxParamCnt_ = minParamCnt_ = params.size();
bool needOptional = false;
for (const auto& param : params) {
bool hasOptional = false;
if (param.isString()) { // param name
params_.emplace_back(param.getString(), nullptr, true);
} else if (param.isObject()) { // object (name & default)
auto name = asStringPiece(
tryGet(param, "name", "Macro param object"),
"Macro param object name");
auto optionalPtr = param.get_ptr("optional");
if (optionalPtr) {
checkLogic(
optionalPtr->isBool(),
"Incorrect definition for parameter '{}' in macro '{}'. Expected "
"optional parameter 'optional' to be boolean, but got {}!",
name,
name_,
optionalPtr->typeName());
}
if (auto defaultPtr = param.get_ptr("default")) {
if (optionalPtr && !optionalPtr->getBool()) {
throwLogic(
"Conflicting options provided for parameter '{}' in "
"macro '{}'. Default was set, but the parameter is also "
"explicitly marked as not optional.",
name,
name_);
}
hasOptional = true;
--minParamCnt_;
params_.emplace_back(name.str(), *defaultPtr, false);
} else if (optionalPtr && optionalPtr->getBool()) {
hasOptional = true;
--minParamCnt_;
params_.emplace_back(name.str(), nullptr, false);
} else {
params_.emplace_back(name.str(), nullptr, true);
}
} else {
throwLogic(
"Macro param is {}, expected string/object", param.typeName());
}
checkLogic(
hasOptional || !needOptional,
"Incorrect defaults/optionals in macro {}. "
"All params after optional/default one should also be "
"optional or have default value",
name_);
needOptional = needOptional || hasOptional;
}
}