/*
 Copyright 2019 Alain Dargelas

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/*
 * File:   Compiler.cpp
 * Author: alain
 *
 * Created on March 4, 2017, 5:16 PM
 */
#include <stdint.h>

#include "CommandLine/CommandLineParser.h"
#include "ErrorReporting/ErrorContainer.h"
#include "SourceCompile/SymbolTable.h"
#include "SourceCompile/CompilationUnit.h"
#include "SourceCompile/PreprocessFile.h"
#include "SourceCompile/CompilationUnit.h"
#include "SourceCompile/CompileSourceFile.h"
#include "SourceCompile/Compiler.h"
#include "SourceCompile/CheckCompile.h"
#include "antlr4-runtime.h"
#include "DesignCompile/CompileDesign.h"
#include "SourceCompile/AnalyzeFile.h"
#include "Library/ParseLibraryDef.h"
#include "Utils/FileUtils.h"
#include "Package/Precompiled.h"
#include "Utils/StringUtils.h"
#include "Utils/Timer.h"
#include <math.h>
using namespace antlr4;

#include "API/PythonAPI.h"
#include "SourceCompile/CheckCompile.h"
#include <mutex>
#include <thread>
#include <vector>
#include <iostream>
#include <fstream>
using namespace SURELOG;

Compiler::Compiler(CommandLineParser* commandLineParser, ErrorContainer* errors,
                   SymbolTable* symbolTable)
    : m_commandLineParser(commandLineParser),
      m_errors(errors),
      m_symbolTable(symbolTable),
      m_commonCompilationUnit(NULL) {
  m_design = NULL;
#ifdef USETBB
  if (getCommandLineParser()->useTbb() &&
      (getCommandLineParser()->getNbMaxTreads() > 0))
    tbb::task_scheduler_init init(getCommandLineParser()->getNbMaxTreads());
#endif
}

Compiler::Compiler(const Compiler& orig) {}

Compiler::~Compiler() {
  std::map<SymbolId, PreprocessFile::AntlrParserHandler*>::iterator itr;
  for (itr = m_antlrPpMap.begin(); itr != m_antlrPpMap.end(); itr++) {
    delete (*itr).second;
  }
  if (m_commonCompilationUnit) {
    delete m_commonCompilationUnit;
  }
  cleanup_();
}

struct FunctorCompileOneFile {
  FunctorCompileOneFile(CompileSourceFile* compileSource,
                        CompileSourceFile::Action action)
      : m_compileSourceFile(compileSource), m_action(action) {}

  int operator()() const {
    if (m_compileSourceFile->getCommandLineParser()->pythonListener() ||
        m_compileSourceFile->getCommandLineParser()
            ->pythonEvalScriptPerFile()) {
      PyThreadState* interpState = PythonAPI::initNewInterp();
      m_compileSourceFile->setPythonInterp(interpState);
    }
    return m_compileSourceFile->compile(m_action);
  }

 private:
  CompileSourceFile* m_compileSourceFile;
  CompileSourceFile::Action m_action;
};

bool Compiler::compileOneFile_(CompileSourceFile* compiler,
                               CompileSourceFile::Action action) {
  bool status = compiler->compile(action);
  return status;
}

bool Compiler::isLibraryFile(SymbolId id) {
  if (m_libraryFiles.find(id) == m_libraryFiles.end()) {
    return false;
  } else {
    return true;
  }
}

