blob: e2dea08036f6768d9d39ee0d3db67b58fd75265f [file] [log] [blame]
Jiyong Parke5c45292020-05-26 19:06:24 +09001/*
2 * Copyright (C) 2019, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include "aidl_language.h"
20#include "aidl_typenames.h"
Jooyung Han8451a202021-01-16 03:07:06 +090021#include "comments.h"
Jiyong Parke5c45292020-05-26 19:06:24 +090022#include "io_delegate.h"
Steven Moreland21780812020-09-11 01:29:45 +000023#include "logging.h"
Jiyong Parke5c45292020-05-26 19:06:24 +090024#include "options.h"
25
26#include <memory>
27#include <string>
28#include <vector>
29
30struct yy_buffer_state;
31typedef yy_buffer_state* YY_BUFFER_STATE;
32
Jiyong Park187bcc92020-07-22 18:40:30 +090033class AidlToken {
34 public:
Jooyung Han8451a202021-01-16 03:07:06 +090035 AidlToken(const std::string& text, android::aidl::Comments comments)
36 : text_(text), comments_(std::move(comments)) {}
Jiyong Park187bcc92020-07-22 18:40:30 +090037 ~AidlToken() = default;
38
39 AidlToken(const AidlToken&) = delete;
40 AidlToken(AidlToken&&) = delete;
41 AidlToken& operator=(const AidlToken&) = delete;
42 AidlToken& operator=(AidlToken&&) = delete;
43
44 const std::string& GetText() const { return text_; }
Jooyung Han8451a202021-01-16 03:07:06 +090045 const android::aidl::Comments& GetComments() const { return comments_; }
Jiyong Park187bcc92020-07-22 18:40:30 +090046
Jooyung Han9bcf80e2020-10-05 16:25:34 +090047 template <typename T>
48 void Append(T&& text) {
49 text_ += std::forward<T>(text);
50 }
51
Jiyong Park187bcc92020-07-22 18:40:30 +090052 private:
53 std::string text_;
Jooyung Han8451a202021-01-16 03:07:06 +090054 android::aidl::Comments comments_;
Jiyong Park187bcc92020-07-22 18:40:30 +090055};
56
Jooyung Han29813842020-12-08 01:28:03 +090057using TypeResolver = std::function<bool(const AidlDocument*, AidlTypeSpecifier*)>;
58
Jiyong Parke5c45292020-05-26 19:06:24 +090059class Parser {
60 public:
61 // non-copyable, non-assignable
62 Parser(const Parser&) = delete;
63 Parser& operator=(const Parser&) = delete;
64
65 ~Parser();
66
67 // Parse contents of file |filename|. Should only be called once.
68 static std::unique_ptr<Parser> Parse(const std::string& filename,
69 const android::aidl::IoDelegate& io_delegate,
70 AidlTypenames& typenames);
71
72 void AddError() { error_++; }
Jiyong Park8e79b7f2020-07-20 20:52:38 +090073 bool HasError() const { return error_ != 0; }
Jiyong Parke5c45292020-05-26 19:06:24 +090074
75 const std::string& FileName() const { return filename_; }
76 void* Scanner() const { return scanner_; }
77
Steven Moreland6c07b832020-10-29 23:39:53 +000078 // This restricts the grammar to something more reasonable. One alternative
79 // would be to support multiple sets of type specifiers in our AST, but then a
80 // lot of later code would have to deal with this more complicated type. So,
81 // in order to keep the AST simpler, restricting the grammar here.
82 //
83 // Takes ownership of type_args, modifies type.
84 void SetTypeParameters(AidlTypeSpecifier* type,
85 std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args);
86
Jiyong Park18132182020-06-08 20:24:40 +090087 void SetPackage(const std::string& package) { package_ = package; }
88 const std::string& Package() const { return package_; }
Jiyong Parke5c45292020-05-26 19:06:24 +090089
90 void DeferResolution(AidlTypeSpecifier* typespec) {
91 unresolved_typespecs_.emplace_back(typespec);
92 }
93
94 const vector<AidlTypeSpecifier*>& GetUnresolvedTypespecs() const { return unresolved_typespecs_; }
95
Jooyung Han29813842020-12-08 01:28:03 +090096 bool Resolve(TypeResolver& type_resolver);
Jiyong Park62515512020-06-08 15:57:11 +090097 void SetDocument(std::unique_ptr<AidlDocument>&& document) {
Jiyong Park8e79b7f2020-07-20 20:52:38 +090098 // The parsed document is owned by typenames_. This parser object only has
99 // a reference to it.
100 document_ = document.get();
101 if (!typenames_.AddDocument(std::move(document))) {
102 document_ = nullptr;
103 AddError();
Jiyong Parke5c45292020-05-26 19:06:24 +0900104 }
105 }
106
Jiyong Park8e79b7f2020-07-20 20:52:38 +0900107 const AidlDocument& ParsedDocument() const {
Steven Moreland21780812020-09-11 01:29:45 +0000108 AIDL_FATAL_IF(HasError(), FileName());
Jiyong Park8e79b7f2020-07-20 20:52:38 +0900109 return *document_;
110 }
Jiyong Parke5c45292020-05-26 19:06:24 +0900111
112 private:
113 explicit Parser(const std::string& filename, std::string& raw_buffer,
114 android::aidl::AidlTypenames& typenames);
115
116 std::string filename_;
Jiyong Park18132182020-06-08 20:24:40 +0900117 std::string package_;
Jiyong Parke5c45292020-05-26 19:06:24 +0900118 AidlTypenames& typenames_;
119
120 void* scanner_ = nullptr;
121 YY_BUFFER_STATE buffer_;
122 int error_ = 0;
123
Jiyong Parke5c45292020-05-26 19:06:24 +0900124 vector<AidlTypeSpecifier*> unresolved_typespecs_;
Jiyong Park8e79b7f2020-07-20 20:52:38 +0900125 const AidlDocument* document_;
Jiyong Parke5c45292020-05-26 19:06:24 +0900126};