// SPDX-License-Identifier: MIT #ifndef DBC_STATEMENT_HANDLER_H #define DBC_STATEMENT_HANDLER_H #include "dbc_database.h" #include "dbc_diagnostic.h" #include "typefactory.h" #include #include #include struct PendingValueDescriptions { std::uint32_t canId; bool isExtended; std::string signalName; ValueDescriptions descriptions; std::size_t lineNumber; }; struct PendingComment { std::uint32_t canId; bool isExtended; bool isSignal; std::string signalName; std::string comment; std::size_t lineNumber; }; /** Carries deferred validation locations without parsing exception text. */ class DbcDiagnosticError : public std::runtime_error { public: DbcDiagnosticError(DbcDiagnosticCode code, const std::string &filePath, std::size_t lineNumber, const std::string &message) : std::runtime_error(filePath + ":" + std::to_string(lineNumber) + ": " + message), diagnostic{DbcDiagnosticSeverity::Error, code, filePath, lineNumber, message} {} DbcDiagnostic diagnostic; }; /** Mutable state belonging to one file parse. Handlers do not retain it. */ struct DbcParseContext { DbcDatabase &database; FrameInfo *currentFrame = nullptr; std::size_t lineNumber = 0U; std::vector pendingValues = {}; std::vector> signalLines = {}; void ValidateMultiplexing(const std::string &filePath) const; std::vector pendingComments = {}; void ResolveComments(const std::string &filePath); void ResolveValueDescriptions(const std::string &filePath); }; class DbcStatementHandler { public: virtual ~DbcStatementHandler() = default; virtual void Handle(const std::string &line, DbcParseContext &context) const = 0; }; class DbcFrameHandler : public DbcStatementHandler { public: void Handle(const std::string &line, DbcParseContext &context) const override; private: static FrameInfo ParseFrameLine(const std::string &line); }; class DbcSignalHandler : public DbcStatementHandler { public: void Handle(const std::string &line, DbcParseContext &context) const override; private: static SignalInfo ParseSignalLine(const std::string &line); }; class DbcCommentHandler : public DbcStatementHandler { public: void Handle(const std::string &line, DbcParseContext &context) const override; }; class DbcValueDescriptionHandler : public DbcStatementHandler { public: void Handle(const std::string &line, DbcParseContext &context) const override; }; class DbcUnsupportedMultiplexingHandler : public DbcStatementHandler { public: void Handle(const std::string &line, DbcParseContext &context) const override; }; /** Common header metadata does not change the supported decode definitions. */ class DbcHeaderHandler : public DbcStatementHandler { public: void Handle(const std::string &line, DbcParseContext &context) const override; }; /** Exact-key dispatch to handlers created once per registration via TypeFactory. */ class DbcStatementDispatcher { public: DbcStatementDispatcher(); template void RegisterType(const std::string &keyword) { m_factory.registerType(keyword); m_handlers.insert_or_assign(keyword, m_factory.create(keyword)); } /** Returns false for an unregistered keyword; input must be trimmed. */ bool Dispatch(const std::string &line, DbcParseContext &context) const; private: using HandlerMap = std::unordered_map>; TypeFactory m_factory; HandlerMap m_handlers; }; #endif /* DBC_STATEMENT_HANDLER_H */