// $Id: KitchenSink.idl 95071 2011-11-20 19:35:35Z mcorino $
/**
 * @file KitchenSink.idl
 * @author Jeff Parsons <j.parsons@vanderbilt.edu>
 *
 * Tests TAO_IDL generation of CIAO servant, executor IDL
 * and executor implementation stencil for a variety of
 * IDL3+ constructs.
 */

#include <Components.idl>

#if !defined (CCM_LW)
module mod
{
  valuetype future_key : Components::PrimaryKeyBase
  {
    public string info;
  };
};
#endif

interface iface
{
  exception iface_excep {};

  void iface_op (in string inarg);
};

typedef sequence<iface> ifaceSeq;

#if !defined (CCM_NOEVENT)
eventtype ev
{
};

module orange
{
  module apple
  {
    eventtype Bar;
    eventtype Bar;
  };
};
#endif

module GlobalTyped<typename A, typename B>
{
  typedef short x;
};

#if !defined (CCM_NOEVENT)
module orange
{
  module apple
  {
    eventtype Bar
    {
    };
  };
};
#endif

module A
{
  local interface C
  {
  };

  module Nested<typename T, sequence <T> TSeq>
  {
    typedef short y;

    abstract interface abs_XX
    {
    };

    interface XX
    {
    };

    // To make sure the overrides of _is_nil() and
    // release() that we need for mixed parentage
    // interfaces get generated when the template
    // module is instantiated.
    interface mixed_XX : abs_XX, XX
    {
    };

    union Nested_Union switch (y)
    {
      case 2: string strmem;
      case 0: T Tmem;
    };

    enum Nested_Enum
    {
      ZERO,
      ONE,
      TWO
    };

    // A regular module may be nested inside a template module,
    // but another template module may not.
    module GoodNested
    {
      typedef long Lo;
    };
/*
    module BadNested<typename S>
    {
      typedef S S_Tdef;
    };
*/
  };

  module Nested<iface, ifaceSeq> Nested_Inst;
};

module second<exception X, typename W>
{
  typedef short sho;

#if !defined (CCM_LW)
  valuetype pkey : Components::PrimaryKeyBase
  {
    public long id_key;
  };
#endif
};

module B
{
  module second_B<typename T, sequence <T> TSeq>
  {
    alias A::Nested<T, TSeq> NestedA;

    interface do : NestedA::XX
    {
    };
  };
};

module T
{
  typedef unsigned long MyLongType;

  module Typed <typename T, sequence <T> TSeq>
  {
    local interface X
    {
      void send (in MyLongType a);
    };

    porttype Y
    {
      uses X data;
      attribute string str_attr;
      attribute T T_attr;
    };

    component Z
    {
      port Y my_port;
      port Y my_second_port;
    };

    connector C
    {
      port Y my_m_port;
      mirrorport Y my_second_m_port;
    };
  };
};

struct XX
{
  string YY;
};

typedef sequence <XX> XX_Seq;

module T
{
  module ::T::Typed < ::XX, ::XX_Seq> XX;
};

module V
{
  component JJ : T::XX::Z
  {
  };
};

connector Comp3_T
{
  provides iface Conn_T_Port;
};

module B::second_B<iface, ifaceSeq> second_B_Inst;

module H
{
  module Nested_H<typename T, sequence <T> TSeq>
  {
    alias A::Nested<T, TSeq> NestedA;
    interface B
    {
      void send (in T arg);
    };
    connector Y
    {
      provides B myport;
      provides NestedA::XX myxx;
    };
  };
};

module I
{
  module Nested_I<typename T, sequence <T> TSeq>
  {
    alias A::Nested<T, TSeq> NestedA;

    interface B
    {
      void send (in T arg);
    };

    connector Y
    {
      provides B myport;
      provides NestedA::XX myxx;
    };
  };
};

module H::Nested_H<iface, ifaceSeq> nested_H_inst;
module I::Nested_I<iface, ifaceSeq> nested_I_inst;

module Ast<typename T,
           eventtype E,
           exception S,
           valuetype V,
           sequence<T> TSeq,
           const unsigned long M>
{
  interface Foo : T
  {
    attribute T Foo_Attr getraises (S);

    void Foo_Op (inout long inoutarg,
                 in T inarg,
                 out T outarg,
                 in TSeq seq_inarg)
      raises (S);
  };

  alias second<S, T> second_ref;

  valuetype VT_T : V supports T
  {
    private T T_member;

    factory make_VT_T ();

    factory create_VT_T (in T T_arg,
                         in string str_arg)
      raises (S);
  };

  porttype PT_T
  {
    provides iface iface_facet;
    uses multiple T T_Recep;
  };

  component Comp_T
  {
    uses multiple T Comp_T_Recep;

    mirrorport PT_T Comp_T_Mirror_Port;
    provides T Comp_T_Facet;
    emits E Comp_T_Emit;

    // Tests unique lookup mechanism for types referenced
    // from an aliased template module.
    attribute second_ref::sho sho_attr;
  };

#if !defined (CCM_LW)
  home Comp_T_Home manages Comp_T primarykey second_ref::pkey
  {
    factory create_Comp_T (in TSeq inarg);
    finder find_Comp_T (in T inarg);
  };

  // TAO IDL compiler uses the same code for both component
  // and home 'supports' constructs, so we test it here
  // where there is no conflict with the port interfaces.
  home Comp_T_Home_2 supports T manages Comp_T primarykey V
  {
  };
#endif

  connector Comp2_T
  {
    port PT_T Comp2_T_Port;
    provides T Comp2_T_Facet;
  };

  connector Conn_T
  {
    port PT_T Conn_T_Port;
    provides T Conn_T_Facet;
  };

  const unsigned long Ast_Const = M;
  const unsigned long LC = 7;

  typedef sequence<T, M> AnotherTSeq;

  struct boo
  {
    T T_field;
    Foo Foo_field;
  };

  typedef T T_array[M][Ast_Const][LC];
};

#if !defined (CCM_LW) && !defined (CCM_NOEVENT)
module Ast<iface,
           ev,
           iface::iface_excep,
           mod::future_key,
           ifaceSeq,
           101>
  Ast_Inst;
#endif

module M
{
  module N <typename T>
  {
    interface A {
      void do_something (in T arg);
    };
  };
};

module T
{
  struct X
  {
    unsigned long Z;
  };
  typedef sequence <X> XSeq;
};

/// An instantiated template module can be a reopening
/// of an existing module.
module ::M::N < ::T::X> T;


/*
Support for native is there, but this results in non compiling code
native NAT;
module M {
  module N <NAT> N_NAT;
};
*/
