#ifndef VHDLJJPARSER_H
#define VHDLJJPARSER_H

#include <vector>
#include <memory>
#include <string>

#include "parserintf.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>

#include "types.h"
#include "entry.h"
#include "vhdldocgen.h"
#include "config.h"
#include "util.h"

enum  class VhdlSection { UNKNOWN = 0, GEN_SEC=0x1, PARAM_SEC,CONTEXT_SEC,PROTECTED_SEC } ;
//void  parserVhdlfile(const char* inputBuffer);

/** \brief VHDL parser using state-based lexical scanning.
 *
 * This is the VHDL language parser for analyze.
 */
class VHDLOutlineParser : public OutlineParserInterface
{
  public:
    VHDLOutlineParser();
   ~VHDLOutlineParser() override;
    NON_COPYABLE(VHDLOutlineParser)
    void parseInput(const OGString &fileName,
                    const char *fileBuf,
                    const std::shared_ptr<Entry> &root,
                    ClangTUParser *clangParser) override;

    bool needsPreprocessing(const OGString &) const override { return TRUE; }
    void parsePrototype(const OGString &text) override;


    // interface for generated parser code

    void setLineParsed(int tok);
    int getLine(int tok);
    int getLine();
    void lineCount(const OGString &);
    void lineCount();
    void addProto(const OGString &s1,const OGString &s2,const OGString &s3,const OGString &s4,const OGString &s5,const OGString &s6);
    void createFunction(const OGString &impure,VhdlSpecifier spec,const OGString &fname);
    void addVhdlType(const OGString &n,int startLine,EntryType section, VhdlSpecifier spec,const OGString &args,const OGString &type,Protection prot);
    void addCompInst(const OGString &n, const OGString &instName, const OGString &comp,int iLine);
    void handleCommentBlock(const OGString &doc,bool brief);
    void handleFlowComment(const OGString &);
    void initEntry(Entry *e);
    void newEntry();
    bool isFuncProcProced();
    void pushLabel(OGString &,OGString&);
    OGString popLabel(OGString & q);
    bool addLibUseClause(const OGString &type);
    void mapLibPackage( Entry* root);
    void createFlow();
    void error_skipto(int kind);
    void oneLineComment(OGString qcs);
    void setMultCommentLine();
    bool checkMultiComment(OGString& qcs,int line);
    void insertEntryAtLine(std::shared_ptr<Entry> ce,int line);
    OGString getNameID();
    int checkInlineCode(OGString & doc);
  private:
    struct Private;
    std::unique_ptr<Private> p;
};


const EntryList &getVhdlInstList();

OGString filter2008VhdlComment(const OGString &s);

#endif
