/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 * $Id$
 */

#if !defined(XERCESC_INCLUDE_GUARD_SCHEMAGRAMMAR_HPP)
#define XERCESC_INCLUDE_GUARD_SCHEMAGRAMMAR_HPP

#include <xercesc/framework/XMLNotationDecl.hpp>
#include <xercesc/util/RefHash3KeysIdPool.hpp>
#include <xercesc/util/NameIdPool.hpp>
#include <xercesc/util/StringPool.hpp>
#include <xercesc/validators/common/Grammar.hpp>
#include <xercesc/validators/schema/SchemaElementDecl.hpp>
#include <xercesc/util/ValueVectorOf.hpp>
#include <xercesc/validators/datatype/IDDatatypeValidator.hpp>
#include <xercesc/validators/datatype/DatatypeValidatorFactory.hpp>
#include <xercesc/framework/XMLSchemaDescription.hpp>

XERCES_CPP_NAMESPACE_BEGIN

//
// This class stores the Schema information
//  NOTE: Schemas are not namespace aware, so we just use regular NameIdPool
//  data structures to store element and attribute decls. They are all set
//  to be in the global namespace and the full QName is used as the base name
//  of the decl. This means that all the URI parameters below are expected
//  to be null pointers (and anything else will cause an exception.)
//

// ---------------------------------------------------------------------------
//  Forward Declarations
// ---------------------------------------------------------------------------
class ComplexTypeInfo;
class XercesGroupInfo;
class XercesAttGroupInfo;
class XSAnnotation;

// ---------------------------------------------------------------------------
//  typedef declaration
// ---------------------------------------------------------------------------
typedef ValueVectorOf<SchemaElementDecl*> ElemVector;


