## 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.
// This file automatically generated by:
//   $now
// This file is automatically created and should not be edited!
// Re-implement these methods by overriding them in Impl$intf.name()$suffix.

#set($i = $intf.name())
#set($intfname = "$i$suffix")
#set($clname = "Base$intfname")
#if ($helper.isServer($mc))
#set($peer = "client")
#else
#set($peer = "server")
#end

\#include "common/EtchRuntimeException.h"
\#include "$inc"

using namespace $namespace;

  /**
   * Base implementation of $intfname, with default method implementations
   * which throw runtime_error. Extend this class to provide
   * implementations of messages from the $peer.
   *
   * @see Impl$intfname
   */

#foreach ($mthd in $intf.iterator())
#if ($mthd.isMsgDir($mc) || $mthd.isMsgDirBoth())
#if (!$mthd.isHidden())
#if(!$methodList.contains($mthd.name().name()))
#set ( $addMethodListStatus = $methodList.add($mthd.name().name()) )
  $intfname::$mthd.name()AsyncResultPtr $clname::$mthd.name()(#set( $sep = "" )#foreach($param in $mthd.iterator())$sep$helper.getEtchTypeName($param.type(), true) $param.name() #set( $sep = ", " )#end)
  {
#if(!($helper.getEtchTypeName($mthd.type(), true) == "void"))
    $mthd.name()AsyncResultPtr res = new EtchAsyncResult<$helper.getEtchTypeName($mthd.type(), false)>();
#else
    $mthd.name()AsyncResultPtr res = new EtchAsyncResultNone();
#end
    res->setException(new EtchRuntimeException("${mthd.name()} not implemented!", ETCH_EUNIMPL));
    return res;
  }

#end
#end
#end
#end

#foreach($x in $intf.iterator())
#if( $x.isMixin() )
#set( $m = $x.getModule() )
#set( $z = $m.iterator().next() )
#foreach( $n in $z.messages( true ) )
#if($n.isMsgDir($mc) || $n.isMsgDirBoth() )
#if(!$n.isHidden())
#if(!$methodList.contains($n.name().name()))
#set ( $addMethodListStatus = $methodList.add($n.name().name()) )
#if($n.isOneway())

  $intfname::$n.name()AsyncResultPtr $clname::$n.name()(#set($sep = "")#foreach($p in $n.iterator())$sep$helper.getEtchTypeName($p.type(), true) $p.name() #set($sep = ", ")
    #if(!($helper.getEtchTypeName($p.type(), true) == "void")), $helper.getEtchTypeName($p.type(), true) returnValue#end )
  {
#if(!($helper.getEtchTypeName($n.type(), true) == "void"))
    $p.name()AsyncResultPtr res = new EtchAsyncResult<$helper.getEtchTypeName($p.type(), false)>();
#else
    $p.name()AsyncResultPtr res = new EtchAsyncResultNone();
#end
    res->setException(new EtchRuntimeException("${p.name()} not implemented!", ETCH_EUNIMPL));
    return res;
  }
#end
#else

$intfname::$n.name()AsyncResultPtr $clname::$n.name()(#set($sep = "")#foreach($p in $n.iterator())$sep$helper.getEtchTypeName($p.type(), true) $p.name() #set($sep = ", ")#end #if(!($helper.getEtchTypeName($n.type(), true) == "void")), $helper.getEtchTypeName($n.type(), true) returnValue #end);#if(!$n.hasThrown())
  {
    return EtchRuntimeException("${p.name()} not implemented!", ETCH_EUNIMPL));
  }#end
#if($n.hasThrown())
  {
#if(!($helper.getEtchTypeName($n.type(), true) == "void"))
  $p.name()AsyncResultPtr res = new EtchAsyncResult<$helper.getEtchTypeName($p.type(), false)>();
#else
  $p.name()AsyncResultPtr res = new EtchAsyncResultNone();
#end
    res->setException(new EtchRuntimeException("${p.name()} not implemented!", ETCH_EUNIMPL));
    return res;
#foreach($t in $n.thrown().iterator())
    //TODO:
    return ($sep$intf.name()::$t.getNamed().name()()
#end
  }
#end
#end
#end
#end
#end
#end
#end
#end
