/*
 * Copyright (C) 2016, The Android Open Source Project
 *
 * 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.
 */

%{
#include "aidl_language.h"
#include "parser.h"
#include "aidl_language_y.h"
#include "logging.h"
#include <android-base/parseint.h>
#include <set>
#include <map>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);

AidlLocation loc(const yy::parser::location_type& begin, const yy::parser::location_type& end) {
  AIDL_FATAL_IF(begin.begin.filename != begin.end.filename, AIDL_LOCATION_HERE);
  AIDL_FATAL_IF(begin.end.filename != end.begin.filename, AIDL_LOCATION_HERE);
  AIDL_FATAL_IF(end.begin.filename != end.end.filename, AIDL_LOCATION_HERE);
  AidlLocation::Point begin_point {
    .line = begin.begin.line,
    .column = begin.begin.column,
  };
  AidlLocation::Point end_point {
    .line = end.end.line,
    .column = end.end.column,
  };
  return AidlLocation(*begin.begin.filename, begin_point, end_point, AidlLocation::Source::EXTERNAL);
}

AidlLocation loc(const yy::parser::location_type& l) {
  return loc(l, l);
}

#define lex_scanner ps->Scanner()

%}

%initial-action {
    @$.begin.filename = @$.end.filename =
        const_cast<std::string *>(&ps->FileName());
}

%parse-param { Parser* ps }
%lex-param { void *lex_scanner }

%glr-parser
%skeleton "glr.cc"

%expect-rr 0

%define parse.error verbose
%locations

%union {
    AidlToken* token;
    char character;
    std::string *str;
    AidlAnnotation* annotation;
    AidlAnnotationParameter* param;
    std::map<std::string, std::shared_ptr<AidlConstantValue>>* param_list;
    std::vector<AidlAnnotation>* annotation_list;
    AidlTypeSpecifier* type;
    AidlArgument* arg;
    AidlArgument::Direction direction;
    AidlConstantValue* const_expr;
    AidlEnumerator* enumerator;
    std::vector<std::unique_ptr<AidlEnumerator>>* enumerators;
    std::vector<std::unique_ptr<AidlConstantValue>>* constant_value_list;
    std::vector<std::unique_ptr<AidlArgument>>* arg_list;
    AidlVariableDeclaration* variable;
    AidlMethod* method;
    AidlMember* constant;
    std::vector<std::unique_ptr<AidlMember>>* members;
    AidlDefinedType* declaration;
    std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args;
    std::vector<std::string>* type_params;
    std::vector<std::unique_ptr<AidlImport>>* imports;
    AidlImport* import;
    AidlPackage* package;
    std::vector<std::unique_ptr<AidlDefinedType>>* declarations;
}

%destructor { } <direction>
%destructor { delete ($$); } <*>

%token<token> PACKAGE "package"
%token<token> IMPORT "import"
%token<token> ANNOTATION "annotation"
%token<token> C_STR "string literal"
%token<token> IDENTIFIER "identifier"
%token<token> INTERFACE "interface"
%token<token> PARCELABLE "parcelable"
%token<token> ONEWAY "oneway"
%token<token> ENUM "enum"
%token<token> UNION "union"
%token<token> CONST "const"

%token<token> CHARVALUE "char literal"
%token<token> FLOATVALUE "float literal"
%token<token> HEXVALUE "hex literal"
%token<token> INTVALUE "int literal"

%token '(' ')' ',' '=' '[' ']' '.' '{' '}' ';'
%token UNKNOWN "unrecognized character"
%token<token> CPP_HEADER "cpp_header (which can also be used as an identifier)"
%token IN "in"
%token INOUT "inout"
%token OUT "out"
%token TRUE_LITERAL "true"
%token FALSE_LITERAL "false"

/* Operator precedence and associativity, as per
 * http://en.cppreference.com/w/cpp/language/operator_precedence */
/* Precedence level 13 - 14, LTR, logical operators*/
%left LOGICAL_OR
%left LOGICAL_AND
/* Precedence level 10 - 12, LTR, bitwise operators*/
%left '|'
%left '^'
%left '&'
/* Precedence level 9, LTR */
%left EQUALITY NEQ
/* Precedence level 8, LTR */
%left '<' '>' LEQ GEQ
/* Precedence level 7, LTR */
%left LSHIFT RSHIFT
/* Precedence level 6, LTR */
%left '+' '-'
/* Precedence level 5, LTR */
%left '*' '/' '%'
/* Precedence level 3, RTL; but we have to use %left here */
%right UNARY_PLUS UNARY_MINUS  '!' '~'

