/*
 * Copyright (C) 2019, 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 "aidl_typenames.h"
#include "logging.h"

#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <limits>
#include <memory>

#include <android-base/parsedouble.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>

using android::base::ConsumeSuffix;
using android::base::EndsWith;
using android::base::Join;
using android::base::StartsWith;
using std::string;
using std::unique_ptr;
using std::vector;

template <typename T>
constexpr int CLZ(T x) {
  // __builtin_clz(0) is undefined
  if (x == 0) return sizeof(T) * 8;
  return (sizeof(T) == sizeof(uint64_t)) ? __builtin_clzl(x) : __builtin_clz(x);
}

template <typename T>
class OverflowGuard {
 public:
  OverflowGuard(T value) : mValue(value) {}
  bool Overflowed() const { return mOverflowed; }

  T operator+() { return +mValue; }
  T operator-() {
    if (isMin()) {
      mOverflowed = true;
      return 0;
    }
    return -mValue;
  }
  T operator!() { return !mValue; }
  T operator~() { return ~mValue; }

  T operator+(T o) {
    T out;
    mOverflowed = __builtin_add_overflow(mValue, o, &out);
    return out;
  }
  T operator-(T o) {
    T out;
    mOverflowed = __builtin_sub_overflow(mValue, o, &out);
    return out;
  }
  T operator*(T o) {
    T out;
#ifdef _WIN32
    // ___mulodi4 not on windows https://bugs.llvm.org/show_bug.cgi?id=46669
    // we should still get an error here from ubsan, but the nice error
    // is needed on linux for aidl_parser_fuzzer, where we are more
    // concerned about overflows elsewhere in the compiler in addition to
    // those in interfaces.
    out = mValue * o;
#else
    mOverflowed = __builtin_mul_overflow(mValue, o, &out);
#endif
    return out;
  }
  T operator/(T o) {
    if (o == 0 || (isMin() && o == -1)) {
      mOverflowed = true;
      return 0;
    }
    return mValue / o;
  }
  T operator%(T o) {
    if (o == 0 || (isMin() && o == -1)) {
      mOverflowed = true;
      return 0;
    }
    return mValue % o;
  }
  T operator|(T o) { return mValue | o; }
  T operator^(T o) { return mValue ^ o; }
  T operator&(T o) { return mValue & o; }
  T operator<(T o) { return mValue < o; }
  T operator>(T o) { return mValue > o; }
  T operator<=(T o) { return mValue <= o; }
  T operator>=(T o) { return mValue >= o; }
  T operator==(T o) { return mValue == o; }
  T operator!=(T o) { return mValue != o; }
  T operator>>(T o) {
    if (o < 0 || o >= static_cast<T>(sizeof(T) * 8) || mValue < 0) {
      mOverflowed = true;
      return 0;
    }
    return mValue >> o;
  }
  T operator<<(T o) {
    if (o < 0 || mValue < 0 || o > CLZ(mValue) || o >= static_cast<T>(sizeof(T) * 8)) {
      mOverflowed = true;
      return 0;
    }
    return mValue << o;
  }
  T operator||(T o) { return mValue || o; }
  T operator&&(T o) { return mValue && o; }

 private:
  bool isMin() { return mValue == std::numeric_limits<T>::min(); }

  T mValue;
  bool mOverflowed = false;
};

template <typename T>
bool processGuard(const OverflowGuard<T>& guard, const AidlConstantValue& context) {
  if (guard.Overflowed()) {
    AIDL_ERROR(context) << "Constant expression computation overflows.";
    return false;
  }
  return true;
}

// TODO: factor out all these macros
#define SHOULD_NOT_REACH() AIDL_FATAL(AIDL_LOCATION_HERE) << "Should not reach."
#define OPEQ(__y__) (string(op_) == string(__y__))
#define COMPUTE_UNARY(T, __op__)         \
  if (op == string(#__op__)) {           \
    OverflowGuard<T> guard(val);         \
    *out = __op__ guard;                 \
    return processGuard(guard, context); \
  }
#define COMPUTE_BINARY(T, __op__)        \
  if (op == string(#__op__)) {           \
    OverflowGuard<T> guard(lval);        \
    *out = guard __op__ rval;            \
    return processGuard(guard, context); \
  }
#define OP_IS_BIN_ARITHMETIC (OPEQ("+") || OPEQ("-") || OPEQ("*") || OPEQ("/") || OPEQ("%"))
#define OP_IS_BIN_BITFLIP (OPEQ("|") || OPEQ("^") || OPEQ("&"))
#define OP_IS_BIN_COMP \
  (OPEQ("<") || OPEQ(">") || OPEQ("<=") || OPEQ(">=") || OPEQ("==") || OPEQ("!="))
#define OP_IS_BIN_SHIFT (OPEQ(">>") || OPEQ("<<"))
#define OP_IS_BIN_LOGICAL (OPEQ("||") || OPEQ("&&"))

// NOLINT to suppress missing parentheses warnings about __def__.
#define SWITCH_KIND(__cond__, __action__, __def__) \
  switch (__cond__) {                              \
    case Type::BOOLEAN:                            \
      __action__(bool);                            \
    case Type::INT8:                               \
      __action__(int8_t);                          \
    case Type::INT32:                              \
      __action__(int32_t);                         \
    case Type::INT64:                              \
      __action__(int64_t);                         \
    default:                                       \
      __def__; /* NOLINT */                        \
  }