class VALIDATORS_EXPORT SchemaGrammar : public Grammar
{
public:
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    SchemaGrammar(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
    virtual ~SchemaGrammar();

    // -----------------------------------------------------------------------
    //  Implementation of Virtual Interface
    // -----------------------------------------------------------------------
    virtual Grammar::GrammarType getGrammarType() const;
    virtual const XMLCh* getTargetNamespace() const;

    // this method should only be used while the grammar is being
    // constructed, not while it is being used
    // in a validation episode!
    virtual XMLElementDecl* findOrAddElemDecl
    (
        const   unsigned int    uriId
        , const XMLCh* const    baseName
        , const XMLCh* const    prefixName
        , const XMLCh* const    qName
        , unsigned int          scope
        ,       bool&           wasAdded
    ) ;

    virtual XMLSize_t getElemId
    (
        const   unsigned int    uriId
        , const XMLCh* const    baseName
        , const XMLCh* const    qName
        , unsigned int          scope
    )   const ;

    virtual const XMLElementDecl* getElemDecl
    (
        const   unsigned int    uriId
        , const XMLCh* const    baseName
        , const XMLCh* const    qName
        , unsigned int          scope
    )   const ;

    virtual XMLElementDecl* getElemDecl
    (
        const   unsigned int    uriId
        , const XMLCh* const    baseName
        , const XMLCh* const    qName
        , unsigned int          scope
    );

    virtual const XMLElementDecl* getElemDecl
    (
        const   unsigned int    elemId
    )   const;

    virtual XMLElementDecl* getElemDecl
    (
        const   unsigned int    elemId
    );

    virtual const XMLNotationDecl* getNotationDecl
    (
        const   XMLCh* const    notName
    )   const;

    virtual XMLNotationDecl* getNotationDecl
    (
        const   XMLCh* const    notName
    );

    virtual bool getValidated() const;

    virtual XMLElementDecl* putElemDecl
    (
        const   unsigned int    uriId
        , const XMLCh* const    baseName
        , const XMLCh* const    prefixName
        , const XMLCh* const    qName
        , unsigned int          scope
        , const bool            notDeclared = false
    );

    virtual XMLSize_t putElemDecl
    (
        XMLElementDecl* const elemDecl
        , const bool          notDeclared = false
    )   ;

    virtual XMLSize_t putNotationDecl
    (
        XMLNotationDecl* const notationDecl
    )   const;

    virtual void setValidated(const bool newState);

    virtual void reset();

    // -----------------------------------------------------------------------
    //  Getter methods
    // -----------------------------------------------------------------------
    RefHash3KeysIdPoolEnumerator<SchemaElementDecl> getElemEnumerator() const;
    NameIdPoolEnumerator<XMLNotationDecl> getNotationEnumerator() const;
    RefHashTableOf<XMLAttDef>* getAttributeDeclRegistry() const;
    RefHashTableOf<ComplexTypeInfo>* getComplexTypeRegistry() const;
    RefHashTableOf<XercesGroupInfo>* getGroupInfoRegistry() const;
    RefHashTableOf<XercesAttGroupInfo>* getAttGroupInfoRegistry() const;
    DatatypeValidatorFactory* getDatatypeRegistry();
    RefHash2KeysTableOf<ElemVector>* getValidSubstitutionGroups() const;

    // -----------------------------------------------------------------------
    //  Setter methods
    // -----------------------------------------------------------------------
    void setTargetNamespace(const XMLCh* const targetNamespace);
    void setAttributeDeclRegistry(RefHashTableOf<XMLAttDef>* const attReg);
    void setComplexTypeRegistry(RefHashTableOf<ComplexTypeInfo>* const other);
    void setGroupInfoRegistry(RefHashTableOf<XercesGroupInfo>* const other);
    void setAttGroupInfoRegistry(RefHashTableOf<XercesAttGroupInfo>* const other);
    void setValidSubstitutionGroups(RefHash2KeysTableOf<ElemVector>* const);

    virtual void                    setGrammarDescription( XMLGrammarDescription*);
    virtual XMLGrammarDescription*  getGrammarDescription() const;

    // -----------------------------------------------------------------------
    //  Helper methods
    // -----------------------------------------------------------------------
    XMLSize_t putGroupElemDecl
    (
        XMLElementDecl* const elemDecl
    )   const;

    // -----------------------------------------------------------------------
    // Annotation management methods
    // -----------------------------------------------------------------------
    /**
      * Add annotation to the list of annotations for a given key
      */
    void putAnnotation(void* key, XSAnnotation* const annotation);

    /**
      * Add global annotation
      *
      * Note: XSAnnotation acts as a linked list
      */
    void addAnnotation(XSAnnotation* const annotation);

    /**
     * Retrieve the annotation that is associated with the specified key
     *
     * @param  key   represents a schema component object (i.e. SchemaGrammar)
     * @return XSAnnotation associated with the key object
     */
    XSAnnotation* getAnnotation(const void* const key);

    /**
     * Retrieve the annotation that is associated with the specified key
     *
     * @param  key   represents a schema component object (i.e. SchemaGrammar)
     * @return XSAnnotation associated with the key object
     */
    const XSAnnotation* getAnnotation(const void* const key) const;

    /**
      * Get global annotation
      */
    XSAnnotation* getAnnotation();
    const XSAnnotation* getAnnotation() const;

    /**
      * Get annotation hash table, to enumerate through them
      */
    RefHashTableOf<XSAnnotation, PtrHasher>*  getAnnotations();
    const RefHashTableOf<XSAnnotation, PtrHasher>*  getAnnotations() const;

    /**
     * Get/set scope count.
     */
    unsigned int getScopeCount () const;
    void setScopeCount (unsigned int);

    /**
     * Get/set anonymous type count.
     */
    unsigned int getAnonTypeCount () const;
    void setAnonTypeCount (unsigned int);

    /***
     * Support for Serialization/De-serialization
     ***/
    DECL_XSERIALIZABLE(SchemaGrammar)

private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    SchemaGrammar(const SchemaGrammar&);
    SchemaGrammar& operator=(const SchemaGrammar&);

    // -----------------------------------------------------------------------
    //  Helper methods
    // -----------------------------------------------------------------------
    void cleanUp();

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fElemDeclPool
    //      This is the element decl pool. It contains all of the elements
    //      declared in the Schema (and their associated attributes.)
    //
    //  fElemNonDeclPool
    //      This is the element decl pool that is is populated as new elements
    //      are seen in the XML document (not declared in the Schema), and they
    //      are given default characteristics.
    //
    //  fGroupElemDeclPool
    //      This is the element decl pool for elements in a group that are
    //      referenced in different scope. It contains all of the elements
    //      declared in the Schema (and their associated attributes.)
    //
    //  fNotationDeclPool
    //      This is a pool of NotationDecl objects, which contains all of the
    //      notations declared in the Schema.
    //
    //  fTargetNamespace
    //      Target name space for this grammar.
    //
    //  fAttributeDeclRegistry
    //      Global attribute declarations
    //
    //  fComplexTypeRegistry
    //      Stores complexType declaration info
    //
    //  fGroupInfoRegistry
    //      Stores global <group> declaration info
    //
    //  fAttGroupInfoRegistry
    //      Stores global <attributeGroup> declaration info
    //
    //  fDatatypeRegistry
    //      Datatype validator factory
    //
    //  fValidSubstitutionGroups
    //      Valid list of elements that can substitute a given element
    //
    //  fIDRefList
    //      List of ids of schema declarations extracted during schema grammar
    //      traversal
    //
    //  fValidated
    //      Indicates if the content of the Grammar has been pre-validated
    //      or not (UPA checking, etc.). When using a cached grammar, no need
    //      for pre content validation.
    //
    //  fGramDesc: adopted
    //
    // -----------------------------------------------------------------------
    XMLCh*                                   fTargetNamespace;
    RefHash3KeysIdPool<SchemaElementDecl>*   fElemDeclPool;
    RefHash3KeysIdPool<SchemaElementDecl>*   fElemNonDeclPool;
    RefHash3KeysIdPool<SchemaElementDecl>*   fGroupElemDeclPool;
    NameIdPool<XMLNotationDecl>*             fNotationDeclPool;
    RefHashTableOf<XMLAttDef>*               fAttributeDeclRegistry;
    RefHashTableOf<ComplexTypeInfo>*         fComplexTypeRegistry;
    RefHashTableOf<XercesGroupInfo>*         fGroupInfoRegistry;
    RefHashTableOf<XercesAttGroupInfo>*      fAttGroupInfoRegistry;
    RefHash2KeysTableOf<ElemVector>*         fValidSubstitutionGroups;
    MemoryManager*                           fMemoryManager;
    XMLSchemaDescription*                    fGramDesc;
    RefHashTableOf<XSAnnotation, PtrHasher>* fAnnotations;

    bool                                   fValidated;
    DatatypeValidatorFactory               fDatatypeRegistry;

    unsigned int                             fScopeCount;
    unsigned int                             fAnonTypeCount;
};


// ---------------------------------------------------------------------------
//  SchemaGrammar: Getter methods
// ---------------------------------------------------------------------------
inline RefHash3KeysIdPoolEnumerator<SchemaElementDecl>
SchemaGrammar::getElemEnumerator() const
{
    return RefHash3KeysIdPoolEnumerator<SchemaElementDecl>(fElemDeclPool, false, fMemoryManager);
}

inline NameIdPoolEnumerator<XMLNotationDecl>
SchemaGrammar::getNotationEnumerator() const
{
    return NameIdPoolEnumerator<XMLNotationDecl>(fNotationDeclPool, fMemoryManager);
}

inline RefHashTableOf<XMLAttDef>* SchemaGrammar::getAttributeDeclRegistry() const {

    return fAttributeDeclRegistry;
}

inline RefHashTableOf<ComplexTypeInfo>*
SchemaGrammar::getComplexTypeRegistry() const {

    return fComplexTypeRegistry;
}

inline RefHashTableOf<XercesGroupInfo>*
SchemaGrammar::getGroupInfoRegistry() const {

    return fGroupInfoRegistry;
}

inline RefHashTableOf<XercesAttGroupInfo>*
SchemaGrammar::getAttGroupInfoRegistry() const {

    return fAttGroupInfoRegistry;
}

inline DatatypeValidatorFactory* SchemaGrammar::getDatatypeRegistry() {

    return &fDatatypeRegistry;
}

inline RefHash2KeysTableOf<ElemVector>*
SchemaGrammar::getValidSubstitutionGroups() const {

    return fValidSubstitutionGroups;
}

inline XMLGrammarDescription* SchemaGrammar::getGrammarDescription() const
{
    return fGramDesc;
}

inline XSAnnotation* SchemaGrammar::getAnnotation(const void* const key)
{
    return fAnnotations->get(key);
}

inline const XSAnnotation* SchemaGrammar::getAnnotation(const void* const key) const
{
    return fAnnotations->get(key);
}

inline XSAnnotation* SchemaGrammar::getAnnotation()
{
    return fAnnotations->get(this);
}

inline const XSAnnotation* SchemaGrammar::getAnnotation() const
{
    return fAnnotations->get(this);
}

inline RefHashTableOf<XSAnnotation, PtrHasher>* SchemaGrammar::getAnnotations()
{
    return fAnnotations;
}

inline const RefHashTableOf<XSAnnotation, PtrHasher>* SchemaGrammar::getAnnotations() const
{
    return fAnnotations;
}
// -----------------------------------------------------------------------
//  Setter methods
// -----------------------------------------------------------------------
inline void SchemaGrammar::setTargetNamespace(const XMLCh* const targetNamespace)
{
    if (fTargetNamespace)
        fMemoryManager->deallocate(fTargetNamespace);//delete [] fTargetNamespace;
    fTargetNamespace = XMLString::replicate(targetNamespace, fMemoryManager);
}

inline void
SchemaGrammar::setAttributeDeclRegistry(RefHashTableOf<XMLAttDef>* const attReg) {

    fAttributeDeclRegistry = attReg;
}

inline void
SchemaGrammar::setComplexTypeRegistry(RefHashTableOf<ComplexTypeInfo>* const other) {

    fComplexTypeRegistry = other;
}

inline void
SchemaGrammar::setGroupInfoRegistry(RefHashTableOf<XercesGroupInfo>* const other) {

    fGroupInfoRegistry = other;
}

inline void
SchemaGrammar::setAttGroupInfoRegistry(RefHashTableOf<XercesAttGroupInfo>* const other) {

    fAttGroupInfoRegistry = other;
}

inline void
SchemaGrammar::setValidSubstitutionGroups(RefHash2KeysTableOf<ElemVector>* const other) {

    fValidSubstitutionGroups = other;
}


// ---------------------------------------------------------------------------
//  SchemaGrammar: Virtual methods
// ---------------------------------------------------------------------------
inline Grammar::GrammarType SchemaGrammar::getGrammarType() const {
    return Grammar::SchemaGrammarType;
}

inline const XMLCh* SchemaGrammar::getTargetNamespace() const {
    return fTargetNamespace;
}

// Element Decl
inline XMLSize_t SchemaGrammar::getElemId (const   unsigned int  uriId
                                              , const XMLCh* const    baseName
                                              , const XMLCh* const
                                              , unsigned int          scope ) const
{
    //
    //  In this case, we don't return zero to mean 'not found', so we have to
    //  map it to the official not found value if we don't find it.
    //
    const SchemaElementDecl* decl = fElemDeclPool->getByKey(baseName, uriId, scope);
    if (!decl) {

        decl = fGroupElemDeclPool->getByKey(baseName, uriId, scope);

        if (!decl)
            return XMLElementDecl::fgInvalidElemId;
    }
    return decl->getId();
}

inline const XMLElementDecl* SchemaGrammar::getElemDecl( const   unsigned int  uriId
                                              , const XMLCh* const    baseName
                                              , const XMLCh* const
                                              , unsigned int          scope )   const
{
    const SchemaElementDecl* decl = fElemDeclPool->getByKey(baseName, uriId, scope);

    if (!decl) {

        decl = fGroupElemDeclPool->getByKey(baseName, uriId, scope);

        if (!decl && fElemNonDeclPool)
            decl = fElemNonDeclPool->getByKey(baseName, uriId, scope);
    }

    return decl;
}

inline XMLElementDecl* SchemaGrammar::getElemDecl (const   unsigned int  uriId
                                              , const XMLCh* const    baseName
                                              , const XMLCh* const
                                              , unsigned int          scope )
{
    SchemaElementDecl* decl = fElemDeclPool->getByKey(baseName, uriId, scope);

    if (!decl) {

        decl = fGroupElemDeclPool->getByKey(baseName, uriId, scope);

        if (!decl && fElemNonDeclPool)
            decl = fElemNonDeclPool->getByKey(baseName, uriId, scope);
    }

    return decl;
}

inline const XMLElementDecl* SchemaGrammar::getElemDecl(const unsigned int elemId) const
{
    // Look up this element decl by id
    const SchemaElementDecl* decl = fElemDeclPool->getById(elemId);

    if (!decl)
        decl = fGroupElemDeclPool->getById(elemId);

    return decl;
}

inline XMLElementDecl* SchemaGrammar::getElemDecl(const unsigned int elemId)
{
    // Look up this element decl by id
    SchemaElementDecl* decl = fElemDeclPool->getById(elemId);

    if (!decl)
        decl = fGroupElemDeclPool->getById(elemId);

    return decl;
}

inline XMLSize_t
SchemaGrammar::putElemDecl(XMLElementDecl* const elemDecl,
                           const bool notDeclared)
{
    if (notDeclared)
    {
        if(!fElemNonDeclPool)
            fElemNonDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);
        return fElemNonDeclPool->put(elemDecl->getBaseName(), elemDecl->getURI(), ((SchemaElementDecl* )elemDecl)->getEnclosingScope(), (SchemaElementDecl*) elemDecl);
    }

