DataBinderWriter.kt revision 6047998943beebd81e0ae1068df39c0cbee38628
143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar/*
243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * you may not use this file except in compliance with the License.
543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * You may obtain a copy of the License at
643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * Unless required by applicable law or agreed to in writing, software
843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * See the License for the specific language governing permissions and
1143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * limitations under the License.
1243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar */
1343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar
14fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.writer
1543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar
16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.LayoutBinder
1743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar
18e7c2a5e45d7651899790bd347da635875f9c73fbGeorge Mountclass DataBinderWriter(val pkg: String, val projectPackage: String, val className: String,
19e7c2a5e45d7651899790bd347da635875f9c73fbGeorge Mount        val layoutBinders : List<LayoutBinder>, val minSdk : kotlin.Int) {
204df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar    fun write(brWriter : BRWriter) = kcode("") {
2196e1c821dd446d1ed78f8ae61131550588f60a24George Mount        nl("package $pkg;")
2296e1c821dd446d1ed78f8ae61131550588f60a24George Mount        nl("import $projectPackage.BR;")
236047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        block("class $className") {
246047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            nl("final static int TARGET_MIN_SDK = $minSdk;")
2596e1c821dd446d1ed78f8ae61131550588f60a24George Mount            nl("")
266047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            block("public $className()") {
27ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount            }
28ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount            nl("")
296047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            block("public android.databinding.ViewDataBinding getDataBinder(android.databinding.DataBindingComponent bindingComponent, android.view.View view, int layoutId)") {
306047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                block("switch(layoutId)") {
31af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                    layoutBinders.groupBy{it.layoutname }.forEach {
32af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                        val firstVal = it.value[0]
33af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                        tab("case ${firstVal.modulePackage}.R.layout.${firstVal.layoutname}:") {
3459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar                            if (it.value.size == 1) {
35af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                                if (firstVal.isMerge) {
36af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                                    tab("return new ${firstVal.`package`}.${firstVal.implementationName}(bindingComponent, new android.view.View[]{view});")
3796e1c821dd446d1ed78f8ae61131550588f60a24George Mount                                } else {
38af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                                    tab("return ${firstVal.`package`}.${firstVal.implementationName}.bind(view, bindingComponent);")
3996e1c821dd446d1ed78f8ae61131550588f60a24George Mount                                }
4096e1c821dd446d1ed78f8ae61131550588f60a24George Mount                            } else {
4196e1c821dd446d1ed78f8ae61131550588f60a24George Mount                                // we should check the tag to decide which layout we need to inflate
426047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                block("") {
4396e1c821dd446d1ed78f8ae61131550588f60a24George Mount                                    tab("final Object tag = view.getTag();")
4496e1c821dd446d1ed78f8ae61131550588f60a24George Mount                                    tab("if(tag == null) throw new java.lang.RuntimeException(\"view must have a tag\");")
4596e1c821dd446d1ed78f8ae61131550588f60a24George Mount                                    it.value.forEach {
466047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                        block("if (\"${it.tag}_0\".equals(tag))") {
47af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                                            if (it.isMerge) {
48af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                                                tab("return new ${it.`package`}.${it.implementationName}(bindingComponent, new android.view.View[]{view});")
4996e1c821dd446d1ed78f8ae61131550588f60a24George Mount                                            } else {
50af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                                                tab("return new ${it.`package`}.${it.implementationName}(bindingComponent, view);")
515bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar                                            }
526047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                        }
535bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar                                    }
54af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                                    tab("throw new java.lang.IllegalArgumentException(\"The tag for ${firstVal.layoutname} is invalid. Received: \" + tag);");
556047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                }
5643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar                            }
5796e1c821dd446d1ed78f8ae61131550588f60a24George Mount
5843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar                        }
5943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar                    }
6096e1c821dd446d1ed78f8ae61131550588f60a24George Mount                }
616047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                nl("return null;")
6296e1c821dd446d1ed78f8ae61131550588f60a24George Mount            }
636047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            block("android.databinding.ViewDataBinding getDataBinder(android.databinding.DataBindingComponent bindingComponent, android.view.View[] views, int layoutId)") {
646047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                block("switch(layoutId)") {
65af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                    layoutBinders.filter{it.isMerge }.groupBy{it.layoutname }.forEach {
66af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                        val firstVal = it.value[0]
676047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                        block("case ${firstVal.modulePackage}.R.layout.${firstVal.layoutname}:") {
6859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar                            if (it.value.size == 1) {
69af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                                tab("return new ${firstVal.`package`}.${firstVal.implementationName}(bindingComponent, views);")
7096e1c821dd446d1ed78f8ae61131550588f60a24George Mount                            } else {
7196e1c821dd446d1ed78f8ae61131550588f60a24George Mount                                // we should check the tag to decide which layout we need to inflate
726047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                nl("final Object tag = views[0].getTag();")
736047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                nl("if(tag == null) throw new java.lang.RuntimeException(\"view must have a tag\");")
746047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                it.value.forEach {
756047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                    block("if (\"${it.tag}_0\".equals(tag))") {
766047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                        nl("return new ${it.`package`}.${it.implementationName}(bindingComponent, views);")
7796e1c821dd446d1ed78f8ae61131550588f60a24George Mount                                    }
786047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                }
7996e1c821dd446d1ed78f8ae61131550588f60a24George Mount                            }
8096e1c821dd446d1ed78f8ae61131550588f60a24George Mount                        }
8196e1c821dd446d1ed78f8ae61131550588f60a24George Mount                    }
8243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar                }
836047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                nl("return null;")
8496e1c821dd446d1ed78f8ae61131550588f60a24George Mount            }
8596e1c821dd446d1ed78f8ae61131550588f60a24George Mount
866047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            block("int getLayoutId(String tag)") {
876047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                block("if (tag == null)") {
886047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                    nl("return 0;");
894df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                }
904df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                // String.hashCode is well defined in the API so we can rely on it being the same on the device and the host machine
916047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                nl("final int code = tag.hashCode();");
926047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                block("switch(code)") {
93af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar                    layoutBinders.groupBy {"${it.tag}_0".hashCode()}.forEach {
946047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                        block("case ${it.key}:") {
954df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                            it.value.forEach {
966047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                block("if(tag.equals(\"${it.tag}_0\"))") {
976047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                                    nl("return ${it.modulePackage}.R.layout.${it.layoutname};")
984df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                                }
994df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                            }
1006047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                            nl("break;")
1014df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                        }
1024df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar
1034df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                    }
104ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount                }
1056047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                nl("return 0;")
106ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount            }
1074df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar
1086047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            block("String convertBrIdToString(int id)") {
1096047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                block("if (id < 0 || id >= InnerBrLookup.sKeys.length)") {
1106047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                    nl("return null;")
1116047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                }
1126047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                nl("return InnerBrLookup.sKeys[id];")
1136047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            }
1144df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar
1156047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            block("private static class InnerBrLookup") {
1166047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                nl("static String[] sKeys = new String[]{") {
1174df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                    tab("\"_all\"")
1184df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                    brWriter.indexedProps.forEach {
1194df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                        tab(",\"${it.value}\"")
1204df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                    }
1214df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar                }.app("};")
1226047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            }
12396e1c821dd446d1ed78f8ae61131550588f60a24George Mount        }
12496e1c821dd446d1ed78f8ae61131550588f60a24George Mount    }.generate()
12543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar}