Back to home page

Project CMSSW displayed by LXR

 
 

    


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       // not brief
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 }  // namespace edm