/*
 *                         OpenSplice DDS
 *
 *   This software and documentation are Copyright 2006 to TO_YEAR PrismTech
 *   Limited, its affiliated companies and licensors. All rights reserved.
 *
 *   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.
 *
 */
#ifndef _XBE_ATTRIBUTE_HH
#define _XBE_ATTRIBUTE_HH

#include "xbe_codegen.h"
#include "xbe_type.h"
#include "xbe_classgen.h"
#include "xbe_interface.h"

class be_attribute :
   public virtual AST_Attribute,
   public be_CodeGenerator
{

public:

   enum AT_SignatureType {
      AT_Declaration,     // signature in function declaration
      AT_Implementation,    // signature in beginning of definition
      // of attribute function
      AT_Invoke,      // signature in statement that calls
      // attribute function
      AT_TieImplementation,  // signature of beginning of definition
      // inside a tie template
      AT_TieInvoke    // signature of statement inside a tie
      // template that calls the tied function
   };

public:

   static be_attribute * _narrow(AST_Decl * decl);

   be_attribute ();
   be_attribute
   (
      bool ro,
      AST_Type *ft,
      UTL_ScopedName *n,
      const UTL_Pragmas &p
   );

   DDS_StdString Scope(const DDS_StdString& name);
   DDS_StdString LocalName();
   void Initialize(be_interface* owner, const DDS_StdString& className);
   DDS_StdString StubClassname();
   const DDS_StdString& InterfaceBasename();

   //APV
   DDS_StdString GetSignature(
      AT_SignatureType sigType,
      const DDS_StdString& className,
      DDS::Boolean pureVirtual = pbtrue);
   //APV
   DDS_StdString SetSignature(
      AT_SignatureType sigType,
      const DDS_StdString& className,
      DDS::Boolean pureVirtual,
      const DDS_StdString& argName = NilString);
   void GenerateImpureRequestCall(be_ClientImplementation&);
   void GenerateGetDispatcher(be_ServerImplementation& source,
      const DDS_StdString& implbasename);
   void GenerateSetDispatcher(be_ServerImplementation& source,
      const DDS_StdString& implbasename);
   void GenerateVirtual(be_Source& source, const DDS_StdString& className);
   void GenerateGetStub(be_ClientImplementation& source);
   void GenerateSetStub(be_ClientImplementation& source);

   // BE_CODEGENERATOR VIRTUALS
   virtual void Generate(be_ClientHeader& source);
   virtual void Generate(be_ClientImplementation& source);
   virtual void Generate(be_ServerHeader&)
   {}

   virtual void Generate(be_ServerImplementation& dispatchImpl);

   DEF_NARROW_METHODS2(be_attribute, AST_Attribute, be_CodeGenerator);
   DEF_NARROW_FROM_DECL(be_attribute);

private:

   friend class be_interface;

   DDS_StdString interfaceBasename;
   DDS_StdString enclosingScope;
   DDS_StdString setOpKey;
   DDS_StdString getOpKey;
   be_DispatchableType* fieldType;
   DDS::Boolean m_getDispatchDone;
   DDS::Boolean m_setDispatchDone;
};

inline DDS_StdString
be_attribute::Scope(const DDS_StdString& name)
{
   DDS_StdString ret = enclosingScope;

   if (ret.length())
   {
      ret += "::";
   }

   return ret + name;
}

#endif
