//===-- GoParser.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <vector>

#include "GoParser.h"

#include "Plugins/ExpressionParser/Go/GoAST.h"
#include "lldb/Utility/Status.h"
#include "llvm/ADT/SmallString.h"

using namespace lldb_private;
using namespace lldb;

namespace {
llvm::StringRef DescribeToken(GoLexer::TokenType t) {
  switch (t) {
  case GoLexer::TOK_EOF:
    return "<eof>";
  case GoLexer::TOK_IDENTIFIER:
    return "identifier";
  case GoLexer::LIT_FLOAT:
    return "float";
  case GoLexer::LIT_IMAGINARY:
    return "imaginary";
  case GoLexer::LIT_INTEGER:
    return "integer";
  case GoLexer::LIT_RUNE:
    return "rune";
  case GoLexer::LIT_STRING:
    return "string";
  default:
    return GoLexer::LookupToken(t);
  }
}
} // namespace

class GoParser::Rule {
public:
  Rule(llvm::StringRef name, GoParser *p)
      : m_name(name), m_parser(p), m_pos(p->m_pos) {}

  std::nullptr_t error() {
    if (!m_parser->m_failed) {
      // Set m_error in case this is the top level.
      if (m_parser->m_last_tok == GoLexer::TOK_INVALID)
        m_parser->m_error = m_parser->m_last;
      else
        m_parser->m_error = DescribeToken(m_parser->m_last_tok);
      // And set m_last in case it isn't.
      m_parser->m_last = m_name;
      m_parser->m_last_tok = GoLexer::TOK_INVALID;
      m_parser->m_pos = m_pos;
    }
    return nullptr;
  }

private:
  llvm::StringRef m_name;
  GoParser *m_parser;
  size_t m_pos;
};

GoParser::GoParser(const char *src)
    : m_lexer(src), m_pos(0), m_last_tok(GoLexer::TOK_INVALID),
      m_failed(false) {}

GoASTStmt *GoParser::Statement() {
  Rule r("Statement", this);
  GoLexer::TokenType t = peek();
  GoASTStmt *ret = nullptr;
  switch (t) {
  case GoLexer::TOK_EOF:
  case GoLexer::OP_SEMICOLON:
  case GoLexer::OP_RPAREN:
  case GoLexer::OP_RBRACE:
  case GoLexer::TOK_INVALID:
    return EmptyStmt();
  case GoLexer::OP_LBRACE:
    return Block();

  /*      TODO:
case GoLexer::KEYWORD_GO:
  return GoStmt();
case GoLexer::KEYWORD_RETURN:
  return ReturnStmt();
case GoLexer::KEYWORD_BREAK:
case GoLexer::KEYWORD_CONTINUE:
case GoLexer::KEYWORD_GOTO:
case GoLexer::KEYWORD_FALLTHROUGH:
  return BranchStmt();
case GoLexer::KEYWORD_IF:
  return IfStmt();
case GoLexer::KEYWORD_SWITCH:
  return SwitchStmt();
case GoLexer::KEYWORD_SELECT:
  return SelectStmt();
case GoLexer::KEYWORD_FOR:
  return ForStmt();
case GoLexer::KEYWORD_DEFER:
  return DeferStmt();
case GoLexer::KEYWORD_CONST:
case GoLexer::KEYWORD_TYPE:
case GoLexer::KEYWORD_VAR:
  return DeclStmt();
case GoLexer::TOK_IDENTIFIER:
  if ((ret = LabeledStmt()) ||
      (ret = ShortVarDecl()))
  {
      return ret;
  }
*/
  default:
    break;
  }
  GoASTExpr *expr = Expression();
  if (expr == nullptr)
    return r.error();
  if (/*(ret = SendStmt(expr)) ||*/
      (ret = IncDecStmt(expr)) || (ret = Assignment(expr)) ||
      (ret = ExpressionStmt(expr))) {
    return ret;
  }
  delete expr;
  return r.error();
}

GoASTStmt *GoParser::ExpressionStmt(GoASTExpr *e) {
  if (Semicolon())
    return new GoASTExprStmt(e);
  return nullptr;
}

