/*
 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:   SV3_1aTreeShapeHelper.h
 * Author: alain
 *
 * Created on June 25, 2017, 2:51 PM
 */

#ifndef SV3_1ATREESHAPEHELPER_H
#define SV3_1ATREESHAPEHELPER_H
#include <stack>
#include <map>
#include <unordered_map>
#include "../Utils/ParseUtils.h"
#include "../SourceCompile/SymbolTable.h"
#include "../Design/TimeInfo.h"
#include "../Design/DesignElement.h"
#include "../Design/FileContent.h"
#include "ParseFile.h"
#include "CompilationUnit.h"
#include "CompileSourceFile.h"
#include "VObjectTypes.h"
#include "../Library/ParseLibraryDef.h"
#include "IncludeFileInfo.h"

namespace SURELOG {
 
#define SV_MAX_IDENTIFIER_SIZE 1024
#define SV_MAX_STRING_SIZE 4*1024*1024
    
    class SV3_1aTreeShapeHelper {
    public:
        typedef enum { Verilog1995, Verilog2001, Verilog2005, Verilog2009, SystemVerilog } VerilogVersion;
        
        SV3_1aTreeShapeHelper(ParseFile* pf, antlr4::CommonTokenStream* tokens, unsigned int lineOffset);
        SV3_1aTreeShapeHelper(ParseLibraryDef* pf, antlr4::CommonTokenStream* tokens);
        
        virtual ~SV3_1aTreeShapeHelper();
        
        void logError(ErrorDefinition::ErrorType error, ParserRuleContext* ctx, std::string object, bool printColumn = false);
        
        void logError(ErrorDefinition::ErrorType, Location& loc, bool showDuplicates = false);
        
        void logError(ErrorDefinition::ErrorType, Location& loc, Location& extraLoc, bool showDuplicates = false);

        NodeId generateDesignElemId();
        
        NodeId generateNodeId();

	SymbolId registerSymbol(std::string symbol);

	int registerObject(VObject& object);

	int LastObjIndex();
        
        int ObjectIndexFromContext(tree::ParseTree* ctx);

	VObject& Object(NodeId index);
        
        NodeId UniqueId(NodeId index);
        
        SymbolId& Name(NodeId index);
        
        NodeId& Child(NodeId index);
        
        NodeId& Sibling(NodeId index);
        
        NodeId& Definition(NodeId index);
        
        NodeId& Parent(NodeId index);
        
        unsigned short& Type(NodeId index) ;
        
        unsigned int& Line(NodeId index);
        
        void addNestedDesignElement( ParserRuleContext* ctx, std::string name, DesignElement::ElemType elemtype, VObjectType objtype);
                
        void addDesignElement( ParserRuleContext* ctx, std::string name, DesignElement::ElemType elemtype, VObjectType objtype);
        
        int addVObject( ParserRuleContext* ctx, std::string name, VObjectType objtype);
        
        int addVObject( ParserRuleContext* ctx, VObjectType objtype);
        
        void addParentChildRelations(int indexParent, ParserRuleContext* ctx);
                           
        NodeId getObjectId(ParserRuleContext* ctx);
        
        std::pair<double, TimeInfo::Unit> getTimeValue(SV3_1aParser::Time_literalContext* ctx);
        
        FileContent* getFileContent() { return m_fileContent;}
        
        unsigned int getFileLine(ParserRuleContext* ctx, SymbolId& fileId);       
        
        void setVerilogVersion(VerilogVersion version) { m_version = version; }
        
        VerilogVersion getVerilogVersion() { return m_version; }
        
    protected:
        ParseFile* m_pf;
        FileContent* m_fileContent;
        DesignElement* m_currentElement;
        std::stack<DesignElement*> m_nestedElements;
        typedef std::unordered_map<tree::ParseTree*, NodeId> ContextToObjectMap;
        ContextToObjectMap m_contextToObjectMap;
        antlr4::CommonTokenStream* m_tokens;
        unsigned int m_lineOffset;
        bool m_ppOutputFileLocation;
        std::stack<IncludeFileInfo> m_includeFileInfo;
        VerilogVersion m_version;
    };

};

#endif /* SV3_1ATREESHAPEHELPER_H */




