21 #include "TDictAttributeMap.h" 37 anyProductProduced_(
false),
38 productLookups_{{std::make_unique<ProductResolverIndexHelper>(),
39 std::make_unique<ProductResolverIndexHelper>(),
40 std::make_unique<ProductResolverIndexHelper>(),
41 std::make_unique<ProductResolverIndexHelper>()}},
44 for (
bool& isProduced : productProduced_)
50 for (
bool& isProduced : productProduced_)
52 anyProductProduced_ =
false;
55 for (
auto& iterProductLookup : productLookups_) {
56 iterProductLookup = std::make_unique<ProductResolverIndexHelper>();
58 nextIndexValues_.fill(0);
60 branchIDToIndex_.clear();
71 std::pair<ProductList::iterator, bool>
ret =
78 <<
"\nThe Framework requires a unique branch name for each product\n" 79 <<
"which consists of four parts: a friendly class name, module label,\n" 80 <<
"product instance name, and process name. A product has been\n" 81 <<
"registered with a duplicate branch name. The most common way\n" 82 <<
"to fix this error is to modify the product instance name in\n" 83 <<
"one of the offending 'produces' function calls. Another fix\n" 84 <<
"would be to delete one of them if they are for the same product.\n\n" 85 <<
" friendly class name = " <<
previous.second.friendlyClassName() <<
"\n" 86 <<
" module label = " <<
previous.second.moduleLabel() <<
"\n" 87 <<
" product instance name = " <<
previous.second.productInstanceName() <<
"\n" 88 <<
" process name = " <<
previous.second.processName() <<
"\n\n" 89 <<
"The following additional information is not used as part of\n" 90 <<
"the unique branch identifier.\n\n" 91 <<
" branch types = " <<
previous.second.branchType() <<
" " << productDesc.
branchType() <<
"\n" 92 <<
" class name = " <<
previous.second.fullClassName() <<
"\n\n" 93 <<
"Note that if the four parts of the branch name are the same,\n" 94 <<
"then this error will occur even if the branch types differ!\n\n";
98 <<
"The process name " << productDesc.
processName() <<
" was previously used for products in the input.\n" 99 <<
"This has caused branch name conflicts between input products and new products.\n" 100 <<
"Please modify the configuration file to use a distinct process name.\n" 101 <<
"Alternately, drop all input products using that process name and the\n" 102 <<
"descendants of those products.\n";
131 iter->second.merge(productDesc);
138 if (
it->second.branchType() == brType) {
157 if (initializeLookupInfo) {
164 std::set<TypeID>
const& elementTypesConsumed,
176 <<
"cannot modify the ProductRegistry because it is frozen\n";
183 <<
"cannot read the ProductRegistry because it is not yet frozen\n";
190 std::vector<std::string>
result;
194 result.push_back(product.second.branchName());
200 std::vector<BranchDescription const*>
result;
204 result.push_back(&product.second);
210 for (
auto const& product :
other) {
223 for (
auto const&
prod :
other.productList_) {
230 iter->second.merge(
prod.second);
238 bool hasAliases =
false;
239 std::vector<BranchID> onDemandIDs;
242 unscheduledLabels.end() != unscheduledLabels.find(
prod.second.moduleLabel())) {
243 prod.second.setOnDemand(
true);
244 onDemandIDs.push_back(
prod.second.branchID());
246 if (
prod.second.produced() &&
prod.second.isAlias()) {
253 std::sort(onDemandIDs.begin(), onDemandIDs.end());
255 if (
prod.second.isAlias()) {
256 if (std::binary_search(onDemandIDs.begin(), onDemandIDs.end(),
prod.second.aliasForBranchID())) {
257 prod.second.setOnDemand(
true);
267 std::ostringstream differences;
269 ProductRegistry::ProductList::iterator
j =
productList_.begin();
270 ProductRegistry::ProductList::iterator
s =
productList_.end();
271 ProductRegistry::ProductList::const_iterator
i =
other.productList().begin();
272 ProductRegistry::ProductList::const_iterator
e =
other.productList().end();
275 while (
j !=
s ||
i !=
e) {
276 if (
j !=
s &&
j->second.produced()) {
279 }
else if (
j ==
s || (
i !=
e &&
i->first <
j->first)) {
280 if (
i->second.present()) {
281 differences <<
"Branch '" <<
i->second.branchName() <<
"' is in file '" <<
fileName <<
"'\n";
282 differences <<
" but not in previous files.\n";
289 }
else if (
i ==
e || (
j !=
s &&
j->first <
i->first)) {
290 if (
j->second.present() &&
292 differences <<
"Branch '" <<
j->second.branchName() <<
"' is in previous files\n";
293 differences <<
" but not in file '" <<
fileName <<
"'.\n";
299 j->second.merge(
i->second);
307 return differences.str();
311 std::set<TypeID>
const* elementTypesConsumed,
313 std::map<TypeID, TypeID> containedTypeMap;
314 std::map<TypeID, std::vector<TypeID>> containedTypeToBaseTypesMap;
316 std::vector<std::string> missingDictionaries;
317 std::vector<std::string> branchNamesForMissing;
318 std::vector<std::string> producedTypes;
323 auto const&
desc = product.second;
327 if (
desc.produced() && !
desc.transient()) {
332 if (
desc.present()) {
337 if (!
desc.produced()) {
340 branchNamesForMissing.emplace_back(
desc.branchName());
341 producedTypes.emplace_back(
desc.className() +
std::string(
" (read from input)"));
345 TypeID typeID(
desc.unwrappedType().typeInfo());
347 auto iterContainedType = containedTypeMap.find(typeID);
348 bool alreadySawThisType = (iterContainedType != containedTypeMap.end());
350 if (!
desc.produced() && !alreadySawThisType) {
352 branchNamesForMissing.emplace_back(
desc.branchName());
353 producedTypes.emplace_back(
desc.className() +
std::string(
" (read from input)"));
358 TypeID wrappedTypeID(
desc.wrappedType().typeInfo());
361 if (alreadySawThisType) {
362 containedTypeID = iterContainedType->second;
366 bool hasContainedType = (containedTypeID !=
TypeID(
typeid(
void)) && containedTypeID !=
TypeID());
368 std::vector<TypeID>* baseTypesOfContainedType =
nullptr;
370 if (!alreadySawThisType) {
371 bool alreadyCheckedConstituents =
desc.produced() && !
desc.transient();
372 if (!alreadyCheckedConstituents && !
desc.transient()) {
375 branchNamesForMissing.emplace_back(
desc.branchName());
376 producedTypes.emplace_back(
desc.className() +
std::string(
" (read from input)"));
381 if (hasContainedType) {
382 auto iterBaseTypes = containedTypeToBaseTypesMap.find(containedTypeID);
383 if (iterBaseTypes == containedTypeToBaseTypesMap.end()) {
384 std::vector<TypeID> baseTypes;
386 branchNamesForMissing.emplace_back(
desc.branchName());
387 if (
desc.produced()) {
388 producedTypes.emplace_back(
desc.className() +
std::string(
" (produced in current process)"));
390 producedTypes.emplace_back(
desc.className() +
std::string(
" (read from input)"));
394 iterBaseTypes = containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, baseTypes)).first;
396 baseTypesOfContainedType = &iterBaseTypes->second;
401 containedTypeMap.emplace(typeID, containedTypeID);
403 if (hasContainedType) {
404 auto iterBaseTypes = containedTypeToBaseTypesMap.find(containedTypeID);
405 if (iterBaseTypes != containedTypeToBaseTypesMap.end()) {
406 baseTypesOfContainedType = &iterBaseTypes->second;
411 if (productTypesConsumed !=
nullptr && !
desc.produced()) {
412 bool mainTypeConsumed = (productTypesConsumed->find(typeID) != productTypesConsumed->end());
413 bool containedTypeConsumed =
414 hasContainedType && (elementTypesConsumed->find(containedTypeID) != elementTypesConsumed->end());
415 if (hasContainedType && !containedTypeConsumed && baseTypesOfContainedType !=
nullptr) {
416 for (
TypeID const& baseType : *baseTypesOfContainedType) {
417 if (elementTypesConsumed->find(
TypeID(baseType.typeInfo())) != elementTypesConsumed->end()) {
418 containedTypeConsumed =
true;
423 if (!containedTypeConsumed) {
424 if (mainTypeConsumed) {
429 if (hasContainedType) {
430 containedTypeID =
TypeID(
typeid(
void));
443 desc.moduleLabel().c_str(),
444 desc.productInstanceName().c_str(),
445 desc.processName().c_str(),
447 baseTypesOfContainedType);
452 if (!missingDictionaries.empty()) {
458 iterProductLookup->setFrozen();
461 unsigned int indexIntoNextIndexValue = 0;
464 ++indexIntoNextIndexValue;
468 auto const&
desc = product.second;
475 productTypesConsumed, elementTypesConsumed, containedTypeMap, containedTypeToBaseTypesMap);
481 std::set<TypeID>
const* elementTypesConsumed,
482 std::map<TypeID, TypeID>
const& containedTypeMap,
483 std::map<
TypeID, std::vector<TypeID>>
const& containedTypeToBaseTypesMap) {
486 auto iterContainedType = containedTypeMap.find(std::get<Transients::kType>(
item));
487 if (iterContainedType == containedTypeMap.end()) {
489 ex <<
"containedTypeMap did not contain " << std::get<Transients::kType>(
item).
className()
490 <<
" that is used in EDAlias " << std::get<Transients::kModuleLabel>(
item)
491 <<
".\nThis should not happen, contact framework developers";
492 ex.
addContext(
"Calling ProductRegistry::initializeLookupTables()");
495 auto const& containedTypeID = iterContainedType->second;
496 bool const hasContainedType = (containedTypeID !=
TypeID(
typeid(
void)) && containedTypeID !=
TypeID());
497 if (not hasContainedType) {
501 if (elementTypesConsumed->find(containedTypeID) != elementTypesConsumed->end()) {
504 std::get<Transients::kModuleLabel>(
item),
505 std::get<Transients::kProductInstanceName>(
item),
506 std::get<Transients::kAliasForModuleLabel>(
item));
509 auto iterBaseTypes = containedTypeToBaseTypesMap.find(containedTypeID);
510 if (iterBaseTypes == containedTypeToBaseTypesMap.end()) {
513 for (
TypeID const& baseTypeID : iterBaseTypes->second) {
514 if (elementTypesConsumed->find(baseTypeID) != elementTypesConsumed->end()) {
517 std::get<Transients::kModuleLabel>(
item),
518 std::get<Transients::kProductInstanceName>(
item),
519 std::get<Transients::kAliasForModuleLabel>(
item));
524 std::make_move_iterator(elementAliases.begin()),
525 std::make_move_iterator(elementAliases.end()));
529 std::set<TypeID>
const* productTypesConsumed,
530 std::set<TypeID>
const* elementTypesConsumed,
531 std::map<TypeID, TypeID>
const& containedTypeMap,
532 std::map<
TypeID, std::vector<TypeID>>& containedTypeToBaseTypesMap) {
533 std::vector<std::string> missingDictionaries;
534 std::set<std::string> consumedTypesWithMissingDictionaries;
536 if (productTypesConsumed) {
538 for (
auto const& consumedTypeID : *productTypesConsumed) {
542 if (containedTypeMap.find(consumedTypeID) == containedTypeMap.end()) {
547 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
550 bool transient =
false;
551 TDictAttributeMap*
wp = wrappedType.getClass()->GetAttributeMap();
552 if (
wp &&
wp->HasKey(
"persistent") && !strcmp(
wp->GetPropertyAsString(
"persistent"),
"false")) {
557 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
562 bool hasContainedType = (containedTypeID !=
TypeID(
typeid(
void)) && containedTypeID !=
TypeID());
563 if (hasContainedType) {
564 if (containedTypeToBaseTypesMap.find(containedTypeID) == containedTypeToBaseTypesMap.end()) {
565 std::vector<TypeID> bases;
568 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
570 containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, bases));
575 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
580 if (!missingDictionaries.empty()) {
582 "Calling ProductRegistry::initializeLookupTables, checking dictionaries for consumed products");
587 if (elementTypesConsumed) {
588 missingDictionaries.clear();
589 consumedTypesWithMissingDictionaries.clear();
590 for (
auto const& consumedTypeID : *elementTypesConsumed) {
591 if (containedTypeToBaseTypesMap.find(consumedTypeID) == containedTypeToBaseTypesMap.end()) {
592 std::vector<TypeID> bases;
595 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
599 if (!missingDictionaries.empty()) {
601 "Calling ProductRegistry::initializeLookupTables, checking dictionaries for elements of products consumed " 612 <<
"The process name " << *
processName <<
" was previously used for products in the input.\n" 613 <<
"Please modify the configuration file to use a distinct process name.\n" 614 <<
"Alternately, drop all input products using that process name and the\n" 615 <<
"descendants of those products.\n";
624 return itFind->second;
630 std::string_view productInstanceName)
const {
631 auto aliasFields = [](
auto const&
item) {
632 return std::tie(std::get<Transients::kKind>(
item),
633 std::get<Transients::kType>(
item),
634 std::get<Transients::kModuleLabel>(
item),
635 std::get<Transients::kProductInstanceName>(
item));
643 std::vector<std::string>
ret;
645 ret.emplace_back(std::get<Transients::kAliasForModuleLabel>(*
found));
652 os << product.second <<
"\n-----\n";
std::vector< BranchDescription const * > allBranchDescriptions() const
void setProductProduced(BranchType branchType)
void throwMissingDictionariesException(std::vector< std::string > &missingDictionaries, std::string const &context)
unsigned int ProductResolverIndex
bool public_base_classes(std::vector< std::string > &missingDictionaries, TypeID const &typeID, std::vector< TypeID > &baseTypes)
TypeID getContainedTypeFromWrapper(TypeID const &wrappedtypeID, std::string const &className)
ProductList const & productList() const
BranchID const & branchID() const
ret
prodAgent to be discontinued
BranchType const & branchType() const
std::map< BranchKey, BranchDescription > ProductList
std::vector< std::string > aliasToModules(KindOfType kindOfType, TypeID const &type, std::string_view moduleLabel, std::string_view productInstanceName) const
void addElementTypesForAliases(std::set< TypeID > const *elementTypesConsumed, std::map< TypeID, TypeID > const &containedTypeMap, std::map< TypeID, std::vector< TypeID >> const &containedTypeToBaseTypesMap)
TypeID unwrappedTypeID() const
std::string const & processName() const
constexpr std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
void addLabelAlias(BranchDescription const &productdesc, std::string const &labelAlias, std::string const &instanceAlias)
AliasToOriginalVector aliasToOriginal_
virtual void addCalled(BranchDescription const &, bool iFromListener)
static TypeWithDict byName(std::string const &name)
void initializeLookupTables(std::set< TypeID > const *productTypesConsumed, std::set< TypeID > const *elementTypesConsumed, std::string const *processName)
bool combinable(BranchDescription const &a, BranchDescription const &b)
bool checkDictionary(std::vector< std::string > &missingDictionaries, TypeID const &typeID)
void setUnscheduledProducts(std::set< std::string > const &unscheduledLabels)
std::vector< std::string > allBranchNames() const
ProductResolverIndex & nextIndexValue(BranchType branchType)
bool checkClassDictionaries(std::vector< std::string > &missingDictionaries, TypeID const &typeID)
std::string merge(ProductRegistry const &other, std::string const &fileName, BranchDescription::MatchMode branchesMustMatch=BranchDescription::Permissive)
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
void addFromInput(edm::ProductRegistry const &)
void setFrozen(bool initializeLookupInfo=true)
void freezeIt(bool frozen=true)
std::vector< std::tuple< KindOfType, TypeID, std::string, std::string, std::string > > AliasToOriginalVector
ProductResolverIndex const & getNextIndexValue(BranchType branchType) const
std::string const & className() const
std::array< ProductResolverIndex, NumBranchTypes > nextIndexValues_
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
std::shared_ptr< ProductResolverIndexHelper const > productLookup(BranchType branchType) const
ProductList::size_type size() const
std::array< edm::propagate_const< std::shared_ptr< ProductResolverIndexHelper > >, NumBranchTypes > productLookups_
ProductResolverIndex indexFrom(BranchID const &iID) const
std::string wrappedClassName(std::string const &iFullName)
void print(std::ostream &os) const
void addContext(std::string const &context)
bool anyProducts(BranchType const brType) const
void checkForDuplicateProcessName(BranchDescription const &desc, std::string const *processName) const
void updateFromInput(ProductList const &other)
void throwIfNotFrozen() const
bool checkDictionaryOfWrappedType(std::vector< std::string > &missingDictionaries, TypeID const &unwrappedTypeID)
void checkDictionariesOfConsumedTypes(std::set< TypeID > const *productTypesConsumed, std::set< TypeID > const *elementTypesConsumed, std::map< TypeID, TypeID > const &containedTypeMap, std::map< TypeID, std::vector< TypeID >> &containedTypeToBaseTypesMap)
void throwIfFrozen() const
void addProduct(BranchDescription const &productdesc, bool iFromListener=false)
std::string const & moduleLabel() const
std::map< BranchID, ProductResolverIndex > branchIDToIndex_
std::string className(const T &t)
void copyProduct(BranchDescription const &productdesc)
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName)