1/*
2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package build.tools.jdwpgen;
27
28import java.util.*;
29import java.io.*;
30
31class SelectNode extends AbstractGroupNode implements TypeNode {
32
33    AbstractSimpleTypeNode typeNode = null;
34
35    void prune() {
36        super.prune();
37        Iterator<Node> it = components.iterator();
38
39        if (it.hasNext()) {
40            Node typeNode = it.next();
41
42            if (typeNode instanceof ByteTypeNode ||
43                      typeNode instanceof IntTypeNode) {
44                this.typeNode = (AbstractSimpleTypeNode)typeNode;
45                it.remove();
46            } else {
47                error("Select must be based on 'int' or 'byte'");
48            }
49        } else {
50            error("empty");
51        }
52    }
53
54    void constrain(Context ctx) {
55        super.constrain(ctx);
56        if (components.size() < 2) {
57            error("Select must have at least two options");
58        }
59    }
60
61    void constrainComponent(Context ctx, Node node) {
62        node.constrain(ctx);
63        if (!(node instanceof AltNode)) {
64            error("Select must consist of selector followed by Alt items");
65        }
66    }
67
68    void document(PrintWriter writer) {
69        typeNode.document(writer);
70        super.document(writer);
71    }
72
73    String docType() {
74        // should never call this
75        error("Internal - called SelectNode.docType()");
76        return null;
77    }
78
79    String commonBaseClass() {
80        return name() + "Common";
81    }
82
83    private String commonVar() {
84        return " a" + commonBaseClass();
85    }
86
87    void genJavaClassSpecifics(PrintWriter writer, int depth) {
88        indent(writer, depth);
89        writer.println("abstract static class " + commonBaseClass() + " {");
90        if (context.isWritingCommand()) {
91            indent(writer, depth+1);
92            writer.println("abstract void write(PacketStream ps);");
93        } else {
94            indent(writer, depth+1);
95            writer.println("abstract " + typeNode.javaParam() + "();");
96        }
97        indent(writer, depth);
98        writer.println("}");
99        typeNode.genJavaDeclaration(writer, depth);
100        indent(writer, depth);
101        writer.println(commonBaseClass() + commonVar() + ";");
102        super.genJavaClassSpecifics(writer, depth);
103    }
104
105    void genJavaClassBodyComponents(PrintWriter writer, int depth) {
106        // don't naively include alt components
107    }
108
109    void genJavaWritingClassBody(PrintWriter writer, int depth,
110                                 String className) {
111        writer.println();
112        indent(writer, depth);
113        writer.print(className + "(" + typeNode.javaParam() + ", ");
114        writer.print(commonBaseClass() + commonVar());
115        writer.println(") {");
116        indent(writer, depth+1);
117        writer.println("this." + typeNode.name() + " = " + typeNode.name() + ";");
118        indent(writer, depth+1);
119        writer.println("this." + commonVar() + " =" + commonVar() + ";");
120        indent(writer, depth);
121        writer.println("}");
122    }
123
124    void genJavaWrites(PrintWriter writer, int depth) {
125        typeNode.genJavaWrite(writer, depth, typeNode.name());
126        indent(writer, depth);
127        writer.println(commonVar() + ".write(ps);");
128    }
129
130    void genJavaReads(PrintWriter writer, int depth) {
131        typeNode.genJavaRead(writer, depth, typeNode.name());
132        indent(writer, depth);
133        writer.println("switch (" + typeNode.name() + ") {");
134        for (Node node : components) {
135            AltNode alt = (AltNode)node;
136            alt.genJavaReadsSelectCase(writer, depth+1, commonVar());
137        }
138        indent(writer, depth);
139        writer.println("}");
140    }
141
142    public void genJavaDeclaration(PrintWriter writer, int depth) {
143        typeNode.genJavaDeclaration(writer, depth);
144        super.genJavaDeclaration(writer, depth);
145    }
146
147    public String javaParam() {
148        return typeNode.javaParam() + ", " + name() + " a" + name();
149    }
150}
151