GoASTStmt *GoParser::IncDecStmt(GoASTExpr *e) {
  Rule r("IncDecStmt", this);
  if (match(GoLexer::OP_PLUS_PLUS))
    return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_PLUS_PLUS)
                       : r.error();
  if (match(GoLexer::OP_MINUS_MINUS))
    return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_MINUS_MINUS)
                       : r.error();
  return nullptr;
}

GoASTStmt *GoParser::Assignment(lldb_private::GoASTExpr *e) {
  Rule r("Assignment", this);
  std::vector<std::unique_ptr<GoASTExpr>> lhs;
  for (GoASTExpr *l = MoreExpressionList(); l; l = MoreExpressionList())
    lhs.push_back(std::unique_ptr<GoASTExpr>(l));
  switch (peek()) {
  case GoLexer::OP_EQ:
  case GoLexer::OP_PLUS_EQ:
  case GoLexer::OP_MINUS_EQ:
  case GoLexer::OP_PIPE_EQ:
  case GoLexer::OP_CARET_EQ:
  case GoLexer::OP_STAR_EQ:
  case GoLexer::OP_SLASH_EQ:
  case GoLexer::OP_PERCENT_EQ:
  case GoLexer::OP_LSHIFT_EQ:
  case GoLexer::OP_RSHIFT_EQ:
  case GoLexer::OP_AMP_EQ:
  case GoLexer::OP_AMP_CARET_EQ:
    break;
  default:
    return r.error();
  }
  // We don't want to own e until we know this is an assignment.
  std::unique_ptr<GoASTAssignStmt> stmt(new GoASTAssignStmt(false));
  stmt->AddLhs(e);
  for (auto &l : lhs)
    stmt->AddLhs(l.release());
  for (GoASTExpr *r = Expression(); r; r = MoreExpressionList())
    stmt->AddRhs(r);
  if (!Semicolon() || stmt->NumRhs() == 0)
    return new GoASTBadStmt;
  return stmt.release();
}

GoASTStmt *GoParser::EmptyStmt() {
  if (match(GoLexer::TOK_EOF))
    return nullptr;
  if (Semicolon())
    return new GoASTEmptyStmt;
  return nullptr;
}

GoASTStmt *GoParser::GoStmt() {
  if (match(GoLexer::KEYWORD_GO)) {
    if (GoASTCallExpr *e =
            llvm::dyn_cast_or_null<GoASTCallExpr>(Expression())) {
      return FinishStmt(new GoASTGoStmt(e));
    }
    m_last = "call expression";
    m_failed = true;
    return new GoASTBadStmt();
  }
  return nullptr;
}

GoASTStmt *GoParser::ReturnStmt() {
  if (match(GoLexer::KEYWORD_RETURN)) {
    std::unique_ptr<GoASTReturnStmt> r(new GoASTReturnStmt());
    for (GoASTExpr *e = Expression(); e; e = MoreExpressionList())
      r->AddResults(e);
    return FinishStmt(r.release());
  }
  return nullptr;
}

GoASTStmt *GoParser::BranchStmt() {
  GoLexer::Token *tok;
  if ((tok = match(GoLexer::KEYWORD_BREAK)) ||
      (tok = match(GoLexer::KEYWORD_CONTINUE)) ||
      (tok = match(GoLexer::KEYWORD_GOTO))) {
    auto *e = Identifier();
    if (tok->m_type == GoLexer::KEYWORD_GOTO && !e)
      return syntaxerror();
    return FinishStmt(new GoASTBranchStmt(e, tok->m_type));
  }
  if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH)))
    return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type));

  return nullptr;
}

GoASTIdent *GoParser::Identifier() {
  if (auto *tok = match(GoLexer::TOK_IDENTIFIER))
    return new GoASTIdent(*tok);
  return nullptr;
}

GoASTExpr *GoParser::MoreExpressionList() {
  if (match(GoLexer::OP_COMMA)) {
    auto *e = Expression();
    if (!e)
      return syntaxerror();
    return e;
  }
  return nullptr;
}

GoASTIdent *GoParser::MoreIdentifierList() {
  if (match(GoLexer::OP_COMMA)) {
    auto *i = Identifier();
    if (!i)
      return syntaxerror();
    return i;
  }
  return nullptr;
}

GoASTExpr *GoParser::Expression() {
  Rule r("Expression", this);
  if (GoASTExpr *ret = OrExpr())
    return ret;
  return r.error();
}

GoASTExpr *GoParser::UnaryExpr() {
  switch (peek()) {
  case GoLexer::OP_PLUS:
  case GoLexer::OP_MINUS:
  case GoLexer::OP_BANG:
  case GoLexer::OP_CARET:
  case GoLexer::OP_STAR:
  case GoLexer::OP_AMP:
  case GoLexer::OP_LT_MINUS: {
    const GoLexer::Token t = next();
    if (GoASTExpr *e = UnaryExpr()) {
      if (t.m_type == GoLexer::OP_STAR)
        return new GoASTStarExpr(e);
      else
        return new GoASTUnaryExpr(t.m_type, e);
    }
    return syntaxerror();
  }
  default:
    return PrimaryExpr();
  }
}

GoASTExpr *GoParser::OrExpr() {
  std::unique_ptr<GoASTExpr> l(AndExpr());
  if (l) {
    while (match(GoLexer::OP_PIPE_PIPE)) {
      GoASTExpr *r = AndExpr();
      if (r)
        l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_PIPE_PIPE));
      else
        return syntaxerror();
    }
    return l.release();
  }
  return nullptr;
}

GoASTExpr *GoParser::AndExpr() {
  std::unique_ptr<GoASTExpr> l(RelExpr());
  if (l) {
    while (match(GoLexer::OP_AMP_AMP)) {
      GoASTExpr *r = RelExpr();
      if (r)
        l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_AMP_AMP));
      else
        return syntaxerror();
    }
    return l.release();
  }
  return nullptr;
}

GoASTExpr *GoParser::RelExpr() {
  std::unique_ptr<GoASTExpr> l(AddExpr());
  if (l) {
    for (GoLexer::Token *t;
         (t = match(GoLexer::OP_EQ_EQ)) || (t = match(GoLexer::OP_BANG_EQ)) ||
         (t = match(GoLexer::OP_LT)) || (t = match(GoLexer::OP_LT_EQ)) ||
         (t = match(GoLexer::OP_GT)) || (t = match(GoLexer::OP_GT_EQ));) {
      GoLexer::TokenType op = t->m_type;
      GoASTExpr *r = AddExpr();
      if (r)
        l.reset(new GoASTBinaryExpr(l.release(), r, op));
      else
        return syntaxerror();
    }
    return l.release();
  }
  return nullptr;
}

GoASTExpr *GoParser::AddExpr() {
  std::unique_ptr<GoASTExpr> l(MulExpr());
  if (l) {
    for (GoLexer::Token *t;
         (t = match(GoLexer::OP_PLUS)) || (t = match(GoLexer::OP_MINUS)) ||
         (t = match(GoLexer::OP_PIPE)) || (t = match(GoLexer::OP_CARET));) {
      GoLexer::TokenType op = t->m_type;
      GoASTExpr *r = MulExpr();
      if (r)
        l.reset(new GoASTBinaryExpr(l.release(), r, op));
      else
        return syntaxerror();
    }
    return l.release();
  }
  return nullptr;
}

GoASTExpr *GoParser::MulExpr() {
  std::unique_ptr<GoASTExpr> l(UnaryExpr());
  if (l) {
    for (GoLexer::Token *t;
         (t = match(GoLexer::OP_STAR)) || (t = match(GoLexer::OP_SLASH)) ||
         (t = match(GoLexer::OP_PERCENT)) || (t = match(GoLexer::OP_LSHIFT)) ||
         (t = match(GoLexer::OP_RSHIFT)) || (t = match(GoLexer::OP_AMP)) ||
         (t = match(GoLexer::OP_AMP_CARET));) {
      GoLexer::TokenType op = t->m_type;
      GoASTExpr *r = UnaryExpr();
      if (r)
        l.reset(new GoASTBinaryExpr(l.release(), r, op));
      else
        return syntaxerror();
    }
    return l.release();
  }
  return nullptr;
}

GoASTExpr *GoParser::PrimaryExpr() {
  GoASTExpr *l;
  GoASTExpr *r;
  (l = Conversion()) || (l = Operand());
  if (!l)
    return nullptr;
  while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) ||
         (r = Arguments(l))) {
    l = r;
  }
  return l;
}

GoASTExpr *GoParser::Operand() {
  GoLexer::Token *lit;
  if ((lit = match(GoLexer::LIT_INTEGER)) ||
      (lit = match(GoLexer::LIT_FLOAT)) ||
      (lit = match(GoLexer::LIT_IMAGINARY)) ||
      (lit = match(GoLexer::LIT_RUNE)) || (lit = match(GoLexer::LIT_STRING)))
    return new GoASTBasicLit(*lit);
  if (match(GoLexer::OP_LPAREN)) {
    GoASTExpr *e;
    if (!((e = Expression()) && match(GoLexer::OP_RPAREN)))
      return syntaxerror();
    return e;
  }
  // MethodExpr should be handled by Selector
  if (GoASTExpr *e = CompositeLit())
    return e;
  if (GoASTExpr *n = Name())
    return n;
  return FunctionLit();
}

GoASTExpr *GoParser::FunctionLit() {
  if (!match(GoLexer::KEYWORD_FUNC))
    return nullptr;
  auto *sig = Signature();
  if (!sig)
    return syntaxerror();
  auto *body = Block();
  if (!body) {
    delete sig;
    return syntaxerror();
  }
  return new GoASTFuncLit(sig, body);
}

GoASTBlockStmt *GoParser::Block() {
  if (!match(GoLexer::OP_LBRACE))
    return nullptr;
  std::unique_ptr<GoASTBlockStmt> block(new GoASTBlockStmt);
  for (auto *s = Statement(); s; s = Statement())
    block->AddList(s);
  if (!match(GoLexer::OP_RBRACE))
    return syntaxerror();
  return block.release();
}

GoASTExpr *GoParser::CompositeLit() {
  Rule r("CompositeLit", this);
  GoASTExpr *type;
  (type = StructType()) || (type = ArrayOrSliceType(true)) ||
      (type = MapType()) || (type = Name());
  if (!type)
    return r.error();
  GoASTCompositeLit *lit = LiteralValue();
  if (!lit) {
    delete type;
    return r.error();
  }
  lit->SetType(type);
  return lit;
}

GoASTCompositeLit *GoParser::LiteralValue() {
  if (!match(GoLexer::OP_LBRACE))
    return nullptr;
  std::unique_ptr<GoASTCompositeLit> lit(new GoASTCompositeLit);
  for (GoASTExpr *e = Element(); e; e = Element()) {
    lit->AddElts(e);
    if (!match(GoLexer::OP_COMMA))
      break;
  }
  if (!mustMatch(GoLexer::OP_RBRACE))
    return nullptr;
  return lit.release();
}

GoASTExpr *GoParser::Element() {
  GoASTExpr *key;
  if (!((key = Expression()) || (key = LiteralValue())))
    return nullptr;
  if (!match(GoLexer::OP_COLON))
    return key;
  GoASTExpr *value;
  if ((value = Expression()) || (value = LiteralValue()))
    return new GoASTKeyValueExpr(key, value);
  delete key;
  return syntaxerror();
}

GoASTExpr *GoParser::Selector(GoASTExpr *e) {
  Rule r("Selector", this);
  if (match(GoLexer::OP_DOT)) {
    if (auto *name = Identifier())
      return new GoASTSelectorExpr(e, name);
  }
  return r.error();
}

GoASTExpr *GoParser::IndexOrSlice(GoASTExpr *e) {
  Rule r("IndexOrSlice", this);
  if (match(GoLexer::OP_LBRACK)) {
    std::unique_ptr<GoASTExpr> i1(Expression()), i2, i3;
    bool slice = false;
    if (match(GoLexer::OP_COLON)) {
      slice = true;
      i2.reset(Expression());
      if (i2 && match(GoLexer::OP_COLON)) {
        i3.reset(Expression());
        if (!i3)
          return syntaxerror();
      }
    }
    if (!(slice || i1))
      return syntaxerror();
    if (!mustMatch(GoLexer::OP_RBRACK))
      return nullptr;
    if (slice) {
      bool slice3 = i3.get();
      return new GoASTSliceExpr(e, i1.release(), i2.release(), i3.release(),
                                slice3);
    }
    return new GoASTIndexExpr(e, i1.release());
  }
  return r.error();
}

GoASTExpr *GoParser::TypeAssertion(GoASTExpr *e) {
  Rule r("TypeAssertion", this);
  if (match(GoLexer::OP_DOT) && match(GoLexer::OP_LPAREN)) {
    if (auto *t = Type()) {
      if (!mustMatch(GoLexer::OP_RPAREN))
        return nullptr;
      return new GoASTTypeAssertExpr(e, t);
    }
    return syntaxerror();
  }
  return r.error();
}

GoASTExpr *GoParser::Arguments(GoASTExpr *e) {
  if (match(GoLexer::OP_LPAREN)) {
    std::unique_ptr<GoASTCallExpr> call(new GoASTCallExpr(false));
    GoASTExpr *arg;
    // ( ExpressionList | Type [ "," ExpressionList ] )
    for ((arg = Expression()) || (arg = Type()); arg;
         arg = MoreExpressionList()) {
      call->AddArgs(arg);
    }
    if (match(GoLexer::OP_DOTS))
      call->SetEllipsis(true);

    // Eat trailing comma
    match(GoLexer::OP_COMMA);

    if (!mustMatch(GoLexer::OP_RPAREN))
      return nullptr;
    call->SetFun(e);
    return call.release();
  }
  return nullptr;
}

GoASTExpr *GoParser::Conversion() {
  Rule r("Conversion", this);
  if (GoASTExpr *t = Type2()) {
    std::unique_ptr<GoASTExpr> owner(t);
    if (match(GoLexer::OP_LPAREN)) {
      GoASTExpr *v = Expression();
      if (!v)
        return syntaxerror();
      match(GoLexer::OP_COMMA);
      if (!mustMatch(GoLexer::OP_RPAREN))
        return r.error();
      GoASTCallExpr *call = new GoASTCallExpr(false);
      call->SetFun(t);
      owner.release();
      call->AddArgs(v);
      return call;
    }
  }
  return r.error();
}

GoASTExpr *GoParser::Type2() {
  switch (peek()) {
  case GoLexer::OP_LBRACK:
    return ArrayOrSliceType(false);
  case GoLexer::KEYWORD_STRUCT:
    return StructType();
  case GoLexer::KEYWORD_FUNC:
    return FunctionType();
  case GoLexer::KEYWORD_INTERFACE:
    return InterfaceType();
  case GoLexer::KEYWORD_MAP:
    return MapType();
  case GoLexer::KEYWORD_CHAN:
    return ChanType2();
  default:
    return nullptr;
  }
}

GoASTExpr *GoParser::ArrayOrSliceType(bool allowEllipsis) {
  Rule r("ArrayType", this);
  if (match(GoLexer::OP_LBRACK)) {
    std::unique_ptr<GoASTExpr> len;
    if (allowEllipsis && match(GoLexer::OP_DOTS)) {
      len.reset(new GoASTEllipsis(nullptr));
    } else {
      len.reset(Expression());
    }

    if (!match(GoLexer::OP_RBRACK))
      return r.error();
    GoASTExpr *elem = Type();
    if (!elem)
      return syntaxerror();
    return new GoASTArrayType(len.release(), elem);
  }
  return r.error();
}

GoASTExpr *GoParser::StructType() {
  if (!(match(GoLexer::KEYWORD_STRUCT) && mustMatch(GoLexer::OP_LBRACE)))
    return nullptr;
  std::unique_ptr<GoASTFieldList> fields(new GoASTFieldList);
  while (auto *field = FieldDecl())
    fields->AddList(field);
  if (!mustMatch(GoLexer::OP_RBRACE))
    return nullptr;
  return new GoASTStructType(fields.release());
}