bool Compiler::ppinit_() {
  if (!m_commandLineParser->fileunit()) {
    m_commonCompilationUnit = new CompilationUnit(false);
  }

  CompilationUnit* comp_unit = m_commonCompilationUnit;

  // Source files (.v, .sv on the command line)
  std::set<SymbolId> sourceFiles;
  unsigned int size = m_commandLineParser->getSourceFiles().size();
  for (unsigned int i = 0; i < size; i++) {
    SymbolTable* symbols = m_symbolTable;
    if (m_commandLineParser->fileunit()) {
      comp_unit = new CompilationUnit(true);
      m_compilationUnits.push_back(comp_unit);
      symbols = new SymbolTable(*m_commandLineParser->getSymbolTable());
      m_symbolTables.push_back(symbols);
    }
    ErrorContainer* errors = new ErrorContainer(symbols);
    m_errorContainers.push_back(errors);
    errors->regiterCmdLine(m_commandLineParser);

    SymbolId id = m_commandLineParser->getSourceFiles()[i];

    std::string fileName = m_commandLineParser->getSymbolTable()->getSymbol(id);
    std::string fullPath = FileUtils::getFullPath(fileName);
    SymbolId fullPathId =
        m_commandLineParser->getSymbolTable()->registerSymbol(fullPath);
    Library* library = m_librarySet->getLibrary(fullPathId);
    sourceFiles.insert(fullPathId);

    CompileSourceFile* compiler = new CompileSourceFile(
        m_commandLineParser->getSourceFiles()[i], m_commandLineParser, errors,
        this, symbols, comp_unit, library);
    m_compilers.push_back(compiler);
  }

  // Library files
  std::set<SymbolId> libFiles;
  // (-v <file>)
  size = m_commandLineParser->getLibraryFiles().size();
  for (unsigned int i = 0; i < size; i++) {
    SymbolId id = m_commandLineParser->getLibraryFiles()[i];
    libFiles.insert(id);
  }
  // (-y <path> +libext+<ext>)
  for (auto path : m_commandLineParser->getLibraryPaths()) {
    for (auto ext : m_commandLineParser->getLibraryExtensions()) {
      auto files = FileUtils::collectFiles(
          path, ext, m_commandLineParser->getSymbolTable());
      for (auto file : files) {
        libFiles.insert(file);
      }
    }
  }
  for (auto id : libFiles) {
    SymbolTable* symbols = m_symbolTable;
    if (m_commandLineParser->fileunit()) {
      comp_unit = new CompilationUnit(true);
      m_compilationUnits.push_back(comp_unit);
      symbols = new SymbolTable(*m_commandLineParser->getSymbolTable());
      m_symbolTables.push_back(symbols);
    }
    ErrorContainer* errors = new ErrorContainer(symbols);
    m_errorContainers.push_back(errors);
    errors->regiterCmdLine(m_commandLineParser);

    std::string fullPath = FileUtils::getFullPath(
        m_commandLineParser->getSymbolTable()->getSymbol(id));

    // This line registers the file in the "work" library:
    SymbolId fullPathId =
        m_commandLineParser->getSymbolTable()->registerSymbol(fullPath);
    /*Library* library  = */ m_librarySet->getLibrary(fullPathId);
    m_libraryFiles.insert(id);
    m_libraryFiles.insert(fullPathId);
    // No need to register a compiler
    // CompileSourceFile* compiler = new CompileSourceFile
    // (m_commandLineParser->getLibraryFiles ()[i],
    //                                                     m_commandLineParser,
    //                                                     errors, this,
    //                                                     symbols, comp_unit,
    //                                                     library);
    // m_compilers.push_back (compiler);
  }

  // Libraries (.map)
  for (auto& lib : m_librarySet->getLibraries()) {
    for (auto id : lib.getFiles()) {
      std::string fileName = lib.getSymbols()->getSymbol(id);
      if (sourceFiles.find(id) != sourceFiles.end()) {
        // These files are already included in the command line
        continue;
      }

      if (strstr(fileName.c_str(), ".map")) {
        // .map files are not parsed with the regular parser
        continue;
      }
      SymbolTable* symbols = m_symbolTable;
      if (m_commandLineParser->fileunit()) {
        comp_unit = new CompilationUnit(true);
        m_compilationUnits.push_back(comp_unit);
        symbols = new SymbolTable(*m_commandLineParser->getSymbolTable());
        m_symbolTables.push_back(symbols);
      }
      ErrorContainer* errors = new ErrorContainer(symbols);
      m_errorContainers.push_back(errors);
      errors->regiterCmdLine(m_commandLineParser);

      CompileSourceFile* compiler = new CompileSourceFile(
          id, m_commandLineParser, errors, this, symbols, comp_unit, &lib);
      m_compilers.push_back(compiler);
    }
  }
  return true;
}

