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
19d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport org.antlr.v4.runtime.ANTLRInputStream;
20d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport org.antlr.v4.runtime.CommonTokenStream;
21c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.ParserRuleContext;
22c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.misc.Nullable;
23c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.tree.ErrorNode;
24c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.tree.ParseTreeListener;
25c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.tree.TerminalNode;
26d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
27fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.parser.BindingExpressionLexer;
28fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.parser.BindingExpressionParser;
29fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr;
30fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel;
31c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport android.databinding.tool.store.Location;
32fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.L;
33c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport android.databinding.tool.util.Preconditions;
34c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar
35c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport java.util.ArrayList;
36c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport java.util.List;
37fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount
38d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarpublic class ExpressionParser {
39d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    final ExprModel mModel;
40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    final ExpressionVisitor visitor;
41d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
42d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public ExpressionParser(ExprModel model) {
43d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        mModel = model;
44d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        visitor = new ExpressionVisitor(mModel);
45d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
46d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
47c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar    public Expr parse(String input, @Nullable Location locationInFile) {
48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        ANTLRInputStream inputStream = new ANTLRInputStream(input);
49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        BindingExpressionLexer lexer = new BindingExpressionLexer(inputStream);
50d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        CommonTokenStream tokenStream = new CommonTokenStream(lexer);
51c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar        final BindingExpressionParser parser = new BindingExpressionParser(tokenStream);
52d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        BindingExpressionParser.BindingSyntaxContext root = parser.bindingSyntax();
53c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar        try {
54c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar            mModel.setCurrentLocationInFile(locationInFile);
55c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar            visitor.setParseTreeListener(new ParseTreeListener() {
56c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                List<ParserRuleContext> mStack = new ArrayList<ParserRuleContext>();
57c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                @Override
58c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                public void visitTerminal(TerminalNode node) {
59c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                }
60c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar
61c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                @Override
62c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                public void visitErrorNode(ErrorNode node) {
63c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                }
64c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar
65c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                @Override
66c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                public void enterEveryRule(ParserRuleContext ctx) {
67c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                    mStack.add(ctx);
68c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                    mModel.setCurrentParserContext(ctx);
69c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                }
70c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar
71c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                @Override
72c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                public void exitEveryRule(ParserRuleContext ctx) {
73c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                    Preconditions.check(ctx == mStack.get(mStack.size() - 1),
74c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                            "Inconsistent exit from context. Received %s, expecting %s",
75c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                            ctx.toInfoString(parser),
76c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                            mStack.get(mStack.size() - 1).toInfoString(parser));
77c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                    mStack.remove(mStack.size() - 1);
78c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                    if (mStack.size() > 0) {
79c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                        mModel.setCurrentParserContext(mStack.get(mStack.size() - 1));
80c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                    } else {
81c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                        mModel.setCurrentParserContext(null);
82c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                    }
83c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar                }
84c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar            });
85731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar            return root.accept(visitor);
86c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar        } finally {
87c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar            mModel.setCurrentLocationInFile(null);
88c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar        }
89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar
91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    public ExprModel getModel() {
92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar        return mModel;
93d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar    }
94d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar}
95