GoASTField *GoParser::FieldDecl() {
  std::unique_ptr<GoASTField> f(new GoASTField);
  GoASTExpr *t = FieldNamesAndType(f.get());
  if (!t)
    t = AnonymousFieldType();
  if (!t)
    return nullptr;

  if (auto *tok = match(GoLexer::LIT_STRING))
    f->SetTag(new GoASTBasicLit(*tok));
  if (!Semicolon())
    return syntaxerror();
  return f.release();
}

GoASTExpr *GoParser::FieldNamesAndType(GoASTField *field) {
  Rule r("FieldNames", this);
  for (auto *id = Identifier(); id; id = MoreIdentifierList())
    field->AddNames(id);
  if (m_failed)
    return nullptr;
  GoASTExpr *t = Type();
  if (t)
    return t;
  return r.error();
}

GoASTExpr *GoParser::AnonymousFieldType() {
  bool pointer = match(GoLexer::OP_STAR);
  GoASTExpr *t = Type();
  if (!t)
    return nullptr;
  if (pointer)
    return new GoASTStarExpr(t);
  return t;
}

GoASTExpr *GoParser::FunctionType() {
  if (!match(GoLexer::KEYWORD_FUNC))
    return nullptr;
  return Signature();
}

GoASTFuncType *GoParser::Signature() {
  auto *params = Params();
  if (!params)
    return syntaxerror();
  auto *result = Params();
  if (!result) {
    if (auto *t = Type()) {
      result = new GoASTFieldList;
      auto *f = new GoASTField;
      f->SetType(t);
      result->AddList(f);
    }
  }
  return new GoASTFuncType(params, result);
}

GoASTFieldList *GoParser::Params() {
  if (!match(GoLexer::OP_LPAREN))
    return nullptr;
  std::unique_ptr<GoASTFieldList> l(new GoASTFieldList);
  while (GoASTField *p = ParamDecl()) {
    l->AddList(p);
    if (!match(GoLexer::OP_COMMA))
      break;
  }
  if (!mustMatch(GoLexer::OP_RPAREN))
    return nullptr;
  return l.release();
}

GoASTField *GoParser::ParamDecl() {
  std::unique_ptr<GoASTField> field(new GoASTField);
  GoASTIdent *id = Identifier();
  if (id) {
    // Try `IdentifierList [ "..." ] Type`.
    // If that fails, backtrack and try `[ "..." ] Type`.
    Rule r("NamedParam", this);
    for (; id; id = MoreIdentifierList())
      field->AddNames(id);
    GoASTExpr *t = ParamType();
    if (t) {
      field->SetType(t);
      return field.release();
    }
    field.reset(new GoASTField);
    r.error();
  }
  GoASTExpr *t = ParamType();
  if (t) {
    field->SetType(t);
    return field.release();
  }
  return nullptr;
}

GoASTExpr *GoParser::ParamType() {
  bool dots = match(GoLexer::OP_DOTS);
  GoASTExpr *t = Type();
  if (!dots)
    return t;
  if (!t)
    return syntaxerror();
  return new GoASTEllipsis(t);
}

GoASTExpr *GoParser::InterfaceType() {
  if (!match(GoLexer::KEYWORD_INTERFACE) || !mustMatch(GoLexer::OP_LBRACE))
    return nullptr;
  std::unique_ptr<GoASTFieldList> methods(new GoASTFieldList);
  while (true) {
    Rule r("MethodSpec", this);
    // ( identifier Signature | TypeName ) ;
    std::unique_ptr<GoASTIdent> id(Identifier());
    if (!id)
      break;
    GoASTExpr *type = Signature();
    if (!type) {
      r.error();
      id.reset();
      type = Name();
    }
    if (!Semicolon())
      return syntaxerror();
    auto *f = new GoASTField;
    if (id)
      f->AddNames(id.release());
    f->SetType(type);
    methods->AddList(f);
  }
  if (!mustMatch(GoLexer::OP_RBRACE))
    return nullptr;
  return new GoASTInterfaceType(methods.release());
}

