28 void matchLabel(std::pair<std::string, edm::ParameterSetDescription>
const& thePair,
32 psetDesc = &thePair.second;
37 static const char*
const kSource =
"Source";
44 : baseType_(baseType), pluginName_(
pluginName), defaultDescDefined_(
false) {}
54 add(labelString, psetDescription);
61 "ConfigurationDescriptions::add, when adding a ParameterSetDescription for a source the " 62 "label must be \"source\"\n");
67 "ConfigurationDescriptions::add, for a source only 1 ParameterSetDescription may be added\n");
73 "ConfigurationDescriptions::add, for a service only 1 ParameterSetDescription may be added\n");
79 std::pair<std::string, ParameterSetDescription> pairWithEmptyDescription;
81 std::pair<std::string, ParameterSetDescription>& pair =
descriptions_.back();
84 pair.second = psetDescription;
103 "ConfigurationDescriptions::addDefault, for a source or service only 1 " 104 "ParameterSetDescription may be added\n");
128 if (psetDesc !=
nullptr) {
144 bool wroteClassFile =
false;
148 wroteClassFile =
true;
151 wroteClassFile =
true;
162 auto found = iName.find(
"::");
163 while (
found != std::string::npos) {
164 iName.replace(
found, 2,
"_");
165 found = iName.find(
"::");
169 found = iName.find_first_of(toReplace);
170 while (
found != std::string::npos) {
171 iName.replace(
found, 1,
"_");
172 found = iName.find_first_of(toReplace,
found);
179 bool willUseWithCfis)
const {
186 ex <<
"Opening a file '" <<
fileName <<
"' failed.\n";
187 ex <<
"Error code from errno " << errno <<
": " << std::strerror(errno) <<
"\n";
189 ex.
addContext(
"Executing function ConfigurationDescriptions::writeDefault");
192 outFile <<
"import FWCore.ParameterSet.Config as cms\n\n";
198 bool startWithComma =
true;
204 " for k,v in kwargs.items():\n" 205 " setattr(mod, k, v)\n" 209 return std::holds_alternative<cfi::ClassFile>(ops) ? std::get<cfi::ClassFile>(ops).releasePaths() :
cfi::Paths{};
215 bool isSameAsDefault,
217 std::set<std::string>& usedCfiFileNames) {
220 "ConfigurationDescriptions::writeCfiForLabel\nFor a service the label and the plugin name " 221 "must be the same.\n")
222 <<
"This error is probably caused by an incorrect label being passed\nto the ConfigurationDescriptions::add " 223 "function earlier.\n" 224 <<
"plugin name = \"" <<
pluginName <<
"\" label name = \"" << labelAndDesc.first <<
"\"\n";
228 if (0 == strcmp(baseType.c_str(),
kSource)) {
231 cfi_filename = labelAndDesc.first +
"_cfi.py";
233 if (!usedCfiFileNames.insert(cfi_filename).second) {
235 "Two cfi files are being generated with the same name in the same directory.\n");
236 ex <<
"The cfi file name is '" << cfi_filename <<
"' and\n" 237 <<
"the module label is \'" << labelAndDesc.first <<
"\'.\n" 238 <<
"This error is probably caused by an error in one or more fillDescriptions functions\n" 239 <<
"where duplicate module labels are being passed to the ConfigurationDescriptions::add\n" 240 <<
"function. All such module labels must be unique within a package.\n" 241 <<
"If you do not want the generated cfi file and do not need more than one\n" 242 <<
"description for a plugin, then a way to fix this is to use the addDefault\n" 243 <<
"function instead of the add function.\n" 244 <<
"There are 3 common ways this problem can happen.\n" 245 <<
"1. This can happen when a module label is explicitly duplicated in one or more\n" 246 <<
"fillDescriptions functions. Fix these by changing the module labels to be unique.\n" 247 <<
"2. This can also happen when a module class is a template class and plugins are\n" 248 <<
"defined by instantiations with differing template parameters and these plugins\n" 249 <<
"share the same fillDescriptions function. Fix these by specializing the fillDescriptions\n" 250 <<
"function for each template instantiation.\n" 251 <<
"3. This can also happen when there is an inheritance heirarchy and multiple plugin modules\n" 252 <<
"are defined using derived classes and the base class which share the same fillDescriptions\n" 253 <<
"function. Fix these by redefining the fillDescriptions function in each derived class.\n";
254 ex.
addContext(
"Executing function ConfigurationDescriptions::writeCfiForLabel");
257 std::ofstream
outFile(cfi_filename.c_str());
260 ex <<
"Opening a file '" << cfi_filename <<
"' for module '" << labelAndDesc.first <<
"' failed.\n";
261 ex <<
"Error code from errno " << errno <<
": " << std::strerror(errno) <<
"\n";
263 ex.
addContext(
"Executing function ConfigurationDescriptions::writeCfiForLabel");
267 bool startWithComma =
true;
269 outFile <<
"import FWCore.ParameterSet.Config as cms\n\n";
270 outFile << labelAndDesc.first <<
" = cms." << baseType <<
"('" <<
pluginName <<
"'";
272 outFile <<
"import FWCore.ParameterSet.Config as cms\n\n";
274 auto pythonName = modifyPluginName(
pluginName);
275 outFile <<
"from ." << pythonName <<
" import " << pythonName <<
"\n\n";
276 outFile << labelAndDesc.first <<
" = " << pythonName <<
"(";
277 startWithComma =
false;
279 if (not isSameAsDefault) {
287 if (0 == strcmp(baseType.c_str(),
kSource)) {
297 bool printOnlyLabels,
309 char oldFill =
os.fill();
312 os <<
"There are no PSet descriptions defined for this plugin.\n";
314 os <<
"PSets will not be validated and no cfi files will be generated.\n";
315 os << std::setfill(oldFill);
323 char oldFill =
os.fill();
325 os <<
"This plugin has not implemented the function which defines its\n";
327 os <<
"configuration descriptions yet. No descriptions are available.\n";
329 os <<
"Its PSets will not be validated, and no cfi files will be generated.\n";
330 os << std::setfill(oldFill);
337 std::stringstream
ss;
340 ss <<
"This plugin has only one PSet description. " 341 <<
"This description is always used to validate configurations. " 342 <<
"Because this configuration has no label, no cfi files will be generated.";
344 ss <<
"This plugin has " << (
descriptions_.size() + 1
U) <<
" PSet descriptions. " 345 <<
"The description used to validate a configuration is selected by " 346 <<
"matching the module labels. If none match, then the last description, " 347 <<
"which has no label, is selected. " 348 <<
"A cfi file will be generated for each configuration with a module label.";
352 ss <<
"This plugin has " <<
descriptions_.size() <<
" PSet description. " 353 <<
"This description is always used to validate configurations. " 354 <<
"The label below is used when generating the cfi file.";
356 ss <<
"This plugin has " <<
descriptions_.size() <<
" PSet descriptions. " 357 <<
"The description used to validate a configuration is selected by " 358 <<
"matching the module labels. If none match the first description below is used. " 359 <<
"The module labels below are also used when generating the cfi files.";
394 bool printOnlyLabels,
414 bool printOnlyLabels,
423 std::stringstream
ss;
427 char oldFill =
os.fill();
428 os << std::setfill(
' ') << std::setw(
indentation) <<
"" << std::setfill(oldFill);
431 os <<
"description without a module label\n";
437 os <<
"module label: ";
bool shouldWriteUntyped(CfiOptions const &iOps) noexcept
ConfigurationDescriptions(std::string const &baseType, std::string const &pluginName)
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
void validate(ParameterSet &pset, std::string const &moduleLabel) const
~ConfigurationDescriptions()
static const char *const kService
void print(std::ostream &os, std::string const &moduleLabel, bool brief, bool printOnlyLabels, size_t lineWidth, int indentation, int iPlugin) const
void printForLabel(std::pair< std::string, ParameterSetDescription > const &labelAndDesc, std::ostream &os, std::string const &moduleLabel, bool brief, bool printOnlyLabels, size_t lineWidth, int indentationn, DescriptionCounter &counter) const
cfi::Paths writeClassFile(ParameterSetDescription const &, bool willUseWithCfis) const
ParameterSetDescription * defaultDescription()
Returns 0 if no default has been assigned.
static const char *const kSource
void writeCfis(std::set< std::string > &usedCfiFileNames) const
Func for_all(ForwardSequence &s, Func f)
wrapper for std::for_each
void addDefault(ParameterSetDescription const &psetDescription)
std::vector< std::pair< std::string, ParameterSetDescription > > descriptions_
std::string defaultModuleLabel(std::string label)
void setComment(std::string const &value)
static void writeCfiForLabel(std::pair< std::string, ParameterSetDescription > const &labelAndDesc, std::string const &baseType, std::string const &pluginName, bool isSameAsDefault, CfiOptions &options, std::set< std::string > &usedCfiFileNames)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void addContext(std::string const &context)
void validate(ParameterSet &pset) const
static std::atomic< unsigned int > counter
static const char *const k_source
std::vector< std::pair< std::string, ParameterSetDescription > >::iterator iterator
void writeCfi(std::ostream &os, bool startWithComma, int indentation, CfiOptions &) const
std::string const & comment() const
cfi::CfiOptions CfiOptions
ParameterSetDescription defaultDesc_