Package etch.compiler.ast

Source Code of etch.compiler.ast.Message

/* $Id: Message.java 712730 2008-07-29 06:31:55Z jadixson $
*
* Copyright 2007-2008 Cisco Systems Inc.
*
* 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.
*/

package etch.compiler.ast;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import etch.compiler.Backend;
import etch.compiler.EtchGrammarConstants;
import etch.compiler.ParseException;
import etch.compiler.opt.AsyncReceiver;
import etch.compiler.opt.Authorize;
import etch.compiler.opt.Direction;
import etch.compiler.opt.Oneway;
import etch.compiler.opt.Timeout;

/**
* Description of Message.
*/
public class Message extends ParamList<Service>
{
  /**
   * Constructs the Message.
   * @param intf
   * @param name
   * @param nOpts
   * @param type
   */
  public Message( Service intf, Name name, Map<String, Opt> nOpts, TypeRef type )
  {
    super( intf, name, nOpts );

    this.md = getMessageDirection();
    this.type = type;
  }

  private MessageDirection md;

  private final TypeRef type;
 
  /**
   * @return the suffix of this message's interface given the direction.
   */
  public String suffix()
  {
    return MsgDirHelper.getSuffix( md );
  }
 
  /**
   * @return the vname of this message (the fully qualified name with "_" instead of ".").
   */
  public String mkVname()
  {
    Service intf = parent();
    Name name = name();
    return intf.parent().name().name.replace( '.', '_' )+'_'+intf.name()+'_'+name.name;
  }
 
  /**
   * @return the fully qualified name of this message.
   */
  public String mkFqName()
  {
    Service intf = parent();
    Name name = name();
    return intf.parent().name().name+'.'+intf.name().name+'.'+name.name;
  }

  /**
   * @return the direction of this message.
   */
  public MessageDirection msgDir()
  {
    return md;
  }

  /**
   * Sets the message direction of this message.
   * @param md
   */
  public void setMsgDir( MessageDirection md )
  {
    this.md = md;
  }

  /**
   * @param other
   * @return true if this message's direction equals other.
   */
  public boolean isMsgDir( MessageDirection other )
  {
    return md == other;
  }

  /**
   *
   * @return trus if this message's direction is both
   */
  public boolean isMsgDirBoth()
  {
    return md == MessageDirection.BOTH;
  }

  /**
   * @return the message direction per the Direction opt.
   */
  public MessageDirection getMessageDirection()
  {
    Opt o = getOpt( "Direction" );

    if (o == null)
      return MessageDirection.SERVER;

    Direction d = (Direction) o;
    return d.getMessageDirection();
  }

  /**
   * @return the message timeout per the Timeout opt.
   */
  public int getTimeout()
  {
    Opt o = getOpt( "Timeout" );

    if (o == null)
      return 0;

    Timeout t = (Timeout) o;
    return t.timeout();
  }

  /**
   * @return the type of this message.
   */
  public TypeRef type()
  {
    return type;
  }

  @Override
  public String vname( Backend helper )
  {
    return helper.mtvname( mkVname() );
  }

  /**
   * @return the fully qualified name of this message.
   */
  @Override
  public String fqname()
  {
    return mkFqName();
  }

//  /**
//   * @return the id of this message.
//   */
//  @Override
//  public Integer id()
//  {
//    return mkId();
//  }

  @Override
  public String toString()
  {
    return String.format( "message %s %s %s (%s) throws %s", md, type, name(), getParameters(), thrown );
  }

  /**
   * @return the message description.
   */
  public List<String> returnDescr()
  {
    return returnDescr;
  }

  /**
   * @param returnDescr
   */
  public void setReturnDescr( List<String> returnDescr )
  {
    this.returnDescr = returnDescr;
  }

  private List<String> returnDescr = new ArrayList<String>();

  /**
   * @return the message used to return a result from a call.
   */
  public Message getResultMessage()
  {
    return resultMessage;
  }

  /**
   * @param resultMessage
   */
  public void setResultMessage( Message resultMessage )
  {
    this.resultMessage = resultMessage;
  }

  private Message resultMessage;

  /**
   * @return true if this is a message which contributes to the
   * types and fields but should not appear in the interface
   * (because it is a response message)
   */
  public boolean isHidden()
  {
    return name().name.startsWith( RESULT_MESSAGE_NAME_PREFIX );
  }

  /**
   * @return the expected name of a result message.
   */
  public Name getResultMessageName()
  {
    return new Name( null, RESULT_MESSAGE_NAME_PREFIX+name().name );
  }

  /**
   * The name of the parameter of a result message.
   */
  public static final String RESULT_PARAM_NAME = "result";

  /**
   * The prefix to apply to the name of a result message.
   */
  public static final String RESULT_MESSAGE_NAME_PREFIX = "_result_";

  /**
   * @return the name of the result parameter.
   */
  public Name getResultParamName()
  {
    return new Name( null, RESULT_PARAM_NAME );
  }

  /**
   * @return the result parameter.
   */
  public Parameter getResultParam()
  {
    return getParameter( RESULT_PARAM_NAME );
  }

  /**
   * @return true if this is a call (i.e., returns a value.
   */
  public boolean hasReturn()
  {
    return type.type().kind != EtchGrammarConstants.VOID;
  }

  @Override
  public void dump( String indent )
  {
    System.out.printf( "%smethod %s %s %s\n", indent, md, type, name().name );

    String sIndent = indent+"  ";

    for (String s: descr())
      System.out.printf( "%sdescr %s\n", sIndent, s );

    for (Opt o: opts())
      o.dump( sIndent );

    for (Parameter p: this)
      p.dump( sIndent );

    if (hasReturn())
      System.out.printf( "%sreturnDescr %s\n", sIndent, returnDescr );

    for (Thrown n: thrown)
      n.dump( sIndent );
  }

  /**
   * Adds a name to the list of exceptions thrown by this message.
   * @param n
   * @return the representation object for a thrown exception.
   * @throws ParseException
   */
  public Thrown addThrown( Name n ) throws ParseException
  {
    if (isOneway())
      throw new ParseException( String.format(
        "Oneway message cannot throw exception at line %d", n.token.beginLine ) );

    thrown.check( n );
    Thrown t = new Thrown( this, n );
    thrown.add( n, t );
    return t;
  }

  /**
   * @param n
   * @return any thrown exception by the specified name.
   */
  public Thrown getThrown( String n )
  {
    return thrown.get( n );
  }

  private final NameList<Thrown> thrown = new NameList<Thrown>();

  /**
   * @return true if this message has thrown exceptions.
   */
  public boolean hasThrown()
  {
    return !thrown.list().isEmpty();
  }

  /**
   * @return the async receiver mode.
   */
  public AsyncReceiverMode getAsyncReceiver()
  {
    AsyncReceiver ar = (AsyncReceiver) getOpt( "AsyncReceiver" );

    if (ar == null)
      return AsyncReceiverMode.NONE;

    return ar.getMode();
  }

  /**
   * @return true if this method is marked to have an asynchronous
   * receiver.
   */
  public boolean isAsyncReceiver()
  {
    return getAsyncReceiver() != AsyncReceiverMode.NONE;
  }

  /**
   * @return true if this method is marked to have a queued asynchronous
   * receiver.
   */
  public boolean isQueuedAsyncReceiver()
  {
    return getAsyncReceiver() == AsyncReceiverMode.QUEUED;
  }

  /**
   * @return true if this method is marked to have a free asynchronous
   * receiver.
   */
  public boolean isFreeAsyncReceiver()
  {
    return getAsyncReceiver() == AsyncReceiverMode.FREE;
  }

  /**
   * @return true if this is a oneway message which does not wait
   * for any response from the other end.
   */
  public boolean isOneway()
  {
    Oneway oneway = (Oneway) getOpt( "Oneway" );
    return oneway != null && oneway.isOneway();
  }

  /**
   * @return true if this message requires authorization.
   */
  public Authorize getAuth()
  {
    return (Authorize) getOpt( "Authorize" );
  }

  /**
   * @return true if this message requires authorization.
   */
  public boolean hasAuth()
  {
    Authorize auth = getAuth();
    return auth != null && auth.hasAuth();
  }

  @Override
  public void check() throws ParseException
  {
    checkMessageName( name() );
   
    type.check( parent() );

    for (Parameter p: this)
      p.check();

    for (Thrown n: thrown)
      n.check();

    Authorize auth = getAuth();
    if (auth != null)
      auth.check( parent(), this );
  }

  @Override
  public Service service()
  {
    return parent();
  }

  /**
   * @return the list of thrown exceptions.
   */
  public NameList<Thrown> thrown()
  {
    return thrown;
  }

  /**
   * @return the request message of this result message.
   */
  public Message getRequestMessage()
  {
    return reqMsg;
  }

  /**
   * Sets the request message of this result message.
   * @param reqMsg
   */
  public void setRequestMessage( Message reqMsg )
  {
    this.reqMsg = reqMsg;
  }

  private Message reqMsg;

  @Override
  public void treewalk( TreeWalker walker ) throws ParseException
  {
    walker.preMessage( this );

    walker.doTypeRef( type );

    for (Parameter p: this)
      p.treewalk( walker );

    for (Thrown n: thrown)
      n.treewalk( walker );

    walker.postMessage( this );
  }
}
TOP

Related Classes of etch.compiler.ast.Message

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.