 // -*- C++ -*-


 namespace Hurricane {

 /*! \defgroup     JsonSupport  JSON Support
  *  \brief        JSON Import/Export of the DataBase
  * 
  *  \section      secJsonSupportIntro  Introduction
  *
  *                One key feature of the Hurricane DataBase is it's hierarchical 
  *                managment. But unfortunatly the simple approach of saving a design
  *                Cell by Cell, hierarchical level by hierarchical level makes it
  *                very difficult to save the trans-hierarchical informations (mainly
  *                is the occurrences)
  *
  *                One solution is to save the design and all it's levels, down and
  *                including the standard cells. With all the levels saved, we then
  *                can add the occurrences and all the attached trans-hierarchical
  *                informations. We call that comprehensive saving of a design,
  *                a <em>design blob</em>.
  *
  *                Instead of creating one more ad-hoc format, we just dump the
  *                DataBase objects in a mirror like way in JSON format.
  *
  *                As it is a textual format, the generated files are larges.
  *                So the files are compressed through \c gzip.
  *
  *
  *  \section      secJsonSemantic  JSON Additional Semantic
  *
  *                To ease the work of the parser, some semantic has been added
  *                to the JSON objects representing a Hurricane DataBase.
  *                  -# The first key/value pair must have the key \c "@typename"
  *                     and give the kind of JsonObject associated. The value is
  *                     the string returned by \c JsonObject::getTypeName().
  *                  -# Attributes keys must start by a \c '_' character.
  *                     (yes, I know, the C++ convention has changed and it should
  *                     be put at the end).
  *                  -# Collections or containers must be put \e after all the 
  *                     scalar attributes and their keys must start by a \c '+'
  *                     character.
  *
\code{.json}
{
  "@typename": "Cell",
  "_id": 3,
  "_library": "RootLibrary.AllianceFramework.sxlib",
  "_name": "o3_x2",
  "_abutmentBox": {
    "@typename": "Box",
    "_xMin": 0,
    "_yMin": 0,
    "_xMax": 72000,
    "_yMax": 120000
  },
  "+instanceMap": [],
  "+netMap": [
  ],
}
\endcode
  *
  *  \section      secJsonDriver  JSON Driver Support
  *
  *                The driver is implemented through overloads (template and
  *                non-template) of the \c jsonWriter() function. For the
  *                template overload to work, even for non-Hurricane classes,
  *                it is defined outside the Hurricane namespace.
  *
  *                For POD types, four overloads of \c jsonWriter() are defined:
  *
\code
void  jsonWrite ( JsonWriter* w, const int* v );
void  jsonWrite ( JsonWriter* w,       int  v );
void  jsonWrite ( JsonWriter* w, const std::string& key, const int* value )
void  jsonWrite ( JsonWriter* w, const std::string& key,       int  value )
\endcode
  *
  *                The first two writes the object (here: \c int) "as is" while
  *                the two later writes a pair key/object.
  *
  *                For other class/object that needs to be writen in the JSON file,
  *                they must provide a \c toJson() function. It doesn't even need
  *                to be virtual. For Point:
  *
\code
void  Point::toJson ( JsonWriter* w ) const
{
  w->startObject();
  jsonWrite( w, "@typename", "Point" );
  jsonWrite( w, "_x", getX() );
  jsonWrite( w, "_y", getY() );
  w->endObject();
}
\endcode
  *
  *                This function allows three templates of \c jsonWrite() to be
  *                used with an object of class Point:
  *
\code
template<typename C>
void  jsonWrite ( JsonWriter* w, const C* object );

template<typename C>
void  jsonWrite ( JsonWriter* w, const std::string& key, C* object );

template<typename C>
void  jsonWrite ( JsonWriter* w, const std::string& key, const C* object );
\endcode
  *
  *                Note that through those three overloads we only provides
  *                support for pointers to object. The driving mechanism is
  *                designed in such a way that passing arguments by value is
  *                not supported for non-POD types. Trying to do so will
  *                result in an unsupported message inside the generated
  *                JSON file.
  *
  *
  *  \subsection   secJsonDriverDBo DBos Special Case
  *
  *                For DBo objects, a complete parallel hierarchy of JsonObjects
  *                mimicking the one of DBos has been implemented. The \c toJson()
  *                function is implemented in the DBo base object, and the
  *                derived classes must implement the following virtual functions:
  *
\code
class DBo {
  public:
    virtual void  _toJson            ( JsonWriter* ) const;
    virtual void  _toJsonCollections ( JsonWriter* ) const;
    virtual void  _toJsonSignature   ( JsonWriter* ) const;
            void  toJson             ( JsonWriter* ) const;
            void  toJsonSignature    ( JsonWriter* ) const;
\endcode
  *
  *                The JSON driver functions is splitted in two parts:
  *                  - \c _toJson() must drive the scalar attributes.
  *                  - \c _toJsonCollections() must drive the various collections
  *                       or containers.
  *                This is to ensure that all the scalars attributes are put
  *                before the collections, event through inheritance.
  *
  *                The additionnal \c toJsonSignature() method provide the
  *                signature for an Entity which is used by an occurrence.
  *                The signature of an occurrence is needed when we create
  *                a JSON for a Cell only. In that case we cannot directly save
  *                the transhierarchical informations, so we need a way to
  *                characterize the deep Entity (which is not part of the
  *                saved Cell). Most of the time, the signature is the scalar
  *                attributes of the occurrenced object, it is far from foolproof,
  *                but it will do for now.
  *
  *
  *  \section      secJsonParser  JSON Parser Support
  *
  *                To enable JSON parsing support for an object, say Point,
  *                an associated \c JsonPoint class must be created. This
  *                class must be derived (directly or not) from JsonObject.
  *                It must implement one static functions and four methods,
  *                as shown below.
  *
\code
class JsonPoint : public JsonObject {
  public:
    static  void       initialize ();
                       JsonPoint  (unsigned long flags);
    virtual string     getTypeName() const;
    virtual JsonPoint* clone      (unsigned long flags) const;
    virtual void       toData     (JsonStack&);
};
\endcode
  *
  *                The \c initialize() static function must be present in
  *                concrete class only. It is used to register the Json
  *                object into the parser during the static initialization
  *                of the program.
  *
\code
#include "hurricane/Initializer.h"
#include "hurricane/Point.h"

Initializer<JsonPoint>  jsonPointInit ( 0 );

void  JsonPoint::initialize ()
{ JsonTypes::registerType( new JsonPoint (JsonWriter::RegisterMode) ); }

\endcode
  *
  *                The constructor has to declare requirements, attributes,
  *                and collections needed to build the DataBase object.
  *                Note the the requirements are not part of the objects
  *                but only needed to build it.
  *
\code{.cpp}
JsonPoint::JsonPoint ( unsigned long flags )
  : JsonObject(flags)
{
  add( "_x", typeid(int64_t) );
  add( "_y", typeid(int64_t) );
}
\endcode
  *
  *                The \c getTypeName() virtual function must return the
  *                typename used for the \c "@typename" key in the JSON
  *                file. Most of the time it's the same name as the
  *                object itself, but not always.
  *
\code{.cpp}
string JsonPoint::getTypeName () const
{ return "Point"; }
\endcode
  *
  *                The \c clone() virtual function must return a brand new
  *                Json object of the same type. The datas of the orignal
  *                object \b must not be copied. The cloning is about the
  *                class type, not the contents.
  *
\code
JsonPoint* JsonPoint::clone ( unsigned long flags ) const
{ return new JsonPoint ( flags ); }
\endcode
  *
  *                The \c toData() virtual function actually gather the
  *                attributes to recreate the DataBase object. It needs
  *                the parser stack to pull the attributes and to push
  *                the created object.
  *
\code{.cpp}
void JsonPoint::toData ( JsonStack& stack )
{
  check( stack, "JsonPoint::toData" );
  Point point ( DbU::fromDb(get<int64_t>(stack,"_x"))
              , DbU::fromDb(get<int64_t>(stack,"_y")) );
  update( stack, point );
}
\endcode
  *
  *
  *  \subsection   secJsonArray  JSON Array
  *
  *                JSON array are not translated into containers of any kind.
  *                They are simply ignored (from the stack point of view).
  *                Objects in array comes from a great variety of containers
  *                including Hurricane::Collection, in almost all cases, their
  *                very constructors are responsibles for inserting the object
  *                in the relevant container/collection. So there is no need
  *                to build a mechanism to keep track of all the objects in an
  *                array through a temporary container.
  *
  *                The corollary is that an object in an array must be able to
  *                extract the relevant context information from the stack.
  *                Say, if we are in an array of components, they must belong
  *                to a Net, which must be present in the stack with a key ".Net".
  *
  *
  *  \subsection   secJsonStack  Parser Stack
  *
  *                While performing the parsing, the parser maintain a stack
  *                (JsonStack) containing:
  *                  - The stack of attributes translateds, but not consumeds
  *                    by the parser and the objects currently openeds (that is,
  *                    which parsing is not completed). This stack contains POD
  *                    or Hurricane objects (value or pointer).
  *                      It is a vector of pair \c (key,value) where the \e key
  *                    is either the attribute name (\c _boundingBox, \c _xMin,
  *                    \c _masterCell, ...) or the class name (\c .Net, \c .Cell, ...).
  *                  - The stack of JSON objects currently openeds, thoses objects
  *                    are all derived classes of JsonObject.
  *                  - A stack of currently opened DBo*. This stack is somewhat
  *                    redundant with the first, but is needed because
  *                    \c boost::any_cast<> is not able to perform dynamic conversions.
  *                    You have to know the exact for the conversion to work.
  *                    Here, everything is DBo*, so the problem do not arises.
  *
  *
  *  \subsection   secJsonCycle  JsonObject Life Cycle
  *
\code{.json}
{                          # JsonDummy()  (1).
  "_typename": "Net",      # JsonNet()  CTOR (2).
  "_id": 14622,
  "_name": "saccu(0)",
  "_isGlobal": false,
  "_isExternal": false,
  "_isAutomatic": false,
  "_type": "LOGICAL",
  "_direction": "---- (UNDEFINED)",
  "+aliases": [],          # JsonNet::toData()  (3).
  "+componentSet": [
    {
      "@typename": "RoutingPad",
      "_id": 27410,
      "_bodyHook": "Contact::AnchorHook.46566",
      "_occurrence": {
        "@typename": "Occurrence",
        "_path": "14720.14976",
        "_entity": 3888
      },
      "+propertySet": []
    },
    {
      "@typename": "RoutingPad",
      "_id": 27409,
      "_bodyHook": "Contact::AnchorHook.46574",
      "_occurrence": {
        "@typename": "Occurrence",
        "_path": "14654.18564",
        "_entity": 4529
      },
      "+propertySet": []
    }
  }
}                          # ~JsonNet()  DTOR (4). 
\endcode
  *                
  *                At \c (1) , before \c _typename is encountered, we know that a new
  *                object is about to be created, but do not know what is type will be.
  *                So we push on top of the stack a \c JsonDummy.
  *
  *                At \c (2) , the \c _typename allows us to create the right kind of
  *                JsonObject, which will \e replace the \c JsonDummy on top of the
  *                stack.
  *
  *                At \c (3) , a first non-POD attribute of JsonNet is encountered.
  *                This triggers the call to \c JsonObject::toData(), which creates
  *                the Hurricane object Net, and put it back on the attribute stack
  *                with the key \c ".Net" (because it is \e not an attribute).
  *
  *                At \c (4) , the Json parser knows that the current JsonObject is
  *                finished, so it removes JsonNet from the stack and destroy it.
  *
  *                So, if you need to perform specific post-processing that can only
  *                take place \c after the object and all it's sub-objects has been
  *                fully parsed, you may do it in the destructor of the JsonObject.
  *                For example, this technique is used to rebuild the rings of a Net.
  */


 }  // Hurricane namespace.