template <class T>
bool handleUnary(const AidlConstantValue& context, const string& op, T val, int64_t* out) {
  COMPUTE_UNARY(T, +)
  COMPUTE_UNARY(T, -)
  COMPUTE_UNARY(T, !)
  COMPUTE_UNARY(T, ~)
  AIDL_FATAL(context) << "Could not handleUnary for " << op << " " << val;
  return false;
}
template <>
bool handleUnary<bool>(const AidlConstantValue& context, const string& op, bool val, int64_t* out) {
  COMPUTE_UNARY(bool, +)
  COMPUTE_UNARY(bool, -)
  COMPUTE_UNARY(bool, !)

  if (op == "~") {
    AIDL_ERROR(context) << "Bitwise negation of a boolean expression is always true.";
    return false;
  }
  AIDL_FATAL(context) << "Could not handleUnary for " << op << " " << val;
  return false;
}

template <class T>
bool handleBinaryCommon(const AidlConstantValue& context, T lval, const string& op, T rval,
                        int64_t* out) {
  COMPUTE_BINARY(T, +)
  COMPUTE_BINARY(T, -)
  COMPUTE_BINARY(T, *)
  COMPUTE_BINARY(T, /)
  COMPUTE_BINARY(T, %)
  COMPUTE_BINARY(T, |)
  COMPUTE_BINARY(T, ^)
  COMPUTE_BINARY(T, &)
  // comparison operators: return 0 or 1 by nature.
  COMPUTE_BINARY(T, ==)
  COMPUTE_BINARY(T, !=)
  COMPUTE_BINARY(T, <)
  COMPUTE_BINARY(T, >)
  COMPUTE_BINARY(T, <=)
  COMPUTE_BINARY(T, >=)

  AIDL_FATAL(context) << "Could not handleBinaryCommon for " << lval << " " << op << " " << rval;
  return false;
}

template <class T>
bool handleShift(const AidlConstantValue& context, T lval, const string& op, T rval, int64_t* out) {
  // just cast rval to int64_t and it should fit.
  COMPUTE_BINARY(T, >>)
  COMPUTE_BINARY(T, <<)

  AIDL_FATAL(context) << "Could not handleShift for " << lval << " " << op << " " << rval;
  return false;
}

bool handleLogical(const AidlConstantValue& context, bool lval, const string& op, bool rval,
                   int64_t* out) {
  COMPUTE_BINARY(bool, ||);
  COMPUTE_BINARY(bool, &&);

  AIDL_FATAL(context) << "Could not handleLogical for " << lval << " " << op << " " << rval;
  return false;
}

bool ParseFloating(std::string_view sv, double* parsed) {
  // float literal should be parsed successfully.
  android::base::ConsumeSuffix(&sv, "f");
  return android::base::ParseDouble(std::string(sv).data(), parsed);
}

bool ParseFloating(std::string_view sv, float* parsed) {
  // we only care about float literal (with suffix "f").
  if (!android::base::ConsumeSuffix(&sv, "f")) {
    return false;
  }
  return android::base::ParseFloat(std::string(sv).data(), parsed);
}

