1#include "Type.h"
2
3#include <sys/types.h>
4
5Namespace NAMES;
6
7Type* VOID_TYPE;
8Type* BOOLEAN_TYPE;
9Type* BYTE_TYPE;
10Type* CHAR_TYPE;
11Type* INT_TYPE;
12Type* LONG_TYPE;
13Type* FLOAT_TYPE;
14Type* DOUBLE_TYPE;
15Type* STRING_TYPE;
16Type* OBJECT_TYPE;
17Type* CHAR_SEQUENCE_TYPE;
18Type* TEXT_UTILS_TYPE;
19Type* REMOTE_EXCEPTION_TYPE;
20Type* RUNTIME_EXCEPTION_TYPE;
21Type* IBINDER_TYPE;
22Type* IINTERFACE_TYPE;
23Type* BINDER_NATIVE_TYPE;
24Type* BINDER_PROXY_TYPE;
25Type* PARCEL_TYPE;
26Type* PARCELABLE_INTERFACE_TYPE;
27Type* CONTEXT_TYPE;
28Type* MAP_TYPE;
29Type* LIST_TYPE;
30Type* CLASSLOADER_TYPE;
31Type* RPC_DATA_TYPE;
32Type* RPC_ERROR_TYPE;
33Type* EVENT_FAKE_TYPE;
34
35Expression* NULL_VALUE;
36Expression* THIS_VALUE;
37Expression* SUPER_VALUE;
38Expression* TRUE_VALUE;
39Expression* FALSE_VALUE;
40
41void
42register_base_types()
43{
44    VOID_TYPE = new BasicType("void",
45            "XXX", "XXX", "XXX", "XXX", "XXX",
46            "XXX", "XXX", "XXX", "XXX", "XXX");
47    NAMES.Add(VOID_TYPE);
48
49    BOOLEAN_TYPE = new BooleanType();
50    NAMES.Add(BOOLEAN_TYPE);
51
52    BYTE_TYPE = new BasicType("byte",
53            "writeByte", "readByte", "writeByteArray", "createByteArray", "readByteArray",
54            "putByte", "getByte", "putByteArray", "createByteArray", "getByteArray");
55    NAMES.Add(BYTE_TYPE);
56
57    CHAR_TYPE = new CharType();
58    NAMES.Add(CHAR_TYPE);
59
60    INT_TYPE = new BasicType("int",
61            "writeInt", "readInt", "writeIntArray", "createIntArray", "readIntArray",
62            "putInteger", "getInteger", "putIntegerArray", "createIntegerArray", "getIntegerArray");
63    NAMES.Add(INT_TYPE);
64
65    LONG_TYPE = new BasicType("long",
66            "writeLong", "readLong", "writeLongArray", "createLongArray", "readLongArray",
67            "putLong", "getLong", "putLongArray", "createLongArray", "getLongArray");
68    NAMES.Add(LONG_TYPE);
69
70    FLOAT_TYPE = new BasicType("float",
71            "writeFloat", "readFloat", "writeFloatArray", "createFloatArray", "readFloatArray",
72            "putFloat", "getFloat", "putFloatArray", "createFloatArray", "getFloatArray");
73    NAMES.Add(FLOAT_TYPE);
74
75    DOUBLE_TYPE = new BasicType("double",
76            "writeDouble", "readDouble", "writeDoubleArray", "createDoubleArray", "readDoubleArray",
77            "putDouble", "getDouble", "putDoubleArray", "createDoubleArray", "getDoubleArray");
78    NAMES.Add(DOUBLE_TYPE);
79
80    STRING_TYPE = new StringType();
81    NAMES.Add(STRING_TYPE);
82
83    OBJECT_TYPE = new Type("java.lang", "Object", Type::BUILT_IN, false, false, false);
84    NAMES.Add(OBJECT_TYPE);
85
86    CHAR_SEQUENCE_TYPE = new CharSequenceType();
87    NAMES.Add(CHAR_SEQUENCE_TYPE);
88
89    MAP_TYPE = new MapType();
90    NAMES.Add(MAP_TYPE);
91
92    LIST_TYPE = new ListType();
93    NAMES.Add(LIST_TYPE);
94
95    TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", Type::BUILT_IN, false, false, false);
96    NAMES.Add(TEXT_UTILS_TYPE);
97
98    REMOTE_EXCEPTION_TYPE = new RemoteExceptionType();
99    NAMES.Add(REMOTE_EXCEPTION_TYPE);
100
101    RUNTIME_EXCEPTION_TYPE = new RuntimeExceptionType();
102    NAMES.Add(RUNTIME_EXCEPTION_TYPE);
103
104    IBINDER_TYPE = new IBinderType();
105    NAMES.Add(IBINDER_TYPE);
106
107    IINTERFACE_TYPE = new IInterfaceType();
108    NAMES.Add(IINTERFACE_TYPE);
109
110    BINDER_NATIVE_TYPE = new BinderType();
111    NAMES.Add(BINDER_NATIVE_TYPE);
112
113    BINDER_PROXY_TYPE = new BinderProxyType();
114    NAMES.Add(BINDER_PROXY_TYPE);
115
116    PARCEL_TYPE = new ParcelType();
117    NAMES.Add(PARCEL_TYPE);
118
119    PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType();
120    NAMES.Add(PARCELABLE_INTERFACE_TYPE);
121
122    CONTEXT_TYPE = new Type("android.content", "Context", Type::BUILT_IN, false, false, false);
123    NAMES.Add(CONTEXT_TYPE);
124
125    RPC_DATA_TYPE = new RpcDataType();
126    NAMES.Add(RPC_DATA_TYPE);
127
128    RPC_ERROR_TYPE = new UserDataType("android.support.place.rpc", "RpcError",
129                                    true, __FILE__, __LINE__);
130    NAMES.Add(RPC_ERROR_TYPE);
131
132    EVENT_FAKE_TYPE = new Type("event", Type::BUILT_IN, false, false, false);
133    NAMES.Add(EVENT_FAKE_TYPE);
134
135    CLASSLOADER_TYPE = new ClassLoaderType();
136    NAMES.Add(CLASSLOADER_TYPE);
137
138    NULL_VALUE = new LiteralExpression("null");
139    THIS_VALUE = new LiteralExpression("this");
140    SUPER_VALUE = new LiteralExpression("super");
141    TRUE_VALUE = new LiteralExpression("true");
142    FALSE_VALUE = new LiteralExpression("false");
143
144    NAMES.AddGenericType("java.util", "List", 1);
145    NAMES.AddGenericType("java.util", "Map", 2);
146}
147
148static Type*
149make_generic_type(const string& package, const string& name,
150                    const vector<Type*>& args)
151{
152    if (package == "java.util" && name == "List") {
153        return new GenericListType("java.util", "List", args);
154    }
155    return NULL;
156    //return new GenericType(package, name, args);
157}
158
159// ================================================================
160
161Type::Type(const string& name, int kind, bool canWriteToParcel, bool canWriteToRpcData,
162        bool canBeOut)
163    :m_package(),
164     m_name(name),
165     m_declFile(""),
166     m_declLine(-1),
167     m_kind(kind),
168     m_canWriteToParcel(canWriteToParcel),
169     m_canWriteToRpcData(canWriteToRpcData),
170     m_canBeOut(canBeOut)
171{
172    m_qualifiedName = name;
173}
174
175Type::Type(const string& package, const string& name,
176            int kind, bool canWriteToParcel, bool canWriteToRpcData,
177            bool canBeOut, const string& declFile, int declLine)
178    :m_package(package),
179     m_name(name),
180     m_declFile(declFile),
181     m_declLine(declLine),
182     m_kind(kind),
183     m_canWriteToParcel(canWriteToParcel),
184     m_canWriteToRpcData(canWriteToRpcData),
185     m_canBeOut(canBeOut)
186{
187    if (package.length() > 0) {
188        m_qualifiedName = package;
189        m_qualifiedName += '.';
190    }
191    m_qualifiedName += name;
192}
193
194Type::~Type()
195{
196}
197
198bool
199Type::CanBeArray() const
200{
201    return false;
202}
203
204string
205Type::ImportType() const
206{
207    return m_qualifiedName;
208}
209
210string
211Type::CreatorName() const
212{
213    return "";
214}
215
216string
217Type::RpcCreatorName() const
218{
219    return "";
220}
221
222string
223Type::InstantiableName() const
224{
225    return QualifiedName();
226}
227
228
229void
230Type::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
231{
232    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn",
233            __FILE__, __LINE__, m_qualifiedName.c_str());
234    addTo->Add(new LiteralExpression("/* WriteToParcel error "
235                + m_qualifiedName + " */"));
236}
237
238void
239Type::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
240{
241    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
242            __FILE__, __LINE__, m_qualifiedName.c_str());
243    addTo->Add(new LiteralExpression("/* CreateFromParcel error "
244                + m_qualifiedName + " */"));
245}
246
247void
248Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
249{
250    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
251            __FILE__, __LINE__, m_qualifiedName.c_str());
252    addTo->Add(new LiteralExpression("/* ReadFromParcel error "
253                + m_qualifiedName + " */"));
254}
255
256void
257Type::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
258{
259    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
260            __FILE__, __LINE__, m_qualifiedName.c_str());
261    addTo->Add(new LiteralExpression("/* WriteArrayToParcel error "
262                + m_qualifiedName + " */"));
263}
264
265void
266Type::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
267                            Variable* parcel, Variable**)
268{
269    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
270            __FILE__, __LINE__, m_qualifiedName.c_str());
271    addTo->Add(new LiteralExpression("/* CreateArrayFromParcel error "
272                + m_qualifiedName + " */"));
273}
274
275void
276Type::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
277{
278    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
279            __FILE__, __LINE__, m_qualifiedName.c_str());
280    addTo->Add(new LiteralExpression("/* ReadArrayFromParcel error "
281                + m_qualifiedName + " */"));
282}
283
284void
285Type::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
286        Variable* data, int flags)
287{
288    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
289            __FILE__, __LINE__, m_qualifiedName.c_str());
290    addTo->Add(new LiteralExpression("/* WriteToRpcData error "
291                + m_qualifiedName + " */"));
292}
293
294void
295Type::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
296        Variable** cl)
297{
298    fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n",
299            __FILE__, __LINE__, m_qualifiedName.c_str());
300    addTo->Add(new LiteralExpression("/* ReadFromRpcData error "
301                + m_qualifiedName + " */"));
302}
303
304void
305Type::SetQualifiedName(const string& qualified)
306{
307    m_qualifiedName = qualified;
308}
309
310Expression*
311Type::BuildWriteToParcelFlags(int flags)
312{
313    if (flags == 0) {
314        return new LiteralExpression("0");
315    }
316    if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0) {
317        return new FieldVariable(PARCELABLE_INTERFACE_TYPE,
318                "PARCELABLE_WRITE_RETURN_VALUE");
319    }
320    return new LiteralExpression("0");
321}
322
323// ================================================================
324
325BasicType::BasicType(const string& name, const string& marshallParcel,
326          const string& unmarshallParcel, const string& writeArrayParcel,
327          const string& createArrayParcel, const string& readArrayParcel,
328          const string& marshallRpc, const string& unmarshallRpc,
329          const string& writeArrayRpc, const string& createArrayRpc, const string& readArrayRpc)
330    :Type(name, BUILT_IN, true, true, false),
331     m_marshallParcel(marshallParcel),
332     m_unmarshallParcel(unmarshallParcel),
333     m_writeArrayParcel(writeArrayParcel),
334     m_createArrayParcel(createArrayParcel),
335     m_readArrayParcel(readArrayParcel),
336     m_marshallRpc(marshallRpc),
337     m_unmarshallRpc(unmarshallRpc),
338     m_writeArrayRpc(writeArrayRpc),
339     m_createArrayRpc(createArrayRpc),
340     m_readArrayRpc(readArrayRpc)
341{
342}
343
344void
345BasicType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
346{
347    addTo->Add(new MethodCall(parcel, m_marshallParcel, 1, v));
348}
349
350void
351BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
352{
353    addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallParcel)));
354}
355
356bool
357BasicType::CanBeArray() const
358{
359    return true;
360}
361
362void
363BasicType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
364{
365    addTo->Add(new MethodCall(parcel, m_writeArrayParcel, 1, v));
366}
367
368void
369BasicType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
370                            Variable* parcel, Variable**)
371{
372    addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayParcel)));
373}
374
375void
376BasicType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
377{
378    addTo->Add(new MethodCall(parcel, m_readArrayParcel, 1, v));
379}
380
381void
382BasicType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
383        Variable* data, int flags)
384{
385    addTo->Add(new MethodCall(data, m_marshallRpc, 2, k, v));
386}
387
388void
389BasicType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
390        Variable** cl)
391{
392    addTo->Add(new Assignment(v, new MethodCall(data, m_unmarshallRpc, 1, k)));
393}
394
395// ================================================================
396
397BooleanType::BooleanType()
398    :Type("boolean", BUILT_IN, true, true, false)
399{
400}
401
402void
403BooleanType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
404{
405    addTo->Add(new MethodCall(parcel, "writeInt", 1,
406                new Ternary(v, new LiteralExpression("1"),
407                    new LiteralExpression("0"))));
408}
409
410void
411BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
412{
413    addTo->Add(new Assignment(v, new Comparison(new LiteralExpression("0"),
414                    "!=", new MethodCall(parcel, "readInt"))));
415}
416
417bool
418BooleanType::CanBeArray() const
419{
420    return true;
421}
422
423void
424BooleanType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
425{
426    addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v));
427}
428
429void
430BooleanType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
431                            Variable* parcel, Variable**)
432{
433    addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
434}
435
436void
437BooleanType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
438{
439    addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
440}
441
442void
443BooleanType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
444        Variable* data, int flags)
445{
446    addTo->Add(new MethodCall(data, "putBoolean", 2, k, v));
447}
448
449void
450BooleanType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
451        Variable** cl)
452{
453    addTo->Add(new Assignment(v, new MethodCall(data, "getBoolean", 1, k)));
454}
455
456// ================================================================
457
458CharType::CharType()
459    :Type("char", BUILT_IN, true, true, false)
460{
461}
462
463void
464CharType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
465{
466    addTo->Add(new MethodCall(parcel, "writeInt", 1,
467                    new Cast(INT_TYPE, v)));
468}
469
470void
471CharType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
472{
473    addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
474}
475
476bool
477CharType::CanBeArray() const
478{
479    return true;
480}
481
482void
483CharType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
484{
485    addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v));
486}
487
488void
489CharType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
490                            Variable* parcel, Variable**)
491{
492    addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
493}
494
495void
496CharType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
497{
498    addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
499}
500
501void
502CharType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
503        Variable* data, int flags)
504{
505    addTo->Add(new MethodCall(data, "putChar", 2, k, v));
506}
507
508void
509CharType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
510        Variable** cl)
511{
512    addTo->Add(new Assignment(v, new MethodCall(data, "getChar", 1, k)));
513}
514
515// ================================================================
516
517StringType::StringType()
518    :Type("java.lang", "String", BUILT_IN, true, true, false)
519{
520}
521
522string
523StringType::CreatorName() const
524{
525    return "android.os.Parcel.STRING_CREATOR";
526}
527
528void
529StringType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
530{
531    addTo->Add(new MethodCall(parcel, "writeString", 1, v));
532}
533
534void
535StringType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
536{
537    addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
538}
539
540bool
541StringType::CanBeArray() const
542{
543    return true;
544}
545
546void
547StringType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
548{
549    addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v));
550}
551
552void
553StringType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
554                            Variable* parcel, Variable**)
555{
556    addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
557}
558
559void
560StringType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
561{
562    addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
563}
564
565void
566StringType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
567        Variable* data, int flags)
568{
569    addTo->Add(new MethodCall(data, "putString", 2, k, v));
570}
571
572void
573StringType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
574        Variable* data, Variable**)
575{
576    addTo->Add(new Assignment(v, new MethodCall(data, "getString", 1, k)));
577}
578
579// ================================================================
580
581CharSequenceType::CharSequenceType()
582    :Type("java.lang", "CharSequence", BUILT_IN, true, true, false)
583{
584}
585
586string
587CharSequenceType::CreatorName() const
588{
589    return "android.os.Parcel.STRING_CREATOR";
590}
591
592void
593CharSequenceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
594{
595    // if (v != null) {
596    //     parcel.writeInt(1);
597    //     v.writeToParcel(parcel);
598    // } else {
599    //     parcel.writeInt(0);
600    // }
601    IfStatement* elsepart = new IfStatement();
602    elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1,
603                                new LiteralExpression("0")));
604    IfStatement* ifpart = new IfStatement;
605    ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
606    ifpart->elseif = elsepart;
607    ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1,
608                                new LiteralExpression("1")));
609    ifpart->statements->Add(new MethodCall(TEXT_UTILS_TYPE, "writeToParcel",
610                                3, v, parcel, BuildWriteToParcelFlags(flags)));
611
612    addTo->Add(ifpart);
613}
614
615void
616CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
617                                Variable* parcel, Variable**)
618{
619    // if (0 != parcel.readInt()) {
620    //     v = TextUtils.createFromParcel(parcel)
621    // } else {
622    //     v = null;
623    // }
624    IfStatement* elsepart = new IfStatement();
625    elsepart->statements->Add(new Assignment(v, NULL_VALUE));
626
627    IfStatement* ifpart = new IfStatement();
628    ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
629                new MethodCall(parcel, "readInt"));
630    ifpart->elseif = elsepart;
631    ifpart->statements->Add(new Assignment(v,
632                new MethodCall(TEXT_UTILS_TYPE,
633                                    "CHAR_SEQUENCE_CREATOR.createFromParcel", 1, parcel)));
634
635    addTo->Add(ifpart);
636}
637
638
639// ================================================================
640
641RemoteExceptionType::RemoteExceptionType()
642    :Type("android.os", "RemoteException", BUILT_IN, false, false, false)
643{
644}
645
646void
647RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
648{
649    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
650}
651
652void
653RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
654{
655    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
656}
657
658// ================================================================
659
660RuntimeExceptionType::RuntimeExceptionType()
661    :Type("java.lang", "RuntimeException", BUILT_IN, false, false, false)
662{
663}
664
665void
666RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
667{
668    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
669}
670
671void
672RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
673{
674    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
675}
676
677
678// ================================================================
679
680IBinderType::IBinderType()
681    :Type("android.os", "IBinder", BUILT_IN, true, false, false)
682{
683}
684
685void
686IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
687{
688    addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v));
689}
690
691void
692IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
693{
694    addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
695}
696
697void
698IBinderType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
699{
700    addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v));
701}
702
703void
704IBinderType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
705                            Variable* parcel, Variable**)
706{
707    addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
708}
709
710void
711IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
712{
713    addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
714}
715
716
717// ================================================================
718
719IInterfaceType::IInterfaceType()
720    :Type("android.os", "IInterface", BUILT_IN, false, false, false)
721{
722}
723
724void
725IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
726{
727    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
728}
729
730void
731IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
732{
733    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
734}
735
736
737// ================================================================
738
739BinderType::BinderType()
740    :Type("android.os", "Binder", BUILT_IN, false, false, false)
741{
742}
743
744void
745BinderType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
746{
747    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
748}
749
750void
751BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
752                                    Variable* parcel, Variable**)
753{
754    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
755}
756
757
758// ================================================================
759
760BinderProxyType::BinderProxyType()
761    :Type("android.os", "BinderProxy", BUILT_IN, false, false, false)
762{
763}
764
765void
766BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
767{
768    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
769}
770
771void
772BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
773                                    Variable* parcel, Variable**)
774{
775    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
776}
777
778
779// ================================================================
780
781ParcelType::ParcelType()
782    :Type("android.os", "Parcel", BUILT_IN, false, false, false)
783{
784}
785
786void
787ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
788{
789    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
790}
791
792void
793ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
794{
795    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
796}
797
798// ================================================================
799
800ParcelableInterfaceType::ParcelableInterfaceType()
801    :Type("android.os", "Parcelable", BUILT_IN, false, false, false)
802{
803}
804
805void
806ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
807{
808    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
809}
810
811void
812ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
813{
814    fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
815}
816
817// ================================================================
818
819MapType::MapType()
820    :Type("java.util", "Map", BUILT_IN, true, false, true)
821{
822}
823
824void
825MapType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
826{
827    addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
828}
829
830static void EnsureClassLoader(StatementBlock* addTo, Variable** cl)
831{
832    // We don't want to look up the class loader once for every
833    // collection argument, so ensure we do it at most once per method.
834    if (*cl == NULL) {
835        *cl = new Variable(CLASSLOADER_TYPE, "cl");
836        addTo->Add(new VariableDeclaration(*cl,
837                new LiteralExpression("this.getClass().getClassLoader()"),
838                CLASSLOADER_TYPE));
839    }
840}
841
842void
843MapType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
844{
845    EnsureClassLoader(addTo, cl);
846    addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl)));
847}
848
849void
850MapType::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
851{
852    EnsureClassLoader(addTo, cl);
853    addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
854}
855
856
857// ================================================================
858
859ListType::ListType()
860    :Type("java.util", "List", BUILT_IN, true, true, true)
861{
862}
863
864string
865ListType::InstantiableName() const
866{
867    return "java.util.ArrayList";
868}
869
870void
871ListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
872{
873    addTo->Add(new MethodCall(parcel, "writeList", 1, v));
874}
875
876void
877ListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable** cl)
878{
879    EnsureClassLoader(addTo, cl);
880    addTo->Add(new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
881}
882
883void
884ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
885                    Variable* parcel, Variable** cl)
886{
887    EnsureClassLoader(addTo, cl);
888    addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
889}
890
891void
892ListType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
893        Variable* data, int flags)
894{
895    addTo->Add(new MethodCall(data, "putList", 2, k, v));
896}
897
898void
899ListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
900        Variable** cl)
901{
902    addTo->Add(new Assignment(v, new MethodCall(data, "getList", 1, k)));
903}
904
905// ================================================================
906
907UserDataType::UserDataType(const string& package, const string& name,
908                        bool builtIn, bool canWriteToParcel, bool canWriteToRpcData,
909                        const string& declFile, int declLine)
910    :Type(package, name, builtIn ? BUILT_IN : USERDATA, canWriteToParcel, canWriteToRpcData,
911            true, declFile, declLine)
912{
913}
914
915string
916UserDataType::CreatorName() const
917{
918    return QualifiedName() + ".CREATOR";
919}
920
921string
922UserDataType::RpcCreatorName() const
923{
924    return QualifiedName() + ".RPC_CREATOR";
925}
926
927void
928UserDataType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
929{
930    // if (v != null) {
931    //     parcel.writeInt(1);
932    //     v.writeToParcel(parcel);
933    // } else {
934    //     parcel.writeInt(0);
935    // }
936    IfStatement* elsepart = new IfStatement();
937    elsepart->statements->Add(new MethodCall(parcel, "writeInt", 1,
938                                new LiteralExpression("0")));
939    IfStatement* ifpart = new IfStatement;
940    ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
941    ifpart->elseif = elsepart;
942    ifpart->statements->Add(new MethodCall(parcel, "writeInt", 1,
943                                new LiteralExpression("1")));
944    ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2,
945                                parcel, BuildWriteToParcelFlags(flags)));
946
947    addTo->Add(ifpart);
948}
949
950void
951UserDataType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
952{
953    // if (0 != parcel.readInt()) {
954    //     v = CLASS.CREATOR.createFromParcel(parcel)
955    // } else {
956    //     v = null;
957    // }
958    IfStatement* elsepart = new IfStatement();
959    elsepart->statements->Add(new Assignment(v, NULL_VALUE));
960
961    IfStatement* ifpart = new IfStatement();
962    ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
963                new MethodCall(parcel, "readInt"));
964    ifpart->elseif = elsepart;
965    ifpart->statements->Add(new Assignment(v,
966                new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel)));
967
968    addTo->Add(ifpart);
969}
970
971void
972UserDataType::ReadFromParcel(StatementBlock* addTo, Variable* v,
973                    Variable* parcel, Variable**)
974{
975    // TODO: really, we don't need to have this extra check, but we
976    // don't have two separate marshalling code paths
977    // if (0 != parcel.readInt()) {
978    //     v.readFromParcel(parcel)
979    // }
980    IfStatement* ifpart = new IfStatement();
981    ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
982                new MethodCall(parcel, "readInt"));
983    ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel));
984    addTo->Add(ifpart);
985}
986
987bool
988UserDataType::CanBeArray() const
989{
990    return true;
991}
992
993void
994UserDataType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
995{
996    addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v,
997                BuildWriteToParcelFlags(flags)));
998}
999
1000void
1001UserDataType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
1002                            Variable* parcel, Variable**)
1003{
1004    string creator = v->type->QualifiedName() + ".CREATOR";
1005    addTo->Add(new Assignment(v, new MethodCall(parcel,
1006                "createTypedArray", 1, new LiteralExpression(creator))));
1007}
1008
1009void
1010UserDataType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
1011{
1012    string creator = v->type->QualifiedName() + ".CREATOR";
1013    addTo->Add(new MethodCall(parcel, "readTypedArray", 2,
1014                    v, new LiteralExpression(creator)));
1015}
1016
1017void
1018UserDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
1019                                    Variable* data, int flags)
1020{
1021    // data.putFlattenable(k, v);
1022    addTo->Add(new MethodCall(data, "putFlattenable", 2, k, v));
1023}
1024
1025void
1026UserDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
1027                                    Variable* data, Variable** cl)
1028{
1029    // data.getFlattenable(k, CLASS.RPC_CREATOR);
1030    addTo->Add(new Assignment(v, new MethodCall(data, "getFlattenable", 2, k,
1031                new FieldVariable(v->type, "RPC_CREATOR"))));
1032}
1033
1034// ================================================================
1035
1036InterfaceType::InterfaceType(const string& package, const string& name,
1037                        bool builtIn, bool oneway,
1038                        const string& declFile, int declLine)
1039    :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false, false,
1040                        declFile, declLine)
1041    ,m_oneway(oneway)
1042{
1043}
1044
1045bool
1046InterfaceType::OneWay() const
1047{
1048    return m_oneway;
1049}
1050
1051void
1052InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
1053{
1054    // parcel.writeStrongBinder(v != null ? v.asBinder() : null);
1055    addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1,
1056                new Ternary(
1057                    new Comparison(v, "!=", NULL_VALUE),
1058                    new MethodCall(v, "asBinder"),
1059                    NULL_VALUE)));
1060}
1061
1062void
1063InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
1064{
1065    // v = Interface.asInterface(parcel.readStrongBinder());
1066    string type = v->type->QualifiedName();
1067    type += ".Stub";
1068    addTo->Add(new Assignment(v,
1069                new MethodCall( NAMES.Find(type), "asInterface", 1,
1070                    new MethodCall(parcel, "readStrongBinder"))));
1071}
1072
1073
1074// ================================================================
1075
1076GenericType::GenericType(const string& package, const string& name,
1077                         const vector<Type*>& args)
1078    :Type(package, name, BUILT_IN, true, true, true)
1079{
1080    m_args = args;
1081
1082    m_importName = package + '.' + name;
1083
1084    string gen = "<";
1085    int N = args.size();
1086    for (int i=0; i<N; i++) {
1087        Type* t = args[i];
1088        gen += t->QualifiedName();
1089        if (i != N-1) {
1090            gen += ',';
1091        }
1092    }
1093    gen += '>';
1094    m_genericArguments = gen;
1095    SetQualifiedName(m_importName + gen);
1096}
1097
1098const vector<Type*>&
1099GenericType::GenericArgumentTypes() const
1100{
1101    return m_args;
1102}
1103
1104string
1105GenericType::GenericArguments() const
1106{
1107    return m_genericArguments;
1108}
1109
1110string
1111GenericType::ImportType() const
1112{
1113    return m_importName;
1114}
1115
1116void
1117GenericType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
1118{
1119    fprintf(stderr, "implement GenericType::WriteToParcel\n");
1120}
1121
1122void
1123GenericType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
1124{
1125    fprintf(stderr, "implement GenericType::CreateFromParcel\n");
1126}
1127
1128void
1129GenericType::ReadFromParcel(StatementBlock* addTo, Variable* v,
1130                            Variable* parcel, Variable**)
1131{
1132    fprintf(stderr, "implement GenericType::ReadFromParcel\n");
1133}
1134
1135
1136// ================================================================
1137
1138GenericListType::GenericListType(const string& package, const string& name,
1139                         const vector<Type*>& args)
1140    :GenericType(package, name, args),
1141     m_creator(args[0]->CreatorName())
1142{
1143}
1144
1145string
1146GenericListType::CreatorName() const
1147{
1148    return "android.os.Parcel.arrayListCreator";
1149}
1150
1151string
1152GenericListType::InstantiableName() const
1153{
1154    return "java.util.ArrayList" + GenericArguments();
1155}
1156
1157void
1158GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
1159{
1160    if (m_creator == STRING_TYPE->CreatorName()) {
1161        addTo->Add(new MethodCall(parcel, "writeStringList", 1, v));
1162    } else if (m_creator == IBINDER_TYPE->CreatorName()) {
1163        addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v));
1164    } else {
1165        // parcel.writeTypedListXX(arg);
1166        addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v));
1167    }
1168}
1169
1170void
1171GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
1172{
1173    if (m_creator == STRING_TYPE->CreatorName()) {
1174        addTo->Add(new Assignment(v,
1175                   new MethodCall(parcel, "createStringArrayList", 0)));
1176    } else if (m_creator == IBINDER_TYPE->CreatorName()) {
1177        addTo->Add(new Assignment(v,
1178                   new MethodCall(parcel, "createBinderArrayList", 0)));
1179    } else {
1180        // v = _data.readTypedArrayList(XXX.creator);
1181        addTo->Add(new Assignment(v,
1182                   new MethodCall(parcel, "createTypedArrayList", 1,
1183                   new LiteralExpression(m_creator))));
1184    }
1185}
1186
1187void
1188GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
1189                            Variable* parcel, Variable**)
1190{
1191    if (m_creator == STRING_TYPE->CreatorName()) {
1192        addTo->Add(new MethodCall(parcel, "readStringList", 1, v));
1193    } else if (m_creator == IBINDER_TYPE->CreatorName()) {
1194        addTo->Add(new MethodCall(parcel, "readBinderList", 1, v));
1195    } else {
1196        // v = _data.readTypedList(v, XXX.creator);
1197        addTo->Add(new MethodCall(parcel, "readTypedList", 2,
1198                       v,
1199                       new LiteralExpression(m_creator)));
1200    }
1201}
1202
1203void
1204GenericListType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
1205        Variable* data, int flags)
1206{
1207    Type* generic = GenericArgumentTypes()[0];
1208    if (generic == RPC_DATA_TYPE) {
1209        addTo->Add(new MethodCall(data, "putRpcDataList", 2, k, v));
1210    } else if (generic->RpcCreatorName() != "") {
1211        addTo->Add(new MethodCall(data, "putFlattenableList", 2, k, v));
1212    } else {
1213        addTo->Add(new MethodCall(data, "putList", 2, k, v));
1214    }
1215}
1216
1217void
1218GenericListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
1219        Variable* data, Variable** cl)
1220{
1221    Type* generic = GenericArgumentTypes()[0];
1222    if (generic == RPC_DATA_TYPE) {
1223        addTo->Add(new Assignment(v, new MethodCall(data, "getRpcDataList", 2, k)));
1224    } else if (generic->RpcCreatorName() != "") {
1225        addTo->Add(new Assignment(v, new MethodCall(data, "getFlattenableList", 2, k,
1226                        new LiteralExpression(generic->RpcCreatorName()))));
1227    } else {
1228        string classArg = GenericArgumentTypes()[0]->QualifiedName();
1229        classArg += ".class";
1230        addTo->Add(new Assignment(v, new MethodCall(data, "getList", 2, k,
1231                        new LiteralExpression(classArg))));
1232    }
1233}
1234
1235
1236// ================================================================
1237
1238RpcDataType::RpcDataType()
1239    :UserDataType("android.support.place.rpc", "RpcData", true, true, true)
1240{
1241}
1242
1243void
1244RpcDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
1245        Variable* data, int flags)
1246{
1247    addTo->Add(new MethodCall(data, "putRpcData", 2, k, v));
1248}
1249
1250void
1251RpcDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, Variable* data,
1252        Variable** cl)
1253{
1254    addTo->Add(new Assignment(v, new MethodCall(data, "getRpcData", 1, k)));
1255}
1256
1257
1258// ================================================================
1259
1260ClassLoaderType::ClassLoaderType()
1261    :Type("java.lang", "ClassLoader", BUILT_IN, false, false, false)
1262{
1263}
1264
1265
1266// ================================================================
1267
1268Namespace::Namespace()
1269{
1270}
1271
1272Namespace::~Namespace()
1273{
1274    int N = m_types.size();
1275    for (int i=0; i<N; i++) {
1276        delete m_types[i];
1277    }
1278}
1279
1280void
1281Namespace::Add(Type* type)
1282{
1283    Type* t = Find(type->QualifiedName());
1284    if (t == NULL) {
1285        m_types.push_back(type);
1286    }
1287}
1288
1289void
1290Namespace::AddGenericType(const string& package, const string& name, int args)
1291{
1292    Generic g;
1293        g.package = package;
1294        g.name = name;
1295        g.qualified = package + '.' + name;
1296        g.args = args;
1297    m_generics.push_back(g);
1298}
1299
1300Type*
1301Namespace::Find(const string& name) const
1302{
1303    int N = m_types.size();
1304    for (int i=0; i<N; i++) {
1305        if (m_types[i]->QualifiedName() == name) {
1306            return m_types[i];
1307        }
1308    }
1309    return NULL;
1310}
1311
1312Type*
1313Namespace::Find(const char* package, const char* name) const
1314{
1315    string s;
1316    if (package != NULL) {
1317        s += package;
1318        s += '.';
1319    }
1320    s += name;
1321    return Find(s);
1322}
1323
1324static string
1325normalize_generic(const string& s)
1326{
1327    string r;
1328    int N = s.size();
1329    for (int i=0; i<N; i++) {
1330        char c = s[i];
1331        if (!isspace(c)) {
1332            r += c;
1333        }
1334    }
1335    return r;
1336}
1337
1338Type*
1339Namespace::Search(const string& name)
1340{
1341    // an exact match wins
1342    Type* result = Find(name);
1343    if (result != NULL) {
1344        return result;
1345    }
1346
1347    // try the class names
1348    // our language doesn't allow you to not specify outer classes
1349    // when referencing an inner class.  that could be changed, and this
1350    // would be the place to do it, but I don't think the complexity in
1351    // scoping rules is worth it.
1352    int N = m_types.size();
1353    for (int i=0; i<N; i++) {
1354        if (m_types[i]->Name() == name) {
1355            return m_types[i];
1356        }
1357    }
1358
1359    // we got to here and it's not a generic, give up
1360    if (name.find('<') == name.npos) {
1361        return NULL;
1362    }
1363
1364    // remove any whitespace
1365    string normalized = normalize_generic(name);
1366
1367    // find the part before the '<', find a generic for it
1368    ssize_t baseIndex = normalized.find('<');
1369    string base(normalized.c_str(), baseIndex);
1370    const Generic* g = search_generic(base);
1371    if (g == NULL) {
1372        return NULL;
1373    }
1374
1375    // For each of the args, do a recursive search on it.  We don't allow
1376    // generics within generics like Java does, because we're really limiting
1377    // them to just built-in container classes, at least for now.  Our syntax
1378    // ensures this right now as well.
1379    vector<Type*> args;
1380    size_t start = baseIndex + 1;
1381    size_t end = start;
1382    while (normalized[start] != '\0') {
1383        end = normalized.find(',', start);
1384        if (end == normalized.npos) {
1385            end = normalized.find('>', start);
1386        }
1387        string s(normalized.c_str()+start, end-start);
1388        Type* t = this->Search(s);
1389        if (t == NULL) {
1390            // maybe we should print a warning here?
1391            return NULL;
1392        }
1393        args.push_back(t);
1394        start = end+1;
1395    }
1396
1397    // construct a GenericType, add it to our name set so they always get
1398    // the same object, and return it.
1399    result = make_generic_type(g->package, g->name, args);
1400    if (result == NULL) {
1401        return NULL;
1402    }
1403
1404    this->Add(result);
1405    return this->Find(result->QualifiedName());
1406}
1407
1408const Namespace::Generic*
1409Namespace::search_generic(const string& name) const
1410{
1411    int N = m_generics.size();
1412
1413    // first exact match
1414    for (int i=0; i<N; i++) {
1415        const Generic& g = m_generics[i];
1416        if (g.qualified == name) {
1417            return &g;
1418        }
1419    }
1420
1421    // then name match
1422    for (int i=0; i<N; i++) {
1423        const Generic& g = m_generics[i];
1424        if (g.name == name) {
1425            return &g;
1426        }
1427    }
1428
1429    return NULL;
1430}
1431
1432void
1433Namespace::Dump() const
1434{
1435    int n = m_types.size();
1436    for (int i=0; i<n; i++) {
1437        Type* t = m_types[i];
1438        printf("type: package=%s name=%s qualifiedName=%s\n",
1439                t->Package().c_str(), t->Name().c_str(),
1440                t->QualifiedName().c_str());
1441    }
1442}
1443