/*
 * 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 "AST.h"
#include "Annotation.h"
#include "ArrayType.h"
#include "CompoundType.h"
#include "ConstantExpression.h"
#include "Coordinator.h"
#include "DocComment.h"
#include "EnumType.h"
#include "Interface.h"
#include "Location.h"
#include "Method.h"
#include "Scope.h"
#include "TypeDef.h"
#include "VectorType.h"

#include "hidl-gen_y-helpers.h"

#include <android-base/logging.h>
#include <hidl-util/FQName.h>
#include <hidl-util/StringHelper.h>
#include <stdio.h>

using namespace android;

extern int yylex(yy::parser::semantic_type*, yy::parser::location_type*, void*, AST* const,
                 Scope** const);

void enterScope(AST* /* ast */, Scope** scope, Scope* container) {
    CHECK(container->parent() == (*scope));
    *scope = container;
}

void leaveScope(AST* ast, Scope** scope) {
    CHECK((*scope) != &ast->getRootScope());
    *scope = (*scope)->parent();
}

::android::Location convertYYLoc(const yy::parser::location_type& loc, const AST* ast) {
    return ::android::Location(
            ::android::Position(ast->getCoordinator().makeRelative(*(loc.begin.filename)),
                                loc.begin.line, loc.begin.column),
            ::android::Position(ast->getCoordinator().makeRelative(*(loc.end.filename)),
                                loc.end.line, loc.end.column));
}

bool isValidInterfaceField(const std::string& identifier, std::string *errorMsg) {
    static const std::vector<std::string> reserved({
        // Injected names to C++ interfaces by auto-generated code
        "isRemote", "descriptor", "hidlStaticBlock", "onTransact",
        "castFrom", "Proxy", "Stub", "getService",

        // Injected names to Java interfaces by auto-generated code
        "asInterface", "castFrom", "getService", "toString",

        // Inherited methods from IBase is detected in addMethod. Not added here
        // because we need hidl-gen to compile IBase.

        // Inherited names by interfaces from IInterface / IBinder
        "onAsBinder", "asBinder", "queryLocalInterface", "getInterfaceDescriptor", "isBinderAlive",
        "pingBinder", "dump", "transact", "checkSubclass", "attachObject", "findObject",
        "detachObject", "localBinder", "remoteBinder", "mImpl",

        // Inherited names from HidlInstrumentor
        "InstrumentationEvent", "configureInstrumentation", "registerInstrumentationCallbacks",
        "isInstrumentationLib", "mInstrumentationCal1lbacks", "mEnableInstrumentation",
        "mInstrumentationLibPackage", "mInterfaceName",

        // Collide with names in BsFoo
        "mImpl", "addOnewayTask", "mOnewayQueue",

        // Inherited names from Java IHwInterface
        "asBinder",
    });
    if (std::find(reserved.begin(), reserved.end(), identifier) != reserved.end()) {
        *errorMsg = identifier + " cannot be a name inside an interface";
        return false;
    }
    return true;
}

bool isValidStructField(const std::string& identifier, std::string *errorMsg) {
    static const std::vector<std::string> reserved({
        // Injected names to structs and unions by auto-generated code
        "readEmbeddedFromParcel", "writeEmbeddedToParcel", "readVectorFromParcel",
        "writeVectorToParcel", "writeEmbeddedToBlob",
    });
    if (std::find(reserved.begin(), reserved.end(), identifier) != reserved.end()) {
        *errorMsg = identifier + " cannot be a name inside an struct or union";
        return false;
    }
    return true;
}

bool isValidCompoundTypeField(CompoundType::Style style, const std::string& identifier,
                              std::string *errorMsg) {
    // Unions don't support fix-up types; as such, they can't
    // have name collisions with embedded read/write methods.
    if (style == CompoundType::STYLE_UNION) { return true; }

    return isValidStructField(identifier, errorMsg);;
}

bool isValidIdentifier(const std::string& identifier, std::string *errorMsg) {
    static const std::vector<std::string> keywords({
        "uint8_t", "uint16_t", "uint32_t", "uint64_t",
        "int8_t", "int16_t", "int32_t", "int64_t", "bool", "float", "double",
        "interface", "struct", "union", "string", "vec", "enum", "ref", "handle",
        "package", "import", "typedef", "generates", "oneway", "extends",
        "fmq_sync", "fmq_unsync", "safe_union",
    });
    static const std::vector<std::string> cppKeywords({
        "alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit",
        "atomic_noexcept", "auto", "bitand", "bitor", "bool", "break", "case", "catch",
        "char", "char16_t", "char32_t", "class", "compl", "concept", "const", "constexpr",
        "const_cast", "continue", "decltype", "default", "delete", "do", "double",
        "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float",
        "for", "friend", "goto", "if", "inline", "int", "import", "long", "module", "mutable",
        "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
        "private", "protected", "public", "register", "reinterpret_cast", "requires", "return",
        "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct",
        "switch", "synchronized", "template", "this", "thread_local", "throw", "true", "try",
        "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void",
        "volatile", "wchar_t", "while", "xor", "xor_eq",
    });
    static const std::vector<std::string> javaKeywords({
        "abstract", "continue", "for", "new", "switch", "assert", "default", "goto", "package",
        "synchronized", "boolean", "do", "if", "private", "this", "break", "double",
        "implements", "protected", "throw", "byte", "else", "import", "public", "throws",
        "case", "enum", "instanceof", "return", "transient", "catch", "extends", "int",
        "short", "try", "char", "final", "interface", "static", "void", "class", "finally",
        "long", "strictfp", "volatile", "const", "float", "native", "super", "while",
    });
    static const std::vector<std::string> cppCollide({
        "size_t", "offsetof",
    });

    // errors
    if (std::find(keywords.begin(), keywords.end(), identifier) != keywords.end()) {
        *errorMsg = identifier + " is a HIDL keyword "
            "and is therefore not a valid identifier";
        return false;
    }
    if (std::find(cppKeywords.begin(), cppKeywords.end(), identifier) != cppKeywords.end()) {
        *errorMsg = identifier + " is a C++ keyword "
            "and is therefore not a valid identifier";
        return false;
    }
    if (std::find(javaKeywords.begin(), javaKeywords.end(), identifier) != javaKeywords.end()) {
        *errorMsg = identifier + " is a Java keyword "
            "and is therefore not a valid identifier";
        return false;
    }
    if (std::find(cppCollide.begin(), cppCollide.end(), identifier) != cppCollide.end()) {
        *errorMsg = identifier + " collides with reserved names in C++ code "
            "and is therefore not a valid identifier";
        return false;
    }
    if (StringHelper::StartsWith(identifier, "_hidl_")) {
        *errorMsg = identifier + " starts with _hidl_ "
            "and is therefore not a valid identifier";
        return false;
    }
    if (StringHelper::StartsWith(identifier, "hidl_")) {
        *errorMsg = identifier + " starts with hidl_ "
            "and is therefore not a valid identifier";
        return false;
    }
    if (StringHelper::EndsWith(identifier, "_cb")) {
        *errorMsg = identifier + " ends with _cb "
            "and is therefore not a valid identifier";
        return false;
    }

    return true;
}

// Return true if identifier is an acceptable name for an UDT.
bool isValidTypeName(const std::string& identifier, std::string *errorMsg) {
    if (!isValidIdentifier(identifier, errorMsg)) {
        return false;
    }

    if (identifier == "toString") {
        *errorMsg = identifier + " is not a valid type name";
        return false;
    }

    return true;
}

%}

%initial-action {
    // Initialize the initial location.
    @$.begin.filename = @$.end.filename =
        const_cast<std::string *>(&ast->getFilename());
}

%parse-param { void* scanner }
%parse-param { android::AST* const ast }
%parse-param { android::Scope** const scope }
%lex-param { void* scanner }
%lex-param { android::AST* const ast }
%lex-param { android::Scope** const scope }
%glr-parser
%skeleton "glr.cc"

%expect-rr 0
%define parse.error verbose
%locations

%verbose
%debug

%token<str> MULTILINE_COMMENT "multiline comment"
%token<str> DOC_COMMENT "doc comment"

%token<void> ENUM "keyword `enum`"
%token<void> EXTENDS "keyword `extends`"
%token<str> FQNAME "fully-qualified name"
%token<void> GENERATES "keyword `generates`"
%token<str> IDENTIFIER "identifier"
%token<void> IMPORT "keyword `import`"
%token<str> INTEGER "integer value"
%token<str> FLOAT "float value"
%token<void> INTERFACE "keyword `interface`"
%token<str> PACKAGE "keyword `package`"
%token<type> TYPE "type"
%token<void> STRUCT "keyword `struct`"
%token<str> STRING_LITERAL "string literal"
%token<void> TYPEDEF "keyword `typedef`"
%token<void> UNION "keyword `union`"
%token<void> SAFE_UNION "keyword `safe_union`"
%token<templatedType> TEMPLATED "templated type"
%token<void> ONEWAY "keyword `oneway`"
%token<str> UNKNOWN "unknown character"

/* Operator precedence and associativity, as per
 * http://en.cppreference.com/w/cpp/language/operator_precedence */
/* Precedence level 15 ternary operator */
%right '?' ':'
/* 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 */
%left UNARY_MINUS UNARY_PLUS '!' '~'

%token '#'

%type<docComment> doc_comment doc_comments ignore_doc_comments

%type<str> error_stmt error
%type<str> package
%type<fqName> fqname
%type<referenceToType> fqtype
%type<str> valid_identifier valid_type_name

%type<referenceToType> type enum_storage_type type_or_inplace_compound_declaration
%type<referenceToType> array_type_base
%type<arrayType> array_type
%type<referenceToType> opt_extends
%type<type> type_declaration commentable_type_declaration type_declaration_body
%type<type> interface_declaration typedef_declaration
%type<type> named_struct_or_union_declaration named_enum_declaration
%type<type> compound_declaration annotated_compound_declaration

%type<docCommentable> field_declaration commentable_field_declaration
%type<fields> field_declarations struct_or_union_body
%type<constantExpression> const_expr
%type<enumValue> enum_value commentable_enum_value
%type<enumValues> enum_values enum_declaration_body
%type<typedVars> typed_vars non_empty_typed_vars
%type<typedVar> typed_var uncommented_typed_var
%type<method> method_declaration commentable_method_declaration
%type<compoundStyle> struct_or_union_keyword
%type<stringVec> annotation_string_values annotation_string_value
%type<annotationParam> annotation_param
%type<annotationParams> opt_annotation_params annotation_params
%type<annotation> annotation
%type<annotations> opt_annotations

%start program

%union {
    const char *str;
    android::Type* type;
    android::Reference<android::Type>* referenceToType;
    android::ArrayType *arrayType;
    android::TemplatedType *templatedType;
    android::FQName *fqName;
    android::CompoundType *compoundType;
    android::NamedReference<android::Type>* field;
    std::vector<android::NamedReference<android::Type>*>* fields;
    android::EnumValue *enumValue;
    android::ConstantExpression *constantExpression;
    std::vector<android::EnumValue *> *enumValues;
    android::NamedReference<android::Type>* typedVar;
    android::TypedVarVector *typedVars;
    android::Method *method;
    android::CompoundType::Style compoundStyle;
    std::vector<std::string> *stringVec;
    android::AnnotationParam *annotationParam;
    android::AnnotationParamVector *annotationParams;
    android::Annotation *annotation;
    std::vector<android::Annotation *> *annotations;
    android::DocComment* docComment;
    android::DocCommentable* docCommentable;
}

%%

program
    : doc_comments package declarations ignore_doc_comments
      {
        ast->setHeader($1);
      }
    | package declarations ignore_doc_comments
    ;

doc_comment
    : DOC_COMMENT { $$ = new DocComment($1, convertYYLoc(@1, ast), CommentType::DOC_MULTILINE); }
    | MULTILINE_COMMENT { $$ = new DocComment($1, convertYYLoc(@1, ast), CommentType::MULTILINE); }
    ;

doc_comments
    : doc_comment { $$ = $1; }
    | doc_comments doc_comment
      {
        $1->merge($2);
        $$ = $1;
      }
    ;

ignore_doc_comments
    : /*empty*/ { $$ = nullptr; }
    | doc_comments { ast->addUnhandledComment($1); $$ = $1; }
    ;

valid_identifier
    : IDENTIFIER
      {
        std::string errorMsg;
        if (!isValidIdentifier($1, &errorMsg)) {
            std::cerr << "ERROR: " << errorMsg << " at " << @1 << "\n";
            YYERROR;
        }
        $$ = $1;
      }
    ;

valid_type_name
    : IDENTIFIER
      {
        std::string errorMsg;
        if (!isValidTypeName($1, &errorMsg)) {
            std::cerr << "ERROR: " << errorMsg << " at " << @1 << "\n";
            YYERROR;
        }
        $$ = $1;
      }
    ;

opt_annotations
    : /* empty */
      {
          $$ = new std::vector<Annotation *>;
      }
    | opt_annotations annotation
      {
          $$ = $1;
          $$->push_back($2);
      }
    ;

annotation
    : '@' IDENTIFIER opt_annotation_params
      {
          $$ = new Annotation($2, $3);
      }
    ;

opt_annotation_params
    : /* empty */
      {
          $$ = new AnnotationParamVector;
      }
    | '(' annotation_params ')'
      {
          $$ = $2;
      }
    ;

annotation_params
    : annotation_param
      {
          $$ = new AnnotationParamVector;
          $$->push_back($1);
      }
    | annotation_params ',' annotation_param
      {
          $$ = $1;
          $$->push_back($3);
      }
    ;

annotation_param
    : IDENTIFIER '=' annotation_string_value
      {
          $$ = new StringAnnotationParam($1, $3);
      }
    ;

annotation_string_value
    : STRING_LITERAL
      {
          $$ = new std::vector<std::string>;
          $$->push_back($1);
      }
    | '{' annotation_string_values '}' { $$ = $2; }
    ;

annotation_string_values
    : STRING_LITERAL
      {
          $$ = new std::vector<std::string>;
          $$->push_back($1);
      }
    | annotation_string_values ',' STRING_LITERAL
      {
          $$ = $1;
          $$->push_back($3);
      }
    ;

error_stmt
  : error ';'
    {
      $$ = $1;
      ast->addSyntaxError();
    }
  ;

require_semicolon
    : ';'
    | /* empty */
      {
          std::cerr << "ERROR: missing ; at " << @$ << "\n";
          ast->addSyntaxError();
      }
    ;

fqname
    : FQNAME
      {
          $$ = new FQName();
          if(!FQName::parse($1, $$)) {
              std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
                        << @1
                        << ".\n";
              YYERROR;
          }
      }
    | valid_type_name
      {
          $$ = new FQName();
          if(!FQName::parse($1, $$)) {
              std::cerr << "ERROR: FQName '" << $1 << "' is not valid at "
                        << @1
                        << ".\n";
              YYERROR;
          }
      }
    ;

fqtype
    : fqname
      {
          $$ = new Reference<Type>($1->string(), *$1, convertYYLoc(@1, ast));
      }
    | TYPE
      {
          $$ = new Reference<Type>($1->definedName(), $1, convertYYLoc(@1, ast));
      }
    ;

package
    : PACKAGE FQNAME require_semicolon
      {
          if (!ast->setPackage($2)) {
              std::cerr << "ERROR: Malformed package identifier '"
                        << $2
                        << "' at "
                        << @2
                        << "\n";

              YYERROR;
          }
      }
    | error
    {
      std::cerr << "ERROR: Package statement must be at the beginning of the file (" << @1 << ")\n";
      $$ = $1;
      ast->addSyntaxError();
    }
    ;

import_stmt
    : IMPORT FQNAME require_semicolon
      {
          if (!ast->addImport($2, convertYYLoc(@2, ast))) {
              std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2
                        << "\n";
              ast->addSyntaxError();
          }
      }
    | IMPORT valid_type_name require_semicolon
      {
          if (!ast->addImport($2, convertYYLoc(@2, ast))) {
              std::cerr << "ERROR: Unable to import '" << $2 << "' at " << @2
                        << "\n";
              ast->addSyntaxError();
          }
      }
    | IMPORT error_stmt
    ;

opt_extends
    : /* empty */ { $$ = nullptr; }
    | EXTENDS fqtype { $$ = $2; }
    ;

interface_declarations
    : /* empty */
    | interface_declarations commentable_type_declaration
      {
          CHECK((*scope)->isInterface());

          std::string errorMsg;
          if ($2 != nullptr && $2->isNamedType() &&
              !isValidInterfaceField(static_cast<NamedType*>($2)->definedName().c_str(),
                    &errorMsg)) {
              std::cerr << "ERROR: " << errorMsg << " at "
                        << @2 << "\n";
              YYERROR;
          }
      }
    | interface_declarations commentable_method_declaration
      {
          CHECK((*scope)->isInterface());

          std::string errorMsg;
          if ($2 != nullptr &&
              !isValidInterfaceField($2->name().c_str(), &errorMsg)) {
              std::cerr << "ERROR: " << errorMsg << " at "
                        << @2 << "\n";
              YYERROR;
          }

          if ($2 != nullptr) {
            Interface *iface = static_cast<Interface*>(*scope);
            if (!ast->addMethod($2, iface)) {
                std::cerr << "ERROR: Unable to add method '" << $2->name()
                          << "' at " << @2 << "\n";

                YYERROR;
            }
          }
          // ignore if $2 is nullptr (from error recovery)
      }
    ;

declarations
    : /* empty */
    | error_stmt
    | declarations commentable_declaration
    ;

commentable_declaration
    : doc_comments type_declaration
      {
        $2->setDocComment($1);
      }
    | type_declaration
    | ignore_doc_comments import_stmt
      {
        // Import statements must be first. The grammar allows them later so that:
        // - there is a nice error if imports are later
        // - doc_comments can be factored out here to avoid shift/reduce conflicts
        if (!ast->getRootScope().getDefinedTypes().empty()) {
            std::cerr << "ERROR: import at " << @2
                      << " follows type definitions, but imports must come first" << std::endl;

            YYERROR;
        }
      }
    ;

/*
 * For orthogonality/simplicity in the future, import_stmt could be made to share inheritance
 * hierarchy with type_declaration, and then we could explicitly disallow import inside of
 * interfaces
 */
commentable_type_declaration
    : doc_comments type_declaration
      {
        $2->setDocComment($1);
        $$ = $2;
      }
    | type_declaration { $$ = $1; }
    ;

type_declaration
    : opt_annotations type_declaration_body
      {
          if (!$2->isTypeDef()) {
              CHECK($2->isScope());
              static_cast<Scope*>($2)->setAnnotations($1);
          } else if (!$1->empty()) {
              // Since typedefs are always resolved to their target it makes
              // little sense to annotate them and have their annotations
              // impose semantics other than their target type.
              std::cerr << "ERROR: typedefs cannot be annotated at " << @2
                        << "\n";

              YYERROR;
          }
          $$ = $2;
      }
    ;

type_declaration_body
    : named_struct_or_union_declaration require_semicolon
    | named_enum_declaration require_semicolon
    | typedef_declaration require_semicolon
    | interface_declaration require_semicolon
    ;

interface_declaration
    : INTERFACE valid_type_name opt_extends
      {
          Reference<Type>* superType = $3;
          bool isIBase = ast->package().package() == gIBaseFqName.package();

          if (isIBase) {
              if (superType != nullptr) {
                  std::cerr << "ERROR: IBase must not extend any interface at " << @3
                        << "\n";

                  YYERROR;
              }
              superType = new Reference<Type>();
          } else {
              if (!ast->addImplicitImport(gIBaseFqName)) {
                  std::cerr << "ERROR: Unable to automatically import '"
                            << gIBaseFqName.string()
                            << "' at " << @$
                            << "\n";
                  YYERROR;
              }

              if (superType == nullptr) {
                  superType = new Reference<Type>(gIBaseFqName.string(), gIBaseFqName, convertYYLoc(@$, ast));
              }
          }

          if ($2[0] != 'I') {
              std::cerr << "ERROR: All interface names must start with an 'I' "
                        << "prefix at " << @2 << "\n";

              YYERROR;
          }

          if (*scope != &ast->getRootScope()) {
              std::cerr << "ERROR: All interface must declared in "
                        << "global scope at " << @2 << "\n";

              YYERROR;
          }

          Interface* iface = new Interface(
              $2, ast->makeFullName($2, *scope), convertYYLoc(@2, ast),
              *scope, *superType, ast->getFileHash());

          enterScope(ast, scope, iface);
      }
      interface_declaration_body
      {
          CHECK((*scope)->isInterface());

          Interface *iface = static_cast<Interface *>(*scope);
          CHECK(ast->addAllReservedMethodsToInterface(iface));

          leaveScope(ast, scope);
          ast->addScopedType(iface, *scope);
          $$ = iface;
      }
    ;

interface_declaration_body
    : '{' interface_declarations ignore_doc_comments '}'
    ;

typedef_declaration
    : TYPEDEF type valid_type_name
      {
          // The reason we wrap the given type in a TypeDef is simply to suppress
          // emitting any type definitions later on, since this is just an alias
          // to a type defined elsewhere.
          TypeDef* typeDef = new TypeDef(
              $3, ast->makeFullName($3, *scope), convertYYLoc(@2, ast), *scope, *$2);
          ast->addScopedType(typeDef, *scope);
          $$ = typeDef;
      }
    ;

const_expr
    : INTEGER
      {
          $$ = LiteralConstantExpression::tryParse($1);

          if ($$ == nullptr) {
              std::cerr << "ERROR: Could not parse literal: "
                        << $1 << " at " << @1 << ".\n";
              YYERROR;
          }
      }
    | fqname
      {
          if(!$1->isValidValueName()) {
              std::cerr << "ERROR: '" << $1->string()
                        << "' does not refer to an enum value at "
                        << @1 << ".\n";
              YYERROR;
          }

          $$ = new ReferenceConstantExpression(
              Reference<LocalIdentifier>($1->string(), *$1, convertYYLoc(@1, ast)), $1->string());
      }
    | fqname '#' IDENTIFIER
      {
          $$ = new AttributeConstantExpression(
              Reference<Type>($1->string(), *$1, convertYYLoc(@1, ast)), $1->string(), $3);
      }
    | const_expr '?' const_expr ':' const_expr
      {
          $$ = new TernaryConstantExpression($1, $3, $5);
      }
    | const_expr LOGICAL_OR const_expr  { $$ = new BinaryConstantExpression($1, "||", $3); }
    | const_expr LOGICAL_AND const_expr { $$ = new BinaryConstantExpression($1, "&&", $3); }
    | const_expr '|' const_expr { $$ = new BinaryConstantExpression($1, "|" , $3); }
    | const_expr '^' const_expr { $$ = new BinaryConstantExpression($1, "^" , $3); }
    | const_expr '&' const_expr { $$ = new BinaryConstantExpression($1, "&" , $3); }
    | const_expr EQUALITY const_expr { $$ = new BinaryConstantExpression($1, "==", $3); }
    | const_expr NEQ const_expr { $$ = new BinaryConstantExpression($1, "!=", $3); }
    | const_expr '<' const_expr { $$ = new BinaryConstantExpression($1, "<" , $3); }
    | const_expr '>' const_expr { $$ = new BinaryConstantExpression($1, ">" , $3); }
    | const_expr LEQ const_expr { $$ = new BinaryConstantExpression($1, "<=", $3); }
    | const_expr GEQ const_expr { $$ = new BinaryConstantExpression($1, ">=", $3); }
    | const_expr LSHIFT const_expr { $$ = new BinaryConstantExpression($1, "<<", $3); }
    | const_expr RSHIFT const_expr { $$ = new BinaryConstantExpression($1, ">>", $3); }
    | const_expr '+' const_expr { $$ = new BinaryConstantExpression($1, "+" , $3); }
    | const_expr '-' const_expr { $$ = new BinaryConstantExpression($1, "-" , $3); }
    | const_expr '*' const_expr { $$ = new BinaryConstantExpression($1, "*" , $3); }
    | const_expr '/' const_expr { $$ = new BinaryConstantExpression($1, "/" , $3); }
    | const_expr '%' const_expr { $$ = new BinaryConstantExpression($1, "%" , $3); }
    | '+' const_expr %prec UNARY_PLUS  { $$ = new UnaryConstantExpression("+", $2); }
    | '-' const_expr %prec UNARY_MINUS { $$ = new UnaryConstantExpression("-", $2); }
    | '!' const_expr { $$ = new UnaryConstantExpression("!", $2); }
    | '~' const_expr { $$ = new UnaryConstantExpression("~", $2); }
    | '(' const_expr ')'
      {
        $2->surroundWithParens();
        $$ = $2;
      }
    | '(' error ')'
      {
        ast->addSyntaxError();
        // to avoid segfaults
        $$ = ConstantExpression::Zero(ScalarType::KIND_INT32).release();
      }
    ;

commentable_method_declaration
    : doc_comments method_declaration
      {
        if ($2 != nullptr) $2->setDocComment($1);
        $$ = $2;
      }
    | method_declaration
      {
        $$ = $1;
      }

method_declaration
    : error_stmt { $$ = nullptr; }
    | opt_annotations valid_identifier '(' typed_vars ')' require_semicolon
      {
          $$ = new Method($2 /* name */,
                          $4 /* args */,
                          new std::vector<NamedReference<Type>*> /* results */,
                          false /* oneway */,
                          $1 /* annotations */,
                          convertYYLoc(@$, ast));
      }
    | opt_annotations ONEWAY valid_identifier '(' typed_vars ')' require_semicolon
      {
          $$ = new Method($3 /* name */,
                          $5 /* args */,
                          new std::vector<NamedReference<Type>*> /* results */,
                          true /* oneway */,
                          $1 /* annotations */,
                          convertYYLoc(@$, ast));
      }
    | opt_annotations valid_identifier '(' typed_vars ')' GENERATES '(' typed_vars ')' require_semicolon
      {
          if ($8->empty()) {
              std::cerr << "ERROR: generates clause used without result at " << @1 << "\n";
              ast->addSyntaxError();
          }

          $$ = new Method($2 /* name */,
                          $4 /* args */,
                          $8 /* results */,
                          false /* oneway */,
                          $1 /* annotations */,
                          convertYYLoc(@$, ast));
      }
    ;

typed_vars
    : /* empty */
      {
          $$ = new TypedVarVector();
      }
    | non_empty_typed_vars
      {
          $$ = $1;
      }
    ;

non_empty_typed_vars
    : typed_var
      {
          $$ = new TypedVarVector();
          if (!$$->add($1)) {
              std::cerr << "ERROR: duplicated argument or result name "
                  << $1->name() << " at " << @1 << "\n";
              ast->addSyntaxError();
          }
      }
    | non_empty_typed_vars ',' typed_var
      {
          $$ = $1;
          if (!$$->add($3)) {
              std::cerr << "ERROR: duplicated argument or result name "
                  << $3->name() << " at " << @3 << "\n";
              ast->addSyntaxError();
          }
      }
    ;

typed_var
    : ignore_doc_comments uncommented_typed_var { $$ = $2; }
    ;

uncommented_typed_var
    : type valid_identifier ignore_doc_comments
      {
          $$ = new NamedReference<Type>($2, *$1, convertYYLoc(@2, ast));
      }
    | type
      {
          $$ = new NamedReference<Type>("", *$1, convertYYLoc(@1, ast));

          const std::string typeName = $$->isResolved()
              ? $$->get()->typeName() : $$->getLookupFqName().string();

          std::cerr << "ERROR: variable of type " << typeName
              << " is missing a variable name at " << @1 << "\n";
          ast->addSyntaxError();
      }
    ;


struct_or_union_keyword
    : STRUCT { $$ = CompoundType::STYLE_STRUCT; }
    | UNION { $$ = CompoundType::STYLE_UNION; }
    | SAFE_UNION { $$ = CompoundType::STYLE_SAFE_UNION; }
    ;

named_struct_or_union_declaration
    : struct_or_union_keyword valid_type_name
      {
          CompoundType *container = new CompoundType(
              $1, $2, ast->makeFullName($2, *scope), convertYYLoc(@2, ast), *scope);
          enterScope(ast, scope, container);
      }
      struct_or_union_body
      {
          CHECK((*scope)->isCompoundType());
          CompoundType *container = static_cast<CompoundType *>(*scope);

          leaveScope(ast, scope);
          ast->addScopedType(container, *scope);
          $$ = container;
      }
    ;

struct_or_union_body
    : '{' field_declarations ignore_doc_comments '}' { $$ = $2; }
    ;

field_declarations
    : /* empty */ { $$ = nullptr; }
    | field_declarations commentable_field_declaration
      {
          $$ = nullptr;
      }
    ;

commentable_field_declaration
    : doc_comments field_declaration
    {
      if ($2 != nullptr) $2->setDocComment($1);
      $$ = $2;
    }
    | field_declaration { $$ = $1; }

field_declaration
    : error_stmt { $$ = nullptr; }
    | type_or_inplace_compound_declaration valid_identifier require_semicolon
      {
          CHECK((*scope)->isCompoundType());

          std::string errorMsg;
          CompoundType* compoundType = static_cast<CompoundType *>(*scope);
          auto style = compoundType->style();

          if (!isValidCompoundTypeField(style, $2, &errorMsg)) {
              std::cerr << "ERROR: " << errorMsg << " at "
                        << @2 << "\n";
              YYERROR;
          }

          NamedReference<Type>* field = new NamedReference<Type>($2, *$1, convertYYLoc(@2, ast));
          compoundType->addField(field);
          $$ = field;
      }
    | annotated_compound_declaration ';'
      {
          CHECK((*scope)->isCompoundType());

          std::string errorMsg;
          auto style = static_cast<CompoundType *>(*scope)->style();

          if ($1 != nullptr && $1->isNamedType() &&
              !isValidCompoundTypeField(style, static_cast<NamedType*>(
                        $1)->definedName().c_str(), &errorMsg)) {
              std::cerr << "ERROR: " << errorMsg << " at "
                        << @2 << "\n";
              YYERROR;
          }

          $$ = $1;
      }
    ;

annotated_compound_declaration
    : opt_annotations compound_declaration
      {
          CHECK($2->isScope());
          static_cast<Scope*>($2)->setAnnotations($1);
          $$ = $2;
      }
    ;

compound_declaration
    : named_struct_or_union_declaration { $$ = $1; }
    | named_enum_declaration { $$ = $1; }
    ;

enum_storage_type
    : ':' fqtype ignore_doc_comments { $$ = $2; }
    | /* empty */ { $$ = nullptr; }
    ;

named_enum_declaration
    : ENUM valid_type_name enum_storage_type
      {
          auto storageType = $3;

          if (storageType == nullptr) {
              std::cerr << "ERROR: Must explicitly specify enum storage type for "
                        << $2 << " at " << @2 << "\n";
              ast->addSyntaxError();
              ScalarType* scalar = new ScalarType(ScalarType::KIND_INT64, *scope);
              storageType = new Reference<Type>(scalar->definedName(), scalar, convertYYLoc(@2, ast));
          }

          EnumType* enumType = new EnumType(
              $2, ast->makeFullName($2, *scope), convertYYLoc(@2, ast), *storageType, *scope);
          enterScope(ast, scope, enumType);
      }
      enum_declaration_body
      {
          CHECK((*scope)->isEnum());
          EnumType* enumType = static_cast<EnumType*>(*scope);

          leaveScope(ast, scope);
          ast->addScopedType(enumType, *scope);
          $$ = enumType;
      }
    ;

enum_declaration_body
    : '{' enum_values '}' { $$ = $2; }
    | '{' enum_values ',' ignore_doc_comments '}' { $$ = $2; }
    ;

commentable_enum_value
    : doc_comments enum_value ignore_doc_comments
      {
        $2->setDocComment($1);
        $$ = $2;
      }
    | enum_value { $$ = $1; }
    ;

enum_value
    : valid_identifier
      {
          $$ = new EnumValue($1 /* name */, nullptr /* value */, convertYYLoc(@$, ast));
      }
    | valid_identifier '=' const_expr
      {
          $$ = new EnumValue($1 /* name */, $3 /* value */, convertYYLoc(@$, ast));
      }
    ;

enum_values
    : /* empty */
      { /* do nothing */ }
    | commentable_enum_value
      {
          CHECK((*scope)->isEnum());
          static_cast<EnumType *>(*scope)->addValue($1);
      }
    | enum_values ',' commentable_enum_value
      {
          CHECK((*scope)->isEnum());
          static_cast<EnumType *>(*scope)->addValue($3);
      }
    | error ',' commentable_enum_value
      {
          ast->addSyntaxError();

          CHECK((*scope)->isEnum());
          static_cast<EnumType *>(*scope)->addValue($3);
      }
    | enum_values ',' error ',' commentable_enum_value
      {
          ast->addSyntaxError();

          CHECK((*scope)->isEnum());
          static_cast<EnumType *>(*scope)->addValue($5);
      }
    ;

array_type_base
    : fqtype { $$ = $1; }
    | TEMPLATED '<' type '>'
      {
          $1->setElementType(*$3);
          $$ = new Reference<Type>($1->definedName(), $1, convertYYLoc(@1, ast));
      }
    | TEMPLATED '<' TEMPLATED '<' type RSHIFT
      {
          $3->setElementType(*$5);
          $1->setElementType(Reference<Type>($3->definedName(), $3, convertYYLoc(@3, ast)));
          $$ = new Reference<Type>($1->definedName(), $1, convertYYLoc(@1, ast));
      }
    ;

array_type
    : array_type_base ignore_doc_comments '[' const_expr ']'
      {
          $$ = new ArrayType(*$1, $4, *scope);
      }
    | array_type '[' const_expr ']'
      {
          $$ = $1;
          $$->appendDimension($3);
      }
    ;

type
    : array_type_base ignore_doc_comments { $$ = $1; }
    | array_type ignore_doc_comments
      {
        $$ = new Reference<Type>($1->definedName(), $1, convertYYLoc(@1, ast));
      }
    | INTERFACE ignore_doc_comments
      {
        // "interface" is a synonym of android.hidl.base@1.0::IBase
        $$ = new Reference<Type>("interface", gIBaseFqName, convertYYLoc(@1, ast));
      }
    ;

type_or_inplace_compound_declaration
    : type { $$ = $1; }
    | annotated_compound_declaration ignore_doc_comments
      {
          $$ = new Reference<Type>($1->definedName(), $1, convertYYLoc(@1, ast), true);
      }
    ;

%%

void yy::parser::error(
        const yy::parser::location_type &where,
        const std::string &errstr) {
    std::cerr << "ERROR: " << errstr << " at " << where << "\n";
}