bool Compiler::createFileList_()
{
  if (m_commandLineParser->writePpOutput() ||
          (m_commandLineParser->writePpOutputFileId() != 0)) {
    SymbolTable* symbolTable = getSymbolTable();
    const std::string& directory =
            symbolTable->getSymbol(m_commandLineParser->getFullCompileDir());
    std::ofstream ofs;
    std::string fileList = directory + "/file.lst";
    ofs.open(fileList);
    if (ofs.good()) {
      unsigned int size = m_compilers.size();
      for (unsigned int i = 0; i < size; i++) {
        std::string fileName = m_compilers[i]->getSymbolTable()->getSymbol(
                m_compilers[i]->getPpOutputFileId());
        fileName = StringUtils::replaceAll(fileName, "//", "/");
        ofs << fileName << std::flush << std::endl;
      }
      ofs.close();
    } else {
      std::cout << "Could not create filelist: " << fileList << std::endl;
    }
  }
  return true;
}
 

bool Compiler::parseinit_() {
  Precompiled* prec = Precompiled::getSingleton();
  // Single out the large files.
  // Small files are going to be scheduled in multiple threads based on size.
  // Large files are going to be compiled in a different batch in multithread
  
  if (!m_commandLineParser->fileunit()) {
    unsigned int size = m_symbolTables.size();
    for (unsigned int i = 0; i < size; i++) {
      delete m_symbolTables[i];
    }
    size = m_errorContainers.size();
    for (unsigned int i = 0; i < size; i++) {
      delete m_errorContainers[i];
    }
    m_symbolTables.clear();
    m_errorContainers.clear();
  }

  std::vector<CompileSourceFile*> tmp_compilers;
  unsigned int size = m_compilers.size();
  for (unsigned int i = 0; i < size; i++) {
    std::string fileName = m_compilers[i]->getSymbolTable()->getSymbol(
        m_compilers[i]->getPpOutputFileId());
    std::string origFile = m_compilers[i]->getSymbolTable()->getSymbol(
        m_compilers[i]->getFileId());
    unsigned int nbThreads = m_commandLineParser->getNbMaxTreads();
    std::string root = fileName;
    root = StringUtils::getRootFileName(root);
    if (prec->isFilePrecompiled(root)) {
      nbThreads = 0;
    }
    int effectiveNbThreads = 0;
    if (nbThreads > 4)
      effectiveNbThreads = (int)(log(((float)nbThreads + 1.0) / 4.0) * 10.0);
    else
      effectiveNbThreads = nbThreads;

    AnalyzeFile* fileAnalyzer = new AnalyzeFile(
        m_commandLineParser, m_design, fileName, origFile, effectiveNbThreads);
    fileAnalyzer->analyze();
    m_compilers[i]->setFileAnalyzer(fileAnalyzer);
    if (fileAnalyzer->getSplitFiles().size() > 1) {
      // Schedule parent
      m_compilersParentFiles.push_back(m_compilers[i]);
      m_compilers[i]->initParser();

      if (!m_commandLineParser->fileunit()) {
        SymbolTable* symbols =
            new SymbolTable(*m_commandLineParser->getSymbolTable());
        m_symbolTables.push_back(symbols);
        m_compilers[i]->setSymbolTable(symbols);
        // fileContent->setSymbolTable(symbols);
        ErrorContainer* errors = new ErrorContainer(symbols);
        m_errorContainers.push_back(errors);
        errors->regiterCmdLine(m_commandLineParser);
        m_compilers[i]->setErrorContainer(errors);
      }

      FileContent* fileContent =
          new FileContent(m_compilers[i]->getParser()->getFileId(0),
                          m_compilers[i]->getParser()->getLibrary(),
                          m_compilers[i]->getSymbolTable(),
                          m_compilers[i]->getErrorContainer(), NULL, 0);
      m_compilers[i]->getParser()->setFileContent(fileContent);

      int j = 0;
      for (auto chunk : fileAnalyzer->getSplitFiles()) {
        SymbolTable* symbols =
            new SymbolTable(*m_commandLineParser->getSymbolTable());
        m_symbolTables.push_back(symbols);
        SymbolId ppId = symbols->registerSymbol(chunk);
        symbols->registerSymbol(
            m_compilers[i]->getParser()->getFileName(LINE1));
        CompileSourceFile* chunkCompiler = new CompileSourceFile(
            m_compilers[i], ppId, fileAnalyzer->getLineOffsets()[j]);
        // Schedule chunk
        tmp_compilers.push_back(chunkCompiler);

        chunkCompiler->setSymbolTable(symbols);
        ErrorContainer* errors = new ErrorContainer(symbols);
        m_errorContainers.push_back(errors);
        errors->regiterCmdLine(m_commandLineParser);
        chunkCompiler->setErrorContainer(errors);
        // chunkCompiler->getParser ()->setFileContent (fileContent);

        FileContent* fileContent =
            new FileContent(m_compilers[i]->getParser()->getFileId(0),
                            m_compilers[i]->getParser()->getLibrary(), symbols,
                            errors, NULL, ppId);
        chunkCompiler->getParser()->setFileContent(fileContent);
        getDesign()->addFileContent(m_compilers[i]->getParser()->getFileId(0),
                                    fileContent);

        j++;
      }
    } else {
      if (!m_commandLineParser->fileunit()) {
        SymbolTable* symbols =
            new SymbolTable(*m_commandLineParser->getSymbolTable());
        m_symbolTables.push_back(symbols);
        m_compilers[i]->setSymbolTable(symbols);
        ErrorContainer* errors = new ErrorContainer(symbols);
        m_errorContainers.push_back(errors);
        errors->regiterCmdLine(m_commandLineParser);
        m_compilers[i]->setErrorContainer(errors);
      }

      tmp_compilers.push_back(m_compilers[i]);
    }
  }
  m_compilers = tmp_compilers;

  return true;
}