GoASTExpr *GoParser::MapType() {
  if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK)))
    return nullptr;
  std::unique_ptr<GoASTExpr> key(Type());
  if (!key)
    return syntaxerror();
  if (!mustMatch(GoLexer::OP_RBRACK))
    return nullptr;
  auto *elem = Type();
  if (!elem)
    return syntaxerror();
  return new GoASTMapType(key.release(), elem);
}

GoASTExpr *GoParser::ChanType() {
  Rule r("chan", this);
  if (match(GoLexer::OP_LT_MINUS)) {
    if (match(GoLexer::KEYWORD_CHAN)) {
      auto *elem = Type();
      if (!elem)
        return syntaxerror();
      return new GoASTChanType(GoASTNode::eChanRecv, elem);
    }
    return r.error();
  }
  return ChanType2();
}

GoASTExpr *GoParser::ChanType2() {
  if (!match(GoLexer::KEYWORD_CHAN))
    return nullptr;
  auto dir = GoASTNode::eChanBidir;
  if (match(GoLexer::OP_LT_MINUS))
    dir = GoASTNode::eChanSend;
  auto *elem = Type();
  if (!elem)
    return syntaxerror();
  return new GoASTChanType(dir, elem);
}

GoASTExpr *GoParser::Type() {
  if (GoASTExpr *t = Type2())
    return t;
  if (GoASTExpr *t = Name())
    return t;
  if (GoASTExpr *t = ChanType())
    return t;
  if (match(GoLexer::OP_STAR)) {
    GoASTExpr *t = Type();
    if (!t)
      return syntaxerror();
    return new GoASTStarExpr(t);
  }
  if (match(GoLexer::OP_LPAREN)) {
    std::unique_ptr<GoASTExpr> t(Type());
    if (!t || !match(GoLexer::OP_RPAREN))
      return syntaxerror();
    return t.release();
  }
  return nullptr;
}

bool GoParser::Semicolon() {
  if (match(GoLexer::OP_SEMICOLON))
    return true;
  switch (peek()) {
  case GoLexer::OP_RPAREN:
  case GoLexer::OP_RBRACE:
  case GoLexer::TOK_EOF:
    return true;
  default:
    return false;
  }
}

GoASTExpr *GoParser::Name() {
  if (auto *id = Identifier()) {
    if (GoASTExpr *qual = QualifiedIdent(id))
      return qual;
    return id;
  }
  return nullptr;
}

GoASTExpr *GoParser::QualifiedIdent(lldb_private::GoASTIdent *p) {
  Rule r("QualifiedIdent", this);
  llvm::SmallString<32> path(p->GetName().m_value);
  GoLexer::Token *next;
  bool have_slashes = false;
  // LLDB extension: support full/package/path.name
  while (match(GoLexer::OP_SLASH) && (next = match(GoLexer::TOK_IDENTIFIER))) {
    have_slashes = true;
    path.append("/");
    path.append(next->m_value);
  }
  if (match(GoLexer::OP_DOT)) {
    auto *name = Identifier();
    if (name) {
      if (have_slashes) {
        p->SetName(GoLexer::Token(GoLexer::TOK_IDENTIFIER, CopyString(path)));
      }
      return new GoASTSelectorExpr(p, name);
    }
  }
  return r.error();
}

llvm::StringRef GoParser::CopyString(llvm::StringRef s) {
  return m_strings.insert(std::make_pair(s, 'x')).first->getKey();
}

void GoParser::GetError(Status &error) {
  llvm::StringRef want;
  if (m_failed)
    want =
        m_last_tok == GoLexer::TOK_INVALID ? DescribeToken(m_last_tok) : m_last;
  else
    want = m_error;
  size_t len = m_lexer.BytesRemaining();
  if (len > 10)
    len = 10;
  llvm::StringRef got;
  if (len == 0)
    got = "<eof>";
  else
    got = m_lexer.GetString(len);
  error.SetErrorStringWithFormat("Syntax error: expected %s before '%s'.",
                                 want.str().c_str(), got.str().c_str());
}