bool AidlUnaryConstExpression::IsCompatibleType(Type type, const string& op) {
  // Verify the unary type here
  switch (type) {
    case Type::BOOLEAN:  // fall-through
    case Type::INT8:     // fall-through
    case Type::INT32:    // fall-through
    case Type::INT64:
      return true;
    case Type::FLOATING:
      return (op == "+" || op == "-");
    default:
      return false;
  }
}

bool AidlBinaryConstExpression::AreCompatibleTypes(Type t1, Type t2) {
  switch (t1) {
    case Type::STRING:
      if (t2 == Type::STRING) {
        return true;
      }
      break;
    case Type::BOOLEAN:  // fall-through
    case Type::INT8:     // fall-through
    case Type::INT32:    // fall-through
    case Type::INT64:
      switch (t2) {
        case Type::BOOLEAN:  // fall-through
        case Type::INT8:     // fall-through
        case Type::INT32:    // fall-through
        case Type::INT64:
          return true;
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }

  return false;
}

// Returns the promoted kind for both operands
AidlConstantValue::Type AidlBinaryConstExpression::UsualArithmeticConversion(Type left,
                                                                             Type right) {
  // These are handled as special cases
  AIDL_FATAL_IF(left == Type::STRING || right == Type::STRING, AIDL_LOCATION_HERE);
  AIDL_FATAL_IF(left == Type::FLOATING || right == Type::FLOATING, AIDL_LOCATION_HERE);

  // Kinds in concern: bool, (u)int[8|32|64]
  if (left == right) return left;  // easy case
  if (left == Type::BOOLEAN) return right;
  if (right == Type::BOOLEAN) return left;

  return left < right ? right : left;
}

// Returns the promoted integral type where INT32 is the smallest type
AidlConstantValue::Type AidlBinaryConstExpression::IntegralPromotion(Type in) {
  return (Type::INT32 < in) ? in : Type::INT32;
}

AidlConstantValue* AidlConstantValue::Default(const AidlTypeSpecifier& specifier) {
  AidlLocation location = specifier.GetLocation();

  // allocation of int[0] is a bit wasteful in Java
  if (specifier.IsArray()) {
    return nullptr;
  }

  const std::string name = specifier.GetName();
  if (name == "boolean") {
    return Boolean(location, false);
  }
  if (name == "char") {
    return Character(location, "'\\0'");  // literal to be used in backends
  }
  if (name == "byte" || name == "int" || name == "long") {
    return Integral(location, "0");
  }
  if (name == "float") {
    return Floating(location, "0.0f");
  }
  if (name == "double") {
    return Floating(location, "0.0");
  }
  return nullptr;
}

AidlConstantValue* AidlConstantValue::Boolean(const AidlLocation& location, bool value) {
  return new AidlConstantValue(location, Type::BOOLEAN, value ? "true" : "false");
}

AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location,
                                                const std::string& value) {
  return new AidlConstantValue(location, Type::CHARACTER, value);
}

AidlConstantValue* AidlConstantValue::Floating(const AidlLocation& location,
                                               const std::string& value) {
  return new AidlConstantValue(location, Type::FLOATING, value);
}

bool AidlConstantValue::IsHex(const string& value) {
  return StartsWith(value, "0x") || StartsWith(value, "0X");
}

bool AidlConstantValue::ParseIntegral(const string& value, int64_t* parsed_value,
                                      Type* parsed_type) {
  if (parsed_value == nullptr || parsed_type == nullptr) {
    return false;
  }

  const bool isLong = EndsWith(value, 'l') || EndsWith(value, 'L');
  const std::string value_substr = isLong ? value.substr(0, value.size() - 1) : value;

  if (IsHex(value)) {
    // AIDL considers 'const int foo = 0xffffffff' as -1, but if we want to
    // handle that when computing constant expressions, then we need to
    // represent 0xffffffff as a uint32_t. However, AIDL only has signed types;
    // so we parse as an unsigned int when possible and then cast to a signed
    // int. One example of this is in ICameraService.aidl where a constant int
    // is used for bit manipulations which ideally should be handled with an
    // unsigned int.
    //
    // Note, for historical consistency, we need to consider small hex values
    // as an integral type. Recognizing them as INT8 could break some files,
    // even though it would simplify this code.
    if (uint32_t rawValue32;
        !isLong && android::base::ParseUint<uint32_t>(value_substr, &rawValue32)) {
      *parsed_value = static_cast<int32_t>(rawValue32);
      *parsed_type = Type::INT32;
    } else if (uint64_t rawValue64; android::base::ParseUint<uint64_t>(value_substr, &rawValue64)) {
      *parsed_value = static_cast<int64_t>(rawValue64);
      *parsed_type = Type::INT64;
    } else {
      *parsed_value = 0;
      *parsed_type = Type::ERROR;
      return false;
    }
    return true;
  }

  if (!android::base::ParseInt<int64_t>(value_substr, parsed_value)) {
    *parsed_value = 0;
    *parsed_type = Type::ERROR;
    return false;
  }

  if (isLong) {
    *parsed_type = Type::INT64;
  } else {
    // guess literal type.
    if (*parsed_value <= INT8_MAX && *parsed_value >= INT8_MIN) {
      *parsed_type = Type::INT8;
    } else if (*parsed_value <= INT32_MAX && *parsed_value >= INT32_MIN) {
      *parsed_type = Type::INT32;
    } else {
      *parsed_type = Type::INT64;
    }
  }
  return true;
}

AidlConstantValue* AidlConstantValue::Integral(const AidlLocation& location, const string& value) {
  AIDL_FATAL_IF(value.empty(), location);

  Type parsed_type;
  int64_t parsed_value = 0;
  bool success = ParseIntegral(value, &parsed_value, &parsed_type);
  if (!success) {
    return nullptr;
  }

  return new AidlConstantValue(location, parsed_type, parsed_value, value);
}

AidlConstantValue* AidlConstantValue::Array(
    const AidlLocation& location, std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values) {
  AIDL_FATAL_IF(values == nullptr, location);
  std::vector<std::string> str_values;
  for (const auto& v : *values) {
    str_values.push_back(v->value_);
  }
  return new AidlConstantValue(location, Type::ARRAY, std::move(values), Join(str_values, ", "));
}

AidlConstantValue* AidlConstantValue::String(const AidlLocation& location, const string& value) {
  return new AidlConstantValue(location, Type::STRING, value);
}

string AidlConstantValue::ValueString(const AidlTypeSpecifier& type,
                                      const ConstantValueDecorator& decorator) const {
  if (type.IsGeneric()) {
    AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
    return "";
  }
  if (!is_evaluated_) {
    // TODO(b/142722772) CheckValid() should be called before ValueString()
    bool success = CheckValid();
    success &= evaluate();
    if (!success) {
      // the detailed error message shall be printed in evaluate
      return "";
    }
  }
  if (!is_valid_) {
    AIDL_ERROR(this) << "Invalid constant value: " + value_;
    return "";
  }

  const AidlDefinedType* defined_type = type.GetDefinedType();
  if (defined_type && !type.IsArray()) {
    const AidlEnumDeclaration* enum_type = defined_type->AsEnumDeclaration();
    if (!enum_type) {
      AIDL_ERROR(this) << "Invalid type (" << defined_type->GetCanonicalName()
                       << ") for a const value (" << value_ << ")";
      return "";
    }
    if (type_ != Type::REF) {
      AIDL_ERROR(this) << "Invalid value (" << value_ << ") for enum "
                       << enum_type->GetCanonicalName();
      return "";
    }
    return decorator(type, value_);
  }

  const string& type_string = type.GetName();
  int err = 0;

  switch (final_type_) {
    case Type::CHARACTER:
      if (type_string == "char") {
        return decorator(type, final_string_value_);
      }
      err = -1;
      break;
    case Type::STRING:
      if (type_string == "String") {
        return decorator(type, final_string_value_);
      }
      err = -1;
      break;
    case Type::BOOLEAN:  // fall-through
    case Type::INT8:     // fall-through
    case Type::INT32:    // fall-through
    case Type::INT64:
      if (type_string == "byte") {
        if (final_value_ > INT8_MAX || final_value_ < INT8_MIN) {
          err = -1;
          break;
        }
        return decorator(type, std::to_string(static_cast<int8_t>(final_value_)));
      } else if (type_string == "int") {
        if (final_value_ > INT32_MAX || final_value_ < INT32_MIN) {
          err = -1;
          break;
        }
        return decorator(type, std::to_string(static_cast<int32_t>(final_value_)));
      } else if (type_string == "long") {
        return decorator(type, std::to_string(final_value_));
      } else if (type_string == "boolean") {
        return decorator(type, final_value_ ? "true" : "false");
      }
      err = -1;
      break;
    case Type::ARRAY: {
      if (!type.IsArray()) {
        err = -1;
        break;
      }
      vector<string> value_strings;
      value_strings.reserve(values_.size());
      bool success = true;

      for (const auto& value : values_) {
        const AidlTypeSpecifier& array_base = type.ArrayBase();
        const string value_string = value->ValueString(array_base, decorator);
        if (value_string.empty()) {
          success = false;
          break;
        }
        value_strings.push_back(value_string);
      }
      if (!success) {
        err = -1;
        break;
      }

      return decorator(type, "{" + Join(value_strings, ", ") + "}");
    }
    case Type::FLOATING: {
      if (type_string == "double") {
        double parsed_value;
        if (!ParseFloating(value_, &parsed_value)) {
          AIDL_ERROR(this) << "Could not parse " << value_;
          err = -1;
          break;
        }
        return decorator(type, std::to_string(parsed_value));
      }
      if (type_string == "float") {
        float parsed_value;
        if (!ParseFloating(value_, &parsed_value)) {
          AIDL_ERROR(this) << "Could not parse " << value_;
          err = -1;
          break;
        }
        return decorator(type, std::to_string(parsed_value) + "f");
      }
      err = -1;
      break;
    }
    default:
      err = -1;
      break;
  }

  AIDL_FATAL_IF(err == 0, this);
  AIDL_ERROR(this) << "Invalid type specifier for " << ToString(final_type_) << ": " << type_string;
  return "";
}

bool AidlConstantValue::CheckValid() const {
  // Nothing needs to be checked here. The constant value will be validated in
  // the constructor or in the evaluate() function.
  if (is_evaluated_) return is_valid_;

  switch (type_) {
    case Type::BOOLEAN:    // fall-through
    case Type::INT8:       // fall-through
    case Type::INT32:      // fall-through
    case Type::INT64:      // fall-through
    case Type::CHARACTER:  // fall-through
    case Type::STRING:     // fall-through
    case Type::REF:        // fall-through
    case Type::FLOATING:   // fall-through
    case Type::UNARY:      // fall-through
    case Type::BINARY:
      is_valid_ = true;
      break;
    case Type::ARRAY:
      is_valid_ = true;
      for (const auto& v : values_) is_valid_ &= v->CheckValid();
      break;
    case Type::ERROR:
      return false;
    default:
      AIDL_FATAL(this) << "Unrecognized constant value type: " << ToString(type_);
      return false;
  }

  return true;
}

bool AidlConstantValue::evaluate() const {
  if (is_evaluated_) {
    return is_valid_;
  }
  int err = 0;
  is_evaluated_ = true;

  switch (type_) {
    case Type::ARRAY: {
      Type array_type = Type::ERROR;
      bool success = true;
      for (const auto& value : values_) {
        success = value->CheckValid();
        if (success) {
          success = value->evaluate();
          if (!success) {
            AIDL_ERROR(this) << "Invalid array element: " << value->value_;
            break;
          }
          if (array_type == Type::ERROR) {
            array_type = value->final_type_;
          } else if (!AidlBinaryConstExpression::AreCompatibleTypes(array_type,
                                                                    value->final_type_)) {
            AIDL_ERROR(this) << "Incompatible array element type: " << ToString(value->final_type_)
                             << ". Expecting type compatible with " << ToString(array_type);
            success = false;
            break;
          }
        } else {
          break;
        }
      }
      if (!success) {
        err = -1;
        break;
      }
      final_type_ = type_;
      break;
    }
    case Type::BOOLEAN:
      if ((value_ != "true") && (value_ != "false")) {
        AIDL_ERROR(this) << "Invalid constant boolean value: " << value_;
        err = -1;
        break;
      }
      final_value_ = (value_ == "true") ? 1 : 0;
      final_type_ = type_;
      break;
    case Type::INT8:   // fall-through
    case Type::INT32:  // fall-through
    case Type::INT64:
      // Parsing happens in the constructor
      final_type_ = type_;
      break;
    case Type::CHARACTER:  // fall-through
    case Type::STRING:
      final_string_value_ = value_;
      final_type_ = type_;
      break;
    case Type::FLOATING:
      // Just parse on the fly in ValueString
      final_type_ = type_;
      break;
    default:
      AIDL_FATAL(this) << "Unrecognized constant value type: " << ToString(type_);
      err = -1;
  }

  return (err == 0) ? true : false;
}

string AidlConstantValue::ToString(Type type) {
  switch (type) {
    case Type::BOOLEAN:
      return "a literal boolean";
    case Type::INT8:
      return "an int8 literal";
    case Type::INT32:
      return "an int32 literal";
    case Type::INT64:
      return "an int64 literal";
    case Type::ARRAY:
      return "a literal array";
    case Type::CHARACTER:
      return "a literal char";
    case Type::STRING:
      return "a literal string";
    case Type::REF:
      return "a reference";
    case Type::FLOATING:
      return "a literal float";
    case Type::UNARY:
      return "a unary expression";
    case Type::BINARY:
      return "a binary expression";
    case Type::ERROR:
      AIDL_FATAL(AIDL_LOCATION_HERE) << "aidl internal error: error type failed to halt program";
      return "";
    default:
      AIDL_FATAL(AIDL_LOCATION_HERE)
          << "aidl internal error: unknown constant type: " << static_cast<int>(type);
      return "";  // not reached
  }
}

AidlConstantReference::AidlConstantReference(const AidlLocation& location, const std::string& value)
    : AidlConstantValue(location, Type::REF, value) {
  const auto pos = value.find_last_of('.');
  if (pos == string::npos) {
    field_name_ = value;
  } else {
    ref_type_ = std::make_unique<AidlTypeSpecifier>(location, value.substr(0, pos), false, nullptr,
                                                    Comments{});
    field_name_ = value.substr(pos + 1);
  }
}

const AidlConstantValue* AidlConstantReference::Resolve(const AidlDefinedType* scope) const {
  if (resolved_) return resolved_;

  const AidlDefinedType* defined_type;
  if (ref_type_) {
    defined_type = ref_type_->GetDefinedType();
  } else {
    defined_type = scope;
  }

  if (!defined_type) {
    // This can happen when "const reference" is used in an unsupported way,
    // but missed in checks there. It works as a safety net.
    AIDL_ERROR(*this) << "Can't resolve the reference (" << value_ << ")";
    return nullptr;
  }

  if (auto enum_decl = defined_type->AsEnumDeclaration(); enum_decl) {
    for (const auto& e : enum_decl->GetEnumerators()) {
      if (e->GetName() == field_name_) {
        return resolved_ = e->GetValue();
      }
    }
  } else {
    for (const auto& c : defined_type->GetConstantDeclarations()) {
      if (c->GetName() == field_name_) {
        return resolved_ = &c->GetValue();
      }
    }
  }
  AIDL_ERROR(*this) << "Can't find " << field_name_ << " in " << defined_type->GetName();
  return nullptr;
}

bool AidlConstantReference::CheckValid() const {
  if (is_evaluated_) return is_valid_;
  AIDL_FATAL_IF(!resolved_, this) << "Should be resolved first: " << value_;
  is_valid_ = resolved_->CheckValid();
  return is_valid_;
}

bool AidlConstantReference::evaluate() const {
  if (is_evaluated_) return is_valid_;
  AIDL_FATAL_IF(!resolved_, this) << "Should be resolved first: " << value_;
  is_evaluated_ = true;

  resolved_->evaluate();
  is_valid_ = resolved_->is_valid_;
  final_type_ = resolved_->final_type_;
  if (is_valid_) {
    if (final_type_ == Type::STRING) {
      final_string_value_ = resolved_->final_string_value_;
    } else {
      final_value_ = resolved_->final_value_;
    }
  }
  return is_valid_;
}

bool AidlUnaryConstExpression::CheckValid() const {
  if (is_evaluated_) return is_valid_;
  AIDL_FATAL_IF(unary_ == nullptr, this);

  is_valid_ = unary_->CheckValid();
  if (!is_valid_) {
    final_type_ = Type::ERROR;
    return false;
  }

  return AidlConstantValue::CheckValid();
}

bool AidlUnaryConstExpression::evaluate() const {
  if (is_evaluated_) {
    return is_valid_;
  }
  is_evaluated_ = true;

  // Recursively evaluate the expression tree
  if (!unary_->is_evaluated_) {
    // TODO(b/142722772) CheckValid() should be called before ValueString()
    bool success = CheckValid();
    success &= unary_->evaluate();
    if (!success) {
      is_valid_ = false;
      return false;
    }
  }
  if (!IsCompatibleType(unary_->final_type_, op_)) {
    AIDL_ERROR(unary_) << "'" << op_ << "'"
                       << " is not compatible with " << ToString(unary_->final_type_)
                       << ": " + value_;
    is_valid_ = false;
    return false;
  }
  if (!unary_->is_valid_) {
    AIDL_ERROR(unary_) << "Invalid constant unary expression: " + value_;
    is_valid_ = false;
    return false;
  }
  final_type_ = unary_->final_type_;

  if (final_type_ == Type::FLOATING) {
    // don't do anything here. ValueString() will handle everything.
    is_valid_ = true;
    return true;
  }

#define CASE_UNARY(__type__) \
  return is_valid_ =         \
             handleUnary(*this, op_, static_cast<__type__>(unary_->final_value_), &final_value_);

  SWITCH_KIND(final_type_, CASE_UNARY, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
              is_valid_ = false; return false;)
}

bool AidlBinaryConstExpression::CheckValid() const {
  bool success = false;
  if (is_evaluated_) return is_valid_;
  AIDL_FATAL_IF(left_val_ == nullptr, this);
  AIDL_FATAL_IF(right_val_ == nullptr, this);

  success = left_val_->CheckValid();
  if (!success) {
    final_type_ = Type::ERROR;
    AIDL_ERROR(this) << "Invalid left operand in binary expression: " + value_;
  }

  success = right_val_->CheckValid();
  if (!success) {
    AIDL_ERROR(this) << "Invalid right operand in binary expression: " + value_;
    final_type_ = Type::ERROR;
  }

  if (final_type_ == Type::ERROR) {
    is_valid_ = false;
    return false;
  }

  is_valid_ = true;
  return AidlConstantValue::CheckValid();
}

bool AidlBinaryConstExpression::evaluate() const {
  if (is_evaluated_) {
    return is_valid_;
  }
  is_evaluated_ = true;
  AIDL_FATAL_IF(left_val_ == nullptr, this);
  AIDL_FATAL_IF(right_val_ == nullptr, this);

  // Recursively evaluate the binary expression tree
  if (!left_val_->is_evaluated_ || !right_val_->is_evaluated_) {
    // TODO(b/142722772) CheckValid() should be called before ValueString()
    bool success = CheckValid();
    success &= left_val_->evaluate();
    success &= right_val_->evaluate();
    if (!success) {
      is_valid_ = false;
      return false;
    }
  }
  if (!left_val_->is_valid_ || !right_val_->is_valid_) {
    is_valid_ = false;
    return false;
  }
  is_valid_ = AreCompatibleTypes(left_val_->final_type_, right_val_->final_type_);
  if (!is_valid_) {
    AIDL_ERROR(this) << "Cannot perform operation '" << op_ << "' on "
                     << ToString(right_val_->GetType()) << " and " << ToString(left_val_->GetType())
                     << ".";
    return false;
  }

  bool isArithmeticOrBitflip = OP_IS_BIN_ARITHMETIC || OP_IS_BIN_BITFLIP;

  // Handle String case first
  if (left_val_->final_type_ == Type::STRING) {
    AIDL_FATAL_IF(right_val_->final_type_ != Type::STRING, this);
    if (!OPEQ("+")) {
      AIDL_ERROR(this) << "Only '+' is supported for strings, not '" << op_ << "'.";
      final_type_ = Type::ERROR;
      is_valid_ = false;
      return false;
    }

    // Remove trailing " from lhs
    const string& lhs = left_val_->final_string_value_;
    if (lhs.back() != '"') {
      AIDL_ERROR(this) << "'" << lhs << "' is missing a trailing quote.";
      final_type_ = Type::ERROR;
      is_valid_ = false;
      return false;
    }
    const string& rhs = right_val_->final_string_value_;
    // Remove starting " from rhs
    if (rhs.front() != '"') {
      AIDL_ERROR(this) << "'" << rhs << "' is missing a leading quote.";
      final_type_ = Type::ERROR;
      is_valid_ = false;
      return false;
    }

    final_string_value_ = string(lhs.begin(), lhs.end() - 1).append(rhs.begin() + 1, rhs.end());
    final_type_ = Type::STRING;
    return true;
  }

  // CASE: + - *  / % | ^ & < > <= >= == !=
  if (isArithmeticOrBitflip || OP_IS_BIN_COMP) {
    // promoted kind for both operands.
    Type promoted = UsualArithmeticConversion(IntegralPromotion(left_val_->final_type_),
                                              IntegralPromotion(right_val_->final_type_));
    // result kind.
    final_type_ = isArithmeticOrBitflip
                      ? promoted        // arithmetic or bitflip operators generates promoted type
                      : Type::BOOLEAN;  // comparison operators generates bool

#define CASE_BINARY_COMMON(__type__)                                                        \
  return is_valid_ =                                                                        \
             handleBinaryCommon(*this, static_cast<__type__>(left_val_->final_value_), op_, \
                                static_cast<__type__>(right_val_->final_value_), &final_value_);

    SWITCH_KIND(promoted, CASE_BINARY_COMMON, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
                is_valid_ = false; return false;)
  }

  // CASE: << >>
  string newOp = op_;
  if (OP_IS_BIN_SHIFT) {
    // promoted kind for both operands.
    final_type_ = UsualArithmeticConversion(IntegralPromotion(left_val_->final_type_),
                                            IntegralPromotion(right_val_->final_type_));
    auto numBits = right_val_->final_value_;
    if (numBits < 0) {
      // shifting with negative number of bits is undefined in C. In AIDL it
      // is defined as shifting into the other direction.
      newOp = OPEQ("<<") ? ">>" : "<<";
      numBits = -numBits;
    }

#define CASE_SHIFT(__type__)                                                                   \
  return is_valid_ = handleShift(*this, static_cast<__type__>(left_val_->final_value_), newOp, \
                                 static_cast<__type__>(numBits), &final_value_);

    SWITCH_KIND(final_type_, CASE_SHIFT, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
                is_valid_ = false; return false;)
  }

  // CASE: && ||
  if (OP_IS_BIN_LOGICAL) {
    final_type_ = Type::BOOLEAN;
    // easy; everything is bool.
    return handleLogical(*this, left_val_->final_value_, op_, right_val_->final_value_,
                         &final_value_);
  }

  SHOULD_NOT_REACH();
  is_valid_ = false;
  return false;
}

// Constructor for integer(byte, int, long)
// Keep parsed integer & literal
AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type parsed_type,
                                     int64_t parsed_value, const string& checked_value)
    : AidlNode(location),
      type_(parsed_type),
      value_(checked_value),
      final_type_(parsed_type),
      final_value_(parsed_value) {
  AIDL_FATAL_IF(value_.empty() && type_ != Type::ERROR, location);
  AIDL_FATAL_IF(type_ != Type::INT8 && type_ != Type::INT32 && type_ != Type::INT64, location);
}

// Constructor for non-integer(String, char, boolean, float, double)
// Keep literal as it is. (e.g. String literal has double quotes at both ends)
AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
                                     const string& checked_value)
    : AidlNode(location),
      type_(type),
      value_(checked_value),
      final_type_(type) {
  AIDL_FATAL_IF(value_.empty() && type_ != Type::ERROR, location);
  switch (type_) {
    case Type::INT8:
    case Type::INT32:
    case Type::INT64:
    case Type::ARRAY:
      AIDL_FATAL(this) << "Invalid type: " << ToString(type_);
      break;
    default:
      break;
  }
}

// Constructor for array
AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
                                     std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values,
                                     const std::string& value)
    : AidlNode(location),
      type_(type),
      values_(std::move(*values)),
      value_(value),
      is_valid_(false),
      is_evaluated_(false),
      final_type_(type) {
  AIDL_FATAL_IF(type_ != Type::ARRAY, location);
}

AidlUnaryConstExpression::AidlUnaryConstExpression(const AidlLocation& location, const string& op,
                                                   std::unique_ptr<AidlConstantValue> rval)
    : AidlConstantValue(location, Type::UNARY, op + rval->value_),
      unary_(std::move(rval)),
      op_(op) {
  final_type_ = Type::UNARY;
}

AidlBinaryConstExpression::AidlBinaryConstExpression(const AidlLocation& location,
                                                     std::unique_ptr<AidlConstantValue> lval,
                                                     const string& op,
                                                     std::unique_ptr<AidlConstantValue> rval)
    : AidlConstantValue(location, Type::BINARY, lval->value_ + op + rval->value_),
      left_val_(std::move(lval)),
      right_val_(std::move(rval)),
      op_(op) {
  final_type_ = Type::BINARY;
}