%type<declaration> decl
%type<declaration> unannotated_decl
%type<declaration> interface_decl
%type<declaration> parcelable_decl
%type<declaration> enum_decl
%type<declaration> union_decl
%type<members> parcelable_members interface_members
%type<variable> variable_decl
%type<type_params> optional_type_params
%type<method> method_decl
%type<constant> constant_decl
%type<enumerator> enumerator
%type<enumerators> enumerators enum_decl_body
%type<param> parameter
%type<param_list> parameter_list
%type<param_list> parameter_non_empty_list
%type<annotation> annotation
%type<annotation_list>annotation_list
%type<type> type
%type<type> non_array_type
%type<arg_list> arg_list arg_non_empty_list
%type<arg> arg
%type<direction> direction
%type<type_args> type_args
%type<type_params> type_params
%type<const_expr> const_expr
%type<constant_value_list> constant_value_list
%type<constant_value_list> constant_value_non_empty_list
%type<imports> imports
%type<import> import
%type<package> package
%type<declarations> decls
%type<token> identifier error qualified_name

%%

document
 : package imports decls {
    Comments comments;
    if ($1) {
      comments = $1->GetComments();
    } else if (!$2->empty()) {
      comments = $2->front()->GetComments();
    }
    ps->SetDocument(std::make_unique<AidlDocument>(loc(@1), comments, std::move(*$2), std::move(*$3)));
    delete $1;
    delete $2;
    delete $3;
  }
 ;

/* A couple of tokens that are keywords elsewhere are identifiers when
 * occurring in the identifier position. Therefore identifier is a
 * non-terminal, which is either an IDENTIFIER token, or one of the
 * aforementioned keyword tokens.
 */
identifier
 : IDENTIFIER
 | CPP_HEADER
 ;

package
 : {
    $$ = nullptr;
 }
 | PACKAGE qualified_name ';' {
    $$ = new AidlPackage(loc(@1, @3), $1->GetComments());
    ps->SetPackage($2->GetText());
    delete $1;
    delete $2;
  }
 ;

imports
 : { $$ = new std::vector<std::unique_ptr<AidlImport>>(); }
 | imports import
  {
    $$ = $1;
    auto it = std::find_if($$->begin(), $$->end(), [&](const auto& i) {
      return $2->GetNeededClass() == i->GetNeededClass();
    });
    if (it == $$->end()) {
      $$->emplace_back($2);
    } else {
      delete $2;
    }
  }

import
 : IMPORT qualified_name ';' {
    $$ = new AidlImport(loc(@2), $2->GetText(), $1->GetComments());
    delete $1;
    delete $2;
  };

qualified_name
 : identifier {
    $$ = $1;
  }
 | qualified_name '.' identifier
  { $$ = $1;
    $$->Append('.');
    $$->Append($3->GetText());
    delete $3;
  };

decls
 : decl
  { $$ = new std::vector<std::unique_ptr<AidlDefinedType>>();
    if ($1 != nullptr) {
      $$->emplace_back($1);
    }
  }
 | decls decl
  { $$ = $1;
    if ($2 != nullptr) {
      $$->emplace_back($2);
    }
  }

decl
 : annotation_list unannotated_decl
   {
    $$ = $2;

    if ($1->size() > 0 && $$ != nullptr) {
      // copy comments from annotation to decl
      $$->SetComments($1->begin()->GetComments());
      $$->Annotate(std::move(*$1));
    }

    delete $1;
   }
 ;

unannotated_decl
 : parcelable_decl
 | interface_decl
 | enum_decl
 | union_decl
 ;

type_params
 : identifier {
    $$ = new std::vector<std::string>();
    $$->emplace_back($1->GetText());
    delete $1;
  }
 | type_params ',' identifier {
    $1->emplace_back($3->GetText());
    $$ = $1;
    delete $3;
  };

 optional_type_params
  : /* none */ { $$ = nullptr; }
  | '<' type_params '>' {
    $$ = $2;
  };

parcelable_decl
 : PARCELABLE qualified_name optional_type_params ';' {
    $$ = new AidlParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), "", $3);
    delete $1;
    delete $2;
 }
 | PARCELABLE qualified_name optional_type_params '{' parcelable_members '}' {
    $$ = new AidlStructuredParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $3, $5);
    delete $1;
    delete $2;
 }
 | PARCELABLE qualified_name CPP_HEADER C_STR ';' {
    $$ = new AidlParcelable(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $4->GetText());
    delete $1;
    delete $2;
    delete $3;
    delete $4;
  }
 | PARCELABLE error ';' {
    ps->AddError();
    $$ = nullptr;
    delete $1;
  };

parcelable_members
 : /* empty */ {
    $$ = new std::vector<std::unique_ptr<AidlMember>>();
  }
 | parcelable_members variable_decl {
    $1->emplace_back($2);
    $$ = $1;
  }
 | parcelable_members constant_decl {
    $1->emplace_back($2);
    $$ = $1;
  }
 | parcelable_members error ';' {
    ps->AddError();
    $$ = $1;
  };

variable_decl
 : type identifier ';' {
   $$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText());
   delete $2;
 }
 | type identifier '=' const_expr ';' {
   // TODO(b/123321528): Support enum type default assignments (TestEnum foo = TestEnum.FOO).
   $$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText(),  $4);
   delete $2;
 }
 ;

interface_decl
 : INTERFACE identifier '{' interface_members '}' {
    $$ = new AidlInterface(loc(@1), $2->GetText(), $1->GetComments(), false, ps->Package(), $4);
    delete $1;
    delete $2;
  }
 | ONEWAY INTERFACE identifier '{' interface_members '}' {
    $$ = new AidlInterface(loc(@2), $3->GetText(),  $1->GetComments(), true, ps->Package(), $5);
    delete $1;
    delete $2;
    delete $3;
  }
 | INTERFACE error '{' interface_members '}' {
    ps->AddError();
    $$ = nullptr;
    delete $1;
    delete $4;
  };

interface_members
 :
  { $$ = new std::vector<std::unique_ptr<AidlMember>>(); }
 | interface_members method_decl
  { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
 | interface_members constant_decl
  { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
 | interface_members error ';' {
    ps->AddError();
    $$ = $1;
  };

const_expr
 : TRUE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), true); }
 | FALSE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), false); }
 | CHARVALUE {
    $$ = AidlConstantValue::Character(loc(@1), $1->GetText());
    delete $1;
  }
 | INTVALUE {
    $$ = AidlConstantValue::Integral(loc(@1), $1->GetText());
    if ($$ == nullptr) {
      AIDL_ERROR(loc(@1)) << "Could not parse integer: "
                << $1->GetText();
      ps->AddError();
      $$ = AidlConstantValue::Integral(loc(@1), "0");
    }
    delete $1;
  }
 | FLOATVALUE {
    $$ = AidlConstantValue::Floating(loc(@1), $1->GetText());
    delete $1;
  }
 | HEXVALUE {
    $$ = AidlConstantValue::Integral(loc(@1), $1->GetText());
    if ($$ == nullptr) {
      AIDL_ERROR(loc(@1)) << "Could not parse hexvalue: "
                << $1->GetText();
      ps->AddError();
      $$ = AidlConstantValue::Integral(loc(@1), "0");
    }
    delete $1;
  }
 | C_STR {
    $$ = AidlConstantValue::String(loc(@1), $1->GetText());
    delete $1;
  }
 | qualified_name {
    $$ = new AidlConstantReference(loc(@1), $1->GetText());
    delete $1;
 }
 | '{' constant_value_list '}' {
    $$ = AidlConstantValue::Array(loc(@1), std::unique_ptr<vector<unique_ptr<AidlConstantValue>>>($2));
  }
 | const_expr LOGICAL_OR const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "||", std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr LOGICAL_AND const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&&", std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '|' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "|" , std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '^' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "^" , std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '&' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&" , std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr EQUALITY const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "==", std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr NEQ const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "!=", std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '<' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<" , std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '>' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">" , std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr LEQ const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<=", std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr GEQ const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">=", std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr LSHIFT const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<<", std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr RSHIFT const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">>", std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '+' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "+" , std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '-' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "-" , std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '*' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "*" , std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '/' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "/" , std::unique_ptr<AidlConstantValue>($3));
  }
 | const_expr '%' const_expr {
    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "%" , std::unique_ptr<AidlConstantValue>($3));
  }
 | '+' const_expr %prec UNARY_PLUS  {
    $$ = new AidlUnaryConstExpression(loc(@1), "+", std::unique_ptr<AidlConstantValue>($2));
  }
 | '-' const_expr %prec UNARY_MINUS {
    $$ = new AidlUnaryConstExpression(loc(@1), "-", std::unique_ptr<AidlConstantValue>($2));
  }
 | '!' const_expr {
    $$ = new AidlUnaryConstExpression(loc(@1), "!", std::unique_ptr<AidlConstantValue>($2));
  }
 | '~' const_expr {
    $$ = new AidlUnaryConstExpression(loc(@1), "~", std::unique_ptr<AidlConstantValue>($2));
  }
 | '(' const_expr ')'
  {
    $$ = $2;
  }
 | '(' error ')'
   {
     AIDL_ERROR(loc(@1)) << "invalid const expression within parenthesis";
     ps->AddError();
     // to avoid segfaults
     $$ = AidlConstantValue::Integral(loc(@1), "0");
   }
 ;

