in source/Frame.cpp [174:246]
AccessPath validate_and_infer_crtex_callee_port(
const Json::Value& value,
const AccessPath& callee_port,
const CanonicalNameSetAbstractDomain& canonical_names,
const RootSetAbstractDomain& via_type_of_ports) {
mt_assert(canonical_names.is_value() && !canonical_names.elements().empty());
// Anchor ports only go with templated canonical names. Producer ports only
// go with instantiated canonical names. No other ports are allowed.
bool is_templated = false;
bool is_instantiated = false;
for (const auto& canonical_name : canonical_names.elements()) {
if (canonical_name.instantiated_value()) {
is_instantiated = true;
} else {
is_templated = true;
}
}
if (is_instantiated == is_templated) {
throw JsonValidationError(
value,
/* field */ "canonical_names",
"all instantiated, or all templated values, not mix of both");
}
if (is_templated) {
auto num_via_type_of_ports =
via_type_of_ports.is_value() ? via_type_of_ports.elements().size() : 0;
for (const auto& canonical_name : canonical_names.elements()) {
auto is_via_type_of = canonical_name.is_via_type_of_template();
if (is_via_type_of && num_via_type_of_ports != 1) {
throw JsonValidationError(
value,
/* field */ std::nullopt,
"exactly one 'via_type_of' port when canonical name contains 'via_type_of' template");
}
}
}
// If callee_port is user-specified and not Leaf, validate it.
if (callee_port.root().is_anchor() && is_instantiated) {
throw JsonValidationError(
value,
/* field */ std::nullopt,
"`Anchor` callee ports to go with templated canonical names.");
} else if (callee_port.root().is_producer() && is_templated) {
throw JsonValidationError(
value,
/* field */ std::nullopt,
"`Producer` callee ports to go with instantiated canonical names.");
} else if (!callee_port.root().is_leaf_port()) {
throw JsonValidationError(
value,
/* field */ std::nullopt,
"`Anchor` or `Producer` callee port for crtex frame with canonical_names defined.");
}
if (callee_port.root().is_leaf()) {
if (is_instantiated) {
throw JsonValidationError(
value,
/* field */ std::nullopt,
"Instantiated canonical names must have callee_port defined as `Producer.<producer_id>.<canonical_port>`");
}
// If the callee_port is defaulted to Leaf, it should be updated to an
// Anchor to enable detection that this comes from a CRTEX producer.
return AccessPath(Root(Root::Kind::Anchor));
}
return callee_port;
}