Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef FWCore_ParameterSet_ParameterSetDescription_h
0002 #define FWCore_ParameterSet_ParameterSetDescription_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     ParameterSet
0006 // Class  :     ParameterSetDescription
0007 //
0008 /**\class ParameterSetDescription ParameterSetDescription.h FWCore/ParameterSet/interface/ParameterSetDescription.h
0009 
0010  Description: Used to describe the allowed values in a ParameterSet
0011 
0012  Usage:
0013     <usage>
0014 
0015 
0016  Implementation Details:
0017 
0018     Note that there are some comments in the file ParameterDescriptionNode.h
0019     that might be useful for someone attempting to understand the implementation
0020     details.  This class holds a container full of nodes.  One node can represent
0021     a description of a single parameter or some logical restriction on the
0022     combinations of parameters allowed in a ParameterSet.  Often these logical
0023     restrictions are implemented by the nodes themselves containing a tree
0024     structure of other nodes.
0025 */
0026 //
0027 // Original Author:  Chris Jones
0028 //         Created:  Tue Jul 31 15:18:40 EDT 2007
0029 //
0030 
0031 #include "FWCore/Utilities/interface/value_ptr.h"
0032 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
0033 
0034 #include <vector>
0035 #include <set>
0036 #include <string>
0037 #include <memory>
0038 #include <iosfwd>
0039 
0040 namespace edm {
0041 
0042   class ParameterSet;
0043   class ParameterDescriptionBase;
0044   class ParameterWildcardBase;
0045   class ParameterDescriptionNode;
0046   template <typename T>
0047   class ParameterDescription;
0048   template <typename T>
0049   class ParameterDescriptionCases;
0050   class DocFormatHelper;
0051 
0052   class ParameterSetDescription {
0053   public:
0054     using Modifier = ParameterModifier;
0055     class SetDescriptionEntry {
0056     public:
0057       bool optional() const { return modifier_ == Modifier::kOptional; }
0058       bool obsolete() const { return modifier_ == Modifier::kObsolete; }
0059       Modifier modifier() const { return modifier_; }
0060       bool writeToCfi() const { return writeToCfi_; }
0061       edm::value_ptr<ParameterDescriptionNode> const& node() const { return node_; }
0062 
0063       void setModifier(Modifier value) { modifier_ = value; }
0064       void setWriteToCfi(bool value) { writeToCfi_ = value; }
0065       ParameterDescriptionNode* setNode(std::unique_ptr<ParameterDescriptionNode> node) {
0066         node_ = std::move(node);
0067         return node_.operator->();
0068       }
0069 
0070     private:
0071       Modifier modifier_;
0072       bool writeToCfi_;
0073       edm::value_ptr<ParameterDescriptionNode> node_;
0074     };
0075 
0076     typedef std::vector<SetDescriptionEntry> SetDescriptionEntries;
0077     typedef SetDescriptionEntries::const_iterator const_iterator;
0078 
0079     ParameterSetDescription();
0080     virtual ~ParameterSetDescription();
0081 
0082     std::string const& comment() const { return comment_; }
0083     void setComment(std::string const& value);
0084     void setComment(char const* value);
0085 
0086     ///allow any parameter label/value pairs
0087     void setAllowAnything();
0088 
0089     // This is set only for parameterizables which have not set their descriptions.
0090     // This should only be called to allow backwards compatibility.
0091     void setUnknown();
0092 
0093     // ***** In these next 8 functions named "add", T is the parameter type ******
0094     // Exceptions: For parameters of type ParameterSet, T should be a
0095     // ParameterSetDescription instead of a ParameterSet.  And do not
0096     // use these next 8 functions for parameters of type vector<ParameterSet>
0097 
0098     template <typename T, typename U>
0099     ParameterDescriptionBase* add(U const& iLabel, T const& value) {
0100       return add<T, U>(iLabel, value, true, Modifier::kNone, true);
0101     }
0102 
0103     template <typename T, typename U>
0104     ParameterDescriptionBase* addUntracked(U const& iLabel, T const& value) {
0105       return add<T, U>(iLabel, value, false, Modifier::kNone, true);
0106     }
0107 
0108     template <typename T, typename U>
0109     ParameterDescriptionBase* addOptional(U const& iLabel, T const& value) {
0110       return add<T, U>(iLabel, value, true, Modifier::kOptional, true);
0111     }
0112 
0113     template <typename T, typename U>
0114     ParameterDescriptionBase* addOptionalUntracked(U const& iLabel, T const& value) {
0115       return add<T, U>(iLabel, value, false, Modifier::kOptional, true);
0116     }
0117 
0118     // For the next 4 functions, there is no default so they will not get injected
0119     // during validation if missing and they will not get written into cfi files.
0120 
0121     template <typename T, typename U>
0122     ParameterDescriptionBase* add(U const& iLabel) {
0123       return add<T, U>(iLabel, true, Modifier::kNone, true);
0124     }
0125 
0126     template <typename T, typename U>
0127     ParameterDescriptionBase* addUntracked(U const& iLabel) {
0128       return add<T, U>(iLabel, false, Modifier::kNone, true);
0129     }
0130 
0131     template <typename T, typename U>
0132     ParameterDescriptionBase* addOptional(U const& iLabel) {
0133       return add<T, U>(iLabel, true, Modifier::kOptional, true);
0134     }
0135 
0136     template <typename T, typename U>
0137     ParameterDescriptionBase* addOptionalUntracked(U const& iLabel) {
0138       return add<T, U>(iLabel, false, Modifier::kOptional, true);
0139     }
0140 
0141     template <typename T, typename U>
0142     ParameterDescriptionBase* addObsolete(U const& iLabel) {
0143       if constexpr (std::is_same_v<T, edm::ParameterSetDescription>) {
0144         return add<T, U>(iLabel, T(), true, Modifier::kObsolete, true);
0145       } else {
0146         return add<T, U>(iLabel, true, Modifier::kObsolete, true);
0147       }
0148     }
0149 
0150     template <typename T, typename U>
0151     ParameterDescriptionBase* addObsoleteUntracked(U const& iLabel) {
0152       if constexpr (std::is_same_v<T, edm::ParameterSetDescription>) {
0153         return add<T, U>(iLabel, T(), false, Modifier::kObsolete, true);
0154       } else {
0155         return add<T, U>(iLabel, false, Modifier::kObsolete, true);
0156       }
0157     }
0158 
0159     // ***** Use these 8 functions for parameters of type vector<ParameterSet> *****
0160     // When a vector<ParameterSet> appears in a configuration, all of its
0161     // elements will be validated using the description in the argument named
0162     // "validator" below.  The argument named "defaults" is used when the
0163     // a vector<ParameterSet> is required to be in the configuration and
0164     // is absent.  Note that these default ParameterSet's will be validated
0165     // as if they had appeared in the configuration so they must be consistent
0166     // with the description and missing parameters that have defaults in
0167     // in the description will be inserted during validation.  These defaults
0168     // are also used when writing cfi files.
0169 
0170     template <typename U>
0171     ParameterDescriptionBase* addVPSet(U const& iLabel,
0172                                        ParameterSetDescription const& validator,
0173                                        std::vector<ParameterSet> const& defaults) {
0174       return addVPSet<U>(iLabel, validator, defaults, true, Modifier::kNone, true);
0175     }
0176 
0177     template <typename U>
0178     ParameterDescriptionBase* addVPSetUntracked(U const& iLabel,
0179                                                 ParameterSetDescription const& validator,
0180                                                 std::vector<ParameterSet> const& defaults) {
0181       return addVPSet<U>(iLabel, validator, defaults, false, Modifier::kNone, true);
0182     }
0183 
0184     template <typename U>
0185     ParameterDescriptionBase* addVPSetOptional(U const& iLabel,
0186                                                ParameterSetDescription const& validator,
0187                                                std::vector<ParameterSet> const& defaults) {
0188       return addVPSet<U>(iLabel, validator, defaults, true, Modifier::kOptional, true);
0189     }
0190 
0191     template <typename U>
0192     ParameterDescriptionBase* addVPSetOptionalUntracked(U const& iLabel,
0193                                                         ParameterSetDescription const& validator,
0194                                                         std::vector<ParameterSet> const& defaults) {
0195       return addVPSet<U>(iLabel, validator, defaults, false, Modifier::kOptional, true);
0196     }
0197 
0198     template <typename U>
0199     ParameterDescriptionBase* addVPSet(U const& iLabel, ParameterSetDescription const& validator) {
0200       return addVPSet<U>(iLabel, validator, true, Modifier::kNone, true);
0201     }
0202 
0203     template <typename U>
0204     ParameterDescriptionBase* addVPSetUntracked(U const& iLabel, ParameterSetDescription const& validator) {
0205       return addVPSet<U>(iLabel, validator, false, Modifier::kNone, true);
0206     }
0207 
0208     template <typename U>
0209     ParameterDescriptionBase* addVPSetOptional(U const& iLabel, ParameterSetDescription const& validator) {
0210       return addVPSet<U>(iLabel, validator, true, Modifier::kOptional, true);
0211     }
0212 
0213     template <typename U>
0214     ParameterDescriptionBase* addVPSetOptionalUntracked(U const& iLabel, ParameterSetDescription const& validator) {
0215       return addVPSet<U>(iLabel, validator, false, Modifier::kOptional, true);
0216     }
0217 
0218     template <typename U>
0219     ParameterDescriptionBase* addVPSetObsolete(U const& iLabel) {
0220       ParameterSetDescription validator;
0221       return addVPSet<U>(iLabel, validator, true, Modifier::kObsolete, true);
0222     }
0223     template <typename U>
0224     ParameterDescriptionBase* addVPSetObsoleteUntracked(U const& iLabel) {
0225       ParameterSetDescription validator;
0226       return addVPSet<U>(iLabel, validator, false, Modifier::kObsolete, true);
0227     }
0228 
0229     // ********* Wildcards *********
0230 
0231     template <typename T, typename U>
0232     ParameterWildcardBase* addWildcard(U const& pattern) {
0233       return addWildcard<T, U>(pattern, true);
0234     }
0235 
0236     template <typename T, typename U>
0237     ParameterWildcardBase* addWildcardUntracked(U const& pattern) {
0238       return addWildcard<T, U>(pattern, false);
0239     }
0240 
0241     // ********* Used to insert generic nodes of any type ************
0242 
0243     ParameterDescriptionNode* addNode(ParameterDescriptionNode const& node);
0244     ParameterDescriptionNode* addNode(std::unique_ptr<ParameterDescriptionNode> node);
0245     ParameterDescriptionNode* addOptionalNode(ParameterDescriptionNode const& node, bool writeToCfi);
0246     ParameterDescriptionNode* addOptionalNode(std::unique_ptr<ParameterDescriptionNode> node, bool writeToCfi);
0247 
0248     // ********* Switches ************
0249     // ifValue will only work with type T as a bool, int, or string.
0250     // T holds the value of the switch variable.
0251     // If you try using any other type, then it will not compile.
0252     template <typename T>
0253     ParameterDescriptionNode* ifValue(ParameterDescription<T> const& switchParameter,
0254                                       std::unique_ptr<ParameterDescriptionCases<T>> cases) {
0255       return ifValue<T>(switchParameter, std::move(cases), Modifier::kNone, true);
0256     }
0257 
0258     template <typename T>
0259     ParameterDescriptionNode* ifValueOptional(ParameterDescription<T> const& switchParameter,
0260                                               std::unique_ptr<ParameterDescriptionCases<T>> cases,
0261                                               bool writeToCfi) {
0262       return ifValue<T>(switchParameter, std::move(cases), Modifier::kOptional, writeToCfi);
0263     }
0264 
0265     // ********* if exists ************
0266     ParameterDescriptionNode* ifExists(ParameterDescriptionNode const& node1, ParameterDescriptionNode const& node2) {
0267       return ifExists(node1, node2, Modifier::kNone, true);
0268     }
0269 
0270     ParameterDescriptionNode* ifExistsOptional(ParameterDescriptionNode const& node1,
0271                                                ParameterDescriptionNode const& node2,
0272                                                bool writeToCfi) {
0273       return ifExists(node1, node2, Modifier::kOptional, writeToCfi);
0274     }
0275 
0276     // ********* for parameters that are a list of allowed labels *********
0277     template <typename T, typename U>
0278     ParameterDescriptionNode* labelsFrom(U const& iLabel) {
0279       return labelsFrom<T, U>(iLabel, true, Modifier::kNone, true);
0280     }
0281 
0282     template <typename T, typename U>
0283     ParameterDescriptionNode* labelsFromUntracked(U const& iLabel) {
0284       return labelsFrom<T, U>(iLabel, false, Modifier::kNone, true);
0285     }
0286 
0287     template <typename T, typename U>
0288     ParameterDescriptionNode* labelsFromOptional(U const& iLabel, bool writeToCfi) {
0289       return labelsFrom<T, U>(iLabel, true, Modifier::kOptional, writeToCfi);
0290     }
0291 
0292     template <typename T, typename U>
0293     ParameterDescriptionNode* labelsFromOptionalUntracked(U const& iLabel, bool writeToCfi) {
0294       return labelsFrom<T, U>(iLabel, false, Modifier::kOptional, writeToCfi);
0295     }
0296 
0297     // These next four functions only work when the template
0298     // parameters are:
0299     // T = ParameterSetDescription and V = ParameterSetDescription
0300     // or
0301     // T = vector<ParameterSet> and V = ParameterSetDescription
0302     // In either case U can be either a string or char*
0303     // Note the U and V can be determined from the arguments, but
0304     // T must be explicitly specified by the calling function.
0305     template <typename T, typename U, typename V>
0306     ParameterDescriptionNode* labelsFrom(U const& iLabel, V const& desc) {
0307       return labelsFrom<T, U, V>(iLabel, true, Modifier::kNone, true, desc);
0308     }
0309 
0310     template <typename T, typename U, typename V>
0311     ParameterDescriptionNode* labelsFromUntracked(U const& iLabel, V const& desc) {
0312       return labelsFrom<T, U, V>(iLabel, false, Modifier::kNone, true, desc);
0313     }
0314 
0315     template <typename T, typename U, typename V>
0316     ParameterDescriptionNode* labelsFromOptional(U const& iLabel, bool writeToCfi, V const& desc) {
0317       return labelsFrom<T, U, V>(iLabel, true, Modifier::kOptional, writeToCfi, desc);
0318     }
0319 
0320     template <typename T, typename U, typename V>
0321     ParameterDescriptionNode* labelsFromOptionalUntracked(U const& iLabel, bool writeToCfi, V const& desc) {
0322       return labelsFrom<T, U, V>(iLabel, false, Modifier::kOptional, writeToCfi, desc);
0323     }
0324 
0325     bool anythingAllowed() const { return anythingAllowed_; }
0326     bool isUnknown() const { return unknown_; }
0327 
0328     const_iterator begin() const { return entries_.begin(); }
0329 
0330     const_iterator end() const { return entries_.end(); }
0331 
0332     bool empty() const noexcept { return entries_.empty(); }
0333     // Better performance if space is reserved for the number of
0334     // top level parameters before any are added.
0335     void reserve(SetDescriptionEntries::size_type n) { entries_.reserve(n); }
0336 
0337     void validate(ParameterSet& pset) const;
0338 
0339     void writeCfi(std::ostream& os, bool startWithComma, int indentation, CfiOptions&) const;
0340 
0341     void print(std::ostream& os, DocFormatHelper& dfh) const;
0342 
0343     bool isLabelUnused(std::string const& label) const;
0344 
0345   private:
0346     template <typename T, typename U>
0347     ParameterDescriptionBase* add(U const& iLabel, T const& value, bool isTracked, Modifier modifier, bool writeToCfi);
0348 
0349     template <typename T, typename U>
0350     ParameterDescriptionBase* add(U const& iLabel, bool isTracked, Modifier modifier, bool writeToCfi);
0351 
0352     template <typename U>
0353     ParameterDescriptionBase* addVPSet(U const& iLabel,
0354                                        ParameterSetDescription const& validator,
0355                                        std::vector<ParameterSet> const& defaults,
0356                                        bool isTracked,
0357                                        Modifier modifier,
0358                                        bool writeToCfi);
0359 
0360     template <typename U>
0361     ParameterDescriptionBase* addVPSet(
0362         U const& iLabel, ParameterSetDescription const& validator, bool isTracked, Modifier modifier, bool writeToCfi);
0363 
0364     template <typename T, typename U>
0365     ParameterWildcardBase* addWildcard(U const& pattern, bool isTracked);
0366 
0367     ParameterDescriptionNode* addNode(std::unique_ptr<ParameterDescriptionNode> node,
0368                                       Modifier modifier,
0369                                       bool writeToCfi);
0370 
0371     template <typename T>
0372     ParameterDescriptionNode* ifValue(ParameterDescription<T> const& switchParameter,
0373                                       std::unique_ptr<ParameterDescriptionCases<T>> cases,
0374                                       Modifier modifier,
0375                                       bool writeToCfi);
0376 
0377     ParameterDescriptionNode* ifExists(ParameterDescriptionNode const& node1,
0378                                        ParameterDescriptionNode const& node2,
0379                                        Modifier modifier,
0380                                        bool writeToCfi);
0381 
0382     template <typename T, typename U>
0383     ParameterDescriptionNode* labelsFrom(U const& iLabel, bool isTracked, Modifier modifier, bool writeToCfi);
0384 
0385     template <typename T, typename U, typename V>
0386     ParameterDescriptionNode* labelsFrom(
0387         U const& iLabel, bool isTracked, Modifier modifier, bool writeToCfi, V const& desc);
0388 
0389     static void validateNode(SetDescriptionEntry const& entry,
0390                              ParameterSet& pset,
0391                              std::set<std::string>& validatedNames);
0392 
0393     static void throwIllegalParameters(std::vector<std::string> const& parameterNames,
0394                                        std::set<std::string> const& validatedNames);
0395 
0396     static void writeNode(SetDescriptionEntry const& entry,
0397                           std::ostream& os,
0398                           bool& startWithComma,
0399                           int indentation,
0400                           CfiOptions&,
0401                           bool& wroteSomething);
0402 
0403     static void printNode(SetDescriptionEntry const& entry, std::ostream& os, DocFormatHelper& dfh);
0404 
0405     void throwIfLabelsAlreadyUsed(std::set<std::string> const& nodeLabels);
0406     void throwIfWildcardCollision(std::set<ParameterTypes> const& nodeParameterTypes,
0407                                   std::set<ParameterTypes> const& nodeWildcardTypes);
0408 
0409     bool anythingAllowed_;
0410     bool unknown_;
0411     SetDescriptionEntries entries_;
0412 
0413     std::set<std::string> usedLabels_;
0414     std::set<ParameterTypes> typesUsedForParameters_;
0415     std::set<ParameterTypes> typesUsedForWildcards_;
0416 
0417     std::string comment_;
0418   };
0419 }  // namespace edm
0420 
0421 #include "FWCore/ParameterSet/interface/ParameterWildcard.h"
0422 #include "FWCore/ParameterSet/interface/ParameterSwitch.h"
0423 #include "FWCore/ParameterSet/interface/AllowedLabelsDescription.h"
0424 
0425 namespace edm {
0426 
0427   template <typename T, typename U>
0428   ParameterDescriptionBase* ParameterSetDescription::add(
0429       U const& iLabel, T const& value, bool isTracked, Modifier modifier, bool writeToCfi) {
0430     std::unique_ptr<ParameterDescriptionNode> node =
0431         std::make_unique<ParameterDescription<T>>(iLabel, value, isTracked);
0432     ParameterDescriptionNode* pnode = addNode(std::move(node), modifier, writeToCfi);
0433     return static_cast<ParameterDescriptionBase*>(pnode);
0434   }
0435 
0436   template <typename T, typename U>
0437   ParameterDescriptionBase* ParameterSetDescription::add(U const& iLabel,
0438                                                          bool isTracked,
0439                                                          Modifier modifier,
0440                                                          bool writeToCfi) {
0441     std::unique_ptr<ParameterDescriptionNode> node = std::make_unique<ParameterDescription<T>>(iLabel, isTracked);
0442     ParameterDescriptionNode* pnode = addNode(std::move(node), modifier, writeToCfi);
0443     return static_cast<ParameterDescriptionBase*>(pnode);
0444   }
0445 
0446   template <typename U>
0447   ParameterDescriptionBase* ParameterSetDescription::addVPSet(U const& iLabel,
0448                                                               ParameterSetDescription const& validator,
0449                                                               std::vector<ParameterSet> const& defaults,
0450                                                               bool isTracked,
0451                                                               Modifier modifier,
0452                                                               bool writeToCfi) {
0453     std::unique_ptr<ParameterDescriptionNode> node =
0454         std::make_unique<ParameterDescription<std::vector<ParameterSet>>>(iLabel, validator, isTracked, defaults);
0455     ParameterDescriptionNode* pnode = addNode(std::move(node), modifier, writeToCfi);
0456     return static_cast<ParameterDescriptionBase*>(pnode);
0457   }
0458 
0459   template <typename U>
0460   ParameterDescriptionBase* ParameterSetDescription::addVPSet(
0461       U const& iLabel, ParameterSetDescription const& validator, bool isTracked, Modifier modifier, bool writeToCfi) {
0462     std::unique_ptr<ParameterDescriptionNode> node =
0463         std::make_unique<ParameterDescription<std::vector<ParameterSet>>>(iLabel, validator, isTracked);
0464     ParameterDescriptionNode* pnode = addNode(std::move(node), modifier, writeToCfi);
0465     return static_cast<ParameterDescriptionBase*>(pnode);
0466   }
0467 
0468   template <typename T, typename U>
0469   ParameterWildcardBase* ParameterSetDescription::addWildcard(U const& pattern, bool isTracked) {
0470     std::unique_ptr<ParameterDescriptionNode> node =
0471         std::make_unique<ParameterWildcard<T>>(pattern, RequireZeroOrMore, isTracked);
0472     ParameterDescriptionNode* pnode = addNode(std::move(node), Modifier::kOptional, true);
0473     return static_cast<ParameterWildcardBase*>(pnode);
0474   }
0475 
0476   template <typename T>
0477   ParameterDescriptionNode* ParameterSetDescription::ifValue(ParameterDescription<T> const& switchParameter,
0478                                                              std::unique_ptr<ParameterDescriptionCases<T>> cases,
0479                                                              Modifier modifier,
0480                                                              bool writeToCfi) {
0481     std::unique_ptr<ParameterDescriptionNode> pdswitch =
0482         std::make_unique<ParameterSwitch<T>>(switchParameter, std::move(cases));
0483     return addNode(std::move(pdswitch), modifier, writeToCfi);
0484   }
0485 
0486   template <typename T, typename U>
0487   ParameterDescriptionNode* ParameterSetDescription::labelsFrom(U const& iLabel,
0488                                                                 bool isTracked,
0489                                                                 Modifier modifier,
0490                                                                 bool writeToCfi) {
0491     std::unique_ptr<ParameterDescriptionNode> pd = std::make_unique<AllowedLabelsDescription<T>>(iLabel, isTracked);
0492     return addNode(std::move(pd), modifier, writeToCfi);
0493   }
0494 
0495   template <typename T, typename U, typename V>
0496   ParameterDescriptionNode* ParameterSetDescription::labelsFrom(
0497       U const& iLabel, bool isTracked, Modifier modifier, bool writeToCfi, V const& desc) {
0498     std::unique_ptr<ParameterDescriptionNode> pd =
0499         std::make_unique<AllowedLabelsDescription<T>>(iLabel, desc, isTracked);
0500     return addNode(std::move(pd), modifier, writeToCfi);
0501   }
0502 }  // namespace edm
0503 
0504 #endif