constant_value_list
 : /* empty */ {
    $$ = new std::vector<std::unique_ptr<AidlConstantValue>>;
 }
 | constant_value_non_empty_list {
    $$ = $1;
 }
 | constant_value_non_empty_list  ',' {
    $$ = $1;
 }
 ;

constant_value_non_empty_list
 : const_expr {
    $$ = new std::vector<std::unique_ptr<AidlConstantValue>>;
    $$->push_back(std::unique_ptr<AidlConstantValue>($1));
 }
 | constant_value_non_empty_list ',' const_expr {
    $$ = $1;
    $$->push_back(std::unique_ptr<AidlConstantValue>($3));
 }
 ;

constant_decl
 : annotation_list CONST type identifier '=' const_expr ';' {
    if ($1->size() > 0) {
      $3->SetComments($1->begin()->GetComments());
    } else {
      $3->SetComments($2->GetComments());
    }
    // TODO(b/151102494) do not merge annotations.
    $3->Annotate(std::move(*$1));
    $$ = new AidlConstantDeclaration(loc(@4), $3, $4->GetText(), $6);
    delete $1;
    delete $2;
    delete $4;
   }
 ;

enumerator
 : identifier '=' const_expr {
    $$ = new AidlEnumerator(loc(@1), $1->GetText(), $3, $1->GetComments());
    delete $1;
   }
 | identifier {
    $$ = new AidlEnumerator(loc(@1), $1->GetText(), nullptr, $1->GetComments());
    delete $1;
   }
 ;

enumerators
 : enumerator {
    $$ = new std::vector<std::unique_ptr<AidlEnumerator>>();
    $$->push_back(std::unique_ptr<AidlEnumerator>($1));
   }
 | enumerators ',' enumerator {
    $1->push_back(std::unique_ptr<AidlEnumerator>($3));
    $$ = $1;
   }
 ;

enum_decl_body
 : '{' enumerators '}' { $$ = $2; }
 | '{' enumerators ',' '}' { $$ = $2; }
 ;

enum_decl
 : ENUM identifier enum_decl_body {
    $$ = new AidlEnumDeclaration(loc(@2), $2->GetText(), $3, ps->Package(), $1->GetComments());
    delete $1;
    delete $2;
    delete $3;
   }
 ;

union_decl
 : UNION qualified_name optional_type_params '{' parcelable_members '}' {
    $$ = new AidlUnionDecl(loc(@2), $2->GetText(), ps->Package(), $1->GetComments(), $3, $5);
    delete $1;
    delete $2;
  }
 ;

method_decl
 : type identifier '(' arg_list ')' ';' {
    $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments());
    delete $2;
  }
 | annotation_list ONEWAY type identifier '(' arg_list ')' ';' {
    const auto& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
    $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, comments);
    $3->Annotate(std::move(*$1));
    delete $1;
    delete $2;
    delete $4;
  }
 | type identifier '(' arg_list ')' '=' INTVALUE ';' {
    int32_t serial = 0;
    if (!android::base::ParseInt($7->GetText(), &serial)) {
        AIDL_ERROR(loc(@7)) << "Could not parse int value: " << $7->GetText();
        ps->AddError();
    }
    $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments(), serial);
    delete $2;
    delete $7;
  }
 | annotation_list ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
    const auto& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
    int32_t serial = 0;
    if (!android::base::ParseInt($9->GetText(), &serial)) {
        AIDL_ERROR(loc(@9)) << "Could not parse int value: " << $9->GetText();
        ps->AddError();
    }
    $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, comments, serial);
    $3->Annotate(std::move(*$1));
    delete $1;
    delete $2;
    delete $4;
    delete $9;
  };

arg_non_empty_list
 : arg {
    $$ = new std::vector<std::unique_ptr<AidlArgument>>();
    $$->push_back(std::unique_ptr<AidlArgument>($1));
  }
 | arg_non_empty_list ',' arg {
    $$ = $1;
    $$->push_back(std::unique_ptr<AidlArgument>($3));
  };

arg_list
 : /*empty*/
   { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); }
 | arg_non_empty_list { $$ = $1; }
 ;

arg
 : direction type identifier {
    $$ = new AidlArgument(loc(@3), $1, $2, $3->GetText());
    delete $3;
  }
 | type identifier {
    $$ = new AidlArgument(loc(@2), $1, $2->GetText());
    delete $2;
  };

non_array_type
 : annotation_list qualified_name {
    $$ = new AidlTypeSpecifier(loc(@2), $2->GetText(), false, nullptr, $2->GetComments());
    ps->DeferResolution($$);
    if (!$1->empty()) {
      $$->SetComments($1->begin()->GetComments());
      $$->Annotate(std::move(*$1));
    }
    delete $1;
    delete $2;
  }
 | non_array_type '<' type_args '>' {
    ps->SetTypeParameters($1, $3);
    $$ = $1;
  }
 | non_array_type '<' non_array_type '<' type_args RSHIFT {
    ps->SetTypeParameters($3, $5);
    auto params = new std::vector<std::unique_ptr<AidlTypeSpecifier>>();
    params->emplace_back($3);
    ps->SetTypeParameters($1, params);
    $$ = $1;
  }
 | non_array_type '<' type_args ',' non_array_type '<' type_args RSHIFT {
    ps->SetTypeParameters($5, $7);
    $3->emplace_back($5);
    ps->SetTypeParameters($1, $3);
    $$ = $1;
  };

type
 : non_array_type
 | type annotation_list '[' ']' {
    if (!$2->empty()) {
      AIDL_ERROR(loc(@2)) << "Annotations for arrays are not supported.";
      ps->AddError();
    }
    if (!$1->SetArray()) {
      AIDL_ERROR(loc(@1)) << "Can only have one dimensional arrays.";
      ps->AddError();
    }
    $$ = $1;
    delete $2;
  }
 ;

type_args
 : type {
    if (!$1->GetAnnotations().empty()) {
      AIDL_ERROR(loc(@1)) << "Annotations for type arguments are not supported.";
      ps->AddError();
    }
    $$ = new std::vector<std::unique_ptr<AidlTypeSpecifier>>();
    $$->emplace_back($1);
  }
 | type_args ',' type {
    $1->emplace_back($3);
    $$ = $1;
  };

annotation_list
 :
  { $$ = new std::vector<AidlAnnotation>(); }
 | annotation_list annotation
  {
    if ($2 != nullptr) {
      $1->emplace_back(std::move(*$2));
      delete $2;
    }
    $$ = $1;
  };

parameter
  : identifier '=' const_expr {
    $$ = new AidlAnnotationParameter{$1->GetText(), std::unique_ptr<AidlConstantValue>($3)};
    delete $1;
  };

parameter_list
  : /*empty*/{
    $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>();
  }
  | parameter_non_empty_list  {
    $$ = $1;
  };

parameter_non_empty_list
  : parameter {
    $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>();
    $$->emplace(std::move($1->name), $1->value.release());
    delete $1;
  }
  | parameter_non_empty_list ',' parameter {
    $$ = $1;
    if ($$->find($3->name) != $$->end()) {
      AIDL_ERROR(loc(@3)) << "Trying to redefine parameter " << $3->name << ".";
      ps->AddError();
    }
    $$->emplace(std::move($3->name), std::move($3->value));
    delete $3;
  };

annotation
 : ANNOTATION {
    $$ = AidlAnnotation::Parse(loc(@1), $1->GetText(), nullptr, $1->GetComments());
    if (!$$) {
      ps->AddError();
    }
    delete $1;
  }
 | ANNOTATION '(' parameter_list ')' {
    $$ = AidlAnnotation::Parse(loc(@1, @4), $1->GetText(), $3, $1->GetComments());
    if (!$$) {
      ps->AddError();
    }
    delete $1;
    delete $3;
  }
 ;

direction
 : IN
  { $$ = AidlArgument::IN_DIR; }
 | OUT
  { $$ = AidlArgument::OUT_DIR; }
 | INOUT
  { $$ = AidlArgument::INOUT_DIR; };

%%

#include <ctype.h>
#include <stdio.h>

void yy::parser::error(const yy::parser::location_type& l, const std::string& errstr) {
  AIDL_ERROR(loc(l)) << errstr;
  // parser will return error value
}