    return fElemDeclPool->put(elemDecl->getBaseName(), elemDecl->getURI(), ((SchemaElementDecl* )elemDecl)->getEnclosingScope(), (SchemaElementDecl*) elemDecl);
}

inline XMLSize_t SchemaGrammar::putGroupElemDecl (XMLElementDecl* const elemDecl)   const
{
    return fGroupElemDeclPool->put(elemDecl->getBaseName(), elemDecl->getURI(), ((SchemaElementDecl* )elemDecl)->getEnclosingScope(), (SchemaElementDecl*) elemDecl);
}

// Notation Decl
inline const XMLNotationDecl* SchemaGrammar::getNotationDecl(const XMLCh* const notName) const
{
    return fNotationDeclPool->getByKey(notName);
}

inline XMLNotationDecl* SchemaGrammar::getNotationDecl(const XMLCh* const notName)
{
    return fNotationDeclPool->getByKey(notName);
}

inline XMLSize_t SchemaGrammar::putNotationDecl(XMLNotationDecl* const notationDecl)   const
{
    return fNotationDeclPool->put(notationDecl);
}

inline bool SchemaGrammar::getValidated() const
{
    return fValidated;
}

inline void SchemaGrammar::setValidated(const bool newState)
{
    fValidated = newState;
}

inline unsigned int
SchemaGrammar::getScopeCount () const
{
  return fScopeCount;
}

inline void
SchemaGrammar::setScopeCount (unsigned int scopeCount)
{
  fScopeCount = scopeCount;
}

inline unsigned int
SchemaGrammar::getAnonTypeCount () const
{
  return fAnonTypeCount;
}

inline void
SchemaGrammar::setAnonTypeCount (unsigned int count)
{
  fAnonTypeCount = count;
}

XERCES_CPP_NAMESPACE_END

#endif
