Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-26 01:51:13

0001 
0002 #include "FWCore/ParameterSet/src/ORGroupDescription.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   ORGroupDescription::ORGroupDescription(ParameterDescriptionNode const& node_left,
0014                                          ParameterDescriptionNode const& node_right)
0015       : node_left_(node_left.clone()), node_right_(node_right.clone()) {}
0016 
0017   ORGroupDescription::ORGroupDescription(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   ORGroupDescription::ORGroupDescription(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   ORGroupDescription::ORGroupDescription(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 ORGroupDescription::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 ORGroupDescription::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       if (leftExists)
0064         node_left_->validate(pset, validatedLabels, Modifier::kNone);
0065       if (rightExists)
0066         node_right_->validate(pset, validatedLabels, Modifier::kNone);
0067       return;
0068     }
0069 
0070     if (modifier != Modifier::kNone)
0071       return;
0072 
0073     node_left_->validate(pset, validatedLabels, Modifier::kNone);
0074   }
0075 
0076   void ORGroupDescription::writeCfi_(std::ostream& os,
0077                                      Modifier modifier,
0078                                      bool& startWithComma,
0079                                      int indentation,
0080                                      CfiOptions& options,
0081                                      bool& wroteSomething) const {
0082     node_left_->writeCfi(os, modifier, startWithComma, indentation, options, wroteSomething);
0083   }
0084 
0085   void ORGroupDescription::print_(std::ostream& os, Modifier modifier, bool writeToCfi, DocFormatHelper& dfh) const {
0086     if (dfh.parent() == DocFormatHelper::OR) {
0087       dfh.decrementCounter();
0088       node_left_->print(os, Modifier::kNone, true, dfh);
0089       node_right_->print(os, Modifier::kNone, true, dfh);
0090       return;
0091     }
0092 
0093     const bool optional = (modifier == Modifier::kOptional);
0094     const bool obsolete = (modifier == Modifier::kObsolete);
0095     if (dfh.pass() == 1) {
0096       dfh.indent(os);
0097       os << "OR group:";
0098 
0099       if (dfh.brief()) {
0100         if (optional)
0101           os << " optional";
0102         if (obsolete)
0103           os << " obsolete";
0104 
0105         if (!writeToCfi)
0106           os << " (do not write to cfi)";
0107 
0108         os << " see Section " << dfh.section() << "." << dfh.counter() << "\n";
0109       }
0110       // not brief
0111       else {
0112         os << "\n";
0113         dfh.indent2(os);
0114 
0115         if (optional)
0116           os << "optional";
0117         if (obsolete)
0118           os << " obsolete";
0119         if (!writeToCfi)
0120           os << " (do not write to cfi)";
0121         if (optional || !writeToCfi) {
0122           os << "\n";
0123           dfh.indent2(os);
0124         }
0125 
0126         os << "see Section " << dfh.section() << "." << dfh.counter() << "\n";
0127 
0128         if (!comment().empty()) {
0129           DocFormatHelper::wrapAndPrintText(os, comment(), dfh.startColumn2(), dfh.commentWidth());
0130         }
0131         os << "\n";
0132       }
0133     }
0134   }
0135 
0136   void ORGroupDescription::printNestedContent_(std::ostream& os, bool optional, DocFormatHelper& dfh) const {
0137     if (dfh.parent() == DocFormatHelper::OR) {
0138       dfh.decrementCounter();
0139       node_left_->printNestedContent(os, false, dfh);
0140       node_right_->printNestedContent(os, false, dfh);
0141       return;
0142     }
0143 
0144     int indentation = dfh.indentation();
0145     if (dfh.parent() != DocFormatHelper::TOP) {
0146       indentation -= DocFormatHelper::offsetSectionContent();
0147     }
0148 
0149     std::stringstream ss;
0150     ss << dfh.section() << "." << dfh.counter();
0151     std::string newSection = ss.str();
0152 
0153     printSpaces(os, indentation);
0154     os << "Section " << newSection << " OR group description:\n";
0155     printSpaces(os, indentation);
0156     if (optional) {
0157       // An optional OR group is kind of pointless, it would be
0158       // easier just make the parameters be independent optional parameters
0159       // I only allow it to make the behavior analogous to the other groups
0160       os << "This optional OR group requires at least one or none of the following to be in the PSet\n";
0161     } else {
0162       os << "This OR group requires at least one of the following to be in the PSet\n";
0163     }
0164     if (!dfh.brief())
0165       os << "\n";
0166 
0167     DocFormatHelper new_dfh(dfh);
0168     new_dfh.init();
0169     new_dfh.setSection(newSection);
0170     new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
0171     new_dfh.setParent(DocFormatHelper::OR);
0172 
0173     node_left_->print(os, Modifier::kNone, true, new_dfh);
0174     node_right_->print(os, Modifier::kNone, true, new_dfh);
0175 
0176     new_dfh.setPass(1);
0177     new_dfh.setCounter(0);
0178 
0179     node_left_->print(os, Modifier::kNone, true, new_dfh);
0180     node_right_->print(os, Modifier::kNone, true, new_dfh);
0181 
0182     new_dfh.setPass(2);
0183     new_dfh.setCounter(0);
0184 
0185     node_left_->printNestedContent(os, false, new_dfh);
0186     node_right_->printNestedContent(os, false, new_dfh);
0187   }
0188 
0189   bool ORGroupDescription::exists_(ParameterSet const& pset) const {
0190     return node_left_->exists(pset) || node_right_->exists(pset);
0191   }
0192 
0193   bool ORGroupDescription::partiallyExists_(ParameterSet const& pset) const { return exists(pset); }
0194 
0195   int ORGroupDescription::howManyXORSubNodesExist_(ParameterSet const& pset) const { return exists(pset) ? 1 : 0; }
0196 
0197   void ORGroupDescription::throwIfDuplicateLabels(std::set<std::string> const& labelsLeft,
0198                                                   std::set<std::string> const& labelsRight) const {
0199     std::set<std::string> duplicateLabels;
0200     std::insert_iterator<std::set<std::string> > insertIter(duplicateLabels, duplicateLabels.begin());
0201     std::set_intersection(labelsLeft.begin(), labelsLeft.end(), labelsRight.begin(), labelsRight.end(), insertIter);
0202     if (!duplicateLabels.empty()) {
0203       std::stringstream ss;
0204       for (std::set<std::string>::const_iterator iter = duplicateLabels.begin(), iEnd = duplicateLabels.end();
0205            iter != iEnd;
0206            ++iter) {
0207         ss << " \"" << *iter << "\"\n";
0208       }
0209       throw edm::Exception(errors::LogicError) << "Labels used in a node of a ParameterSetDescription\n"
0210                                                << "\"or\" expression must be not be the same as labels used\n"
0211                                                << "in other nodes of the expression.  The following duplicate\n"
0212                                                << "labels were detected:\n"
0213                                                << ss.str() << "\n";
0214     }
0215   }
0216 
0217   void ORGroupDescription::throwIfDuplicateTypes(std::set<ParameterTypes> const& types1,
0218                                                  std::set<ParameterTypes> const& types2) const {
0219     if (!types1.empty()) {
0220       std::set<ParameterTypes> duplicateTypes;
0221       std::insert_iterator<std::set<ParameterTypes> > insertIter(duplicateTypes, duplicateTypes.begin());
0222       std::set_intersection(types1.begin(), types1.end(), types2.begin(), types2.end(), insertIter);
0223       if (!duplicateTypes.empty()) {
0224         std::stringstream ss;
0225         for (std::set<ParameterTypes>::const_iterator iter = duplicateTypes.begin(), iEnd = duplicateTypes.end();
0226              iter != iEnd;
0227              ++iter) {
0228           ss << " \"" << parameterTypeEnumToString(*iter) << "\"\n";
0229         }
0230         throw edm::Exception(errors::LogicError)
0231             << "Types used for wildcards in a node of a ParameterSetDescription\n"
0232             << "\"or\" expression must be different from types used for other parameters\n"
0233             << "in other nodes.  The following duplicate types were detected:\n"
0234             << ss.str() << "\n";
0235       }
0236     }
0237   }
0238 }  // namespace edm