123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862 |
- #include "aidl_language.h"
- #include "aidl_typenames.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <algorithm>
- #include <cassert>
- #include <iostream>
- #include <set>
- #include <sstream>
- #include <string>
- #include <utility>
- #include <android-base/parsedouble.h>
- #include <android-base/parseint.h>
- #include <android-base/strings.h>
- #include "aidl_language_y.h"
- #include "logging.h"
- #include "type_java.h"
- #include "type_namespace.h"
- #ifdef _WIN32
- int isatty(int fd)
- {
- return (fd == 0);
- }
- #endif
- using android::aidl::IoDelegate;
- using android::base::Join;
- using android::base::Split;
- using std::cerr;
- using std::endl;
- using std::pair;
- using std::set;
- using std::string;
- using std::unique_ptr;
- using std::vector;
- void yylex_init(void **);
- void yylex_destroy(void *);
- void yyset_in(FILE *f, void *);
- int yyparse(Parser*);
- YY_BUFFER_STATE yy_scan_buffer(char *, size_t, void *);
- void yy_delete_buffer(YY_BUFFER_STATE, void *);
- AidlToken::AidlToken(const std::string& text, const std::string& comments)
- : text_(text),
- comments_(comments) {}
- AidlLocation::AidlLocation(const std::string& file, Point begin, Point end)
- : file_(file), begin_(begin), end_(end) {}
- std::ostream& operator<<(std::ostream& os, const AidlLocation& l) {
- os << l.file_ << ":" << l.begin_.line << "." << l.begin_.column << "-";
- if (l.begin_.line != l.end_.line) {
- os << l.end_.line << ".";
- }
- os << l.end_.column;
- return os;
- }
- AidlNode::AidlNode(const AidlLocation& location) : location_(location) {}
- std::string AidlNode::PrintLocation() const {
- std::stringstream ss;
- ss << location_.file_ << ":" << location_.begin_.line;
- return ss.str();
- }
- AidlError::AidlError(bool fatal) : os_(std::cerr), fatal_(fatal) {
- os_ << "ERROR: ";
- }
- static const string kNullable("nullable");
- static const string kUtf8InCpp("utf8InCpp");
- static const string kUnsupportedAppUsage("UnsupportedAppUsage");
- static const string kSystemApi("SystemApi");
- static const string kStableParcelable("JavaOnlyStableParcelable");
- static const set<string> kAnnotationNames{kNullable, kUtf8InCpp, kUnsupportedAppUsage, kSystemApi,
- kStableParcelable};
- AidlAnnotation* AidlAnnotation::Parse(const AidlLocation& location, const string& name) {
- if (kAnnotationNames.find(name) == kAnnotationNames.end()) {
- std::ostringstream stream;
- stream << "'" << name << "' is not a recognized annotation. ";
- stream << "It must be one of:";
- for (const string& kv : kAnnotationNames) {
- stream << " " << kv;
- }
- stream << ".";
- AIDL_ERROR(location) << stream.str();
- return nullptr;
- }
- return new AidlAnnotation(location, name);
- }
- AidlAnnotation::AidlAnnotation(const AidlLocation& location, const string& name)
- : AidlNode(location), name_(name) {}
- static bool HasAnnotation(const vector<AidlAnnotation>& annotations, const string& name) {
- for (const auto& a : annotations) {
- if (a.GetName() == name) {
- return true;
- }
- }
- return false;
- }
- AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
- bool AidlAnnotatable::IsNullable() const {
- return HasAnnotation(annotations_, kNullable);
- }
- bool AidlAnnotatable::IsUtf8InCpp() const {
- return HasAnnotation(annotations_, kUtf8InCpp);
- }
- bool AidlAnnotatable::IsUnsupportedAppUsage() const {
- return HasAnnotation(annotations_, kUnsupportedAppUsage);
- }
- bool AidlAnnotatable::IsSystemApi() const {
- return HasAnnotation(annotations_, kSystemApi);
- }
- bool AidlAnnotatable::IsStableParcelable() const {
- return HasAnnotation(annotations_, kStableParcelable);
- }
- string AidlAnnotatable::ToString() const {
- vector<string> ret;
- for (const auto& a : annotations_) {
- ret.emplace_back(a.ToString());
- }
- std::sort(ret.begin(), ret.end());
- return Join(ret, " ");
- }
- AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
- bool is_array,
- vector<unique_ptr<AidlTypeSpecifier>>* type_params,
- const string& comments)
- : AidlAnnotatable(location),
- unresolved_name_(unresolved_name),
- is_array_(is_array),
- type_params_(type_params),
- comments_(comments) {}
- AidlTypeSpecifier AidlTypeSpecifier::ArrayBase() const {
- AIDL_FATAL_IF(!is_array_, this);
- AidlTypeSpecifier arrayBase = *this;
- arrayBase.is_array_ = false;
- return arrayBase;
- }
- string AidlTypeSpecifier::ToString() const {
- string ret = GetName();
- if (IsGeneric()) {
- vector<string> arg_names;
- for (const auto& ta : GetTypeParameters()) {
- arg_names.emplace_back(ta->ToString());
- }
- ret += "<" + Join(arg_names, ",") + ">";
- }
- if (IsArray()) {
- ret += "[]";
- }
- return ret;
- }
- string AidlTypeSpecifier::Signature() const {
- string ret = ToString();
- string annotations = AidlAnnotatable::ToString();
- if (annotations != "") {
- ret = annotations + " " + ret;
- }
- return ret;
- }
- bool AidlTypeSpecifier::Resolve(android::aidl::AidlTypenames& typenames) {
- assert(!IsResolved());
- pair<string, bool> result = typenames.ResolveTypename(unresolved_name_);
- if (result.second) {
- fully_qualified_name_ = result.first;
- }
- return result.second;
- }
- bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
- if (IsGeneric()) {
- const string& type_name = GetName();
- const int num = GetTypeParameters().size();
- if (type_name == "List") {
- if (num > 1) {
- AIDL_ERROR(this) << " List cannot have type parameters more than one, but got "
- << "'" << ToString() << "'";
- return false;
- }
- } else if (type_name == "Map") {
- if (num != 0 && num != 2) {
- AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
- << "'" << ToString() << "'";
- return false;
- }
- }
- }
- if (GetName() == "void") {
- if (IsArray() || IsNullable() || IsUtf8InCpp()) {
- AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
- return false;
- }
- }
- if (IsArray()) {
- const auto definedType = typenames.TryGetDefinedType(GetName());
- if (definedType != nullptr && definedType->AsInterface() != nullptr) {
- AIDL_ERROR(this) << "Binder type cannot be an array";
- return false;
- }
- }
- if (IsNullable()) {
- if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
- AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
- return false;
- }
- }
- return true;
- }
- std::string AidlConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
- const std::string& raw_value) {
- return raw_value;
- }
- AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
- AidlTypeSpecifier* type, const std::string& name)
- : AidlVariableDeclaration(location, type, name, nullptr /*default_value*/) {}
- AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
- AidlTypeSpecifier* type, const std::string& name,
- AidlConstantValue* default_value)
- : AidlNode(location), type_(type), name_(name), default_value_(default_value) {}
- bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
- bool valid = true;
- valid &= type_->CheckValid(typenames);
- if (default_value_ == nullptr) return valid;
- valid &= default_value_->CheckValid();
- if (!valid) return false;
- return !ValueString(AidlConstantValueDecorator).empty();
- }
- string AidlVariableDeclaration::ToString() const {
- string ret = type_->Signature() + " " + name_;
- if (default_value_ != nullptr) {
- ret += " = " + ValueString(AidlConstantValueDecorator);
- }
- return ret;
- }
- string AidlVariableDeclaration::Signature() const {
- return type_->Signature() + " " + name_;
- }
- std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
- if (default_value_ != nullptr) {
- return GetDefaultValue()->As(GetType(), decorator);
- } else {
- return "";
- }
- }
- AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
- AidlTypeSpecifier* type, const std::string& name)
- : AidlVariableDeclaration(location, type, name),
- direction_(direction),
- direction_specified_(true) {}
- AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
- const std::string& name)
- : AidlVariableDeclaration(location, type, name),
- direction_(AidlArgument::IN_DIR),
- direction_specified_(false) {}
- string AidlArgument::GetDirectionSpecifier() const {
- string ret;
- if (direction_specified_) {
- switch(direction_) {
- case AidlArgument::IN_DIR:
- ret += "in ";
- break;
- case AidlArgument::OUT_DIR:
- ret += "out ";
- break;
- case AidlArgument::INOUT_DIR:
- ret += "inout ";
- break;
- }
- }
- return ret;
- }
- string AidlArgument::ToString() const {
- return GetDirectionSpecifier() + AidlVariableDeclaration::ToString();
- }
- std::string AidlArgument::Signature() const {
- class AidlInterface;
- class AidlInterface;
- class AidlParcelable;
- class AidlStructuredParcelable;
- class AidlParcelable;
- class AidlStructuredParcelable;
- return GetDirectionSpecifier() + AidlVariableDeclaration::Signature();
- }
- AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
- AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
- const std::string& checked_value)
- : AidlNode(location), type_(type), value_(checked_value) {
- CHECK(!value_.empty() || type_ == Type::ERROR);
- CHECK(type_ != Type::ARRAY);
- }
- AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
- std::vector<std::unique_ptr<AidlConstantValue>>* values)
- : AidlNode(location), type_(type), values_(std::move(*values)) {}
- static bool isValidLiteralChar(char c) {
- return !(c <= 0x1f || // control characters are < 0x20
- c >= 0x7f || // DEL is 0x7f
- c == '\\'); // Disallow backslashes for future proofing.
- }
- AidlConstantValue* AidlConstantValue::Boolean(const AidlLocation& location, bool value) {
- return new AidlConstantValue(location, Type::BOOLEAN, value ? "true" : "false");
- }
- AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location, char value) {
- if (!isValidLiteralChar(value)) {
- AIDL_ERROR(location) << "Invalid character literal " << value;
- return new AidlConstantValue(location, Type::ERROR, "");
- }
- return new AidlConstantValue(location, Type::CHARACTER, std::string("'") + value + "'");
- }
- AidlConstantValue* AidlConstantValue::Floating(const AidlLocation& location,
- const std::string& value) {
- return new AidlConstantValue(location, Type::FLOATING, value);
- }
- AidlConstantValue* AidlConstantValue::Hex(const AidlLocation& location, const std::string& value) {
- return new AidlConstantValue(location, Type::HEXIDECIMAL, value);
- }
- AidlConstantValue* AidlConstantValue::Integral(const AidlLocation& location,
- const std::string& value) {
- return new AidlConstantValue(location, Type::INTEGRAL, value);
- }
- AidlConstantValue* AidlConstantValue::Array(
- const AidlLocation& location, std::vector<std::unique_ptr<AidlConstantValue>>* values) {
- return new AidlConstantValue(location, Type::ARRAY, values);
- }
- AidlConstantValue* AidlConstantValue::String(const AidlLocation& location,
- const std::string& value) {
- for (size_t i = 0; i < value.length(); ++i) {
- if (!isValidLiteralChar(value[i])) {
- AIDL_ERROR(location) << "Found invalid character at index " << i << " in string constant '"
- << value << "'";
- return new AidlConstantValue(location, Type::ERROR, "");
- }
- }
- return new AidlConstantValue(location, Type::STRING, value);
- }
- bool AidlConstantValue::CheckValid() const {
- // error always logged during creation
- return type_ != AidlConstantValue::Type::ERROR;
- }
- static string TrimIfSuffix(const string& str, const string& suffix) {
- if (str.size() > suffix.size() &&
- 0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix)) {
- return str.substr(0, str.size() - suffix.size());
- }
- return str;
- }
- string AidlConstantValue::As(const AidlTypeSpecifier& type,
- const ConstantValueDecorator& decorator) const {
- if (type.IsGeneric()) {
- AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
- return "";
- }
- const std::string& type_string = type.GetName();
- if ((type_ == Type::ARRAY) != type.IsArray()) {
- goto mismatch_error;
- }
- switch (type_) {
- case AidlConstantValue::Type::ARRAY: {
- vector<string> raw_values;
- raw_values.reserve(values_.size());
- bool success = true;
- for (const auto& value : values_) {
- const AidlTypeSpecifier& array_base = type.ArrayBase();
- const std::string raw_value = value->As(array_base, decorator);
- success &= !raw_value.empty();
- raw_values.push_back(decorator(array_base, raw_value));
- }
- if (!success) {
- AIDL_ERROR(this) << "Default value must be a literal array of " << type_string << ".";
- return "";
- }
- return decorator(type, "{" + Join(raw_values, ", ") + "}");
- }
- case AidlConstantValue::Type::BOOLEAN:
- if (type_string == "boolean") return decorator(type, value_);
- goto mismatch_error;
- case AidlConstantValue::Type::CHARACTER:
- if (type_string == "char") return decorator(type, value_);
- goto mismatch_error;
- case AidlConstantValue::Type::FLOATING: {
- bool is_float_literal = value_.back() == 'f';
- const std::string raw_value = TrimIfSuffix(value_, "f");
- if (type_string == "double") {
- double parsed_value;
- if (!android::base::ParseDouble(raw_value, &parsed_value)) goto parse_error;
- return decorator(type, std::to_string(parsed_value));
- }
- if (is_float_literal && type_string == "float") {
- float parsed_value;
- if (!android::base::ParseFloat(raw_value, &parsed_value)) goto parse_error;
- return decorator(type, std::to_string(parsed_value) + "f");
- }
- goto mismatch_error;
- }
- case AidlConstantValue::Type::HEXIDECIMAL:
- // For historical reasons, a hexidecimal int needs to have the specified bits interpreted
- // as the signed type, so the other types are made consistent with it.
- if (type_string == "byte") {
- uint8_t unsigned_value;
- if (!android::base::ParseUint<uint8_t>(value_, &unsigned_value)) goto parse_error;
- return decorator(type, std::to_string((int8_t)unsigned_value));
- }
- if (type_string == "int") {
- uint32_t unsigned_value;
- if (!android::base::ParseUint<uint32_t>(value_, &unsigned_value)) goto parse_error;
- return decorator(type, std::to_string((int32_t)unsigned_value));
- }
- if (type_string == "long") {
- uint64_t unsigned_value;
- if (!android::base::ParseUint<uint64_t>(value_, &unsigned_value)) goto parse_error;
- return decorator(type, std::to_string((int64_t)unsigned_value));
- }
- goto mismatch_error;
- case AidlConstantValue::Type::INTEGRAL:
- if (type_string == "byte") {
- if (!android::base::ParseInt<int8_t>(value_, nullptr)) goto parse_error;
- return decorator(type, value_);
- }
- if (type_string == "int") {
- if (!android::base::ParseInt<int32_t>(value_, nullptr)) goto parse_error;
- return decorator(type, value_);
- }
- if (type_string == "long") {
- if (!android::base::ParseInt<int64_t>(value_, nullptr)) goto parse_error;
- return decorator(type, value_);
- }
- goto mismatch_error;
- case AidlConstantValue::Type::STRING:
- if (type_string == "String") return decorator(type, value_);
- goto mismatch_error;
- default:
- AIDL_FATAL(this) << "Unrecognized constant value type";
- }
- mismatch_error:
- AIDL_ERROR(this) << "Expecting type " << type_string << " but constant is " << ToString(type_);
- return "";
- parse_error:
- AIDL_ERROR(this) << "Could not parse " << value_ << " as " << type_string;
- return "";
- }
- string AidlConstantValue::ToString(Type type) {
- switch (type) {
- case Type::ARRAY:
- return "a literal array";
- case Type::BOOLEAN:
- return "a literal boolean";
- case Type::CHARACTER:
- return "a literal char";
- case Type::FLOATING:
- return "a floating-point literal";
- case Type::HEXIDECIMAL:
- return "a hexidecimal literal";
- case Type::INTEGRAL:
- return "an integral literal";
- case Type::STRING:
- return "a literal string";
- case Type::ERROR:
- LOG(FATAL) << "aidl internal error: error type failed to halt program";
- return "";
- default:
- LOG(FATAL) << "aidl internal error: unknown constant type: " << static_cast<int>(type);
- return ""; // not reached
- }
- }
- AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
- AidlTypeSpecifier* type, const std::string& name,
- AidlConstantValue* value)
- : AidlMember(location), type_(type), name_(name), value_(value) {}
- bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
- bool valid = true;
- valid &= type_->CheckValid(typenames);
- valid &= value_->CheckValid();
- if (!valid) return false;
- const static set<string> kSupportedConstTypes = {"String", "int"};
- if (kSupportedConstTypes.find(type_->ToString()) == kSupportedConstTypes.end()) {
- AIDL_ERROR(this) << "Constant of type " << type_->ToString() << " is not supported.";
- return false;
- }
- return !ValueString(AidlConstantValueDecorator).empty();
- }
- string AidlConstantDeclaration::ToString() const {
- return "const " + type_->ToString() + " " + name_ + " = " +
- ValueString(AidlConstantValueDecorator);
- }
- string AidlConstantDeclaration::Signature() const {
- return type_->Signature() + " " + name_;
- }
- AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
- const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
- const std::string& comments)
- : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
- has_id_ = false;
- }
- AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
- const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
- const std::string& comments, int id, bool is_user_defined)
- : AidlMember(location),
- oneway_(oneway),
- comments_(comments),
- type_(type),
- name_(name),
- arguments_(std::move(*args)),
- id_(id),
- is_user_defined_(is_user_defined) {
- has_id_ = true;
- delete args;
- for (const unique_ptr<AidlArgument>& a : arguments_) {
- if (a->IsIn()) { in_arguments_.push_back(a.get()); }
- if (a->IsOut()) { out_arguments_.push_back(a.get()); }
- }
- }
- string AidlMethod::Signature() const {
- vector<string> arg_signatures;
- for (const auto& arg : GetArguments()) {
- arg_signatures.emplace_back(arg->GetType().ToString());
- }
- return GetName() + "(" + Join(arg_signatures, ", ") + ")";
- }
- string AidlMethod::ToString() const {
- vector<string> arg_strings;
- for (const auto& arg : GetArguments()) {
- arg_strings.emplace_back(arg->Signature());
- }
- string ret = (IsOneway() ? "oneway " : "") + GetType().Signature() + " " + GetName() + "(" +
- Join(arg_strings, ", ") + ")";
- if (HasId()) {
- ret += " = " + std::to_string(GetId());
- }
- return ret;
- }
- AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
- const std::string& comments,
- const std::vector<std::string>& package)
- : AidlAnnotatable(location), name_(name), comments_(comments), package_(package) {}
- std::string AidlDefinedType::GetPackage() const {
- return Join(package_, '.');
- }
- std::string AidlDefinedType::GetCanonicalName() const {
- if (package_.empty()) {
- return GetName();
- }
- return GetPackage() + "." + GetName();
- }
- AidlParcelable::AidlParcelable(const AidlLocation& location, AidlQualifiedName* name,
- const std::vector<std::string>& package, const std::string& comments,
- const std::string& cpp_header)
- : AidlDefinedType(location, name->GetDotName(), comments, package),
- name_(name),
- cpp_header_(cpp_header) {
- // Strip off quotation marks if we actually have a cpp header.
- if (cpp_header_.length() >= 2) {
- cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
- }
- }
- bool AidlParcelable::CheckValid(const AidlTypenames&) const {
- static const std::set<string> allowed{kStableParcelable};
- for (const auto& v : GetAnnotations()) {
- if (allowed.find(v.GetName()) == allowed.end()) {
- std::ostringstream stream;
- stream << "Unstructured parcelable can contain only";
- for (const string& kv : allowed) {
- stream << " " << kv;
- }
- stream << ".";
- AIDL_ERROR(this) << stream.str();
- return false;
- }
- }
- return true;
- }
- void AidlParcelable::Write(CodeWriter* writer) const {
- writer->Write("parcelable %s ;\n", GetName().c_str());
- }
- AidlStructuredParcelable::AidlStructuredParcelable(
- const AidlLocation& location, AidlQualifiedName* name, const std::vector<std::string>& package,
- const std::string& comments, std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables)
- : AidlParcelable(location, name, package, comments, "" /*cpp_header*/),
- variables_(std::move(*variables)) {}
- void AidlStructuredParcelable::Write(CodeWriter* writer) const {
- writer->Write("parcelable %s {\n", GetName().c_str());
- writer->Indent();
- for (const auto& field : GetFields()) {
- writer->Write("%s;\n", field->ToString().c_str());
- }
- writer->Dedent();
- writer->Write("}\n");
- }
- bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
- for (const auto& v : GetFields()) {
- if (!(v->CheckValid(typenames))) {
- return false;
- }
- }
- return true;
- }
- AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
- const std::string& comments, bool oneway,
- std::vector<std::unique_ptr<AidlMember>>* members,
- const std::vector<std::string>& package)
- : AidlDefinedType(location, name, comments, package) {
- for (auto& member : *members) {
- AidlMember* local = member.release();
- AidlMethod* method = local->AsMethod();
- AidlConstantDeclaration* constant = local->AsConstantDeclaration();
- CHECK(method == nullptr || constant == nullptr);
- if (method) {
- method->ApplyInterfaceOneway(oneway);
- methods_.emplace_back(method);
- } else if (constant) {
- constants_.emplace_back(constant);
- } else {
- AIDL_FATAL(this) << "Member is neither method nor constant!";
- }
- }
- delete members;
- }
- void AidlInterface::Write(CodeWriter* writer) const {
- writer->Write("interface %s {\n", GetName().c_str());
- writer->Indent();
- for (const auto& method : GetMethods()) {
- writer->Write("%s;\n", method->ToString().c_str());
- }
- for (const auto& constdecl : GetConstantDeclarations()) {
- writer->Write("%s;\n", constdecl->ToString().c_str());
- }
- writer->Dedent();
- writer->Write("}\n");
- }
- bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
- // Has to be a pointer due to deleting copy constructor. No idea why.
- map<string, const AidlMethod*> method_names;
- for (const auto& m : GetMethods()) {
- if (!m->GetType().CheckValid(typenames)) {
- return false;
- }
- if (m->IsOneway() && m->GetType().GetName() != "void") {
- AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot return a value";
- return false;
- }
- set<string> argument_names;
- for (const auto& arg : m->GetArguments()) {
- auto it = argument_names.find(arg->GetName());
- if (it != argument_names.end()) {
- AIDL_ERROR(m) << "method '" << m->GetName() << "' has duplicate argument name '"
- << arg->GetName() << "'";
- return false;
- }
- argument_names.insert(arg->GetName());
- if (!arg->GetType().CheckValid(typenames)) {
- return false;
- }
- if (m->IsOneway() && arg->IsOut()) {
- AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
- return false;
- }
- }
- auto it = method_names.find(m->GetName());
- // prevent duplicate methods
- if (it == method_names.end()) {
- method_names[m->GetName()] = m.get();
- } else {
- AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
- AIDL_ERROR(it->second) << "previously defined here.";
- return false;
- }
- static set<string> reserved_methods{"asBinder()", "getInterfaceVersion()",
- "getTransactionName(int)"};
- if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
- AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use." << endl;
- return false;
- }
- }
- bool success = true;
- set<string> constant_names;
- for (const std::unique_ptr<AidlConstantDeclaration>& constant : GetConstantDeclarations()) {
- if (constant_names.count(constant->GetName()) > 0) {
- LOG(ERROR) << "Found duplicate constant name '" << constant->GetName() << "'";
- success = false;
- }
- constant_names.insert(constant->GetName());
- success = success && constant->CheckValid(typenames);
- }
- return success;
- }
- AidlQualifiedName::AidlQualifiedName(const AidlLocation& location, const std::string& term,
- const std::string& comments)
- : AidlNode(location), terms_({term}), comments_(comments) {
- if (term.find('.') != string::npos) {
- terms_ = Split(term, ".");
- for (const auto& subterm : terms_) {
- if (subterm.empty()) {
- AIDL_FATAL(this) << "Malformed qualified identifier: '" << term << "'";
- }
- }
- }
- }
- void AidlQualifiedName::AddTerm(const std::string& term) {
- terms_.push_back(term);
- }
- AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
- : AidlNode(location), needed_class_(needed_class) {}
- std::unique_ptr<Parser> Parser::Parse(const std::string& filename,
- const android::aidl::IoDelegate& io_delegate,
- AidlTypenames& typenames) {
- // Make sure we can read the file first, before trashing previous state.
- unique_ptr<string> raw_buffer = io_delegate.GetFileContents(filename);
- if (raw_buffer == nullptr) {
- AIDL_ERROR(filename) << "Error while opening file for parsing";
- return nullptr;
- }
- // We're going to scan this buffer in place, and yacc demands we put two
- // nulls at the end.
- raw_buffer->append(2u, '\0');
- std::unique_ptr<Parser> parser(new Parser(filename, *raw_buffer, typenames));
- if (yy::parser(parser.get()).parse() != 0 || parser->HasError()) return nullptr;
- return parser;
- }
- std::vector<std::string> Parser::Package() const {
- if (!package_) {
- return {};
- }
- return package_->GetTerms();
- }
- void Parser::AddImport(AidlImport* import) {
- imports_.emplace_back(import);
- }
- bool Parser::Resolve() {
- bool success = true;
- for (AidlTypeSpecifier* typespec : unresolved_typespecs_) {
- if (!typespec->Resolve(typenames_)) {
- AIDL_ERROR(typespec) << "Failed to resolve '" << typespec->GetUnresolvedName() << "'";
- success = false;
- // don't stop to show more errors if any
- }
- }
- return success;
- }
- Parser::Parser(const std::string& filename, std::string& raw_buffer,
- android::aidl::AidlTypenames& typenames)
- : filename_(filename), typenames_(typenames) {
- yylex_init(&scanner_);
- buffer_ = yy_scan_buffer(&raw_buffer[0], raw_buffer.length(), scanner_);
- }
- Parser::~Parser() {
- yy_delete_buffer(buffer_, scanner_);
- yylex_destroy(scanner_);
- }
|