bool Compiler::pythoninit_() { return parseinit_(); }

ErrorContainer::Stats Compiler::getErrorStats() {
  ErrorContainer::Stats stats;
  unsigned int size = m_errorContainers.size();
  for (unsigned int i = 0; i < size; i++) {
    ErrorContainer::Stats tmp;
    tmp = m_errorContainers[i]->getErrorStats();
    stats += tmp;
  }

  return stats;
}

bool Compiler::cleanup_() {
  unsigned int size = m_compilers.size();
  for (unsigned int i = 0; i < size; i++) {
    delete m_compilers[i];
  }
  size = m_compilationUnits.size();
  for (unsigned int i = 0; i < size; i++) {
    delete m_compilationUnits[i];
  }
  size = m_symbolTables.size();
  for (unsigned int i = 0; i < size; i++) {
    delete m_symbolTables[i];
  }
  size = m_errorContainers.size();
  for (unsigned int i = 0; i < size; i++) {
    delete m_errorContainers[i];
  }
  return true;
}

bool Compiler::compileFileSet_(CompileSourceFile::Action action,
                               bool allowMultithread,
                               std::vector<CompileSourceFile*>& container) {
  unsigned short maxThreadCount = m_commandLineParser->getNbMaxTreads();
  if (allowMultithread == false) {
    maxThreadCount = 0;
  }

  if (maxThreadCount == 0) {
    // Single thread
    unsigned int size = container.size();
    for (unsigned int i = 0; i < size; i++) {
      container[i]->setPythonInterp(PythonAPI::getMainInterp());
      bool status = compileOneFile_(container[i], action);
      m_errors->appendErrors(*container[i]->getErrorContainer());
      m_errors->printMessages(m_commandLineParser->muteStdout());
      if ((!status) || container[i]->getErrorContainer()->hasFatalErrors())
        return false;
    }
  } else if (getCommandLineParser()->useTbb() &&
             (action != CompileSourceFile::Action::Parse)) {
#ifdef USETBB
    // TBB Thread management
    int maxThreadCount = m_commandLineParser->getNbMaxTreads();
    if (allowMultithread == false) {
      maxThreadCount = 0;
    }
    unsigned int size = container.size();
    if (maxThreadCount) {
      for (unsigned int i = 0; i < size; i++) {
        m_taskGroup.run(FunctorCompileOneFile(container[i], action));
      }
      m_taskGroup.wait();
      bool fatalErrors = false;
      for (unsigned int i = 0; i < size; i++) {
        // Promote report to master error container
        m_errors->appendErrors(*container[i]->getErrorContainer());
        if (container[i]->getErrorContainer()->hasFatalErrors()) {
          fatalErrors = true;
        }
        if (getCommandLineParser()->pythonListener()) {
          container[i]->shutdownPythonInterp();
        }
        m_errors->printMessages(m_commandLineParser->muteStdout());
      }
      if (fatalErrors) return false;
    } else {
      for (unsigned int i = 0; i < size; i++) {
        container[i]->setPythonInterp(PythonAPI::getMainInterp());
        bool status = compileOneFile_(container[i], action);
        m_errors->appendErrors(*container[i]->getErrorContainer());
        m_errors->printMessages(m_commandLineParser->muteStdout());
        if ((!status) || container[i]->getErrorContainer()->hasFatalErrors())
          return false;
      }
    }
#endif
  } else {
    // Custom Thread management

    // Optimize the load balance, try to even out the work in each thread by the
    // size of the files
    std::vector<std::vector<CompileSourceFile*>> jobArray(maxThreadCount);

    std::vector<unsigned long> jobSize(maxThreadCount);

    for (unsigned short i = 0; i < maxThreadCount; i++) jobSize[i] = 0;

    for (unsigned int i = 0; i < container.size(); i++) {
      unsigned int size = container[i]->getJobSize(action);
      unsigned int newJobIndex = 0;
      uint64_t minJobQueue = ULLONG_MAX;
      for (unsigned short ii = 0; ii < maxThreadCount; ii++) {
        if (jobSize[ii] < minJobQueue) {
          newJobIndex = ii;
          minJobQueue = jobSize[ii];
        }
      }

      jobSize[newJobIndex] += size;
      jobArray[newJobIndex].push_back(container[i]);
    }

    if (getCommandLineParser()->profile()) {
      if (action == CompileSourceFile::Preprocess)
        std::cout << "Preprocessing task\n";
      else if (action == CompileSourceFile::Parse)
        std::cout << "Parsing task\n";
      else
        std::cout << "Misc Task\n";
      for (unsigned short i = 0; i < maxThreadCount; i++) {
        std::cout << "Thread " << i << " : \n";
        int sum = 0;
        for (unsigned int j = 0; j < jobArray[i].size(); j++) {
          std::string fileName;
          if (jobArray[i][j]->getPreprocessor())
            fileName = jobArray[i][j]->getPreprocessor()->getFileName(0);
          if (jobArray[i][j]->getParser())
            fileName = jobArray[i][j]->getParser()->getFileName(0);
          sum += jobArray[i][j]->getJobSize(action);
          std::cout << jobArray[i][j]->getJobSize(action) << " " << fileName
                    << "\n";
        }
        std::cout << ", Total: " << sum << std::endl << std::flush;
      }
    }

    // Create the threads with their respective workloads
    std::vector<std::thread*> threads;
    for (unsigned short i = 0; i < maxThreadCount; i++) {
      std::thread* th = new std::thread([=] {
        for (unsigned int j = 0; j < jobArray[i].size(); j++) {
          if (getCommandLineParser()->pythonListener() ||
              getCommandLineParser()->pythonEvalScriptPerFile()) {
            PyThreadState* interpState = PythonAPI::initNewInterp();
            jobArray[i][j]->setPythonInterp(interpState);
          }

          jobArray[i][j]->compile(action);

          if (getCommandLineParser()->pythonListener() ||
              getCommandLineParser()->pythonEvalScriptPerFile()) {
            jobArray[i][j]->shutdownPythonInterp();
          }
        }
      });
      threads.push_back(th);
    }

    // Sync the threads
    for (unsigned int th = 0; th < threads.size(); th++) {
      threads[th]->join();
    }

    // Delete the threads
    for (unsigned int th = 0; th < threads.size(); th++) {
      delete threads[th];
    }

    // Promote report to master error container
    bool fatalErrors = false;
    for (unsigned int j = 0; j < container.size(); j++) {
      m_errors->appendErrors(*container[j]->getErrorContainer());
      if (container[j]->getErrorContainer()->hasFatalErrors())
        fatalErrors = true;
    }
    m_errors->printMessages(m_commandLineParser->muteStdout());

    if (fatalErrors) return false;
  }
  return true;
}

bool Compiler::compile() {
  std::string profile;
  Timer tmr;
  Timer tmrTotal;
  // Scan the libraries definition
  if (!parseLibrariesDef_()) return false;

  if (m_commandLineParser->profile()) {
    std::string msg = "Scan libraries took " +
                      StringUtils::to_string(tmr.elapsed_rounded()) + "s\n";
    std::cout << msg << std::endl;
    profile += msg;
    tmr.reset();
  }

  // Preprocess
  ppinit_();
  if (!compileFileSet_(CompileSourceFile::Preprocess,
                       m_commandLineParser->fileunit(), m_compilers))
    return false;

  // Single thread post Preprocess
  if (!compileFileSet_(CompileSourceFile::PostPreprocess, false, m_compilers))
    return false;

  if (m_commandLineParser->profile()) {
    std::string msg = "Preprocessing took " +
                      StringUtils::to_string(tmr.elapsed_rounded()) + "s\n";
    std::cout << msg << std::endl;
    for (unsigned int i = 0; i < m_compilers.size(); i++) {
      msg += m_compilers[i]->getPreprocessor()->getProfileInfo();
    }
    std::cout << msg << std::endl;
    profile += msg;
    tmr.reset();
  }
  createFileList_();
  // Parse
  bool parserInitialized = false;
  if (m_commandLineParser->parse() || m_commandLineParser->pythonListener() ||
      m_commandLineParser->pythonEvalScriptPerFile() ||
      m_commandLineParser->pythonEvalScript()) {
    parseinit_();
    parserInitialized = true;
    if (!compileFileSet_(CompileSourceFile::Parse, true, m_compilers))
      return false;  // Small files and large file chunks
    if (!compileFileSet_(CompileSourceFile::Parse, true,
                         m_compilersParentFiles))
      return false;  // Recombine chunks
  }

  if (m_commandLineParser->profile()) {
    std::string msg =
        "Parsing took " + StringUtils::to_string(tmr.elapsed_rounded()) + "s\n";
    for (unsigned int i = 0; i < m_compilersParentFiles.size(); i++) {
      msg += m_compilersParentFiles[i]->getParser()->getProfileInfo();
    }
    for (unsigned int i = 0; i < m_compilers.size(); i++) {
      msg += m_compilers[i]->getParser()->getProfileInfo();
    }

    std::cout << msg << std::endl;
    profile += msg;
    tmr.reset();
  }

  // Check Parsing
  CheckCompile* checkComp = new CheckCompile(this);
  checkComp->check();
  delete checkComp;
  m_errors->printMessages(m_commandLineParser->muteStdout());

  // Python Listener
  if (m_commandLineParser->pythonListener() ||
      m_commandLineParser->pythonEvalScriptPerFile()) {
    if (!parserInitialized) pythoninit_();
    if (!compileFileSet_(CompileSourceFile::PythonAPI, true, m_compilers))
      return false;
    if (!compileFileSet_(CompileSourceFile::PythonAPI, true,
                         m_compilersParentFiles))
      return false;

    if (m_commandLineParser->profile()) {
      std::string msg = "Python file processing took " +
                        StringUtils::to_string(tmr.elapsed_rounded()) + "s\n";
      std::cout << msg << std::endl;
      profile += msg;
      tmr.reset();
    }
  }

  if (m_commandLineParser->compile()) {
    // Compile Design, has its own thread management
    CompileDesign* compileDesign = new CompileDesign(this);
    compileDesign->compile();
    m_errors->printMessages(m_commandLineParser->muteStdout());

    if (m_commandLineParser->profile()) {
      std::string msg = "Compilation took " +
                        StringUtils::to_string(tmr.elapsed_rounded()) + "s\n";
      std::cout << msg << std::endl;
      profile += msg;
      tmr.reset();
    }

    if (m_commandLineParser->elaborate()) {
      compileDesign->elaborate();
      m_errors->printMessages(m_commandLineParser->muteStdout());

      if (m_commandLineParser->profile()) {
        std::string msg = "Elaboration took " +
                          StringUtils::to_string(tmr.elapsed_rounded()) + "s\n";
        std::cout << msg << std::endl;
        profile += msg;
        tmr.reset();
      }

      if (m_commandLineParser->pythonEvalScript()) {
        PythonAPI::evalScript(m_commandLineParser->getSymbolTable()->getSymbol(
                                  m_commandLineParser->pythonEvalScriptId()),
                              m_design);
        if (m_commandLineParser->profile()) {
          std::string msg = "Python design processing took " +
                            StringUtils::to_string(tmr.elapsed_rounded()) +
                            "s\n";
          profile += msg;
          std::cout << msg << std::endl;
          tmr.reset();
        }
      }
      m_errors->printMessages(m_commandLineParser->muteStdout());
    }

    delete compileDesign;
  }
  if (m_commandLineParser->profile()) {
    std::string msg = "Total time " +
                      StringUtils::to_string(tmrTotal.elapsed_rounded()) +
                      "s\n";
    profile += msg;
    profile = std::string("==============\n") + "PROFILE\n" +
              std::string("==============\n") + profile + "==============\n";
    std::cout << profile << std::endl;
    m_errors->printToLogFile(profile);
  }
  return true;
}

