LayoutBinder.java revision c1560e6b00b398867da12fbdc5a1fcd1d50b801c
1d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/*
2d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
3d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar *
4d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
5d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * you may not use this file except in compliance with the License.
6d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * You may obtain a copy of the License at
7d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar *
8d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
9d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar *
10d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Unless required by applicable law or agreed to in writing, software
11d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
12d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * See the License for the specific language governing permissions and
14d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * limitations under the License.
15d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */
16d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool;
18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
19c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.misc.Nullable;
20c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar
21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Dependency;
22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr;
23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel;
24716ba89e7f459f49ea85070d4710c1d79d715298George Mountimport android.databinding.tool.expr.ExprModel.ResolveListenersCallback;
25fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.IdentifierExpr;
26c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport android.databinding.tool.store.Location;
27fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.ResourceBundle;
2834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport android.databinding.tool.store.ResourceBundle.BindingTargetBundle;
292611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyarimport android.databinding.tool.util.Preconditions;
30fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.writer.LayoutBinderWriter;
3134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport android.databinding.tool.writer.WriterPackage;
32d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
33d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.ArrayList;
3434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.Collections;
3534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mountimport java.util.Comparator;
365bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyarimport java.util.HashMap;
37d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.List;
385bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyarimport java.util.Map;
39d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/**
41d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Keeps all information about the bindings per layout file
42d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */
43716ba89e7f459f49ea85070d4710c1d79d715298George Mountpublic class LayoutBinder implements ResolveListenersCallback {
4434a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount    private static final Comparator<BindingTarget> COMPARE_FIELD_NAME = new Comparator<BindingTarget>() {
4534a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount        @Override
4634a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount        public int compare(BindingTarget first, BindingTarget second) {
4734a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount            final String fieldName1 = WriterPackage.getFieldName(first);
4834a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount            final String fieldName2 = WriterPackage.getFieldName(second);
4934a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount            return fieldName1.compareTo(fieldName2);
5034a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount        }
5134a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount    };
523bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar
53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    /*
54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    * val pkg: String, val projectPackage: String, val baseClassName: String,
55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        val layoutName:String, val lb: LayoutExprBinding*/
56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    private final ExprModel mExprModel;
57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    private final ExpressionParser mExpressionParser;
58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    private final List<BindingTarget> mBindingTargets;
5996e1c821dd446d1ed78f8ae61131550588f60a24George Mount    private final List<BindingTarget> mSortedBindingTargets;
60a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    private String mModulePackage;
61895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar    private final HashMap<String, String> mUserDefinedVariables = new HashMap<String, String>();
62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
6343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar    private LayoutBinderWriter mWriter;
643bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar    private ResourceBundle.LayoutFileBundle mBundle;
65c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount    private static final String[] sJavaLangClasses = {
66c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Deprecated",
67c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Override",
68c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "SafeVarargs",
69c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "SuppressWarnings",
70c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Appendable",
71c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "AutoCloseable",
72c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "CharSequence",
73c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Cloneable",
74c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Comparable",
75c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Iterable",
76c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Readable",
77c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Runnable",
78c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Thread.UncaughtExceptionHandler",
79c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Boolean",
80c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Byte",
81c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Character",
82c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Character.Subset",
83c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Character.UnicodeBlock",
84c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Class",
85c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ClassLoader",
86c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Compiler",
87c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Double",
88c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Enum",
89c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Float",
90c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "InheritableThreadLocal",
91c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Integer",
92c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Long",
93c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Math",
94c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Number",
95c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Object",
96c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Package",
97c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Process",
98c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ProcessBuilder",
99c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Runtime",
100c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "RuntimePermission",
101c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "SecurityManager",
102c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Short",
103c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "StackTraceElement",
104c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "StrictMath",
105c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "String",
106c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "StringBuffer",
107c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "StringBuilder",
108c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "System",
109c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Thread",
110c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ThreadGroup",
111c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ThreadLocal",
112c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Throwable",
113c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Void",
114c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Thread.State",
115c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ArithmeticException",
116c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ArrayIndexOutOfBoundsException",
117c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ArrayStoreException",
118c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ClassCastException",
119c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ClassNotFoundException",
120c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "CloneNotSupportedException",
121c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "EnumConstantNotPresentException",
122c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Exception",
123c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "IllegalAccessException",
124c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "IllegalArgumentException",
125c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "IllegalMonitorStateException",
126c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "IllegalStateException",
127c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "IllegalThreadStateException",
128c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "IndexOutOfBoundsException",
129c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "InstantiationException",
130c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "InterruptedException",
131c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "NegativeArraySizeException",
132c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "NoSuchFieldException",
133c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "NoSuchMethodException",
134c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "NullPointerException",
135c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "NumberFormatException",
136c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ReflectiveOperationException",
137c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "RuntimeException",
138c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "SecurityException",
139c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "StringIndexOutOfBoundsException",
140c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "TypeNotPresentException",
141c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "UnsupportedOperationException",
142c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "AbstractMethodError",
143c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "AssertionError",
144c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ClassCircularityError",
145c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ClassFormatError",
146c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "Error",
147c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ExceptionInInitializerError",
148c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "IllegalAccessError",
149c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "IncompatibleClassChangeError",
150c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "InstantiationError",
151c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "InternalError",
152c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "LinkageError",
153c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "NoClassDefFoundError",
154c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "NoSuchFieldError",
155c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "NoSuchMethodError",
156c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "OutOfMemoryError",
157c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "StackOverflowError",
158c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "ThreadDeath",
159c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "UnknownError",
160c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "UnsatisfiedLinkError",
161c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "UnsupportedClassVersionError",
162c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "VerifyError",
163c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount            "VirtualMachineError",
164c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount    };
16543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar
1667ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount    public LayoutBinder(ResourceBundle.LayoutFileBundle layoutBundle) {
167d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        mExprModel = new ExprModel();
168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        mExpressionParser = new ExpressionParser(mExprModel);
169895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar        mBindingTargets = new ArrayList<BindingTarget>();
1703bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar        mBundle = layoutBundle;
171a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        mModulePackage = layoutBundle.getModulePackage();
1723bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar        // copy over data.
173c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar        for (ResourceBundle.NameTypeLocation variable : mBundle.getVariables()) {
174c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar            addVariable(variable.name, variable.type, variable.location);
1753bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar        }
1763bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar
177c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar        for (ResourceBundle.NameTypeLocation userImport : mBundle.getImports()) {
178c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar            mExprModel.addImport(userImport.name, userImport.type, userImport.location);
1793bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar        }
180c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount        for (String javaLangClass : sJavaLangClasses) {
181c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar            mExprModel.addImport(javaLangClass, "java.lang." + javaLangClass, null);
182c96847768305d83c6bc4919432af9bd9bfe4c08eGeorge Mount        }
18334a18e6a231f3b64726bd93e7e097a0d5a75995dGeorge Mount        for (BindingTargetBundle targetBundle : mBundle.getBindingTargetBundles()) {
1843bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar            final BindingTarget bindingTarget = createBindingTarget(targetBundle);
1853bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar            for (ResourceBundle.BindingTargetBundle.BindingBundle bindingBundle : targetBundle
1863bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar                    .getBindingBundleList()) {
187c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                bindingTarget.addBinding(bindingBundle.getName(), parse(bindingBundle.getExpr(),
188c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                        targetBundle.getLocation()));
1893bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar            }
190e9b33bac04bb1ce1444d7f1744fcec1ecd3a57daYigit Boyar            bindingTarget.resolveMultiSetters();
1913bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar        }
19296e1c821dd446d1ed78f8ae61131550588f60a24George Mount        mSortedBindingTargets = new ArrayList<BindingTarget>(mBindingTargets);
19396e1c821dd446d1ed78f8ae61131550588f60a24George Mount        Collections.sort(mSortedBindingTargets, COMPARE_FIELD_NAME);
194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
195d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
1965bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar    public void resolveWhichExpressionsAreUsed() {
197895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar        List<Expr> used = new ArrayList<Expr>();
1985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar        for (BindingTarget target : mBindingTargets) {
1995bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar            for (Binding binding : target.getBindings()) {
2005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar                binding.getExpr().setIsUsed(true);
2015bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar                used.add(binding.getExpr());
2025bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar            }
2035bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar        }
2045bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar        while (!used.isEmpty()) {
2055bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar            Expr e = used.remove(used.size() - 1);
2065bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar            for (Dependency dep : e.getDependencies()) {
2075bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar                if (!dep.getOther().isUsed()) {
2085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar                    used.add(dep.getOther());
2095bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar                    dep.getOther().setIsUsed(true);
2105bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar                }
2115bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar            }
2125bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar        }
2135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar    }
2145bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar
215c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar    public IdentifierExpr addVariable(String name, String type, Location location) {
2162611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar        Preconditions.check(!mUserDefinedVariables.containsKey(name),
2175bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar                "%s has already been defined as %s", name, type);
218d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        final IdentifierExpr id = mExprModel.identifier(name);
219d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        id.setUserDefinedType(type);
220d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        id.enableDirectInvalidation();
221c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar        if (location != null) {
222c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar            id.addLocation(location);
223c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar        }
2245bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar        mUserDefinedVariables.put(name, type);
225d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return id;
226d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
227d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
2285bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar    public HashMap<String, String> getUserDefinedVariables() {
2295bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar        return mUserDefinedVariables;
2305bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar    }
2315bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar
2323bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar    public BindingTarget createBindingTarget(ResourceBundle.BindingTargetBundle targetBundle) {
2333bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar        final BindingTarget target = new BindingTarget(targetBundle);
234d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        mBindingTargets.add(target);
235d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        target.setModel(mExprModel);
236d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return target;
237d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
238d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
239c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar    public Expr parse(String input, @Nullable Location locationInFile) {
240c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar        final Expr parsed = mExpressionParser.parse(input, locationInFile);
241d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        parsed.setBindingExpression(true);
242d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return parsed;
243d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
244d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
245d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public List<BindingTarget> getBindingTargets() {
246d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return mBindingTargets;
247d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
248d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
24996e1c821dd446d1ed78f8ae61131550588f60a24George Mount    public List<BindingTarget> getSortedTargets() {
25096e1c821dd446d1ed78f8ae61131550588f60a24George Mount        return mSortedBindingTargets;
25196e1c821dd446d1ed78f8ae61131550588f60a24George Mount    }
25296e1c821dd446d1ed78f8ae61131550588f60a24George Mount
253d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public boolean isEmpty() {
254d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return mExprModel.size() == 0;
255d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
256d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
257d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public ExprModel getModel() {
258d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return mExprModel;
259d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
260d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
26143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar    private void ensureWriter() {
26243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar        if (mWriter == null) {
26343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar            mWriter = new LayoutBinderWriter(this);
26443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar        }
26543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar    }
2663bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar
2678b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar    public String writeViewBinderBaseClass(boolean forLibrary) {
26843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar        ensureWriter();
2698b1da958f181639d33dfaa907c0ee66add2decd6Yigit Boyar        return mWriter.writeBaseClass(forLibrary);
27043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar    }
27143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar
27243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar
27396e1c821dd446d1ed78f8ae61131550588f60a24George Mount    public String writeViewBinder(int minSdk) {
274716ba89e7f459f49ea85070d4710c1d79d715298George Mount        mExprModel.seal(this);
27543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar        ensureWriter();
2767ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount        Preconditions.checkNotNull(getPackage(), "package cannot be null");
2777ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount        Preconditions.checkNotNull(getClassName(), "base class name cannot be null");
27896e1c821dd446d1ed78f8ae61131550588f60a24George Mount        return mWriter.write(minSdk);
279d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
280d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
281d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public String getPackage() {
2827ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount        return mBundle.getBindingClassPackage();
283d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
284d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
28596e1c821dd446d1ed78f8ae61131550588f60a24George Mount    public boolean isMerge() {
28696e1c821dd446d1ed78f8ae61131550588f60a24George Mount        return mBundle.isMerge();
28796e1c821dd446d1ed78f8ae61131550588f60a24George Mount    }
28896e1c821dd446d1ed78f8ae61131550588f60a24George Mount
289a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    public String getModulePackage() {
290a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar        return mModulePackage;
291a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar    }
292a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar
293d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public String getLayoutname() {
2943bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar        return mBundle.getFileName();
295d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
296d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
297dea555cf42dc3583604699c8c018d22681f56166George Mount    public String getImplementationName() {
2985bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar        if (hasVariations()) {
2997ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount            return mBundle.getBindingClassName() + mBundle.getConfigName() + "Impl";
3005bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar        } else {
3017ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount            return mBundle.getBindingClassName();
3025bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar        }
303d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
3043bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar
305dea555cf42dc3583604699c8c018d22681f56166George Mount    public String getClassName() {
3067ff60c24c6de7ba0c674fe65a82ad4a88dab2e5dGeorge Mount        return mBundle.getBindingClassName();
30743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar    }
3085bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar
3090390898cf7c4fcad255e8cfd6802f722b516cb2cGeorge Mount    public String getTag() {
3100390898cf7c4fcad255e8cfd6802f722b516cb2cGeorge Mount        return mBundle.getDirectory() + "/" + mBundle.getFileName();
3115bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar    }
3125bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar
3135bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar    public boolean hasVariations() {
3143bd87eef217d80a233677d7e267224d0ed3c2c55Yigit Boyar        return mBundle.hasVariations();
3155bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar    }
316716ba89e7f459f49ea85070d4710c1d79d715298George Mount
317716ba89e7f459f49ea85070d4710c1d79d715298George Mount    @Override
318716ba89e7f459f49ea85070d4710c1d79d715298George Mount    public void resolveListeners() {
319716ba89e7f459f49ea85070d4710c1d79d715298George Mount        for (BindingTarget target : mBindingTargets) {
320716ba89e7f459f49ea85070d4710c1d79d715298George Mount            for (Binding binding : target.getBindings()) {
321716ba89e7f459f49ea85070d4710c1d79d715298George Mount                binding.resolveListeners();
322716ba89e7f459f49ea85070d4710c1d79d715298George Mount            }
323716ba89e7f459f49ea85070d4710c1d79d715298George Mount        }
324716ba89e7f459f49ea85070d4710c1d79d715298George Mount    }
325d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar}
326