1/*
2 * Copyright (C) 2015, 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#include "type_java.h"
18
19#include <sys/types.h>
20
21#include <android-base/strings.h>
22
23#include "aidl_language.h"
24#include "logging.h"
25
26using std::string;
27using android::base::Split;
28using android::base::Join;
29using android::base::Trim;
30
31namespace android {
32namespace aidl {
33namespace java {
34
35Expression* NULL_VALUE;
36Expression* THIS_VALUE;
37Expression* SUPER_VALUE;
38Expression* TRUE_VALUE;
39Expression* FALSE_VALUE;
40
41// ================================================================
42
43Type::Type(const JavaTypeNamespace* types, const string& name, int kind,
44           bool canWriteToParcel, bool canBeOut)
45    : Type(types, "", name, kind, canWriteToParcel, canBeOut, "", -1) {}
46
47Type::Type(const JavaTypeNamespace* types, const string& package,
48           const string& name, int kind, bool canWriteToParcel,
49           bool canBeOut, const string& declFile, int declLine)
50    : ValidatableType(kind, package, name, declFile, declLine),
51      m_types(types),
52      m_javaType((package.empty()) ? name : package + "." + name),
53      m_canWriteToParcel(canWriteToParcel),
54      m_canBeOut(canBeOut) {
55}
56
57string Type::CreatorName() const { return ""; }
58
59string Type::InstantiableName() const { return JavaType(); }
60
61void Type::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
62                         int flags) const {
63  fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn", __FILE__,
64          __LINE__, m_javaType.c_str());
65  addTo->Add(new LiteralExpression("/* WriteToParcel error " + m_javaType +
66                                   " */"));
67}
68
69void Type::CreateFromParcel(StatementBlock* addTo, Variable* v,
70                            Variable* parcel, Variable**) const {
71  fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", __FILE__,
72          __LINE__, m_javaType.c_str());
73  addTo->Add(new LiteralExpression("/* CreateFromParcel error " +
74                                   m_javaType + " */"));
75}
76
77void Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
78                          Variable**) const {
79  fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", __FILE__,
80          __LINE__, m_javaType.c_str());
81  addTo->Add(new LiteralExpression("/* ReadFromParcel error " +
82                                   m_javaType + " */"));
83}
84
85Expression* Type::BuildWriteToParcelFlags(int flags) const {
86  if (flags == 0) {
87    return new LiteralExpression("0");
88  }
89  if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0) {
90    return new FieldVariable(m_types->ParcelableInterfaceType(),
91                             "PARCELABLE_WRITE_RETURN_VALUE");
92  }
93  return new LiteralExpression("0");
94}
95
96// ================================================================
97
98BasicType::BasicType(const JavaTypeNamespace* types, const string& name,
99                     const string& marshallParcel,
100                     const string& unmarshallParcel,
101                     const string& writeArrayParcel,
102                     const string& createArrayParcel,
103                     const string& readArrayParcel)
104    : Type(types, name, ValidatableType::KIND_BUILT_IN, true, false),
105      m_marshallParcel(marshallParcel),
106      m_unmarshallParcel(unmarshallParcel) {
107  m_array_type.reset(new BasicArrayType(types, name, writeArrayParcel,
108                                        createArrayParcel, readArrayParcel));
109}
110
111void BasicType::WriteToParcel(StatementBlock* addTo, Variable* v,
112                              Variable* parcel, int flags) const {
113  addTo->Add(new MethodCall(parcel, m_marshallParcel, 1, v));
114}
115
116void BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v,
117                                 Variable* parcel, Variable**) const {
118  addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallParcel)));
119}
120
121BasicArrayType::BasicArrayType(const JavaTypeNamespace* types,
122                               const string& name,
123                               const string& writeArrayParcel,
124                               const string& createArrayParcel,
125                               const string& readArrayParcel)
126    : Type(types, name, ValidatableType::KIND_BUILT_IN, true, true),
127      m_writeArrayParcel(writeArrayParcel),
128      m_createArrayParcel(createArrayParcel),
129      m_readArrayParcel(readArrayParcel) {}
130
131
132void BasicArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
133                                   Variable* parcel, int flags) const {
134  addTo->Add(new MethodCall(parcel, m_writeArrayParcel, 1, v));
135}
136
137void BasicArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
138                                      Variable* parcel, Variable**) const {
139  addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayParcel)));
140}
141
142void BasicArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
143                                    Variable* parcel, Variable**) const {
144  addTo->Add(new MethodCall(parcel, m_readArrayParcel, 1, v));
145}
146
147// ================================================================
148
149FileDescriptorType::FileDescriptorType(const JavaTypeNamespace* types)
150    : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN,
151           true, false) {
152    m_array_type.reset(new FileDescriptorArrayType(types));
153}
154
155void FileDescriptorType::WriteToParcel(StatementBlock* addTo, Variable* v,
156                                       Variable* parcel, int flags) const {
157  addTo->Add(new MethodCall(parcel, "writeRawFileDescriptor", 1, v));
158}
159
160void FileDescriptorType::CreateFromParcel(StatementBlock* addTo, Variable* v,
161                                          Variable* parcel, Variable**) const {
162  addTo->Add(new Assignment(v, new MethodCall(parcel, "readRawFileDescriptor")));
163}
164
165FileDescriptorArrayType::FileDescriptorArrayType(const JavaTypeNamespace* types)
166    : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN,
167           true, true) {}
168
169void FileDescriptorArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
170                                            Variable* parcel, int flags) const {
171  addTo->Add(new MethodCall(parcel, "writeRawFileDescriptorArray", 1, v));
172}
173
174void FileDescriptorArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
175                                               Variable* parcel, Variable**) const {
176  addTo->Add(new Assignment(v, new MethodCall(parcel, "createRawFileDescriptorArray")));
177}
178
179void FileDescriptorArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
180                                             Variable* parcel, Variable**) const {
181  addTo->Add(new MethodCall(parcel, "readRawFileDescriptorArray", 1, v));
182}
183
184// ================================================================
185
186BooleanType::BooleanType(const JavaTypeNamespace* types)
187    : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true, false) {
188    m_array_type.reset(new BooleanArrayType(types));
189}
190
191void BooleanType::WriteToParcel(StatementBlock* addTo, Variable* v,
192                                Variable* parcel, int flags) const {
193  addTo->Add(new MethodCall(
194      parcel, "writeInt", 1,
195      new Ternary(v, new LiteralExpression("1"), new LiteralExpression("0"))));
196}
197
198void BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v,
199                                   Variable* parcel, Variable**) const {
200  addTo->Add(
201      new Assignment(v, new Comparison(new LiteralExpression("0"), "!=",
202                                       new MethodCall(parcel, "readInt"))));
203}
204
205BooleanArrayType::BooleanArrayType(const JavaTypeNamespace* types)
206    : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true, true) {}
207
208void BooleanArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
209                                     Variable* parcel, int flags) const {
210  addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v));
211}
212
213void BooleanArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
214                                        Variable* parcel, Variable**) const {
215  addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
216}
217
218void BooleanArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
219                                      Variable* parcel, Variable**) const {
220  addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
221}
222
223// ================================================================
224
225CharType::CharType(const JavaTypeNamespace* types)
226    : Type(types, "char", ValidatableType::KIND_BUILT_IN, true, false) {
227    m_array_type.reset(new CharArrayType(types));
228}
229
230void CharType::WriteToParcel(StatementBlock* addTo, Variable* v,
231                             Variable* parcel, int flags) const {
232  addTo->Add(
233      new MethodCall(parcel, "writeInt", 1, new Cast(m_types->IntType(), v)));
234}
235
236void CharType::CreateFromParcel(StatementBlock* addTo, Variable* v,
237                                Variable* parcel, Variable**) const {
238  addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
239}
240
241CharArrayType::CharArrayType(const JavaTypeNamespace* types)
242    : Type(types, "char", ValidatableType::KIND_BUILT_IN, true, true) {}
243
244void CharArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
245                                  Variable* parcel, int flags) const {
246  addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v));
247}
248
249void CharArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
250                                     Variable* parcel, Variable**) const {
251  addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
252}
253
254void CharArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
255                                   Variable* parcel, Variable**) const {
256  addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
257}
258
259// ================================================================
260
261StringType::StringType(const JavaTypeNamespace* types,
262                       const std::string& package,
263                       const std::string& class_name)
264    : Type(types, package, class_name,
265           ValidatableType::KIND_BUILT_IN, true, false) {
266  m_array_type.reset(new StringArrayType(types));
267}
268
269string StringType::CreatorName() const {
270  return "android.os.Parcel.STRING_CREATOR";
271}
272
273void StringType::WriteToParcel(StatementBlock* addTo, Variable* v,
274                               Variable* parcel, int flags) const {
275  addTo->Add(new MethodCall(parcel, "writeString", 1, v));
276}
277
278void StringType::CreateFromParcel(StatementBlock* addTo, Variable* v,
279                                  Variable* parcel, Variable**) const {
280  addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
281}
282
283StringArrayType::StringArrayType(const JavaTypeNamespace* types)
284    : Type(types, "java.lang", "String", ValidatableType::KIND_BUILT_IN,
285           true, true) {}
286
287string StringArrayType::CreatorName() const {
288  return "android.os.Parcel.STRING_CREATOR";
289}
290
291void StringArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
292                                    Variable* parcel, int flags) const {
293  addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v));
294}
295
296void StringArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
297                                       Variable* parcel, Variable**) const {
298  addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
299}
300
301void StringArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
302                                     Variable* parcel, Variable**) const {
303  addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
304}
305
306// ================================================================
307
308CharSequenceType::CharSequenceType(const JavaTypeNamespace* types)
309    : Type(types, "java.lang", "CharSequence", ValidatableType::KIND_BUILT_IN,
310           true, false) {}
311
312string CharSequenceType::CreatorName() const {
313  return "android.os.Parcel.STRING_CREATOR";
314}
315
316void CharSequenceType::WriteToParcel(StatementBlock* addTo, Variable* v,
317                                     Variable* parcel, int flags) const {
318  // if (v != null) {
319  //     parcel.writeInt(1);
320  //     v.writeToParcel(parcel);
321  // } else {
322  //     parcel.writeInt(0);
323  // }
324  IfStatement* elsepart = new IfStatement();
325  elsepart->statements->Add(
326      new MethodCall(parcel, "writeInt", 1, new LiteralExpression("0")));
327  IfStatement* ifpart = new IfStatement;
328  ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
329  ifpart->elseif = elsepart;
330  ifpart->statements->Add(
331      new MethodCall(parcel, "writeInt", 1, new LiteralExpression("1")));
332  ifpart->statements->Add(new MethodCall(m_types->TextUtilsType(),
333                                         "writeToParcel", 3, v, parcel,
334                                         BuildWriteToParcelFlags(flags)));
335
336  addTo->Add(ifpart);
337}
338
339void CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
340                                        Variable* parcel, Variable**) const {
341  // if (0 != parcel.readInt()) {
342  //     v = TextUtils.createFromParcel(parcel)
343  // } else {
344  //     v = null;
345  // }
346  IfStatement* elsepart = new IfStatement();
347  elsepart->statements->Add(new Assignment(v, NULL_VALUE));
348
349  IfStatement* ifpart = new IfStatement();
350  ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
351                                      new MethodCall(parcel, "readInt"));
352  ifpart->elseif = elsepart;
353  ifpart->statements->Add(new Assignment(
354      v, new MethodCall(m_types->TextUtilsType(),
355                        "CHAR_SEQUENCE_CREATOR.createFromParcel", 1, parcel)));
356
357  addTo->Add(ifpart);
358}
359
360// ================================================================
361
362RemoteExceptionType::RemoteExceptionType(const JavaTypeNamespace* types)
363    : Type(types, "android.os", "RemoteException",
364           ValidatableType::KIND_BUILT_IN, false, false) {}
365
366void RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
367                                        Variable* parcel, int flags) const {
368  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
369}
370
371void RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v,
372                                           Variable* parcel, Variable**) const {
373  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
374}
375
376// ================================================================
377
378RuntimeExceptionType::RuntimeExceptionType(const JavaTypeNamespace* types)
379    : Type(types, "java.lang", "RuntimeException",
380           ValidatableType::KIND_BUILT_IN, false, false) {}
381
382void RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
383                                         Variable* parcel, int flags) const {
384  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
385}
386
387void RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v,
388                                            Variable* parcel,
389                                            Variable**) const {
390  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
391}
392
393// ================================================================
394
395IBinderType::IBinderType(const JavaTypeNamespace* types)
396    : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN,
397           true, false) {
398  m_array_type.reset(new IBinderArrayType(types));
399}
400
401void IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
402                                Variable* parcel, int flags) const {
403  addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v));
404}
405
406void IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
407                                   Variable* parcel, Variable**) const {
408  addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
409}
410
411IBinderArrayType::IBinderArrayType(const JavaTypeNamespace* types)
412    : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN,
413           true, true) {}
414
415void IBinderArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
416                                     Variable* parcel, int flags) const {
417  addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v));
418}
419
420void IBinderArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
421                                        Variable* parcel, Variable**) const {
422  addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
423}
424
425void IBinderArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
426                                      Variable* parcel, Variable**) const {
427  addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
428}
429
430// ================================================================
431
432IInterfaceType::IInterfaceType(const JavaTypeNamespace* types)
433    : Type(types, "android.os", "IInterface", ValidatableType::KIND_BUILT_IN,
434           false, false) {}
435
436void IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
437                                   Variable* parcel, int flags) const {
438  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
439}
440
441void IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
442                                      Variable* parcel, Variable**) const {
443  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
444}
445
446// ================================================================
447
448BinderType::BinderType(const JavaTypeNamespace* types)
449    : Type(types, "android.os", "Binder", ValidatableType::KIND_BUILT_IN,
450           false, false) {}
451
452void BinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
453                               Variable* parcel, int flags) const {
454  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
455}
456
457void BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
458                                  Variable* parcel, Variable**) const {
459  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
460}
461
462// ================================================================
463
464BinderProxyType::BinderProxyType(const JavaTypeNamespace* types)
465    : Type(types, "android.os", "BinderProxy", ValidatableType::KIND_BUILT_IN,
466           false, false) {}
467
468void BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v,
469                                    Variable* parcel, int flags) const {
470  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
471}
472
473void BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
474                                       Variable* parcel, Variable**) const {
475  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
476}
477
478// ================================================================
479
480ParcelType::ParcelType(const JavaTypeNamespace* types)
481    : Type(types, "android.os", "Parcel", ValidatableType::KIND_BUILT_IN,
482           false, false) {}
483
484void ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v,
485                               Variable* parcel, int flags) const {
486  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
487}
488
489void ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v,
490                                  Variable* parcel, Variable**) const {
491  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
492}
493
494// ================================================================
495
496ParcelableInterfaceType::ParcelableInterfaceType(const JavaTypeNamespace* types)
497    : Type(types, "android.os", "Parcelable", ValidatableType::KIND_BUILT_IN,
498           false, false) {}
499
500void ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
501                                            Variable* parcel, int flags) const {
502  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
503}
504
505void ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo,
506                                               Variable* v, Variable* parcel,
507                                               Variable**) const {
508  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
509}
510
511// ================================================================
512
513MapType::MapType(const JavaTypeNamespace* types)
514    : Type(types, "java.util", "Map", ValidatableType::KIND_BUILT_IN,
515           true, true) {}
516
517void MapType::WriteToParcel(StatementBlock* addTo, Variable* v,
518                            Variable* parcel, int flags) const {
519  addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
520}
521
522static void EnsureClassLoader(StatementBlock* addTo, Variable** cl,
523                              const JavaTypeNamespace* types) {
524  // We don't want to look up the class loader once for every
525  // collection argument, so ensure we do it at most once per method.
526  if (*cl == NULL) {
527    *cl = new Variable(types->ClassLoaderType(), "cl");
528    addTo->Add(new VariableDeclaration(
529        *cl, new LiteralExpression("this.getClass().getClassLoader()"),
530        types->ClassLoaderType()));
531  }
532}
533
534void MapType::CreateFromParcel(StatementBlock* addTo, Variable* v,
535                               Variable* parcel, Variable** cl) const {
536  EnsureClassLoader(addTo, cl, m_types);
537  addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl)));
538}
539
540void MapType::ReadFromParcel(StatementBlock* addTo, Variable* v,
541                             Variable* parcel, Variable** cl) const {
542  EnsureClassLoader(addTo, cl, m_types);
543  addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
544}
545
546// ================================================================
547
548ListType::ListType(const JavaTypeNamespace* types)
549    : Type(types, "java.util", "List", ValidatableType::KIND_BUILT_IN,
550           true, true) {}
551
552string ListType::InstantiableName() const { return "java.util.ArrayList"; }
553
554void ListType::WriteToParcel(StatementBlock* addTo, Variable* v,
555                             Variable* parcel, int flags) const {
556  addTo->Add(new MethodCall(parcel, "writeList", 1, v));
557}
558
559void ListType::CreateFromParcel(StatementBlock* addTo, Variable* v,
560                                Variable* parcel, Variable** cl) const {
561  EnsureClassLoader(addTo, cl, m_types);
562  addTo->Add(
563      new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
564}
565
566void ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
567                              Variable* parcel, Variable** cl) const {
568  EnsureClassLoader(addTo, cl, m_types);
569  addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
570}
571
572// ================================================================
573
574UserDataType::UserDataType(const JavaTypeNamespace* types,
575                           const string& package, const string& name,
576                           bool builtIn, bool canWriteToParcel,
577                           const string& declFile, int declLine)
578    : Type(types, package, name,
579           builtIn ? ValidatableType::KIND_BUILT_IN
580                   : ValidatableType::KIND_PARCELABLE,
581           canWriteToParcel, true, declFile, declLine) {
582  m_array_type.reset(new UserDataArrayType(types, package, name, builtIn,
583                                           canWriteToParcel, declFile,
584                                           declLine));
585}
586
587string UserDataType::CreatorName() const {
588  return JavaType() + ".CREATOR";
589}
590
591void UserDataType::WriteToParcel(StatementBlock* addTo, Variable* v,
592                                 Variable* parcel, int flags) const {
593  // if (v != null) {
594  //     parcel.writeInt(1);
595  //     v.writeToParcel(parcel);
596  // } else {
597  //     parcel.writeInt(0);
598  // }
599  IfStatement* elsepart = new IfStatement();
600  elsepart->statements->Add(
601      new MethodCall(parcel, "writeInt", 1, new LiteralExpression("0")));
602  IfStatement* ifpart = new IfStatement;
603  ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
604  ifpart->elseif = elsepart;
605  ifpart->statements->Add(
606      new MethodCall(parcel, "writeInt", 1, new LiteralExpression("1")));
607  ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2, parcel,
608                                         BuildWriteToParcelFlags(flags)));
609
610  addTo->Add(ifpart);
611}
612
613void UserDataType::CreateFromParcel(StatementBlock* addTo, Variable* v,
614                                    Variable* parcel, Variable**) const {
615  // if (0 != parcel.readInt()) {
616  //     v = CLASS.CREATOR.createFromParcel(parcel)
617  // } else {
618  //     v = null;
619  // }
620  IfStatement* elsepart = new IfStatement();
621  elsepart->statements->Add(new Assignment(v, NULL_VALUE));
622
623  IfStatement* ifpart = new IfStatement();
624  ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
625                                      new MethodCall(parcel, "readInt"));
626  ifpart->elseif = elsepart;
627  ifpart->statements->Add(new Assignment(
628      v, new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel)));
629
630  addTo->Add(ifpart);
631}
632
633void UserDataType::ReadFromParcel(StatementBlock* addTo, Variable* v,
634                                  Variable* parcel, Variable**) const {
635  // TODO: really, we don't need to have this extra check, but we
636  // don't have two separate marshalling code paths
637  // if (0 != parcel.readInt()) {
638  //     v.readFromParcel(parcel)
639  // }
640  IfStatement* ifpart = new IfStatement();
641  ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
642                                      new MethodCall(parcel, "readInt"));
643  ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel));
644  addTo->Add(ifpart);
645}
646
647UserDataArrayType::UserDataArrayType(const JavaTypeNamespace* types,
648                           const string& package, const string& name,
649                           bool builtIn, bool canWriteToParcel,
650                           const string& declFile, int declLine)
651    : Type(types, package, name,
652           builtIn ? ValidatableType::KIND_BUILT_IN
653                   : ValidatableType::KIND_PARCELABLE,
654           canWriteToParcel, true, declFile, declLine) {}
655
656string UserDataArrayType::CreatorName() const {
657  return JavaType() + ".CREATOR";
658}
659
660void UserDataArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
661                                      Variable* parcel, int flags) const {
662  addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v,
663                            BuildWriteToParcelFlags(flags)));
664}
665
666void UserDataArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
667                                         Variable* parcel, Variable**) const {
668  string creator = v->type->JavaType() + ".CREATOR";
669  addTo->Add(new Assignment(v, new MethodCall(parcel, "createTypedArray", 1,
670                                              new LiteralExpression(creator))));
671}
672
673void UserDataArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
674                                       Variable* parcel, Variable**) const {
675  string creator = v->type->JavaType() + ".CREATOR";
676  addTo->Add(new MethodCall(parcel, "readTypedArray", 2, v,
677                            new LiteralExpression(creator)));
678}
679
680// ================================================================
681
682InterfaceType::InterfaceType(const JavaTypeNamespace* types,
683                             const string& package, const string& name,
684                             bool builtIn, bool oneway, const string& declFile,
685                             int declLine, const Type* stub, const Type* proxy)
686    : Type(types, package, name, builtIn ? ValidatableType::KIND_BUILT_IN
687                                         : ValidatableType::KIND_INTERFACE,
688           true, false, declFile, declLine),
689      m_oneway(oneway),
690      stub_(stub),
691      proxy_(proxy) {}
692
693bool InterfaceType::OneWay() const { return m_oneway; }
694
695void InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
696                                  Variable* parcel, int flags) const {
697  // parcel.writeStrongBinder(v != null ? v.asBinder() : null);
698  addTo->Add(
699      new MethodCall(parcel, "writeStrongBinder", 1,
700                     new Ternary(new Comparison(v, "!=", NULL_VALUE),
701                                 new MethodCall(v, "asBinder"), NULL_VALUE)));
702}
703
704void InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
705                                     Variable* parcel, Variable**) const {
706  // v = Interface.asInterface(parcel.readStrongBinder());
707  addTo->Add(new Assignment(
708      v, new MethodCall(stub_, "asInterface", 1,
709                        new MethodCall(parcel, "readStrongBinder"))));
710}
711
712// ================================================================
713
714GenericListType::GenericListType(const JavaTypeNamespace* types,
715                                 const Type* contained_type)
716    : Type(types, "java.util", "List<" + contained_type->CanonicalName() + ">",
717           ValidatableType::KIND_BUILT_IN, true, true),
718      m_contained_type(contained_type),
719      m_creator(contained_type->CreatorName()) {}
720
721string GenericListType::CreatorName() const {
722  return "android.os.Parcel.arrayListCreator";
723}
724
725string GenericListType::InstantiableName() const {
726  return "java.util.ArrayList<" + m_contained_type->JavaType() + ">";
727}
728
729void GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v,
730                                    Variable* parcel, int flags) const {
731  if (m_creator == m_types->StringType()->CreatorName()) {
732    addTo->Add(new MethodCall(parcel, "writeStringList", 1, v));
733  } else if (m_creator == m_types->IBinderType()->CreatorName()) {
734    addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v));
735  } else {
736    // parcel.writeTypedListXX(arg);
737    addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v));
738  }
739}
740
741void GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v,
742                                       Variable* parcel, Variable**) const {
743  if (m_creator == m_types->StringType()->CreatorName()) {
744    addTo->Add(
745        new Assignment(v, new MethodCall(parcel, "createStringArrayList", 0)));
746  } else if (m_creator == m_types->IBinderType()->CreatorName()) {
747    addTo->Add(
748        new Assignment(v, new MethodCall(parcel, "createBinderArrayList", 0)));
749  } else {
750    // v = _data.readTypedArrayList(XXX.creator);
751    addTo->Add(
752        new Assignment(v, new MethodCall(parcel, "createTypedArrayList", 1,
753                                         new LiteralExpression(m_creator))));
754  }
755}
756
757void GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
758                                     Variable* parcel, Variable**) const {
759  if (m_creator == m_types->StringType()->CreatorName()) {
760    addTo->Add(new MethodCall(parcel, "readStringList", 1, v));
761  } else if (m_creator == m_types->IBinderType()->CreatorName()) {
762    addTo->Add(new MethodCall(parcel, "readBinderList", 1, v));
763  } else {
764    // v = _data.readTypedList(v, XXX.creator);
765    addTo->Add(new MethodCall(parcel, "readTypedList", 2, v,
766                              new LiteralExpression(m_creator)));
767  }
768}
769
770// ================================================================
771
772ClassLoaderType::ClassLoaderType(const JavaTypeNamespace* types)
773    : Type(types, "java.lang", "ClassLoader", ValidatableType::KIND_BUILT_IN,
774           false, false) {}
775
776// ================================================================
777
778void JavaTypeNamespace::Init() {
779  Add(new BasicType(this, "void", "XXX", "XXX", "XXX", "XXX", "XXX"));
780
781  m_bool_type = new BooleanType(this);
782  Add(m_bool_type);
783
784  Add(new BasicType(this, "byte", "writeByte", "readByte", "writeByteArray",
785                    "createByteArray", "readByteArray"));
786
787  Add(new CharType(this));
788
789  m_int_type = new BasicType(this, "int", "writeInt", "readInt",
790                             "writeIntArray", "createIntArray", "readIntArray");
791  Add(m_int_type);
792
793  Add(new BasicType(this, "long", "writeLong", "readLong", "writeLongArray",
794                    "createLongArray", "readLongArray"));
795
796  Add(new BasicType(this, "float", "writeFloat", "readFloat", "writeFloatArray",
797                    "createFloatArray", "readFloatArray"));
798
799  Add(new BasicType(this, "double", "writeDouble", "readDouble",
800                    "writeDoubleArray", "createDoubleArray",
801                    "readDoubleArray"));
802
803  m_string_type = new class StringType(this, "java.lang", "String");
804  Add(m_string_type);
805  Add(new class StringType(this, ::android::aidl::kAidlReservedTypePackage,
806                           ::android::aidl::kUtf8InCppStringClass));
807
808  Add(new Type(this, "java.lang", "Object", ValidatableType::KIND_BUILT_IN,
809               false, false));
810
811  Add(new FileDescriptorType(this));
812
813  Add(new CharSequenceType(this));
814
815  Add(new MapType(this));
816
817  Add(new ListType(this));
818
819  m_text_utils_type =
820      new Type(this, "android.text", "TextUtils",
821               ValidatableType::KIND_BUILT_IN, false, false);
822  Add(m_text_utils_type);
823
824  m_remote_exception_type = new class RemoteExceptionType(this);
825  Add(m_remote_exception_type);
826
827  m_runtime_exception_type = new class RuntimeExceptionType(this);
828  Add(m_runtime_exception_type);
829
830  m_ibinder_type = new class IBinderType(this);
831  Add(m_ibinder_type);
832
833  m_iinterface_type = new class IInterfaceType(this);
834  Add(m_iinterface_type);
835
836  m_binder_native_type = new class BinderType(this);
837  Add(m_binder_native_type);
838
839  m_binder_proxy_type = new class BinderProxyType(this);
840  Add(m_binder_proxy_type);
841
842  m_parcel_type = new class ParcelType(this);
843  Add(m_parcel_type);
844
845  m_parcelable_interface_type = new class ParcelableInterfaceType(this);
846  Add(m_parcelable_interface_type);
847
848  m_context_type = new class Type(this, "android.content", "Context",
849                                  ValidatableType::KIND_BUILT_IN, false, false);
850  Add(m_context_type);
851
852  m_classloader_type = new class ClassLoaderType(this);
853  Add(m_classloader_type);
854
855  NULL_VALUE = new LiteralExpression("null");
856  THIS_VALUE = new LiteralExpression("this");
857  SUPER_VALUE = new LiteralExpression("super");
858  TRUE_VALUE = new LiteralExpression("true");
859  FALSE_VALUE = new LiteralExpression("false");
860}
861
862bool JavaTypeNamespace::AddParcelableType(const AidlParcelable& p,
863                                          const std::string& filename) {
864  Type* type =
865      new UserDataType(this, p.GetPackage(), p.GetName(), false,
866                       true, filename, p.GetLine());
867  return Add(type);
868}
869
870bool JavaTypeNamespace::AddBinderType(const AidlInterface& b,
871                                      const std::string& filename) {
872  // for interfaces, add the stub, proxy, and interface types.
873  Type* stub = new Type(this, b.GetPackage(),
874                        b.GetName() + ".Stub", ValidatableType::KIND_GENERATED,
875                        false, false, filename, b.GetLine());
876  Type* proxy = new Type(this, b.GetPackage(),
877                         b.GetName() + ".Stub.Proxy",
878                         ValidatableType::KIND_GENERATED,
879                         false, false, filename, b.GetLine());
880  Type* type =
881      new InterfaceType(this, b.GetPackage(), b.GetName(), false,
882                        b.IsOneway(), filename, b.GetLine(), stub, proxy);
883
884  bool success = true;
885  success &= Add(type);
886  success &= Add(stub);
887  success &= Add(proxy);
888  return success;
889}
890
891bool JavaTypeNamespace::AddListType(const std::string& contained_type_name) {
892  const Type* contained_type = FindTypeByCanonicalName(contained_type_name);
893  if (!contained_type) {
894    return false;
895  }
896  Add(new GenericListType(this, contained_type));
897  return true;
898}
899
900bool JavaTypeNamespace::AddMapType(const string& key_type_name,
901                                   const string& value_type_name) {
902  LOG(ERROR) << "Don't know how to create a Map<K,V> container.";
903  return false;
904}
905
906}  // namespace java
907}  // namespace aidl
908}  // namespace android
909