Remove NAMES global type namespace

We now pass around an instance of JavaTypeNamespace to
resolve types.

Add a const pointer to this namespace to java Type objects.
This enables a lot of cases where we need to refer to the
type namespace as we dynamically resolve types.

Prototype a method to remove INT_TYPE global constant by looking
up the appropriate type in an instance of JavaTypeNamespace.

Bug: 24303749
Test: Compiles, unittests pass

Change-Id: I3bb25ffb875e1e55f0548b6cd0e84e3e8bbf817e
diff --git a/aidl.cpp b/aidl.cpp
index d1e4a09..9901675 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -738,12 +738,11 @@
 int compile_aidl_to_cpp(const CppOptions& options) {
   interface_type* interface = nullptr;
   import_info* imports = nullptr;
-  register_base_types();
-  JavaTypeNamespace* types = &NAMES;
+  unique_ptr<JavaTypeNamespace> types(new JavaTypeNamespace());
   int err = load_and_validate_aidl(std::vector<std::string>{},
                                    options.ImportPaths(),
                                    options.InputFileName(),
-                                   types,
+                                   types.get(),
                                    &interface,
                                    &imports);
   if (err != 0) {
@@ -758,12 +757,11 @@
 int compile_aidl_to_java(const JavaOptions& options) {
   interface_type* interface = nullptr;
   import_info* imports = nullptr;
-  register_base_types();
-  JavaTypeNamespace* types = &NAMES;
+  unique_ptr<JavaTypeNamespace> types(new JavaTypeNamespace());
   int err = load_and_validate_aidl(options.preprocessed_files_,
                                    options.import_paths_,
                                    options.input_file_name_,
-                                   types,
+                                   types.get(),
                                    &interface,
                                    &imports);
   if (err != 0) {
@@ -790,7 +788,7 @@
   check_outputFilePath(output_file_name);
 
   err = generate_java(output_file_name, options.input_file_name_.c_str(),
-                      interface, types);
+                      interface, types.get());
 
   return err;
 }
diff --git a/ast_java_unittest.cpp b/ast_java_unittest.cpp
index ecf80c0..b7bbb5a 100644
--- a/ast_java_unittest.cpp
+++ b/ast_java_unittest.cpp
@@ -36,8 +36,9 @@
 }  // namespace
 
 TEST(AstJavaTests, GeneratesClass) {
-  Type class_type("TestClass", Type::GENERATED, false, false);
-  Type extend_type("SuperClass", Type::BUILT_IN, false, false);
+  JavaTypeNamespace types;
+  Type class_type(&types, "TestClass", Type::GENERATED, false, false);
+  Type extend_type(&types, "SuperClass", Type::BUILT_IN, false, false);
   Class a_class;
   a_class.comment = "// class comment";
   a_class.modifiers = FINAL;
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index 3127e8b..52838ed 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -5,6 +5,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <base/macros.h>
+
 #include "parse_helpers.h"
 #include "type_java.h"
 
@@ -15,7 +17,8 @@
 class StubClass : public Class
 {
 public:
-    StubClass(const Type* type, const Type* interfaceType);
+    StubClass(const Type* type, const Type* interfaceType,
+              JavaTypeNamespace* types);
     virtual ~StubClass();
 
     Variable* transact_code;
@@ -24,10 +27,13 @@
     Variable* transact_flags;
     SwitchStatement* transact_switch;
 private:
-    void make_as_interface(const Type* interfaceType);
+    void make_as_interface(const Type* interfaceType, JavaTypeNamespace* types);
+
+    DISALLOW_COPY_AND_ASSIGN(StubClass);
 };
 
-StubClass::StubClass(const Type* type, const Type* interfaceType)
+StubClass::StubClass(const Type* type, const Type* interfaceType,
+                     JavaTypeNamespace* types)
     :Class()
 {
     this->comment = "/** Local-side IPC implementation stub class. */";
@@ -56,7 +62,7 @@
     this->elements.push_back(ctor);
 
     // asInterface
-    make_as_interface(interfaceType);
+    make_as_interface(interfaceType, types);
 
     // asBinder
     Method* asBinder = new Method;
@@ -68,10 +74,10 @@
     this->elements.push_back(asBinder);
 
     // onTransact
-    this->transact_code = new Variable(INT_TYPE, "code");
+    this->transact_code = new Variable(types->IntType(), "code");
     this->transact_data = new Variable(PARCEL_TYPE, "data");
     this->transact_reply = new Variable(PARCEL_TYPE, "reply");
-    this->transact_flags = new Variable(INT_TYPE, "flags");
+    this->transact_flags = new Variable(types->IntType(), "flags");
     Method* onTransact = new Method;
         onTransact->modifiers = PUBLIC | OVERRIDE;
         onTransact->returnType = BOOLEAN_TYPE;
@@ -97,7 +103,8 @@
 }
 
 void
-StubClass::make_as_interface(const Type *interfaceType)
+StubClass::make_as_interface(const Type *interfaceType,
+                             JavaTypeNamespace* types)
 {
     Variable* obj = new Variable(IBINDER_TYPE, "obj");
 
@@ -121,7 +128,7 @@
     // IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
     MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
     queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
-    IInterfaceType* iinType = new IInterfaceType();
+    IInterfaceType* iinType = new IInterfaceType(types);
     Variable *iin = new Variable(iinType, "iin");
     VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, NULL);
     m->statements->Add(iinVd);
@@ -142,7 +149,7 @@
 
     string proxyType = interfaceType->QualifiedName();
     proxyType += ".Stub.Proxy";
-    NewExpression* ne = new NewExpression(NAMES.Find(proxyType));
+    NewExpression* ne = new NewExpression(types->Find(proxyType));
     ne->arguments.push_back(obj);
     m->statements->Add(new ReturnStatement(ne));
 
@@ -202,9 +209,9 @@
 // =================================================
 static void
 generate_new_array(const Type* t, StatementBlock* addTo, Variable* v,
-                            Variable* parcel)
+                            Variable* parcel, JavaTypeNamespace* types)
 {
-    Variable* len = new Variable(INT_TYPE, v->name + "_length");
+    Variable* len = new Variable(types->IntType(), v->name + "_length");
     addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt")));
     IfStatement* lencheck = new IfStatement();
     lencheck->expression = new Comparison(len, "<", new LiteralExpression("0"));
@@ -254,7 +261,8 @@
 
 static void
 generate_method(const method_type* method, Class* interface,
-                    StubClass* stubClass, ProxyClass* proxyClass, int index)
+                StubClass* stubClass, ProxyClass* proxyClass, int index,
+                JavaTypeNamespace* types)
 {
     arg_type* arg;
     int i;
@@ -270,7 +278,7 @@
     sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
 
     Field* transactCode = new Field(STATIC | FINAL,
-                            new Variable(INT_TYPE, transactCodeName));
+                            new Variable(types->IntType(), transactCodeName));
     transactCode->value = transactCodeValue;
     stubClass->elements.push_back(transactCode);
 
@@ -278,14 +286,14 @@
     Method* decl = new Method;
         decl->comment = gather_comments(method->comments_token->extra);
         decl->modifiers = PUBLIC;
-        decl->returnType = NAMES.Search(method->type.type.data);
+        decl->returnType = types->Search(method->type.type.data);
         decl->returnTypeDimension = method->type.dimension;
         decl->name = method->name.data;
 
     arg = method->args;
     while (arg != NULL) {
         decl->parameters.push_back(new Variable(
-                            NAMES.Search(arg->type.type.data), arg->name.data,
+                            types->Search(arg->type.type.data), arg->name.data,
                             arg->type.dimension));
         arg = arg->next;
     }
@@ -309,7 +317,7 @@
     VariableFactory stubArgs("_arg");
     arg = method->args;
     while (arg != NULL) {
-        const Type* t = NAMES.Search(arg->type.type.data);
+        const Type* t = types->Search(arg->type.type.data);
         Variable* v = stubArgs.Get(t);
         v->dimension = arg->type.dimension;
 
@@ -324,7 +332,7 @@
             }
             else if (arg->type.dimension == 1) {
                 generate_new_array(v->type, c->statements, v,
-                        stubClass->transact_data);
+                        stubClass->transact_data, types);
             }
             else {
                 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
@@ -370,7 +378,7 @@
     i = 0;
     arg = method->args;
     while (arg != NULL) {
-        const Type* t = NAMES.Search(arg->type.type.data);
+        const Type* t = types->Search(arg->type.type.data);
         Variable* v = stubArgs.Get(i++);
 
         if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
@@ -391,14 +399,14 @@
     Method* proxy = new Method;
         proxy->comment = gather_comments(method->comments_token->extra);
         proxy->modifiers = PUBLIC | OVERRIDE;
-        proxy->returnType = NAMES.Search(method->type.type.data);
+        proxy->returnType = types->Search(method->type.type.data);
         proxy->returnTypeDimension = method->type.dimension;
         proxy->name = method->name.data;
         proxy->statements = new StatementBlock;
         arg = method->args;
         while (arg != NULL) {
             proxy->parameters.push_back(new Variable(
-                            NAMES.Search(arg->type.type.data), arg->name.data,
+                            types->Search(arg->type.type.data), arg->name.data,
                             arg->type.dimension));
             arg = arg->next;
         }
@@ -437,7 +445,7 @@
     // the parameters
     arg = method->args;
     while (arg != NULL) {
-        const Type* t = NAMES.Search(arg->type.type.data);
+        const Type* t = types->Search(arg->type.type.data);
         Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
         int dir = convert_direction(arg->direction.data);
         if (dir == OUT_PARAMETER && arg->type.dimension != 0) {
@@ -480,7 +488,7 @@
         // the out/inout parameters
         arg = method->args;
         while (arg != NULL) {
-            const Type* t = NAMES.Search(arg->type.type.data);
+            const Type* t = types->Search(arg->type.type.data);
             Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
             if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
                 generate_read_from_parcel(t, tryStatement->statements,
@@ -524,7 +532,7 @@
                                 JavaTypeNamespace* types)
 {
     const InterfaceType* interfaceType = static_cast<const InterfaceType*>(
-        NAMES.Find(iface->package, iface->name.data));
+        types->Find(iface->package, iface->name.data));
 
     // the interface class
     Class* interface = new Class;
@@ -536,13 +544,13 @@
 
     // the stub inner class
     StubClass* stub = new StubClass(
-        NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()),
-        interfaceType);
+        types->Find(iface->package, append(iface->name.data, ".Stub").c_str()),
+        interfaceType, types);
     interface->elements.push_back(stub);
 
     // the proxy inner class
     ProxyClass* proxy = new ProxyClass(
-        NAMES.Find(iface->package,
+        types->Find(iface->package,
                          append(iface->name.data, ".Stub.Proxy").c_str()),
         interfaceType);
     stub->elements.push_back(proxy);
@@ -556,7 +564,8 @@
     while (item != NULL) {
         if (item->item_type == METHOD_TYPE) {
             method_type * method_item = (method_type*) item;
-            generate_method(method_item, interface, stub, proxy, method_item->assigned_id);
+            generate_method(method_item, interface, stub, proxy,
+                            method_item->assigned_id, types);
         }
         item = item->next;
         index++;
diff --git a/type_java.cpp b/type_java.cpp
index d51c76f..cffdf44 100644
--- a/type_java.cpp
+++ b/type_java.cpp
@@ -24,8 +24,6 @@
 namespace android {
 namespace aidl {
 
-JavaTypeNamespace NAMES;
-
 Type* VOID_TYPE;
 Type* BOOLEAN_TYPE;
 Type* BYTE_TYPE;
@@ -57,102 +55,11 @@
 Expression* TRUE_VALUE;
 Expression* FALSE_VALUE;
 
-void register_base_types() {
-  VOID_TYPE = new BasicType("void", "XXX", "XXX", "XXX", "XXX", "XXX");
-  NAMES.Add(VOID_TYPE);
-
-  BOOLEAN_TYPE = new BooleanType();
-  NAMES.Add(BOOLEAN_TYPE);
-
-  BYTE_TYPE = new BasicType("byte", "writeByte", "readByte", "writeByteArray",
-                            "createByteArray", "readByteArray");
-  NAMES.Add(BYTE_TYPE);
-
-  CHAR_TYPE = new CharType();
-  NAMES.Add(CHAR_TYPE);
-
-  INT_TYPE = new BasicType("int", "writeInt", "readInt", "writeIntArray",
-                           "createIntArray", "readIntArray");
-  NAMES.Add(INT_TYPE);
-
-  LONG_TYPE = new BasicType("long", "writeLong", "readLong", "writeLongArray",
-                            "createLongArray", "readLongArray");
-  NAMES.Add(LONG_TYPE);
-
-  FLOAT_TYPE =
-      new BasicType("float", "writeFloat", "readFloat", "writeFloatArray",
-                    "createFloatArray", "readFloatArray");
-  NAMES.Add(FLOAT_TYPE);
-
-  DOUBLE_TYPE =
-      new BasicType("double", "writeDouble", "readDouble", "writeDoubleArray",
-                    "createDoubleArray", "readDoubleArray");
-  NAMES.Add(DOUBLE_TYPE);
-
-  STRING_TYPE = new StringType();
-  NAMES.Add(STRING_TYPE);
-
-  OBJECT_TYPE = new Type("java.lang", "Object", Type::BUILT_IN, false, false);
-  NAMES.Add(OBJECT_TYPE);
-
-  CHAR_SEQUENCE_TYPE = new CharSequenceType();
-  NAMES.Add(CHAR_SEQUENCE_TYPE);
-
-  MAP_TYPE = new MapType();
-  NAMES.Add(MAP_TYPE);
-
-  LIST_TYPE = new ListType();
-  NAMES.Add(LIST_TYPE);
-
-  TEXT_UTILS_TYPE =
-      new Type("android.text", "TextUtils", Type::BUILT_IN, false, false);
-  NAMES.Add(TEXT_UTILS_TYPE);
-
-  REMOTE_EXCEPTION_TYPE = new RemoteExceptionType();
-  NAMES.Add(REMOTE_EXCEPTION_TYPE);
-
-  RUNTIME_EXCEPTION_TYPE = new RuntimeExceptionType();
-  NAMES.Add(RUNTIME_EXCEPTION_TYPE);
-
-  IBINDER_TYPE = new IBinderType();
-  NAMES.Add(IBINDER_TYPE);
-
-  IINTERFACE_TYPE = new IInterfaceType();
-  NAMES.Add(IINTERFACE_TYPE);
-
-  BINDER_NATIVE_TYPE = new BinderType();
-  NAMES.Add(BINDER_NATIVE_TYPE);
-
-  BINDER_PROXY_TYPE = new BinderProxyType();
-  NAMES.Add(BINDER_PROXY_TYPE);
-
-  PARCEL_TYPE = new ParcelType();
-  NAMES.Add(PARCEL_TYPE);
-
-  PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType();
-  NAMES.Add(PARCELABLE_INTERFACE_TYPE);
-
-  CONTEXT_TYPE =
-      new Type("android.content", "Context", Type::BUILT_IN, false, false);
-  NAMES.Add(CONTEXT_TYPE);
-
-  CLASSLOADER_TYPE = new ClassLoaderType();
-  NAMES.Add(CLASSLOADER_TYPE);
-
-  NULL_VALUE = new LiteralExpression("null");
-  THIS_VALUE = new LiteralExpression("this");
-  SUPER_VALUE = new LiteralExpression("super");
-  TRUE_VALUE = new LiteralExpression("true");
-  FALSE_VALUE = new LiteralExpression("false");
-
-  NAMES.AddGenericType("java.util", "List", 1);
-  NAMES.AddGenericType("java.util", "Map", 2);
-}
-
-static Type* make_generic_type(const string& package, const string& name,
+static Type* make_generic_type(const JavaTypeNamespace* types,
+                               const string& package, const string& name,
                                const vector<const Type*>& args) {
   if (package == "java.util" && name == "List") {
-    return new GenericListType("java.util", "List", args);
+    return new GenericListType(types, "java.util", "List", args);
   }
   return NULL;
   // return new GenericType(package, name, args);
@@ -160,8 +67,10 @@
 
 // ================================================================
 
-Type::Type(const string& name, int kind, bool canWriteToParcel, bool canBeOut)
-    : m_package(),
+Type::Type(const JavaTypeNamespace* types, const string& name, int kind,
+           bool canWriteToParcel, bool canBeOut)
+    : m_types(types),
+      m_package(),
       m_name(name),
       m_declFile(""),
       m_declLine(-1),
@@ -171,10 +80,11 @@
   m_qualifiedName = name;
 }
 
-Type::Type(const string& package, const string& name, int kind,
-           bool canWriteToParcel, bool canBeOut, const string& declFile,
-           int declLine)
-    : m_package(package),
+Type::Type(const JavaTypeNamespace* types, const string& package,
+           const string& name, int kind, bool canWriteToParcel, bool canBeOut,
+           const string& declFile, int declLine)
+    : m_types(types),
+      m_package(package),
       m_name(name),
       m_declFile(declFile),
       m_declLine(declLine),
@@ -274,12 +184,13 @@
 
 // ================================================================
 
-BasicType::BasicType(const string& name, const string& marshallParcel,
+BasicType::BasicType(const JavaTypeNamespace* types, const string& name,
+                     const string& marshallParcel,
                      const string& unmarshallParcel,
                      const string& writeArrayParcel,
                      const string& createArrayParcel,
                      const string& readArrayParcel)
-    : Type(name, BUILT_IN, true, false),
+    : Type(types, name, BUILT_IN, true, false),
       m_marshallParcel(marshallParcel),
       m_unmarshallParcel(unmarshallParcel),
       m_writeArrayParcel(writeArrayParcel),
@@ -315,7 +226,8 @@
 
 // ================================================================
 
-BooleanType::BooleanType() : Type("boolean", BUILT_IN, true, false) {}
+BooleanType::BooleanType(const JavaTypeNamespace* types)
+    : Type(types, "boolean", BUILT_IN, true, false) {}
 
 void BooleanType::WriteToParcel(StatementBlock* addTo, Variable* v,
                                 Variable* parcel, int flags) const {
@@ -350,11 +262,13 @@
 
 // ================================================================
 
-CharType::CharType() : Type("char", BUILT_IN, true, false) {}
+CharType::CharType(const JavaTypeNamespace* types)
+    : Type(types, "char", BUILT_IN, true, false) {}
 
 void CharType::WriteToParcel(StatementBlock* addTo, Variable* v,
                              Variable* parcel, int flags) const {
-  addTo->Add(new MethodCall(parcel, "writeInt", 1, new Cast(INT_TYPE, v)));
+  addTo->Add(
+      new MethodCall(parcel, "writeInt", 1, new Cast(m_types->IntType(), v)));
 }
 
 void CharType::CreateFromParcel(StatementBlock* addTo, Variable* v,
@@ -381,7 +295,8 @@
 
 // ================================================================
 
-StringType::StringType() : Type("java.lang", "String", BUILT_IN, true, false) {}
+StringType::StringType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "String", BUILT_IN, true, false) {}
 
 string StringType::CreatorName() const {
   return "android.os.Parcel.STRING_CREATOR";
@@ -416,8 +331,8 @@
 
 // ================================================================
 
-CharSequenceType::CharSequenceType()
-    : Type("java.lang", "CharSequence", BUILT_IN, true, false) {}
+CharSequenceType::CharSequenceType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "CharSequence", BUILT_IN, true, false) {}
 
 string CharSequenceType::CreatorName() const {
   return "android.os.Parcel.STRING_CREATOR";
@@ -469,8 +384,8 @@
 
 // ================================================================
 
-RemoteExceptionType::RemoteExceptionType()
-    : Type("android.os", "RemoteException", BUILT_IN, false, false) {}
+RemoteExceptionType::RemoteExceptionType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "RemoteException", BUILT_IN, false, false) {}
 
 void RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
                                         Variable* parcel, int flags) const {
@@ -484,8 +399,8 @@
 
 // ================================================================
 
-RuntimeExceptionType::RuntimeExceptionType()
-    : Type("java.lang", "RuntimeException", BUILT_IN, false, false) {}
+RuntimeExceptionType::RuntimeExceptionType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "RuntimeException", BUILT_IN, false, false) {}
 
 void RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
                                          Variable* parcel, int flags) const {
@@ -500,8 +415,8 @@
 
 // ================================================================
 
-IBinderType::IBinderType()
-    : Type("android.os", "IBinder", BUILT_IN, true, false) {}
+IBinderType::IBinderType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "IBinder", BUILT_IN, true, false) {}
 
 void IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
                                 Variable* parcel, int flags) const {
@@ -530,8 +445,8 @@
 
 // ================================================================
 
-IInterfaceType::IInterfaceType()
-    : Type("android.os", "IInterface", BUILT_IN, false, false) {}
+IInterfaceType::IInterfaceType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "IInterface", BUILT_IN, false, false) {}
 
 void IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
                                    Variable* parcel, int flags) const {
@@ -545,8 +460,8 @@
 
 // ================================================================
 
-BinderType::BinderType()
-    : Type("android.os", "Binder", BUILT_IN, false, false) {}
+BinderType::BinderType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "Binder", BUILT_IN, false, false) {}
 
 void BinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
                                Variable* parcel, int flags) const {
@@ -560,8 +475,8 @@
 
 // ================================================================
 
-BinderProxyType::BinderProxyType()
-    : Type("android.os", "BinderProxy", BUILT_IN, false, false) {}
+BinderProxyType::BinderProxyType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "BinderProxy", BUILT_IN, false, false) {}
 
 void BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v,
                                     Variable* parcel, int flags) const {
@@ -575,8 +490,8 @@
 
 // ================================================================
 
-ParcelType::ParcelType()
-    : Type("android.os", "Parcel", BUILT_IN, false, false) {}
+ParcelType::ParcelType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "Parcel", BUILT_IN, false, false) {}
 
 void ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v,
                                Variable* parcel, int flags) const {
@@ -590,8 +505,8 @@
 
 // ================================================================
 
-ParcelableInterfaceType::ParcelableInterfaceType()
-    : Type("android.os", "Parcelable", BUILT_IN, false, false) {}
+ParcelableInterfaceType::ParcelableInterfaceType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "Parcelable", BUILT_IN, false, false) {}
 
 void ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
                                             Variable* parcel, int flags) const {
@@ -606,7 +521,8 @@
 
 // ================================================================
 
-MapType::MapType() : Type("java.util", "Map", BUILT_IN, true, true) {}
+MapType::MapType(const JavaTypeNamespace* types)
+    : Type(types, "java.util", "Map", BUILT_IN, true, true) {}
 
 void MapType::WriteToParcel(StatementBlock* addTo, Variable* v,
                             Variable* parcel, int flags) const {
@@ -638,7 +554,8 @@
 
 // ================================================================
 
-ListType::ListType() : Type("java.util", "List", BUILT_IN, true, true) {}
+ListType::ListType(const JavaTypeNamespace* types)
+    : Type(types, "java.util", "List", BUILT_IN, true, true) {}
 
 string ListType::InstantiableName() const { return "java.util.ArrayList"; }
 
@@ -662,11 +579,12 @@
 
 // ================================================================
 
-UserDataType::UserDataType(const string& package, const string& name,
+UserDataType::UserDataType(const JavaTypeNamespace* types,
+                           const string& package, const string& name,
                            bool builtIn, bool canWriteToParcel,
                            const string& declFile, int declLine)
-    : Type(package, name, builtIn ? BUILT_IN : USERDATA, canWriteToParcel, true,
-           declFile, declLine) {}
+    : Type(types, package, name, builtIn ? BUILT_IN : USERDATA,
+           canWriteToParcel, true, declFile, declLine) {}
 
 string UserDataType::CreatorName() const {
   return QualifiedName() + ".CREATOR";
@@ -752,11 +670,12 @@
 
 // ================================================================
 
-InterfaceType::InterfaceType(const string& package, const string& name,
+InterfaceType::InterfaceType(const JavaTypeNamespace* types,
+                             const string& package, const string& name,
                              bool builtIn, bool oneway, const string& declFile,
                              int declLine)
-    : Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false, declFile,
-           declLine),
+    : Type(types, package, name, builtIn ? BUILT_IN : INTERFACE, true, false,
+           declFile, declLine),
       m_oneway(oneway) {}
 
 bool InterfaceType::OneWay() const { return m_oneway; }
@@ -773,18 +692,17 @@
 void InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
                                      Variable* parcel, Variable**) const {
   // v = Interface.asInterface(parcel.readStrongBinder());
-  string type = v->type->QualifiedName();
-  type += ".Stub";
+  string stub_type = v->type->QualifiedName() + ".Stub";
   addTo->Add(new Assignment(
-      v, new MethodCall(NAMES.Find(type), "asInterface", 1,
+      v, new MethodCall(m_types->Find(stub_type), "asInterface", 1,
                         new MethodCall(parcel, "readStrongBinder"))));
 }
 
 // ================================================================
 
-GenericType::GenericType(const string& package, const string& name,
-                         const vector<const Type*>& args)
-    : Type(package, name, BUILT_IN, true, true) {
+GenericType::GenericType(const JavaTypeNamespace* types, const string& package,
+                         const string& name, const vector<const Type*>& args)
+    : Type(types, package, name, BUILT_IN, true, true) {
   m_args = args;
 
   m_importName = package + '.' + name;
@@ -828,9 +746,11 @@
 
 // ================================================================
 
-GenericListType::GenericListType(const string& package, const string& name,
+GenericListType::GenericListType(const JavaTypeNamespace* types,
+                                 const string& package, const string& name,
                                  const vector<const Type*>& args)
-    : GenericType(package, name, args), m_creator(args[0]->CreatorName()) {}
+    : GenericType(types, package, name, args),
+      m_creator(args[0]->CreatorName()) {}
 
 string GenericListType::CreatorName() const {
   return "android.os.Parcel.arrayListCreator";
@@ -883,12 +803,106 @@
 
 // ================================================================
 
-ClassLoaderType::ClassLoaderType()
-    : Type("java.lang", "ClassLoader", BUILT_IN, false, false) {}
+ClassLoaderType::ClassLoaderType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "ClassLoader", BUILT_IN, false, false) {}
 
 // ================================================================
 
-JavaTypeNamespace::JavaTypeNamespace() {}
+JavaTypeNamespace::JavaTypeNamespace() {
+  VOID_TYPE = new BasicType(this, "void", "XXX", "XXX", "XXX", "XXX", "XXX");
+  Add(VOID_TYPE);
+
+  BOOLEAN_TYPE = new BooleanType(this);
+  Add(BOOLEAN_TYPE);
+
+  BYTE_TYPE =
+      new BasicType(this, "byte", "writeByte", "readByte", "writeByteArray",
+                    "createByteArray", "readByteArray");
+  Add(BYTE_TYPE);
+
+  CHAR_TYPE = new CharType(this);
+  Add(CHAR_TYPE);
+
+  INT_TYPE = new BasicType(this, "int", "writeInt", "readInt", "writeIntArray",
+                           "createIntArray", "readIntArray");
+  Add(INT_TYPE);
+  m_int_type = INT_TYPE;
+
+  LONG_TYPE =
+      new BasicType(this, "long", "writeLong", "readLong", "writeLongArray",
+                    "createLongArray", "readLongArray");
+  Add(LONG_TYPE);
+
+  FLOAT_TYPE =
+      new BasicType(this, "float", "writeFloat", "readFloat", "writeFloatArray",
+                    "createFloatArray", "readFloatArray");
+  Add(FLOAT_TYPE);
+
+  DOUBLE_TYPE =
+      new BasicType(this, "double", "writeDouble", "readDouble",
+                    "writeDoubleArray", "createDoubleArray", "readDoubleArray");
+  Add(DOUBLE_TYPE);
+
+  STRING_TYPE = new StringType(this);
+  Add(STRING_TYPE);
+
+  OBJECT_TYPE =
+      new Type(this, "java.lang", "Object", Type::BUILT_IN, false, false);
+  Add(OBJECT_TYPE);
+
+  CHAR_SEQUENCE_TYPE = new CharSequenceType(this);
+  Add(CHAR_SEQUENCE_TYPE);
+
+  MAP_TYPE = new MapType(this);
+  Add(MAP_TYPE);
+
+  LIST_TYPE = new ListType(this);
+  Add(LIST_TYPE);
+
+  TEXT_UTILS_TYPE =
+      new Type(this, "android.text", "TextUtils", Type::BUILT_IN, false, false);
+  Add(TEXT_UTILS_TYPE);
+
+  REMOTE_EXCEPTION_TYPE = new RemoteExceptionType(this);
+  Add(REMOTE_EXCEPTION_TYPE);
+
+  RUNTIME_EXCEPTION_TYPE = new RuntimeExceptionType(this);
+  Add(RUNTIME_EXCEPTION_TYPE);
+
+  IBINDER_TYPE = new IBinderType(this);
+  Add(IBINDER_TYPE);
+
+  IINTERFACE_TYPE = new IInterfaceType(this);
+  Add(IINTERFACE_TYPE);
+
+  BINDER_NATIVE_TYPE = new BinderType(this);
+  Add(BINDER_NATIVE_TYPE);
+
+  BINDER_PROXY_TYPE = new BinderProxyType(this);
+  Add(BINDER_PROXY_TYPE);
+
+  PARCEL_TYPE = new ParcelType(this);
+  Add(PARCEL_TYPE);
+
+  PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType(this);
+  Add(PARCELABLE_INTERFACE_TYPE);
+
+  CONTEXT_TYPE = new Type(this, "android.content", "Context", Type::BUILT_IN,
+                          false, false);
+  Add(CONTEXT_TYPE);
+
+  CLASSLOADER_TYPE = new ClassLoaderType(this);
+  Add(CLASSLOADER_TYPE);
+
+  NULL_VALUE = new LiteralExpression("null");
+  THIS_VALUE = new LiteralExpression("this");
+  SUPER_VALUE = new LiteralExpression("super");
+  TRUE_VALUE = new LiteralExpression("true");
+  FALSE_VALUE = new LiteralExpression("false");
+
+  AddGenericType("java.util", "List", 1);
+  AddGenericType("java.util", "Map", 2);
+}
 
 JavaTypeNamespace::~JavaTypeNamespace() {
   int N = m_types.size();
@@ -914,8 +928,7 @@
   if (type->Kind() != existing->Kind()) {
     fprintf(stderr, "%s:%d attempt to redefine %s as %s,\n",
             type->DeclFile().c_str(), type->DeclLine(),
-            type->QualifiedName().c_str(),
-            type->HumanReadableKind().c_str());
+            type->QualifiedName().c_str(), type->HumanReadableKind().c_str());
     fprintf(stderr, "%s:%d previously defined here as %s.\n",
             existing->DeclFile().c_str(), existing->DeclLine(),
             existing->HumanReadableKind().c_str());
@@ -926,8 +939,7 @@
 }
 
 void JavaTypeNamespace::AddGenericType(const string& package,
-                                       const string& name,
-                                       int args) {
+                                       const string& name, int args) {
   Generic g;
   g.package = package;
   g.name = name;
@@ -971,25 +983,24 @@
 
 bool JavaTypeNamespace::AddParcelableType(user_data_type* p,
                                           const std::string& filename) {
-  Type* type = new UserDataType(p->package ? p->package : "", p->name.data,
-                                false, p->parcelable, filename, p->name.lineno);
+  Type* type =
+      new UserDataType(this, p->package ? p->package : "", p->name.data, false,
+                       p->parcelable, filename, p->name.lineno);
   return Add(type);
 }
 
 bool JavaTypeNamespace::AddBinderType(interface_type* b,
                                       const std::string& filename) {
-  Type* type = new InterfaceType(b->package ? b->package : "",
-                                 b->name.data, false, b->oneway,
-                                 filename, b->name.lineno);
-  // for interfaces, also add the stub and proxy types
-  Type* stub = new Type(b->package ? b->package : "",
-                        string{b->name.data} + ".Stub",
-                        Type::GENERATED, false, false,
-                        filename, b->name.lineno);
-  Type* proxy = new Type(b->package ? b->package : "",
-                         string{b->name.data} + ".Stub.Proxy",
-                         Type::GENERATED, false, false,
-                         filename, b->name.lineno);
+  // for interfaces, add the stub, proxy, and interface types.
+  Type* type =
+      new InterfaceType(this, b->package ? b->package : "", b->name.data, false,
+                        b->oneway, filename, b->name.lineno);
+  Type* stub = new Type(this, b->package ? b->package : "",
+                        string{b->name.data} + ".Stub", Type::GENERATED, false,
+                        false, filename, b->name.lineno);
+  Type* proxy = new Type(this, b->package ? b->package : "",
+                         string{b->name.data} + ".Stub.Proxy", Type::GENERATED,
+                         false, false, filename, b->name.lineno);
 
   bool success = true;
   success &= Add(type);
@@ -1057,7 +1068,7 @@
 
   // construct a GenericType, add it to our name set so they always get
   // the same object, and return it.
-  result = make_generic_type(g->package, g->name, args);
+  result = make_generic_type(this, g->package, g->name, args);
   if (result == NULL) {
     LOG(ERROR) << "internal error";
     return NULL;
@@ -1099,5 +1110,7 @@
   }
 }
 
+const Type* JavaTypeNamespace::IntType() const { return m_int_type; }
+
 }  // namespace aidl
 }  // namespace android
diff --git a/type_java.h b/type_java.h
index 97d9823..deccfe2 100644
--- a/type_java.h
+++ b/type_java.h
@@ -26,6 +26,7 @@
 namespace android {
 namespace aidl {
 
+class JavaTypeNamespace;
 using std::string;
 using std::vector;
 
@@ -37,10 +38,11 @@
   // WriteToParcel flags
   enum { PARCELABLE_WRITE_RETURN_VALUE = 0x0001 };
 
-  Type(const string& name, int kind, bool canWriteToParcel, bool canBeOut);
-  Type(const string& package, const string& name, int kind,
-       bool canWriteToParcel, bool canBeOut, const string& declFile = "",
-       int declLine = -1);
+  Type(const JavaTypeNamespace* types, const string& name, int kind,
+       bool canWriteToParcel, bool canBeOut);
+  Type(const JavaTypeNamespace* types, const string& package,
+       const string& name, int kind, bool canWriteToParcel, bool canBeOut,
+       const string& declFile = "", int declLine = -1);
   virtual ~Type();
 
   inline string Package() const { return m_package; }
@@ -77,6 +79,8 @@
   void SetQualifiedName(const string& qualified);
   Expression* BuildWriteToParcelFlags(int flags) const;
 
+  const JavaTypeNamespace* m_types;
+
  private:
   Type();
   Type(const Type&);
@@ -93,9 +97,10 @@
 
 class BasicType : public Type {
  public:
-  BasicType(const string& name, const string& marshallParcel,
-            const string& unmarshallParcel, const string& writeArrayParcel,
-            const string& createArrayParcel, const string& readArrayParcel);
+  BasicType(const JavaTypeNamespace* types, const string& name,
+            const string& marshallParcel, const string& unmarshallParcel,
+            const string& writeArrayParcel, const string& createArrayParcel,
+            const string& readArrayParcel);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -121,7 +126,7 @@
 
 class BooleanType : public Type {
  public:
-  BooleanType();
+  BooleanType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -140,7 +145,7 @@
 
 class CharType : public Type {
  public:
-  CharType();
+  CharType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -159,7 +164,7 @@
 
 class StringType : public Type {
  public:
-  StringType();
+  StringType(const JavaTypeNamespace* types);
 
   string CreatorName() const override;
 
@@ -180,7 +185,7 @@
 
 class CharSequenceType : public Type {
  public:
-  CharSequenceType();
+  CharSequenceType(const JavaTypeNamespace* types);
 
   string CreatorName() const override;
 
@@ -192,7 +197,7 @@
 
 class RemoteExceptionType : public Type {
  public:
-  RemoteExceptionType();
+  RemoteExceptionType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -202,7 +207,7 @@
 
 class RuntimeExceptionType : public Type {
  public:
-  RuntimeExceptionType();
+  RuntimeExceptionType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -212,7 +217,7 @@
 
 class IBinderType : public Type {
  public:
-  IBinderType();
+  IBinderType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -229,7 +234,7 @@
 
 class IInterfaceType : public Type {
  public:
-  IInterfaceType();
+  IInterfaceType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -239,7 +244,7 @@
 
 class BinderType : public Type {
  public:
-  BinderType();
+  BinderType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -249,7 +254,7 @@
 
 class BinderProxyType : public Type {
  public:
-  BinderProxyType();
+  BinderProxyType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -259,7 +264,7 @@
 
 class ParcelType : public Type {
  public:
-  ParcelType();
+  ParcelType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -269,7 +274,7 @@
 
 class ParcelableInterfaceType : public Type {
  public:
-  ParcelableInterfaceType();
+  ParcelableInterfaceType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -279,7 +284,7 @@
 
 class MapType : public Type {
  public:
-  MapType();
+  MapType(const JavaTypeNamespace* types);
 
   void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
                      int flags) const override;
@@ -291,7 +296,7 @@
 
 class ListType : public Type {
  public:
-  ListType();
+  ListType(const JavaTypeNamespace* types);
 
   string InstantiableName() const override;
 
@@ -305,9 +310,9 @@
 
 class UserDataType : public Type {
  public:
-  UserDataType(const string& package, const string& name, bool builtIn,
-               bool canWriteToParcel, const string& declFile = "",
-               int declLine = -1);
+  UserDataType(const JavaTypeNamespace* types, const string& package,
+               const string& name, bool builtIn, bool canWriteToParcel,
+               const string& declFile = "", int declLine = -1);
 
   string CreatorName() const override;
 
@@ -330,8 +335,9 @@
 
 class InterfaceType : public Type {
  public:
-  InterfaceType(const string& package, const string& name, bool builtIn,
-                bool oneway, const string& declFile, int declLine);
+  InterfaceType(const JavaTypeNamespace* types, const string& package,
+                const string& name, bool builtIn, bool oneway,
+                const string& declFile, int declLine);
 
   bool OneWay() const;
 
@@ -346,8 +352,8 @@
 
 class GenericType : public Type {
  public:
-  GenericType(const string& package, const string& name,
-              const vector<const Type*>& args);
+  GenericType(const JavaTypeNamespace* types, const string& package,
+              const string& name, const vector<const Type*>& args);
 
   const vector<const Type*>& GenericArgumentTypes() const;
   string GenericArguments() const;
@@ -369,13 +375,13 @@
 
 class ClassLoaderType : public Type {
  public:
-  ClassLoaderType();
+  ClassLoaderType(const JavaTypeNamespace* types);
 };
 
 class GenericListType : public GenericType {
  public:
-  GenericListType(const string& package, const string& name,
-                  const vector<const Type*>& args);
+  GenericListType(const JavaTypeNamespace* types, const string& package,
+                  const string& name, const vector<const Type*>& args);
 
   string CreatorName() const override;
   string InstantiableName() const override;
@@ -411,6 +417,8 @@
 
   void Dump() const;
 
+  const Type* IntType() const;
+
  private:
   struct Generic {
     string package;
@@ -424,11 +432,11 @@
   vector<const Type*> m_types;
   vector<Generic> m_generics;
 
+  const Type* m_int_type;
+
   DISALLOW_COPY_AND_ASSIGN(JavaTypeNamespace);
 };
 
-extern JavaTypeNamespace NAMES;
-
 extern Type* VOID_TYPE;
 extern Type* BOOLEAN_TYPE;
 extern Type* BYTE_TYPE;
@@ -458,8 +466,6 @@
 extern Expression* TRUE_VALUE;
 extern Expression* FALSE_VALUE;
 
-void register_base_types();
-
 }  // namespace aidl
 }  // namespace android