17#ifndef CONTROL_PLANE_P4RUNTIMEARCHHANDLER_H_ 
   18#define CONTROL_PLANE_P4RUNTIMEARCHHANDLER_H_ 
   20#pragma GCC diagnostic push 
   21#pragma GCC diagnostic ignored "-Wunused-parameter" 
   22#pragma GCC diagnostic ignored "-Wpedantic" 
   23#include <google/protobuf/util/json_util.h> 
   24#pragma GCC diagnostic pop 
   29#pragma GCC diagnostic push 
   30#pragma GCC diagnostic ignored "-Wunused-parameter" 
   31#pragma GCC diagnostic ignored "-Wpedantic" 
   32#include "p4/config/v1/p4info.pb.h" 
   33#include "p4/v1/p4runtime.pb.h" 
   34#pragma GCC diagnostic pop 
   36#include "frontends/common/resolveReferences/referenceMap.h" 
   37#include "frontends/p4/externInstance.h" 
   38#include "frontends/p4/methodInstance.h" 
   39#include "frontends/p4/typeMap.h" 
   41#include "lib/cstring.h" 
   42#include "lib/ordered_set.h" 
   43#include "typeSpecConverter.h" 
   47using namespace literals;
 
   52namespace ControlPlaneAPI {
 
   54using p4rt_id_t = uint32_t;
 
   70    explicit operator p4rt_id_t()
 const { 
return id; }
 
   75    static P4RuntimeSymbolType P4RT_TABLE() {
 
   76        return P4RuntimeSymbolType(::p4::config::v1::P4Ids::TABLE);
 
   78    static P4RuntimeSymbolType P4RT_VALUE_SET() {
 
   79        return P4RuntimeSymbolType(::p4::config::v1::P4Ids::VALUE_SET);
 
   81    static P4RuntimeSymbolType P4RT_CONTROLLER_HEADER() {
 
   82        return P4RuntimeSymbolType(::p4::config::v1::P4Ids::CONTROLLER_HEADER);
 
   85    static P4RuntimeSymbolType P4RT_OTHER_EXTERNS_START() {
 
   86        return P4RuntimeSymbolType(::p4::config::v1::P4Ids::OTHER_EXTERNS_START);
 
   89    bool operator==(
const P4RuntimeSymbolType &other)
 const { 
return id == other.id; }
 
   91    bool operator!=(
const P4RuntimeSymbolType &other)
 const { 
return !(*
this == other); }
 
   93    bool operator<(
const P4RuntimeSymbolType &other)
 const { 
return id < other.id; }
 
   96    static P4RuntimeSymbolType make(p4rt_id_t 
id) { 
return P4RuntimeSymbolType(
id); }
 
  101    explicit constexpr P4RuntimeSymbolType(p4rt_id_t 
id) noexcept : id(
id) {}
 
 
  116                     std::optional<p4rt_id_t> 
id = std::nullopt) = 0;
 
 
  144        auto decl = block->getContainer();
 
  145        return decl ? decl->controlPlaneName() : cstring::empty;
 
 
  150                                        const IR::TableBlock *tableBlock) = 0;
 
  153                                       const IR::ExternBlock *externBlock) = 0;
 
  156                                            const IR::AssignmentStatement *assign) = 0;
 
  173                                    ::p4::config::v1::P4Info *p4info,
 
  174                                    ::p4::config::v1::Table *table,
 
  175                                    const IR::TableBlock *tableBlock) = 0;
 
  179                                   ::p4::config::v1::P4Info *p4info,
 
  180                                   const IR::ExternBlock *externBlock) = 0;
 
  184                                   ::p4::config::v1::P4Info *p4info,
 
  189                         ::p4::config::v1::P4Info *p4info) = 0;
 
  193                                  const IR::ExternBlock *externBlock) = 0;
 
 
  213        const IR::ToplevelBlock *evaluatedProgram) 
const = 0;
 
 
  225                                                            bool *isConstructedInPlace = 
nullptr);
 
  233template <
