File indexing completed on 2024-05-23 03:13:13
0001 #ifndef FWCore_ParameterSet_PluginDescription_h
0002 #define FWCore_ParameterSet_PluginDescription_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 #include "FWCore/ParameterSet/interface/ParameterDescriptionNode.h"
0086 #include "FWCore/ParameterSet/interface/PluginDescriptionAdaptorBase.h"
0087 #include "FWCore/PluginManager/interface/PluginFactory.h"
0088 #include "FWCore/PluginManager/interface/PluginManager.h"
0089 #include "FWCore/PluginManager/interface/standard.h"
0090 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0091
0092
0093 #include <ostream>
0094 #include <sstream>
0095 #include <string>
0096
0097
0098 namespace edm {
0099 template <typename T>
0100 class PluginDescription : public ParameterDescriptionNode {
0101 public:
0102
0103
0104
0105
0106 PluginDescription(std::string typeLabel, bool typeLabelIsTracked)
0107 : typeLabel_{std::move(typeLabel)}, typeLabelIsTracked_{typeLabelIsTracked} {}
0108
0109
0110
0111
0112
0113
0114 PluginDescription(std::string typeLabel, std::string defaultType, bool typeLabelIsTracked)
0115 : typeLabel_{std::move(typeLabel)},
0116 defaultType_{std::move(defaultType)},
0117 typeLabelIsTracked_{typeLabelIsTracked} {}
0118
0119
0120 ParameterDescriptionNode* clone() const final { return new PluginDescription<T>(*this); }
0121
0122 protected:
0123 void checkAndGetLabelsAndTypes_(std::set<std::string>& usedLabels,
0124 std::set<ParameterTypes>& parameterTypes,
0125 std::set<ParameterTypes>& wildcardTypes) const final {}
0126
0127 void validate_(ParameterSet& pset, std::set<std::string>& validatedLabels, bool optional) const final {
0128 loadDescription(findType(pset)).validate(pset);
0129
0130 auto n = pset.getParameterNames();
0131 validatedLabels.insert(n.begin(), n.end());
0132 }
0133
0134 void writeCfi_(std::ostream& os,
0135 bool optional,
0136 bool& startWithComma,
0137 int indentation,
0138 CfiOptions& options,
0139 bool& wroteSomething) const final {
0140 if (not defaultType_.empty()) {
0141 if (!edmplugin::PluginManager::isAvailable()) {
0142 auto conf = edmplugin::standard::config();
0143 conf.allowNoCache();
0144 edmplugin::PluginManager::configure(conf);
0145 }
0146
0147 CfiOptions ops = cfi::Typed{};
0148 loadDescription(defaultType_).writeCfi(os, startWithComma, indentation, ops);
0149 wroteSomething = true;
0150 }
0151 if (std::holds_alternative<cfi::ClassFile>(options)) {
0152 std::get<cfi::ClassFile>(options).parameterMustBeTyped();
0153 }
0154 }
0155
0156 bool hasNestedContent_() const final { return true; }
0157
0158 void printNestedContent_(std::ostream& os, bool , DocFormatHelper& dfh) const final {
0159 int indentation = dfh.indentation();
0160
0161 using CreatedType = PluginDescriptionAdaptorBase<typename T::CreatedType>;
0162 using Factory = edmplugin::PluginFactory<CreatedType*()>;
0163
0164 std::string const& pluginCategory = Factory::get()->category();
0165
0166 printSpaces(os, indentation);
0167 os << "There are multiple possible different descriptions for this ParameterSet\n";
0168 printSpaces(os, indentation);
0169 os << "because it will be used by a helper plugin object contained inside the top level\n";
0170 printSpaces(os, indentation);
0171 os << "module plugin object and the type of the helper plugin object is configurable.\n";
0172 printSpaces(os, indentation);
0173 os << "Or if it is in a vector of ParameterSets it might be used by multiple\n";
0174 printSpaces(os, indentation);
0175 os << "helper plugin objects and each could be configured with a different plugin type.\n";
0176 printSpaces(os, indentation);
0177 os << "Each plugin type could allow a different set of configuration parameters.\n";
0178 printSpaces(os, indentation);
0179 os << "Each subsection of this section has one of the possible descriptions.\n";
0180 printSpaces(os, indentation);
0181 os << "All of these plugins are from the category \"" << pluginCategory << "\".\n";
0182 printSpaces(os, indentation);
0183 os << "The plugin type is specified by the parameter named \"" << typeLabel_ << "\".\n";
0184
0185 if (!dfh.brief()) {
0186 os << "\n";
0187 }
0188 std::string section = dfh.sectionOfCategoryAlreadyPrinted(pluginCategory);
0189 if (!section.empty()) {
0190 printSpaces(os, indentation);
0191 os << "*** The descriptions for this plugin category already started printing above (see Section " << section
0192 << ")! ***\n";
0193 printSpaces(os, indentation);
0194 os << "*** We might still be in the middle of that printout at this point because it might be recursive. ***\n";
0195 printSpaces(os, indentation);
0196 os << "*** We'll not duplicate that printout and skip it. ***\n";
0197 printSpaces(os, indentation);
0198 os << "*** (N.B. If we tried to print it again, we might fall into an infinite recursion.) ***\n";
0199
0200 if (!dfh.brief()) {
0201 os << "\n";
0202 }
0203 return;
0204 }
0205 dfh.addCategory(pluginCategory, dfh.section());
0206
0207 indentation -= DocFormatHelper::offsetSectionContent();
0208
0209
0210 unsigned int pluginCount = 1;
0211 std::string previousName;
0212 for (auto const& info : edmplugin::PluginManager::get()->categoryToInfos().find(pluginCategory)->second) {
0213
0214 if (previousName == info.name_) {
0215 continue;
0216 }
0217
0218 std::stringstream ss;
0219 ss << dfh.section() << "." << pluginCount;
0220 ++pluginCount;
0221 std::string newSection = ss.str();
0222 printSpaces(os, indentation);
0223 os << "Section " << newSection << " ParameterSet description for plugin named \"" << info.name_ << "\"\n";
0224 if (!dfh.brief())
0225 os << "\n";
0226
0227 DocFormatHelper new_dfh(dfh);
0228 new_dfh.init();
0229 new_dfh.setSection(newSection);
0230
0231 loadDescription(info.name_).print(os, new_dfh);
0232
0233 previousName = info.name_;
0234 }
0235 }
0236
0237 bool exists_(ParameterSet const& pset) const final {
0238 CMS_SA_ALLOW return pset.existsAs<std::string>(typeLabel_, typeLabelIsTracked_);
0239 }
0240
0241 bool partiallyExists_(ParameterSet const& pset) const final { return exists_(pset); }
0242
0243 int howManyXORSubNodesExist_(ParameterSet const& pset) const final { return exists(pset) ? 1 : 0; }
0244
0245 private:
0246 std::string findType(edm::ParameterSet const& iPSet) const {
0247 if (typeLabelIsTracked_) {
0248 CMS_SA_ALLOW if (iPSet.existsAs<std::string>(typeLabel_) || defaultType_.empty()) {
0249 return iPSet.getParameter<std::string>(typeLabel_);
0250 }
0251 else {
0252 return defaultType_;
0253 }
0254 }
0255 if (defaultType_.empty()) {
0256 return iPSet.getUntrackedParameter<std::string>(typeLabel_);
0257 }
0258 return iPSet.getUntrackedParameter<std::string>(typeLabel_, defaultType_);
0259 }
0260
0261 ParameterSetDescription loadDescription(std::string const& iName) const {
0262 using CreatedType = PluginDescriptionAdaptorBase<typename T::CreatedType>;
0263 std::unique_ptr<CreatedType> a(edmplugin::PluginFactory<CreatedType*()>::get()->create(iName));
0264
0265 ParameterSetDescription desc = a->description();
0266
0267
0268 if (typeLabelIsTracked_) {
0269 if (defaultType_.empty()) {
0270 desc.add<std::string>(typeLabel_);
0271 } else {
0272 desc.add<std::string>(typeLabel_, defaultType_);
0273 }
0274 } else {
0275 if (defaultType_.empty()) {
0276 desc.addUntracked<std::string>(typeLabel_);
0277 } else {
0278 desc.addUntracked<std::string>(typeLabel_, defaultType_);
0279 }
0280 }
0281 return desc;
0282 }
0283
0284
0285 std::string typeLabel_;
0286 std::string defaultType_;
0287 bool typeLabelIsTracked_;
0288 };
0289 }
0290
0291 #endif