1 #ifndef AIDL_AIDL_LANGUAGE_H_
2 #define AIDL_AIDL_LANGUAGE_H_
3 
4 #include <memory>
5 #include <string>
6 #include <vector>
7 
8 #include <android-base/macros.h>
9 #include <android-base/strings.h>
10 
11 #include <io_delegate.h>
12 
13 struct yy_buffer_state;
14 typedef yy_buffer_state* YY_BUFFER_STATE;
15 
16 class AidlToken {
17  public:
18   AidlToken(const std::string& text, const std::string& comments);
19 
GetText()20   const std::string& GetText() const { return text_; }
GetComments()21   const std::string& GetComments() const { return comments_; }
22 
23  private:
24   std::string text_;
25   std::string comments_;
26 
27   DISALLOW_COPY_AND_ASSIGN(AidlToken);
28 };
29 
30 class AidlNode {
31  public:
32   AidlNode() = default;
33   virtual ~AidlNode() = default;
34 
35  private:
36   DISALLOW_COPY_AND_ASSIGN(AidlNode);
37 };
38 
39 namespace android {
40 namespace aidl {
41 
42 class ValidatableType;
43 
44 }  // namespace aidl
45 }  // namespace android
46 
47 class AidlAnnotatable : public AidlNode {
48  public:
49   enum Annotation : uint32_t {
50     AnnotationNone = 0,
51     AnnotationNullable = 1 << 0,
52     AnnotationUtf8 = 1 << 1,
53     AnnotationUtf8InCpp = 1 << 2,
54   };
55 
56   AidlAnnotatable() = default;
57   virtual ~AidlAnnotatable() = default;
58 
Annotate(AidlAnnotatable::Annotation annotation)59   void Annotate(AidlAnnotatable::Annotation annotation) {
60     annotations_ =
61         static_cast<AidlAnnotatable::Annotation>(annotations_ | annotation);
62   }
IsNullable()63   bool IsNullable() const {
64     return annotations_ & AnnotationNullable;
65   }
IsUtf8()66   bool IsUtf8() const {
67     return annotations_ & AnnotationUtf8;
68   }
IsUtf8InCpp()69   bool IsUtf8InCpp() const {
70     return annotations_ & AnnotationUtf8InCpp;
71   }
72 
73  private:
74   Annotation annotations_ = AnnotationNone;
75 
76   DISALLOW_COPY_AND_ASSIGN(AidlAnnotatable);
77 };
78 
79 class AidlType : public AidlAnnotatable {
80  public:
81   AidlType(const std::string& name, unsigned line,
82            const std::string& comments, bool is_array);
83   virtual ~AidlType() = default;
84 
GetName()85   const std::string& GetName() const { return name_; }
GetLine()86   unsigned GetLine() const { return line_; }
IsArray()87   bool IsArray() const { return is_array_; }
GetComments()88   const std::string& GetComments() const { return comments_; }
89 
90   std::string ToString() const;
91 
SetLanguageType(const android::aidl::ValidatableType * language_type)92   void SetLanguageType(const android::aidl::ValidatableType* language_type) {
93     language_type_ = language_type;
94   }
95 
96   template<typename T>
GetLanguageType()97   const T* GetLanguageType() const {
98     return reinterpret_cast<const T*>(language_type_);
99   }
100 
101  private:
102   std::string name_;
103   unsigned line_;
104   bool is_array_;
105   std::string comments_;
106   const android::aidl::ValidatableType* language_type_ = nullptr;
107 
108   DISALLOW_COPY_AND_ASSIGN(AidlType);
109 };
110 
111 class AidlArgument : public AidlNode {
112  public:
113   enum Direction { IN_DIR = 1, OUT_DIR = 2, INOUT_DIR = 3 };
114 
115   AidlArgument(AidlArgument::Direction direction, AidlType* type,
116                std::string name, unsigned line);
117   AidlArgument(AidlType* type, std::string name, unsigned line);
118   virtual ~AidlArgument() = default;
119 
GetDirection()120   Direction GetDirection() const { return direction_; }
IsOut()121   bool IsOut() const { return direction_ & OUT_DIR; }
IsIn()122   bool IsIn() const { return direction_ & IN_DIR; }
DirectionWasSpecified()123   bool DirectionWasSpecified() const { return direction_specified_; }
124 
GetName()125   std::string GetName() const { return name_; }
GetLine()126   int GetLine() const { return line_; }
GetType()127   const AidlType& GetType() const { return *type_; }
GetMutableType()128   AidlType* GetMutableType() { return type_.get(); }
129 
130   std::string ToString() const;
131 
132  private:
133   std::unique_ptr<AidlType> type_;
134   Direction direction_;
135   bool direction_specified_;
136   std::string name_;
137   unsigned line_;
138 
139   DISALLOW_COPY_AND_ASSIGN(AidlArgument);
140 };
141 
142 class AidlMethod;
143 class AidlIntConstant;
144 class AidlStringConstant;
145 class AidlMember : public AidlNode {
146  public:
147   AidlMember() = default;
148   virtual ~AidlMember() = default;
149 
AsMethod()150   virtual AidlMethod* AsMethod() { return nullptr; }
AsIntConstant()151   virtual AidlIntConstant* AsIntConstant() { return nullptr; }
AsStringConstant()152   virtual AidlStringConstant* AsStringConstant() { return nullptr; }
153 
154  private:
155   DISALLOW_COPY_AND_ASSIGN(AidlMember);
156 };
157 
158 class AidlIntConstant : public AidlMember {
159  public:
160   AidlIntConstant(std::string name, int32_t value);
161   AidlIntConstant(std::string name, std::string value, unsigned line_number);
162   virtual ~AidlIntConstant() = default;
163 
GetName()164   const std::string& GetName() const { return name_; }
GetValue()165   int GetValue() const { return value_; }
IsValid()166   bool IsValid() const { return is_valid_; }
167 
AsIntConstant()168   AidlIntConstant* AsIntConstant() override { return this; }
169 
170  private:
171   std::string name_;
172   int32_t value_;
173   bool is_valid_;
174 
175   DISALLOW_COPY_AND_ASSIGN(AidlIntConstant);
176 };
177 
178 class AidlStringConstant : public AidlMember {
179  public:
180   AidlStringConstant(std::string name, std::string value, unsigned line_number);
181   virtual ~AidlStringConstant() = default;
182 
GetName()183   const std::string& GetName() const { return name_; }
GetValue()184   const std::string& GetValue() const { return value_; }
IsValid()185   bool IsValid() const { return is_valid_; }
186 
AsStringConstant()187   AidlStringConstant* AsStringConstant() override { return this; }
188 
189  private:
190   std::string name_;
191   std::string value_;
192   bool is_valid_;
193 
194   DISALLOW_COPY_AND_ASSIGN(AidlStringConstant);
195 };
196 
197 class AidlMethod : public AidlMember {
198  public:
199   AidlMethod(bool oneway, AidlType* type, std::string name,
200              std::vector<std::unique_ptr<AidlArgument>>* args,
201              unsigned line, const std::string& comments);
202   AidlMethod(bool oneway, AidlType* type, std::string name,
203              std::vector<std::unique_ptr<AidlArgument>>* args,
204              unsigned line, const std::string& comments, int id);
205   virtual ~AidlMethod() = default;
206 
AsMethod()207   AidlMethod* AsMethod() override { return this; }
208 
GetComments()209   const std::string& GetComments() const { return comments_; }
GetType()210   const AidlType& GetType() const { return *type_; }
GetMutableType()211   AidlType* GetMutableType() { return type_.get(); }
IsOneway()212   bool IsOneway() const { return oneway_; }
GetName()213   const std::string& GetName() const { return name_; }
GetLine()214   unsigned GetLine() const { return line_; }
HasId()215   bool HasId() const { return has_id_; }
GetId()216   int GetId() { return id_; }
SetId(unsigned id)217   void SetId(unsigned id) { id_ = id; }
218 
GetArguments()219   const std::vector<std::unique_ptr<AidlArgument>>& GetArguments() const {
220     return arguments_;
221   }
222   // An inout parameter will appear in both GetInArguments()
223   // and GetOutArguments().  AidlMethod retains ownership of the argument
224   // pointers returned in this way.
GetInArguments()225   const std::vector<const AidlArgument*>& GetInArguments() const {
226     return in_arguments_;
227   }
GetOutArguments()228   const std::vector<const AidlArgument*>& GetOutArguments() const {
229     return out_arguments_;
230   }
231 
232  private:
233   bool oneway_;
234   std::string comments_;
235   std::unique_ptr<AidlType> type_;
236   std::string name_;
237   unsigned line_;
238   const std::vector<std::unique_ptr<AidlArgument>> arguments_;
239   std::vector<const AidlArgument*> in_arguments_;
240   std::vector<const AidlArgument*> out_arguments_;
241   bool has_id_;
242   int id_;
243 
244   DISALLOW_COPY_AND_ASSIGN(AidlMethod);
245 };
246 
247 class AidlParcelable;
248 class AidlInterface;
249 class AidlDocument : public AidlNode {
250  public:
251   AidlDocument() = default;
252   explicit AidlDocument(AidlInterface* interface);
253   virtual ~AidlDocument() = default;
254 
GetInterface()255   const AidlInterface* GetInterface() const { return interface_.get(); }
ReleaseInterface()256   AidlInterface* ReleaseInterface() { return interface_.release(); }
257 
GetParcelables()258   const std::vector<std::unique_ptr<AidlParcelable>>& GetParcelables() const {
259     return parcelables_;
260   }
261 
AddParcelable(AidlParcelable * parcelable)262   void AddParcelable(AidlParcelable* parcelable) {
263     parcelables_.push_back(std::unique_ptr<AidlParcelable>(parcelable));
264   }
265 
266  private:
267   std::vector<std::unique_ptr<AidlParcelable>> parcelables_;
268   std::unique_ptr<AidlInterface> interface_;
269 
270   DISALLOW_COPY_AND_ASSIGN(AidlDocument);
271 };
272 
273 class AidlQualifiedName : public AidlNode {
274  public:
275   AidlQualifiedName(std::string term, std::string comments);
276   virtual ~AidlQualifiedName() = default;
277 
GetTerms()278   const std::vector<std::string>& GetTerms() const { return terms_; }
GetComments()279   const std::string& GetComments() const { return comments_; }
GetDotName()280   std::string GetDotName() const { return android::base::Join(terms_, '.'); }
GetColonName()281   std::string GetColonName() const { return android::base::Join(terms_, "::"); }
282 
283   void AddTerm(const std::string& term);
284 
285  private:
286   std::vector<std::string> terms_;
287   std::string comments_;
288 
289   DISALLOW_COPY_AND_ASSIGN(AidlQualifiedName);
290 };
291 
292 class AidlParcelable : public AidlNode {
293  public:
294   AidlParcelable(AidlQualifiedName* name, unsigned line,
295                  const std::vector<std::string>& package,
296                  const std::string& cpp_header = "");
297   virtual ~AidlParcelable() = default;
298 
GetName()299   std::string GetName() const { return name_->GetDotName(); }
300   // C++ uses "::" instead of "." to refer to a inner class.
GetCppName()301   std::string GetCppName() const { return name_->GetColonName(); }
GetLine()302   unsigned GetLine() const { return line_; }
303   std::string GetPackage() const;
GetSplitPackage()304   const std::vector<std::string>& GetSplitPackage() const { return package_; }
GetCppHeader()305   std::string GetCppHeader() const { return cpp_header_; }
306   std::string GetCanonicalName() const;
307 
308  private:
309   std::unique_ptr<AidlQualifiedName> name_;
310   unsigned line_;
311   const std::vector<std::string> package_;
312   std::string cpp_header_;
313 
314   DISALLOW_COPY_AND_ASSIGN(AidlParcelable);
315 };
316 
317 class AidlInterface : public AidlAnnotatable {
318  public:
319   AidlInterface(const std::string& name, unsigned line,
320                 const std::string& comments, bool oneway_,
321                 std::vector<std::unique_ptr<AidlMember>>* members,
322                 const std::vector<std::string>& package);
323   virtual ~AidlInterface() = default;
324 
GetName()325   const std::string& GetName() const { return name_; }
GetLine()326   unsigned GetLine() const { return line_; }
GetComments()327   const std::string& GetComments() const { return comments_; }
IsOneway()328   bool IsOneway() const { return oneway_; }
GetMethods()329   const std::vector<std::unique_ptr<AidlMethod>>& GetMethods() const
330       { return methods_; }
GetIntConstants()331   const std::vector<std::unique_ptr<AidlIntConstant>>& GetIntConstants() const
332       { return int_constants_; }
333   const std::vector<std::unique_ptr<AidlStringConstant>>&
GetStringConstants()334       GetStringConstants() const { return string_constants_; }
335   std::string GetPackage() const;
336   std::string GetCanonicalName() const;
GetSplitPackage()337   const std::vector<std::string>& GetSplitPackage() const { return package_; }
338 
SetLanguageType(const android::aidl::ValidatableType * language_type)339   void SetLanguageType(const android::aidl::ValidatableType* language_type) {
340     language_type_ = language_type;
341   }
342 
343   template<typename T>
GetLanguageType()344   const T* GetLanguageType() const {
345     return reinterpret_cast<const T*>(language_type_);
346   }
347 
348  private:
349   std::string name_;
350   std::string comments_;
351   unsigned line_;
352   bool oneway_;
353   std::vector<std::unique_ptr<AidlMethod>> methods_;
354   std::vector<std::unique_ptr<AidlIntConstant>> int_constants_;
355   std::vector<std::unique_ptr<AidlStringConstant>> string_constants_;
356   std::vector<std::string> package_;
357 
358   const android::aidl::ValidatableType* language_type_ = nullptr;
359 
360   DISALLOW_COPY_AND_ASSIGN(AidlInterface);
361 };
362 
363 class AidlImport : public AidlNode {
364  public:
365   AidlImport(const std::string& from, const std::string& needed_class,
366              unsigned line);
367   virtual ~AidlImport() = default;
368 
GetFileFrom()369   const std::string& GetFileFrom() const { return from_; }
GetFilename()370   const std::string& GetFilename() const { return filename_; }
GetNeededClass()371   const std::string& GetNeededClass() const { return needed_class_; }
GetLine()372   unsigned GetLine() const { return line_; }
373 
SetFilename(const std::string & filename)374   void SetFilename(const std::string& filename) { filename_ = filename; }
375 
376  private:
377   std::string from_;
378   std::string filename_;
379   std::string needed_class_;
380   unsigned line_;
381 
382   DISALLOW_COPY_AND_ASSIGN(AidlImport);
383 };
384 
385 class Parser {
386  public:
387   explicit Parser(const android::aidl::IoDelegate& io_delegate);
388   ~Parser();
389 
390   // Parse contents of file |filename|.
391   bool ParseFile(const std::string& filename);
392 
393   void ReportError(const std::string& err, unsigned line);
394 
FoundNoErrors()395   bool FoundNoErrors() const { return error_ == 0; }
FileName()396   const std::string& FileName() const { return filename_; }
Scanner()397   void* Scanner() const { return scanner_; }
398 
SetDocument(AidlDocument * doc)399   void SetDocument(AidlDocument* doc) { document_.reset(doc); };
400 
401   void AddImport(AidlQualifiedName* name, unsigned line);
402 
403   std::vector<std::string> Package() const;
SetPackage(AidlQualifiedName * name)404   void SetPackage(AidlQualifiedName* name) { package_.reset(name); }
405 
GetDocument()406   AidlDocument* GetDocument() const { return document_.get(); }
ReleaseDocument()407   AidlDocument* ReleaseDocument() { return document_.release(); }
GetImports()408   const std::vector<std::unique_ptr<AidlImport>>& GetImports() {
409     return imports_;
410   }
411 
ReleaseImports(std::vector<std::unique_ptr<AidlImport>> * ret)412   void ReleaseImports(std::vector<std::unique_ptr<AidlImport>>* ret) {
413       *ret = std::move(imports_);
414       imports_.clear();
415   }
416 
417  private:
418   const android::aidl::IoDelegate& io_delegate_;
419   int error_ = 0;
420   std::string filename_;
421   std::unique_ptr<AidlQualifiedName> package_;
422   void* scanner_ = nullptr;
423   std::unique_ptr<AidlDocument> document_;
424   std::vector<std::unique_ptr<AidlImport>> imports_;
425   std::unique_ptr<std::string> raw_buffer_;
426   YY_BUFFER_STATE buffer_;
427 
428   DISALLOW_COPY_AND_ASSIGN(Parser);
429 };
430 
431 #endif // AIDL_AIDL_LANGUAGE_H_
432