typename Func>
 
  235    std::set<const IR::Block *> visited;
 
  238    while (!frontier.empty()) {
 
  240        auto evaluatedBlock = *frontier.begin();
 
  241        frontier.erase(frontier.begin());
 
  242        visited.insert(evaluatedBlock);
 
  244        function(evaluatedBlock);
 
  247        for (
auto evaluatedChild : evaluatedBlock->constantValue) {
 
  249            if (!evaluatedChild.second) 
continue;
 
  250            if (!evaluatedChild.second->is<IR::Block>()) 
continue;
 
  251            auto evaluatedChildBlock = evaluatedChild.second->to<IR::Block>();
 
  252            if (visited.find(evaluatedChildBlock) != visited.end()) 
continue;
 
  253            frontier.insert(evaluatedChildBlock);
 
 
  262void serializeOneStructuredAnnotation(
const IR::Annotation *annotation,
 
  263                                      ::p4::config::v1::StructuredAnnotation *structuredAnnotation);
 
  270template <
typename Message, 
typename UnaryPredicate>
 
  271void addAnnotations(Message *message, 
const IR::IAnnotated *annotated, UnaryPredicate p) {
 
  275    if (annotated == 
nullptr) 
return;
 
  277    for (
const IR::Annotation *annotation : annotated->getAnnotations()->annotations) {
 
  279        if (annotation->annotationKind() != IR::Annotation::Kind::Unstructured) {
 
  280            serializeOneStructuredAnnotation(annotation, message->add_structured_annotations());
 
  285        if (annotation->name == IR::Annotation::nameAnnotation) 
continue;
 
  286        if (annotation->name == 
"id") 
continue;
 
  290        if (annotation->name == 
"brief" || annotation->name == 
"description") 
continue;
 
  292        if (p(annotation->name)) 
continue;
 
  299template <
typename Message>
 
  300void addAnnotations(Message *message, 
const IR::IAnnotated *annotated) {
 
  301    addAnnotations(message, annotated, [](
cstring) { 
return false; });
 
 
  306template <
typename Message>
 
  311    if (annotated == 
nullptr) 
return;
 
  313    ::p4::config::v1::Documentation doc;
 
  319    for (
const IR::Annotation *annotation : annotated->getAnnotations()->annotations) {
 
  320        if (annotation->name == 
"brief") {
 
  321            auto brief = annotation->expr[0]->to<IR::StringLiteral>();
 
  324            doc.set_brief(brief->value);
 
  328        if (annotation->name == 
"description") {
 
  329            auto description = annotation->expr[0]->to<IR::StringLiteral>();
 
  331            CHECK_NULL(description);
 
  332            doc.set_description(description->value);
 
  338    if (hasDoc) message->mutable_doc()->CopyFrom(doc);
 
 
  344template <
typename UnaryPredicate>
 
  345void setPreamble(::p4::config::v1::Preamble *preamble, p4rt_id_t 
id, 
cstring name, 
cstring alias,
 
  346                 const IR::IAnnotated *annotated, UnaryPredicate p) {
 
  347    CHECK_NULL(preamble);
 
  348    preamble->set_id(
id);
 
  349    preamble->set_name(name);
 
  350    preamble->set_alias(alias);
 
  351    addAnnotations(preamble, annotated, p);
 
  357inline void setPreamble(::p4::config::v1::Preamble *preamble, p4rt_id_t 
id, 
cstring name,
 
  358                        cstring alias, 
const IR::IAnnotated *annotated) {
 
  359    setPreamble(preamble, 
id, name, alias, annotated, [](
cstring) { 
return false; });
 
 
  367template <
typename Kind>
 
  375template <
typename Kind>
 
  393    static std::optional<Counterlike<Kind>> 
from(
const IR::ExternBlock *instance,
 
  395                                                 ::p4::config::v1::P4TypeInfo *p4RtTypeInfo) {
 
  396        CHECK_NULL(instance);
 
  397        auto declaration = instance->node->to<IR::Declaration_Instance>();
 
  402        auto unit = instance->getParameterValue(
"type"_cs);
 
  403        if (!
unit->is<IR::Declaration_ID>()) {
 
  404            ::error(ErrorType::ERR_INVALID,
 
  405                    "%1% '%2%' has a unit type which is not an enum constant: %3%",
 
  412        if (
size->template is<IR::Constant>()) {
 
  413            val = 
size->template to<IR::Constant>()->value;
 
  414        } 
else if (
size->template is<IR::SerEnumMember>()) {
 
  415            auto sem = 
size->template to<IR::SerEnumMember>();
 
  416            val = sem->value->template to<IR::Constant>()->value;
 
  418            ::error(ErrorType::ERR_INVALID, 
"%1% '%2%' has a non-constant size: %3%",
 
  426        if (indexTypeParamIdx != std::nullopt) {
 
  428            BUG_CHECK(declaration->type->is<IR::Type_Specialized>(),
 
  429                      "%1%: expected Type_Specialized", declaration->type);
 
  430            auto type = declaration->type->to<IR::Type_Specialized>();
 
  431            BUG_CHECK(type->arguments->size() > *indexTypeParamIdx,
 
  432                      "%1%: expected at least %2% type arguments", instance,
 
  433                      *indexTypeParamIdx + 1);
 
  434            auto typeArg = type->arguments->at(*indexTypeParamIdx);
 
  442                                 declaration->to<IR::IAnnotated>(),
 
  443                                 unit->to<IR::Declaration_ID>()->name,
 
 
  453                                                       const IR::P4Table *
table) {
 
  455        BUG_CHECK(instance.name != std::nullopt, 
"Caller should've ensured we have a name");
 
  458            ::error(ErrorType::ERR_EXPECTED, 
"Expected a direct %1%: %2%",
 
  463        auto unitArgument = instance.substitution.lookupByName(
"type"_cs)->expression;
 
  464        if (unitArgument == 
nullptr) {
 
  465            ::error(ErrorType::ERR_EXPECTED,
 
  466                    "Direct %1% instance %2% should take a constructor argument",
 
  470        if (!unitArgument->is<IR::Member>()) {
 
  471            ::error(ErrorType::ERR_UNEXPECTED,
 
  472                    "Direct %1% instance %2% has an unexpected constructor argument",
 
  477        auto unit = unitArgument->to<IR::Member>()->member.name;
 
  479                                 instance.annotations,
 
  482                                 table->controlPlaneName(),
 
 
 
  489template <
typename Kind>
 
  494    if (!instance) 
return std::nullopt;
 
 
The Declaration interface, representing objects with names.
Definition declaration.h:26
 
Definition p4RuntimeArchHandler.h:139
 
virtual void collectTableProperties(P4RuntimeSymbolTableIface *symbols, const IR::TableBlock *tableBlock)=0
 
virtual void addExternInstance(const P4RuntimeSymbolTableIface &symbols, ::p4::config::v1::P4Info *p4info, const IR::ExternBlock *externBlock)=0
 
virtual void postAdd(const P4RuntimeSymbolTableIface &symbols, ::p4::config::v1::P4Info *p4info)=0
 
virtual void addTableProperties(const P4RuntimeSymbolTableIface &symbols, ::p4::config::v1::P4Info *p4info, ::p4::config::v1::Table *table, const IR::TableBlock *tableBlock)=0
 
virtual cstring getControlPlaneName(const IR::Block *block)
Get control plane name for @block.
Definition p4RuntimeArchHandler.h:143
 
virtual void collectExternFunction(P4RuntimeSymbolTableIface *symbols, const P4::ExternFunction *externFunction)=0
 
virtual void addExternFunction(const P4RuntimeSymbolTableIface &symbols, ::p4::config::v1::P4Info *p4info, const P4::ExternFunction *externFunction)=0
 
virtual void postCollect(const P4RuntimeSymbolTableIface &symbols)=0
 
virtual google::protobuf::util::JsonPrintOptions getJsonPrintOptions()=0
Control how JSON is output.
 
virtual void collectExternInstance(P4RuntimeSymbolTableIface *symbols, const IR::ExternBlock *externBlock)=0
Collects architecture-specific @externBlock instance in @symbols table.
 
virtual bool filterAnnotations(cstring anno)=0
called when processing annotations via setPreamble
 
virtual void collectExternMethod(P4RuntimeSymbolTableIface *symbols, const P4::ExternMethod *externMethod)=0
Collects architecture-specific @externMethod instance in @symbols table.
 
virtual void collectAssignmentStatement(P4RuntimeSymbolTableIface *symbols, const IR::AssignmentStatement *assign)=0
Collects architecture-specific used in assignment statements.
 
virtual void addExternEntries(const p4::v1::WriteRequest *entries, const P4RuntimeSymbolTableIface &symbols, const IR::ExternBlock *externBlock)=0
This method is called to add target specific extern entries.
 
virtual void collectExtra(P4RuntimeSymbolTableIface *symbols)=0
 
Definition p4RuntimeArchHandler.h:109
 
virtual p4rt_id_t getId(P4RuntimeSymbolType type, const IR::IDeclaration *declaration) const =0
 
virtual cstring getAlias(cstring name) const =0
 
virtual void add(P4RuntimeSymbolType type, const IR::IDeclaration *declaration)=0
Add a @type symbol, extracting the name and id from @declaration.
 
Definition p4RuntimeArchHandler.h:63
 
static const ::p4::config::v1::P4DataTypeSpec * convert(const P4::ReferenceMap *refMap, P4::TypeMap *typeMap, const IR::Type *type, ::p4::config::v1::P4TypeInfo *typeInfo)
Definition typeSpecConverter.cpp:386
 
Definition methodInstance.h:181
 
Definition methodInstance.h:149
 
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
 
Definition ordered_set.h:30
 
void forAllEvaluatedBlocks(const IR::Block *block, Func function)
Definition p4RuntimeArchHandler.h:234
 
std::string serializeOneAnnotation(const IR::Annotation *annotation)
Serialize an unstructured @annotation to a string.
Definition p4RuntimeArchHandler.cpp:119
 
std::optional< ExternInstance > getExternInstanceFromProperty(const IR::P4Table *table, const cstring &propertyName, ReferenceMap *refMap, TypeMap *typeMap, bool *isConstructedInPlace)
Definition p4RuntimeArchHandler.cpp:41
 
bool isExternPropertyConstructedInPlace(const IR::P4Table *table, const cstring &propertyName)
Definition p4RuntimeArchHandler.cpp:77
 
int64_t getTableSize(const IR::P4Table *table)
Definition p4RuntimeArchHandler.cpp:91
 
void addDocumentation(Message *message, const IR::IAnnotated *annotated)
' and '@description' annotations if present.
Definition p4RuntimeArchHandler.h:307
 
std::optional< Counterlike< Kind > > getDirectCounterlike(const IR::P4Table *table, ReferenceMap *refMap, TypeMap *typeMap)
Definition p4RuntimeArchHandler.h:490
 
A traits class describing the properties of "counterlike" things.
Definition p4RuntimeArchHandler.h:368
 
cstring getTypeName(const IR::Type *type, TypeMap *typeMap)
Definition typeSpecConverter.cpp:78
 
Definition applyOptionsPragmas.cpp:24
 
Definition p4RuntimeArchHandler.h:376
 
const std::optional< cstring > table
If not none, the instance is a direct resource associated with @table.
Definition p4RuntimeArchHandler.h:386
 
const cstring name
The name of the instance.
Definition p4RuntimeArchHandler.h:378
 
const IR::IAnnotated * annotations
If non-null, the instance's annotations.
Definition p4RuntimeArchHandler.h:380
 
static std::optional< Counterlike< Kind > > from(const IR::ExternBlock *instance, const ReferenceMap *refMap, P4::TypeMap *typeMap, ::p4::config::v1::P4TypeInfo *p4RtTypeInfo)
Definition p4RuntimeArchHandler.h:393
 
const cstring unit
The units parameter to the instance; valid values vary depending on @Kind.
Definition p4RuntimeArchHandler.h:382
 
const cstring index_type_name
Definition p4RuntimeArchHandler.h:389
 
static std::optional< Counterlike< Kind > > fromDirect(const ExternInstance &instance, const IR::P4Table *table)
Definition p4RuntimeArchHandler.h:452
 
const int64_t size
The size parameter to the instance.
Definition p4RuntimeArchHandler.h:384
 
Definition p4RuntimeArchHandler.h:204
 
virtual P4RuntimeArchHandlerIface * operator()(ReferenceMap *refMap, TypeMap *typeMap, const IR::ToplevelBlock *evaluatedProgram) const =0
 
Definition externInstance.h:51