void Compiler::registerAntlrPpHandlerForId(
    SymbolId id, PreprocessFile::AntlrParserHandler* pp) {
  std::map<SymbolId, PreprocessFile::AntlrParserHandler*>::iterator itr =
      m_antlrPpMap.find(id);
  if (itr != m_antlrPpMap.end()) {
    delete (*itr).second;
    m_antlrPpMap.erase(itr);
    m_antlrPpMap.insert(std::make_pair(id, pp));
    return;
  }
  m_antlrPpMap.insert(std::make_pair(id, pp));
}

PreprocessFile::AntlrParserHandler* Compiler::getAntlrPpHandlerForId(
    SymbolId id) {
  std::map<SymbolId, PreprocessFile::AntlrParserHandler*>::iterator itr =
      m_antlrPpMap.find(id);
  if (itr != m_antlrPpMap.end()) {
    PreprocessFile::AntlrParserHandler* ptr = (*itr).second;
    return ptr;
  }
  return NULL;
}

bool Compiler::parseLibrariesDef_() {
  m_librarySet = new LibrarySet();
  m_configSet = new ConfigSet();
  m_design = new Design(getErrorContainer(), m_librarySet, m_configSet);
  ParseLibraryDef* libParser = new ParseLibraryDef(
      m_commandLineParser, m_errors, m_symbolTable, m_librarySet, m_configSet);
  return libParser->parseLibrariesDefinition();
}
