schema_editor/application.cpp

161 lines
4.6 KiB
C++

//
// Created by bbr on 27.05.22..
//
#include "application.h"
#include "comdel/parser/parse_context.h"
#include "comdel/parser/parser_util.h"
#include "comdel/domain/schema_creator.h"
#include "comdel/domain/comdel_generator.h"
#include "comdel/domain/comdel_validator.h"
std::optional<domain::Library> Application::getLibrary() {
return library;
}
domain::Schema *Application::getSchema() {
return schema;
}
void Application::clear() {
if(schema != nullptr) {
delete schema;
schema = nullptr;
}
library = std::nullopt;
libraryPath = "";
}
bool Application::loadLibrary(std::string& filename, std::ostream &errorOutput) {
clear();
ParseContext parseContext;
auto libraryNode = load_library_from_file(&parseContext, filename.c_str(), errorOutput);
if(libraryNode) {
domain::SchemaCreator generator(validators);
library = generator.loadLibrary(*libraryNode);
for (auto& error : generator.getErrors()) {
parseContext.formatError(error, errorOutput, "ERROR: ");
}
if(library.has_value()) {
libraryPath = filename;
// on library load we create a new schema
schema = new domain::Schema();
} else {
errorOutput<<"Failed creating library model"<<std::endl;
return false;
}
} else {
errorOutput<<"Failed parsing library"<<std::endl;
return false;
}
return true;
}
bool Application::loadSchema(std::string &filename, std::ostream &errorOutput) {
clear();
ParseContext parseContext;
auto schemaNode = load_schema_from_file(&parseContext, filename.c_str(), errorOutput);
if(schemaNode) {
domain::SchemaCreator generator(validators);
library = generator.loadLibrary(*schemaNode->library);
libraryPath = schemaNode->source->asString();
for (auto& error : generator.getErrors()) {
parseContext.formatError(error, errorOutput, "ERROR: ");
}
if(library) {
schema = generator.loadSchema(*schemaNode, *library);
for (auto& error : generator.getErrors()) {
parseContext.formatError(error, errorOutput, "ERROR: ");
}
if(schema == nullptr) {
clear();
return false;
}
} else {
clear();
return false;
}
} else {
errorOutput<<"Failed parsing library"<<std::endl;
return false;
}
return true;
}
bool Application::generateSchema(std::ostringstream &output) {
if(schema == nullptr) {
return false;
}
domain::generate_schema(libraryPath, schema, output);
return true;
}
std::vector<domain::ValidationError> Application::validateSchema() {
if(schema == nullptr) {
return std::vector<domain::ValidationError>{domain::ValidationError(domain::Action::ERROR, "No schema loaded")};
}
domain::ComdelValidator validator{validators};
domain::ValidationContext context;
context.instance = nullptr;
context.attribute = nullptr;
context.addressSpaces = {};
for(auto &lib: library->getAddressSpaces()) {
context.addressSpaces.insert(std::make_pair(lib.getName(), lib));
}
auto errors = validator.validateSchema(*schema, context);
auto countValidation = validator.validateInstanceCount(*schema, *library, context);
errors.insert(errors.end(), countValidation.begin(), countValidation.end());
auto nameValidation = validator.validateInstanceNames(*schema, *library, context);
errors.insert(errors.end(), nameValidation.begin(), nameValidation.end());
auto pinValidation = validator.validatePinConnections(*schema, *library, context);
errors.insert(errors.end(), pinValidation.begin(), pinValidation.end());
return errors;
}
std::vector<domain::ValidationError> Application::generateComdel(std::ostringstream &output) {
auto errors = validateSchema();
if(Application::hasErrors(errors)) {
// as long as all validation errors are warning we continue with build
domain::generate_comdel(schema, library.value(), output);
}
return errors;
}
bool Application::hasErrors(std::vector<domain::ValidationError> errors) {
for(auto& err: errors) {
if(err.type == domain::Action::ERROR) {
return true;
}
}
return false;
}
// static instance of application
static Application *application = nullptr;
Application *Application::instance() {
if(application == nullptr) {
application = new Application();
}
return application;
}