File indexing completed on 2025-03-26 01:51:13
0001
0002 #include "FWCore/ParameterSet/interface/IfExistsDescription.h"
0003 #include "FWCore/Utilities/interface/EDMException.h"
0004 #include "FWCore/ParameterSet/interface/DocFormatHelper.h"
0005
0006 #include <algorithm>
0007 #include <sstream>
0008 #include <ostream>
0009 #include <iomanip>
0010
0011 namespace edm {
0012
0013 IfExistsDescription::IfExistsDescription(ParameterDescriptionNode const& node_left,
0014 ParameterDescriptionNode const& node_right)
0015 : node_left_(node_left.clone()), node_right_(node_right.clone()) {}
0016
0017 IfExistsDescription::IfExistsDescription(std::unique_ptr<ParameterDescriptionNode> node_left,
0018 ParameterDescriptionNode const& node_right)
0019 : node_left_(std::move(node_left)), node_right_(node_right.clone()) {}
0020
0021 IfExistsDescription::IfExistsDescription(ParameterDescriptionNode const& node_left,
0022 std::unique_ptr<ParameterDescriptionNode> node_right)
0023 : node_left_(node_left.clone()), node_right_(std::move(node_right)) {}
0024
0025 IfExistsDescription::IfExistsDescription(std::unique_ptr<ParameterDescriptionNode> node_left,
0026 std::unique_ptr<ParameterDescriptionNode> node_right)
0027 : node_left_(std::move(node_left)), node_right_(std::move(node_right)) {}
0028
0029 void IfExistsDescription::checkAndGetLabelsAndTypes_(std::set<std::string>& usedLabels,
0030 std::set<ParameterTypes>& parameterTypes,
0031 std::set<ParameterTypes>& wildcardTypes) const {
0032 std::set<std::string> labelsLeft;
0033 std::set<ParameterTypes> parameterTypesLeft;
0034 std::set<ParameterTypes> wildcardTypesLeft;
0035 node_left_->checkAndGetLabelsAndTypes(labelsLeft, parameterTypesLeft, wildcardTypesLeft);
0036
0037 std::set<std::string> labelsRight;
0038 std::set<ParameterTypes> parameterTypesRight;
0039 std::set<ParameterTypes> wildcardTypesRight;
0040 node_right_->checkAndGetLabelsAndTypes(labelsRight, parameterTypesRight, wildcardTypesRight);
0041
0042 throwIfDuplicateLabels(labelsLeft, labelsRight);
0043 throwIfDuplicateTypes(wildcardTypesLeft, parameterTypesRight);
0044 throwIfDuplicateTypes(wildcardTypesRight, parameterTypesLeft);
0045
0046 usedLabels.insert(labelsLeft.begin(), labelsLeft.end());
0047 usedLabels.insert(labelsRight.begin(), labelsRight.end());
0048
0049 parameterTypes.insert(parameterTypesRight.begin(), parameterTypesRight.end());
0050 parameterTypes.insert(parameterTypesLeft.begin(), parameterTypesLeft.end());
0051
0052 wildcardTypes.insert(wildcardTypesRight.begin(), wildcardTypesRight.end());
0053 wildcardTypes.insert(wildcardTypesLeft.begin(), wildcardTypesLeft.end());
0054 }
0055
0056 void IfExistsDescription::validate_(ParameterSet& pset,
0057 std::set<std::string>& validatedLabels,
0058 Modifier modifier) const {
0059 bool leftExists = node_left_->exists(pset);
0060 bool rightExists = node_right_->exists(pset);
0061
0062 if (!leftExists && !rightExists) {
0063 return;
0064 } else if (leftExists && rightExists) {
0065 node_left_->validate(pset, validatedLabels, Modifier::kNone);
0066 node_right_->validate(pset, validatedLabels, Modifier::kNone);
0067 } else if (leftExists && !rightExists) {
0068 node_left_->validate(pset, validatedLabels, Modifier::kNone);
0069 if (modifier == Modifier::kNone)
0070 node_right_->validate(pset, validatedLabels, Modifier::kNone);
0071 } else if (!leftExists && rightExists) {
0072 node_left_->validate(pset, validatedLabels, Modifier::kNone);
0073 node_right_->validate(pset, validatedLabels, Modifier::kNone);
0074 }
0075 }
0076
0077 void IfExistsDescription::writeCfi_(std::ostream& os,
0078 Modifier modifier,
0079 bool& startWithComma,
0080 int indentation,
0081 CfiOptions& options,
0082 bool& wroteSomething) const {
0083 node_left_->writeCfi(os, modifier, startWithComma, indentation, options, wroteSomething);
0084 node_right_->writeCfi(os, modifier, startWithComma, indentation, options, wroteSomething);
0085 parameterMustBeTyped(options);
0086 }
0087
0088 void IfExistsDescription::print_(std::ostream& os, Modifier modifier, bool writeToCfi, DocFormatHelper& dfh) const {
0089 if (dfh.pass() == 1) {
0090 dfh.indent(os);
0091 os << "IfExists pair:";
0092
0093 const bool optional = (modifier == Modifier::kOptional);
0094 const bool obsolete = (modifier == Modifier::kObsolete);
0095 if (dfh.brief()) {
0096 if (optional)
0097 os << " optional";
0098 if (obsolete)
0099 os << " obsolete";
0100
0101 if (!writeToCfi)
0102 os << " (do not write to cfi)";
0103
0104 os << " see Section " << dfh.section() << "." << dfh.counter() << "\n";
0105 }
0106
0107 else {
0108 os << "\n";
0109 dfh.indent2(os);
0110
0111 if (optional)
0112 os << "optional";
0113 if (obsolete)
0114 os << " obsolete";
0115 if (!writeToCfi)
0116 os << " (do not write to cfi)";
0117 if (optional || !writeToCfi) {
0118 os << "\n";
0119 dfh.indent2(os);
0120 }
0121
0122 os << "see Section " << dfh.section() << "." << dfh.counter() << "\n";
0123
0124 if (!comment().empty()) {
0125 DocFormatHelper::wrapAndPrintText(os, comment(), dfh.startColumn2(), dfh.commentWidth());
0126 }
0127 os << "\n";
0128 }
0129 }
0130 }
0131
0132 void IfExistsDescription::printNestedContent_(std::ostream& os, bool optional, DocFormatHelper& dfh) const {
0133 int indentation = dfh.indentation();
0134 if (dfh.parent() != DocFormatHelper::TOP) {
0135 indentation -= DocFormatHelper::offsetSectionContent();
0136 }
0137
0138 std::stringstream ss;
0139 ss << dfh.section() << "." << dfh.counter();
0140 std::string newSection = ss.str();
0141
0142 printSpaces(os, indentation);
0143 os << "Section " << newSection;
0144 if (optional)
0145 os << " optional";
0146 os << " IfExists pair description:\n";
0147 printSpaces(os, indentation);
0148 if (optional) {
0149 os << "If the first parameter exists, then the second is allowed to exist\n";
0150 } else {
0151 os << "If the first parameter exists, then the second is required to exist\n";
0152 }
0153 if (!dfh.brief())
0154 os << "\n";
0155
0156 DocFormatHelper new_dfh(dfh);
0157 new_dfh.init();
0158 new_dfh.setSection(newSection);
0159 new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
0160 new_dfh.setParent(DocFormatHelper::OTHER);
0161
0162 node_left_->print(os, Modifier::kNone, true, new_dfh);
0163 node_right_->print(os, Modifier::kNone, true, new_dfh);
0164
0165 new_dfh.setPass(1);
0166 new_dfh.setCounter(0);
0167
0168 node_left_->print(os, Modifier::kNone, true, new_dfh);
0169 node_right_->print(os, Modifier::kNone, true, new_dfh);
0170
0171 new_dfh.setPass(2);
0172 new_dfh.setCounter(0);
0173
0174 node_left_->printNestedContent(os, false, new_dfh);
0175 node_right_->printNestedContent(os, false, new_dfh);
0176 }
0177
0178 bool IfExistsDescription::exists_(ParameterSet const& pset) const {
0179 bool leftExists = node_left_->exists(pset);
0180 bool rightExists = node_right_->exists(pset);
0181
0182 if (leftExists && rightExists)
0183 return true;
0184 else if (!leftExists && !rightExists)
0185 return true;
0186 return false;
0187 }
0188
0189 bool IfExistsDescription::partiallyExists_(ParameterSet const& pset) const { return exists(pset); }
0190
0191 int IfExistsDescription::howManyXORSubNodesExist_(ParameterSet const& pset) const { return exists(pset) ? 1 : 0; }
0192
0193 void IfExistsDescription::throwIfDuplicateLabels(std::set<std::string> const& labelsLeft,
0194 std::set<std::string> const& labelsRight) const {
0195 std::set<std::string> duplicateLabels;
0196 std::insert_iterator<std::set<std::string> > insertIter(duplicateLabels, duplicateLabels.begin());
0197 std::set_intersection(labelsLeft.begin(), labelsLeft.end(), labelsRight.begin(), labelsRight.end(), insertIter);
0198 if (!duplicateLabels.empty()) {
0199 std::stringstream ss;
0200 for (std::set<std::string>::const_iterator iter = duplicateLabels.begin(), iEnd = duplicateLabels.end();
0201 iter != iEnd;
0202 ++iter) {
0203 ss << " \"" << *iter << "\"\n";
0204 }
0205 throw edm::Exception(errors::LogicError) << "Labels used in a node of a ParameterSetDescription\n"
0206 << "\"ifExists\" expression must be not be the same as labels used\n"
0207 << "in other nodes of the expression. The following duplicate\n"
0208 << "labels were detected:\n"
0209 << ss.str() << "\n";
0210 }
0211 }
0212
0213 void IfExistsDescription::throwIfDuplicateTypes(std::set<ParameterTypes> const& types1,
0214 std::set<ParameterTypes> const& types2) const {
0215 if (!types1.empty()) {
0216 std::set<ParameterTypes> duplicateTypes;
0217 std::insert_iterator<std::set<ParameterTypes> > insertIter(duplicateTypes, duplicateTypes.begin());
0218 std::set_intersection(types1.begin(), types1.end(), types2.begin(), types2.end(), insertIter);
0219 if (!duplicateTypes.empty()) {
0220 std::stringstream ss;
0221 for (std::set<ParameterTypes>::const_iterator iter = duplicateTypes.begin(), iEnd = duplicateTypes.end();
0222 iter != iEnd;
0223 ++iter) {
0224 ss << " \"" << parameterTypeEnumToString(*iter) << "\"\n";
0225 }
0226 throw edm::Exception(errors::LogicError)
0227 << "Types used for wildcards in a node of a ParameterSetDescription\n"
0228 << "\"ifExists\" expression must be different from types used for other parameters\n"
0229 << "in other nodes. The following duplicate types were detected:\n"
0230 << ss.str() << "\n";
0231 }
0232 }
0233 }
0234 }