blob: 6ace32b6cc76566fffc8a7ab5232edd54c3a0caa [file] [log] [blame]
/* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.etch.bindings.c.compiler;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.etch.compiler.Backend;
import org.apache.etch.compiler.CmdLineOptions;
import org.apache.etch.compiler.EtchGrammar;
import org.apache.etch.compiler.EtchGrammarConstants;
import org.apache.etch.compiler.EtchHelper;
import org.apache.etch.compiler.LogHandler;
import org.apache.etch.compiler.Output;
import org.apache.etch.compiler.ParseException;
import org.apache.etch.compiler.Token;
import org.apache.etch.compiler.Version;
import org.apache.etch.compiler.ast.Builtin;
import org.apache.etch.compiler.ast.Except;
import org.apache.etch.compiler.ast.Item;
import org.apache.etch.compiler.ast.Message;
import org.apache.etch.compiler.ast.MessageDirection;
import org.apache.etch.compiler.ast.Module;
import org.apache.etch.compiler.ast.MsgDirHelper;
import org.apache.etch.compiler.ast.Name;
import org.apache.etch.compiler.ast.Named;
import org.apache.etch.compiler.ast.ParamList;
import org.apache.etch.compiler.ast.Parameter;
import org.apache.etch.compiler.ast.ReservedWordChecker;
import org.apache.etch.compiler.ast.Service;
import org.apache.etch.compiler.ast.Struct;
import org.apache.etch.compiler.ast.Thrown;
import org.apache.etch.compiler.ast.TypeRef;
import org.apache.etch.compiler.opt.ToString;
import org.apache.etch.compiler.opt.ToString.FieldItem;
import org.apache.etch.compiler.opt.ToString.FmtItem;
import org.apache.etch.compiler.opt.ToString.StringItem;
import org.apache.etch.util.Assertion;
import org.apache.etch.util.Hash;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.log.LogChute;
/**
* Compiler is a helper class not only for Backend, but also for the templates.
* They call methods here to perform "hard" tasks.
*/
public class Compiler extends Backend {
private final static String tmplPath1 = "org/apache/etch/bindings/c/compiler/";
private final static String tmplPath2 = "resources/org/apache/etch/bindings/c/compiler/";
private final static String fnSuffixH = ".h";
private final static String fnSuffixI = ".c";
private final static String VERSION = Version.VERSION + " / "
+ CompilerVersion.VERSION;
/**
* Constructs the Compiler. This is a helper class not only for Backend, but
* also for the templates. They call methods here to perform "hard" tasks.
*
* @throws Exception
*/
public Compiler() throws Exception {
initVelocity();
String[] path = { tmplPath1, tmplPath2 };
// value factory templates
vf_h_vm = getTemplate(path, "vf_h.vm");
vf_c_vm = getTemplate(path, "vf_c.vm");
// interface templates
intf_h_vm = getTemplate(path, "intf_h.vm");
intf_c_vm = getTemplate(path, "intf_c.vm");
implx_c_vm = getTemplate(path, "implx_c.vm");
// remote interface templates
remote_h_vm = getTemplate(path, "remote_h.vm");
remote_c_vm = getTemplate(path, "remote_c.vm");
remote_server_h_vm = getTemplate(path, "remote_server_h.vm");
remote_server_c_vm = getTemplate(path, "remote_server_c.vm");
remote_client_h_vm = getTemplate(path, "remote_client_h.vm");
remote_client_c_vm = getTemplate(path, "remote_client_c.vm");
// interface stub templates
stub_h_vm = getTemplate(path, "stub_h.vm");
stub_c_vm = getTemplate(path, "stub_c.vm");
// helper templates
helper_h_vm = getTemplate(path, "helper_h.vm");
helper_c_vm = getTemplate(path, "helper_c.vm");
// readme template
readme_vm = getTemplate(path, "readme.vm");
// Main template
main_h_vm = getTemplate(path, "main_h.vm");
main_c_vm = getTemplate(path, "main_c.vm");
// Base template
base_h_vm = getTemplate(path, "base_h.vm");
base_c_vm = getTemplate(path, "base_c.vm");
// Implementation template
impl_h_vm = getTemplate(path, "impl_h.vm");
impl_c_vm = getTemplate(path, "impl_c.vm");
etch_keywords_vm = getTemplate(path, "etch_keywords.vm");
// Keyword list
local_kwd = getPath(path, "cKeywords.kwd");
}
// Value Factory
private final Template vf_h_vm;
private final Template vf_c_vm;
// interface templates
private final Template intf_h_vm;
private final Template intf_c_vm;
// remote interface templates
private final Template remote_h_vm;
private final Template remote_c_vm;
private final Template remote_server_h_vm;
private final Template remote_server_c_vm;
private final Template remote_client_h_vm;
private final Template remote_client_c_vm;
// interface stub templates
private final Template stub_h_vm;
private final Template stub_c_vm;
// helper templates
private final Template helper_h_vm;
private final Template helper_c_vm;
// readme template
private final Template readme_vm;
// Main template
private final Template main_h_vm;
private final Template main_c_vm;
// Base template
private final Template base_h_vm;
private final Template base_c_vm;
// Implementation template
private final Template impl_h_vm;
private final Template impl_c_vm;
private final Template implx_c_vm;
private final Template etch_keywords_vm;
private final String local_kwd;
private LogHandler lh;
/**
* Initializes use of velocity engine and sets up resource loaders.
*
* @throws Exception
*/
private void initVelocity() throws Exception {
Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, new MyLogger());
Velocity.setProperty(Velocity.RESOURCE_LOADER, "file, class");
Velocity.setProperty("file.resource.loader.description",
"Velocity File Resource Loader");
Velocity
.setProperty("file.resource.loader.class",
"org.apache.velocity.runtime.resource.loader.FileResourceLoader");
Velocity.setProperty("file.resource.loader.path", ".");
Velocity.setProperty("class.resource.loader.description",
"Velocity Classpath Resource Loader");
Velocity
.setProperty("class.resource.loader.class",
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
Velocity.init();
}
private static class MyLogger implements LogChute {
private final LogHandler lh = null;
public void init(RuntimeServices rts) throws Exception {
// ignore.
}
public boolean isLevelEnabled(int level) {
return level >= 2;
}
public void log(int level, String msg) {
if (level < 2)
return;
if (lh != null)
lh.report(level == 2 ? LogHandler.LEVEL_WARNING
: LogHandler.LEVEL_ERROR, null, msg);
else
System.out.printf("Velocity msg (%d): %s\n", level, msg);
}
public void log(int level, String msg, Throwable e) {
if (level < 2)
return;
if (lh != null)
lh.report(level == 2 ? LogHandler.LEVEL_WARNING
: LogHandler.LEVEL_ERROR, null, msg);
else
System.out.printf("Velocity msg (%d): %s: %s\n", level, msg, e);
}
}
/**
* @param path
* @param fn
* @return the velocity template
* @throws Exception
*/
private Template getTemplate(String[] path, String fn) throws Exception {
ResourceNotFoundException rnfe = null;
for (String p : path) {
if (p == null)
continue;
// System.out.println( "trying to load template "+(p+fn) );
try {
if (Velocity.resourceExists(p + fn))
return Velocity.getTemplate(p + fn);
} catch (ResourceNotFoundException e) {
rnfe = e;
} catch (Exception e) {
System.out.println("ignoring " + e);
}
}
if (rnfe != null)
throw rnfe;
throw new ResourceNotFoundException("could not find resource: " + fn);
}
@Override
public void generate(Module module, CmdLineOptions options)
throws Exception {
// java always wants to not flatten packages:
options.noFlattenPackages = true;
lh = options.lh;
boolean ignoreGlobal = options.ignoreGlobalWordsList;
boolean ignoreLocal = options.ignoreLocalWordsList;
String userWords = options.userWordsList != null ? options.userWordsList
.getPath()
: null;
Set<String> what = options.what;
// Load the reserved words lists if any have been provided.
Map<String, String> words = new HashMap<String, String>();
if (!ignoreGlobal)
mapWords(global_kwd, words);
if (!ignoreLocal)
mapWords(local_kwd, words);
if (userWords != null)
mapWords(userWords, words);
// check for collisions with the reserved word list.
ReservedWordChecker checker = new ReservedWordChecker(words, false, lh);
module.treewalk(checker);
if (!checker.ok()) {
lh.report(LogHandler.LEVEL_ERROR, null,
"Encountered errors during c generation.");
return;
}
// ok, we're ready to generate code. make sure the
// output directories exist.
Output dir = options.output;
Output templateDir = options.templateOutput;
// generate code for each service.
for (Service intf : module) {
generate(intf, what, dir, templateDir);
}
}
public boolean isGenerateImpl() {
return isGenerateImpl;
}
public boolean isGenerateMain() {
return isGenerateMain;
}
boolean isGenerateImpl;
boolean isGenerateMain;
private void generate(final Service intf, Set<String> what, Output dir,
Output templateDir) throws Exception {
what = populateWhat(what);
if (what.isEmpty()) {
return;
}
final MessageDirection msgDir = getMessageDirection(what);
if (what.contains(WHAT_INTF)) {
// Generate the value factory file.
generateVf(intf, dir);
// Generate the interface, remote, and stub files.
generateIntfRemoteStub(intf, dir, msgDir, MessageDirection.BOTH,
false);
generateIntfRemoteStub(intf, dir, msgDir, MessageDirection.SERVER,
true);
generateIntfRemoteStub(intf, dir, msgDir, MessageDirection.CLIENT,
true);
// Generate helper file.
generateHelper(intf, dir, msgDir);
// Generate base file.
generateBase(intf, dir, msgDir, MessageDirection.SERVER, true);
generateBase(intf, dir, msgDir, MessageDirection.CLIENT, true);
// Generate readme file.
generateReadme(intf, dir, msgDir);
generateKeywordList(intf, dir, msgDir, MessageDirection.BOTH, true);
}
// Generate main template file.
if (what.contains(WHAT_MAIN)) {
isGenerateMain = true;
generateMain(intf, templateDir, msgDir);
}
// Generate impl template file.
if (what.contains(WHAT_IMPL)) {
isGenerateImpl = true;
generateImpl(intf, templateDir, msgDir);
}
}
private void generateReadme(final Service intf, Output dir,
final MessageDirection msgDir) throws Exception {
doFile(dir, "readme-etch-c-files.txt", lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateReadme(pw, intf, msgDir);
}
});
}
private void generateVf(final Service intf, Output dir) throws Exception {
doFile(dir, getVfName(intf) + fnSuffixH, lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateVfH(pw, intf);
}
});
doFile(dir, getVfName(intf) + fnSuffixI, lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateVfI(pw, intf);
}
});
}
private void generateHelper(final Service intf, Output dir,
final MessageDirection msgDir) throws Exception {
doFile(dir, getHelperName(intf) + fnSuffixH, lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateHelperH(pw, intf, msgDir);
}
});
doFile(dir, getHelperName(intf) + fnSuffixI, lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateHelperI(pw, intf, msgDir);
}
});
}
private void generateMain(final Service intf, Output dir,
MessageDirection msgDir) throws Exception {
if (msgDir == MessageDirection.BOTH
|| msgDir == MessageDirection.CLIENT) {
doFile(dir, getMainName(intf, MessageDirection.CLIENT) + fnSuffixH,
lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateMainH(pw, intf, MessageDirection.CLIENT,
false);
}
});
doFile(dir, getMainName(intf, MessageDirection.CLIENT) + fnSuffixI,
lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateMainI(pw, intf, MessageDirection.CLIENT,
false);
}
});
}
if (msgDir == MessageDirection.BOTH
|| msgDir == MessageDirection.SERVER) {
doFile(dir, getMainName(intf, MessageDirection.SERVER) + fnSuffixH,
lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateMainH(pw, intf, MessageDirection.SERVER,
false);
}
});
doFile(dir, getMainName(intf, MessageDirection.SERVER) + fnSuffixI,
lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateMainI(pw, intf, MessageDirection.SERVER,
false);
}
});
}
}
private void generateKeywordList(final Service intf, Output dir,
final MessageDirection what, final MessageDirection mc,
final boolean hasBaseClass) throws Exception {
doFile(dir, getKeywordFilename(intf), lh,
new Gen() {
public void run(PrintWriter pw) throws Exception {
generateKeywords(pw, intf, mc, hasBaseClass);
}
});
}
private void generateBase(final Service intf, Output dir,
final MessageDirection what, final MessageDirection mc,
final boolean hasBaseClass) throws Exception {
doFile(dir, getBaseFileNameH(intf, getDirectionName(mc)), lh,
new Gen() {
public void run(PrintWriter pw) throws Exception {
generateBaseH(pw, intf, mc, hasBaseClass);
}
});
doFile(dir, getBaseFileNameI(intf, getDirectionName(mc)), lh,
new Gen() {
public void run(PrintWriter pw) throws Exception {
generateBaseI(pw, intf, mc, hasBaseClass);
}
});
}
private void generateImpl(final Service intf, Output dir,
MessageDirection msgDir) throws Exception {
if (msgDir == MessageDirection.BOTH
|| msgDir == MessageDirection.CLIENT) {
doFile(dir, getImplFileNameH(intf,
getDirectionName(MessageDirection.CLIENT)), lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateImplH(pw, intf, MessageDirection.CLIENT, false);
}
});
doFile(dir, getImplFileNameI(intf,
getDirectionName(MessageDirection.CLIENT)), lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateImplI(pw, intf, MessageDirection.CLIENT, false);
}
});
doFile(dir, getImplXFileNameI(intf,
getDirectionName(MessageDirection.CLIENT)), lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateImplXI(pw, intf, MessageDirection.CLIENT, false);
}
});
}
if (msgDir == MessageDirection.BOTH
|| msgDir == MessageDirection.SERVER) {
doFile(dir, getImplFileNameH(intf,
getDirectionName(MessageDirection.SERVER)), lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateImplH(pw, intf, MessageDirection.SERVER, false);
}
});
doFile(dir, getImplFileNameI(intf,
getDirectionName(MessageDirection.SERVER)), lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateImplI(pw, intf, MessageDirection.SERVER, false);
}
});
doFile(dir, getImplXFileNameI(intf,
getDirectionName(MessageDirection.SERVER)), lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateImplXI(pw, intf, MessageDirection.SERVER, false);
}
});
}
}
private void generateIntfRemoteStub(final Service intf, Output dir,
final MessageDirection what, final MessageDirection mc,
final boolean hasBaseClass) throws Exception {
// Generate interface file
if (mc == MessageDirection.BOTH) {
doFile(dir, getIntfFileNameH(intf), lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateIntfH(pw, intf, mc, hasBaseClass);
}
});
doFile(dir, getIntfFileNameI(intf), lh, new Gen() {
public void run(PrintWriter pw) throws Exception {
generateIntfI(pw, intf, mc, hasBaseClass);
}
});
}
// Generate remote file
if (mc == MessageDirection.BOTH || what == MessageDirection.BOTH
|| mc != what) {
doFile(dir, getRemoteFileNameH(intf, getDirectionName(mc)), lh,
new Gen() {
public void run(PrintWriter pw) throws Exception {
generateRemoteH(pw, intf, mc, hasBaseClass);
}
});
doFile(dir, getRemoteFileNameI(intf, getDirectionName(mc)), lh,
new Gen() {
public void run(PrintWriter pw) throws Exception {
generateRemoteI(pw, intf, mc, hasBaseClass);
}
});
}
// Generate stub file
if (mc != what) {
doFile(dir, getStubFileNameH(intf, getDirectionName(mc)), lh,
new Gen() {
public void run(PrintWriter pw) throws Exception {
generateStubH(pw, intf, mc, hasBaseClass);
}
});
doFile(dir, getStubFileNameI(intf, getDirectionName(mc)), lh,
new Gen() {
public void run(PrintWriter pw) throws Exception {
generateStubI(pw, intf, mc, hasBaseClass);
}
});
}
}
/**
* Generate the value factory header for the service.
*
* @param pw
* @param intf
* @throws Exception
*/
void generateVfH(PrintWriter pw, Service intf) throws Exception {
// params keeps track of the total set of parameters
// named (for enums, structs, exceptions, and messages).
Set<String> params = new HashSet<String>();
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("params", params);
vf_h_vm.merge(context, pw);
}
/**
* Generate the value factory implementation for the service.
*
* @param pw
* @param intf
* @throws Exception
*/
void generateVfI(PrintWriter pw, Service intf) throws Exception {
// params keeps track of the total set of parameters
// named (for enums, structs, exceptions, and messages).
Set<String> params = new HashSet<String>();
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("params", params);
vf_c_vm.merge(context, pw);
}
/**
* Generate the interface header for the service.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateIntfH(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
intf_h_vm.merge(context, pw);
}
/**
* Generate the interface implementation for the service.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateIntfI(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
intf_c_vm.merge(context, pw);
}
/**
* Generate the call to message implementation of the interface. This class
* turns calls on its methods into messages which are sent to the remote
* stub. For two-way calls, it then waits for a response message, returning
* the result therein to the caller.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateRemoteH(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
context.put("methodList", new ArrayList<String>());
switch (mc) {
case BOTH:
remote_h_vm.merge(context, pw);
break;
case SERVER:
remote_server_h_vm.merge(context, pw);
break;
case CLIENT:
remote_client_h_vm.merge(context, pw);
break;
default:
break;
}
}
/**
* Generate the call to message implementation of the interface. This class
* turns calls on its methods into messages which are sent to the remote
* stub. For two-way calls, it then waits for a response message, returning
* the result therein to the caller.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateRemoteI(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
context.put("methodList", new ArrayList<String>());
switch (mc) {
case BOTH:
remote_c_vm.merge(context, pw);
break;
case SERVER:
remote_server_c_vm.merge(context, pw);
break;
case CLIENT:
remote_client_c_vm.merge(context, pw);
break;
default:
break;
}
}
/**
* Generate the message to call implementation. This class accepts a message
* and turns it back into a call on the user's implementation. For two-way
* messages, the return value from the user's implementation method is
* turned into the appropriate response message and sent.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateStubH(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("suffix_remote", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
stub_h_vm.merge(context, pw);
}
/**
* Generate the message to call implementation. This class accepts a message
* and turns it back into a call on the user's implementation. For two-way
* messages, the return value from the user's implementation method is
* turned into the appropriate response message and sent.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateStubI(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("suffix_remote", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
stub_c_vm.merge(context, pw);
}
/**
* Generate the transport plumbing helper.
*
* @param pw
* @param intf
* @param mc
* @throws Exception
*/
void generateHelperH(PrintWriter pw, Service intf, MessageDirection mc)
throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
helper_h_vm.merge(context, pw);
}
/**
* Generate the transport plumbing helper.
*
* @param pw
* @param intf
* @param mc
* @throws Exception
*/
void generateHelperI(PrintWriter pw, Service intf, MessageDirection mc)
throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
helper_c_vm.merge(context, pw);
}
/**
* Generate the readme.txt.
*
* @param pw
* @param intf
* @param mc
* @throws Exception
*/
void generateReadme(PrintWriter pw, Service intf, MessageDirection mc)
throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
readme_vm.merge(context, pw);
}
/**
* Generate the template main program.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateMainH(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
main_h_vm.merge(context, pw);
}
/**
* Generate the template main program.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateMainI(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
main_c_vm.merge(context, pw);
}
/**
* Generates the base implementation of the interfaces, with each method
* throwing an exception to the tune that it isn't implemented. User's impl
* will extend this base implementation.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateBaseH(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
context.put("methodList", new ArrayList<String>());
base_h_vm.merge(context, pw);
}
/**
* Generates the base implementation of the interfaces, with each method
* throwing an exception to the tune that it isn't implemented. User's impl
* will extend this base implementation.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateBaseI(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
context.put("methodList", new ArrayList<String>());
base_c_vm.merge(context, pw);
}
/**
* Generate the template user implemention class which extends the base
* implementation generated above. This class will only have the appropriate
* constructor and reference to the appropriate remote, and a comment
* inviting the user to override methods.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateImplH(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
impl_h_vm.merge(context, pw);
}
/**
* Generate the template user implemention class which extends the base
* implementation generated above. This class will only have the appropriate
* constructor and reference to the appropriate remote, and a comment
* inviting the user to override methods.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateImplI(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
impl_c_vm.merge(context, pw);
}
void generateKeywords(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
etch_keywords_vm.merge(context, pw);
}
/**
* Generate the template user implemention class which extends the base
* implementation generated above. This class will only have the appropriate
* constructor and reference to the appropriate remote, and a comment
* inviting the user to override methods.
*
* @param pw
* @param intf
* @param mc
* @param hasBaseClass
* @throws Exception
*/
void generateImplXI(PrintWriter pw, Service intf, MessageDirection mc,
boolean hasBaseClass) throws Exception {
VelocityContext context = new VelocityContext();
context.put("now", new Date());
context.put("version", VERSION);
context.put("helper", this);
context.put("intf", intf);
context.put("mc", mc);
context.put("suffix", MsgDirHelper.getSuffix(mc).toLowerCase());
context.put("hasBaseClass", hasBaseClass);
implx_c_vm.merge(context, pw);
}
public String getKeywordForWireshark(String fieldname) {
int hash = Hash.hash(fieldname);
return String.format("0x%08x", hash) + "," + fieldname;
}
public MessageDirection getRemoteDirection(MessageDirection mc) {
if (mc == MessageDirection.SERVER) {
return MessageDirection.CLIENT;
}
if (mc == MessageDirection.BOTH) {
return MessageDirection.BOTH;
}
return MessageDirection.SERVER;
}
public String getRemoteDirectionName(MessageDirection mc) {
return getDirectionName(getRemoteDirection(mc));
}
public boolean hasMessageDirectionBoth(Service intf) {
return intf.hasMessageDirection(MessageDirection.BOTH);
}
public boolean isClient(MessageDirection mc) {
return mc == MessageDirection.CLIENT || mc == MessageDirection.BOTH;
}
public boolean isServer(MessageDirection mc) {
return mc == MessageDirection.SERVER || mc == MessageDirection.BOTH;
}
public String getDirectionName(MessageDirection mc) {
return MsgDirHelper.getSuffix(mc).toLowerCase();
}
public MessageDirection getMsgDirServer(){
return MessageDirection.SERVER;
}
public MessageDirection getMsgDirClient(){
return MessageDirection.CLIENT;
}
public String getServiceName(Service intf) {
return intf.name().name().toLowerCase();
}
public String getIntfName(Service intf) {
return getServiceName(intf);
}
public String getIntfFileNameH(Service intf) {
return getIntfName(intf) + "_interface" + fnSuffixH;
}
public String getIntfFileNameI(Service intf) {
return getIntfName(intf) + "_interface" + fnSuffixI;
}
public String getBaseName(Service intf, String suffix) {
return getServiceName(intf)
+ (suffix != null && !suffix.isEmpty() ? "_" + suffix : "");
}
public String getBaseFileNameH(Service intf, String suffix) {
return getBaseName(intf, suffix) + fnSuffixH;
}
public String getKeywordFilename(Service intf) {
return getServiceName(intf) + "_keywords_wireshark.txt";
}
public String getBaseFileNameI(Service intf, String suffix) {
return getBaseName(intf, suffix) + fnSuffixI;
}
public String getRemoteName(Service intf, String suffix) {
return getServiceName(intf) + "_remote"
+ (suffix != null && !suffix.isEmpty() ? "_" + suffix : "");
}
public String getRemoteFileNameH(Service intf, String suffix) {
return getRemoteName(intf, suffix) + fnSuffixH;
}
public String getRemoteFileNameI(Service intf, String suffix) {
return getRemoteName(intf, suffix) + fnSuffixI;
}
public String getStubName(Service intf, String suffix) {
return getServiceName(intf)
+ (suffix != null && !suffix.isEmpty() ? "_" + suffix : "")
+ "_stub";
}
public String getStubFileNameH(Service intf, String suffix) {
return getStubName(intf, suffix) + fnSuffixH;
}
public String getStubFileNameI(Service intf, String suffix) {
return getStubName(intf, suffix) + fnSuffixI;
}
public String getImplName(Service intf, String suffix) {
return getServiceName(intf)
+ (suffix != null && !suffix.isEmpty() ? "_" + suffix : "")
+ "_impl";
}
public String getImplFileNameH(Service intf, String suffix) {
return getImplName(intf, suffix) + fnSuffixH;
}
public String getImplFileNameI(Service intf, String suffix) {
return getImplName(intf, suffix) + fnSuffixI;
}
public String getImplXName(Service intf, String suffix) {
return getServiceName(intf)
+ (suffix != null && !suffix.isEmpty() ? "_" + suffix : "")
+ "_implx";
}
public String getImplXFileNameH(Service intf, String suffix) {
return getImplXName(intf, suffix) + fnSuffixH;
}
public String getImplXFileNameI(Service intf, String suffix) {
return getImplXName(intf, suffix) + fnSuffixI;
}
public String getVfName(Service intf) {
return getServiceName(intf) + "_valufact";
}
public String getVfFileNameH(Service intf) {
return getVfName(intf) + fnSuffixH;
}
public String getVfFileNameI(Service intf) {
return getVfName(intf) + fnSuffixI;
}
public String getMainName(Service intf, MessageDirection mc) {
if (mc == MessageDirection.SERVER)
return getServiceName(intf) + "_listener_main";
return getServiceName(intf) + "_client_main";
}
public String getMainFileNameH(Service intf, MessageDirection mc) {
return getMainName(intf, mc) + fnSuffixH;
}
public String getMainFileNameI(Service intf, MessageDirection mc) {
return getMainName(intf, mc) + fnSuffixI;
}
public String getHelperName(Service intf) {
return getServiceName(intf) + "_helper";
}
public String getHelperFileNameH(Service intf) {
return getHelperName(intf) + fnSuffixH;
}
public String getHelperFileNameI(Service intf) {
return getHelperName(intf) + fnSuffixI;
}
public void test(TypeRef type) {
int i;
System.out.println(type);
System.out.println("builtin " + type.isBuiltin());
type.getNamed(type.intf()).efqname(this);
}
public void testMsg(Message msg) {
int i;
// msg.getResultParam().efqname(this);
// msg.type().getNamed(msg.service()).efqname(this)
msg.getResultParam().efqname(this);
}
@Override
public String asyncReceiverPoolName(Message msg) {
return msg.getAsyncReceiver().toString().toLowerCase();
}
@Override
public String getTypeValue(TypeRef type, Token value) {
Token t = type.type();
switch (t.kind) {
case EtchGrammarConstants.LONG:
return value.image + "LL";
case EtchGrammarConstants.FLOAT:
case EtchGrammarConstants.DOUBLE:
return value.image + (value.image.indexOf('.')>-1 ? "f" : "");
case EtchGrammarConstants.STRING:
return "L" + protectString(value.image);
case EtchGrammarConstants.BOOLEAN:
return value.image.toUpperCase();
default:
return value.image;
}
}
private String protectString(String s) {
StringBuffer sb = new StringBuffer();
sb.append("\"");
for (char c : s.toCharArray()) {
if (c == '\t') {
sb.append("\\t");
continue;
}
if (c == '\r') {
sb.append("\\r");
continue;
}
if (c == '\n') {
sb.append("\\n");
continue;
}
if (c == '\"') {
sb.append("\\\"");
continue;
}
if (c == '\\') {
sb.append("\\\\");
continue;
}
if (c >= 32 && c < 127) {
sb.append(c);
continue;
}
sb.append(String.format("\\u%04x", (int) c));
}
sb.append("\"");
return sb.toString();
}
@Override
public String getTypeName(TypeRef type) {
if (type.dim() > 0)
return "etch_arraytype*";
return getPointerTypeName(type);
}
public String getNativeTypeNameForConstants(TypeRef type) {
if (type.type().kind == EtchGrammarConstants.STRING)
return "wchar_t*";
return getNativeTypeName(type, false);
}
/**
* @param type
* the etch type
* @return the fundamental native type for c so etch int -> c int, while
* etch string -> wchar* string.
*/
@Override
public String getNativeTypeName(TypeRef type) {
return getNativeTypeName(type, false);
}
public String getNativeTypeName(TypeRef type, boolean addStruct) {
return getNativeTypeName(type, false, false);
}
public String getEtchTypeName(TypeRef type) {
return getNativeTypeName(type, false, true);
}
public String getNativeTypeName(TypeRef type, boolean addStruct, boolean etch_type) {
if (type.isArray()) {
return (etch_type ? "etch_arraytype" : "etch_arraytype*");
}
Token t = type.type();
switch (t.kind) {
case EtchGrammarConstants.VOID:
return "void";
case EtchGrammarConstants.BOOLEAN:
return (etch_type ? "etch_boolean" : "boolean");
case EtchGrammarConstants.BYTE:
return (etch_type ? "etch_int8" : "byte");
case EtchGrammarConstants.SHORT:
return (etch_type ? "etch_int16" : "short");
case EtchGrammarConstants.INT:
return (etch_type ? "etch_int32" : "int");
case EtchGrammarConstants.LONG:
return (etch_type ? "etch_int64" : "int64");
case EtchGrammarConstants.FLOAT:
return (etch_type ? "etch_float" : "float");
case EtchGrammarConstants.DOUBLE:
return (etch_type ? "etch_double" : "double");
case EtchGrammarConstants.STRING:
return (etch_type ? "etch_string" : "etch_string*");
case EtchGrammarConstants.OBJECT:
return (etch_type ? "etch_object" : "etch_object*");
default: {
// we have to use a fully qualified name here.
// find the actual type...
Named<?> n = type.intf().get(t.image);
System.out.println("Token:" + t.image);
if (n == null)
throw new IllegalArgumentException(String.format(
"undefined or ambiguous name at line %d: %s",
t.beginLine, t.image));
if (n.isEnumx())
{
return n.efqname(this) + (etch_type ? "" : "_enum");
}
else
{
return (addStruct ? "struct " : "") + n.efqname(this) + (etch_type ? "" : "*");
}
}
}
}
/**
* @param type
* the etch type
* @return the fundamental native reference type for c. so etch int -> java
* etch_int32*, while etch string -> etch_string*.
*/
public String getPointerTypeName(TypeRef type) {
if (type.isArray())
return "etch_arraytype*";
Token t = type.type();
switch (t.kind) {
case EtchGrammarConstants.VOID:
return "void*";
case EtchGrammarConstants.BOOLEAN:
return "etch_boolean*";
case EtchGrammarConstants.BYTE:
return "etch_byte*";
case EtchGrammarConstants.SHORT:
return "etch_int16*";
case EtchGrammarConstants.INT:
return "etch_int32*";
case EtchGrammarConstants.LONG:
return "etch_int64*";
case EtchGrammarConstants.FLOAT:
return "etch_float*";
case EtchGrammarConstants.DOUBLE:
return "etch_double*";
case EtchGrammarConstants.STRING:
return "etch_string*";
case EtchGrammarConstants.OBJECT:
return "etch_object*";
default: {
// we have to use a fully qualified name here.
// find the actual type...
Named<?> n = type.intf().get(t.image);
if (n == null)
throw new IllegalArgumentException(String.format(
"undefined or ambiguous name at line %d: %s",
t.beginLine, t.image));
return n.efqname(this) + "*";
}
}
}
@Override
public String mfvname(String vname) {
return "_mf_" + vname;
}
@Override
public String mtvname(String vname) {
return "_mt_" + vname;
}
@Override
public String getLang() {
return "c";
}
@Override
public String enum_efqname(String fqname, String moduleName,
String serviceName, String enumName) {
// return serviceName.toLowerCase() + "_" + enumName.toLowerCase();
return serviceName.toLowerCase() + "_" + enumName;
}
@Override
public String except_efqname(String fqname, String moduleName,
String serviceName, String exceptName) {
// return serviceName.toLowerCase() + "_" + exceptName.toLowerCase();
return serviceName.toLowerCase() + "_" + exceptName;
}
@Override
public String struct_efqname(String fqname, String moduleName,
String serviceName, String structName) {
// return serviceName.toLowerCase() + "_" + structName.toLowerCase();
return serviceName.toLowerCase() + "_" + structName;
}
@Override
public String qualifyParameterName(Token name) {
return name.image;
}
@Override
public String qualifyConstantName(Service intf, Token name) {
return intf.fqname() + '.' + name.image;
}
@Override
public String qualifyEnumName(Service intf, Token name) {
return intf.fqname() + '.' + name.image;
}
Set<String> history = new HashSet<String>();
public boolean resetHistory() {
history = new HashSet<String>();
return true;
}
public boolean addStringToHistory(String s) {
history.add(s);
return true;
}
public boolean historyContains(String s) {
return history.contains(s);
}
// ///////////////////////////////////////////////
// /////////////////// WORKSPACE /////////////////
// ///////////////////////////////////////////////
@Override
public String formatString(ParamList<Service> n, boolean isExcept)
throws ParseException, IOException {
ToString ts = (ToString) n.getOpt("ToString");
List<FmtItem> list;
if (ts != null) {
list = ts.getFormat();
n.checkFormatList(ts.lineno(), list);
} else if (isExcept)
list = n.mkFormatList(true, ((Except) n).hasExtends());
else
list = n.mkFormatList(false, ((Struct) n).hasExtends());
if (list.size() == 1) {
return list.get(0).value();
}
StringBuffer sb = new StringBuffer();
sb.append("String.format( ");
sb.append("\"");
for (FmtItem i : list) {
if (i instanceof FieldItem) {
sb.append("%s");
} else {
escape(sb, ((StringItem) i).value());
}
}
sb.append("\"");
for (FmtItem i : list) {
if (i instanceof FieldItem) {
sb.append(", ");
sb.append(((FieldItem) i).value());
}
}
sb.append(" )");
return sb.toString();
}
private void escape(StringBuffer sb, String s) throws IOException {
StringReader rdr = new StringReader(s);
int c;
while ((c = rdr.read()) >= 0) {
if (c == '"')
sb.append("\\\"");
else if (c == '\\')
sb.append("\\\\");
else if (c == '\t')
sb.append("\\t");
else if (c == '\r')
sb.append("\\r");
else if (c == '\n')
sb.append("\\n");
else
sb.append((char) c);
}
}
public String getValidator(Service service, Named<?> named) {
// (objmask*) etchvtor_custom_get(ETCHTYPEB_USER,
// get_dynamic_classid_unique(&CLASSID_TESTER_SIMPLESTRUCT),
// tester_valufact_get_static()->_mt_tester_simpleStruct,
// 1))
if (named instanceof Parameter) {
Parameter param = (Parameter) named;
TypeRef type = param.type();
if (type.isBuiltin())
return String.format("(etch_object*)etchvtor_%s_get( %d )", getValidatorStringForParam(param),
type.dim());
Named<?> n = type.getNamed(type.intf());
if (n.isBuiltin()) {
Builtin b = (Builtin) n;
String cn = b.className();
int i = cn.indexOf('<');
if (i >= 0)
cn = cn.substring(0, i);
String classid = getClassIDBuiltin(b);
String messagetype = getMessageTypeBuiltin(b);
return String.format(
"(etch_object*)etchvtor_custom_get(%s, CLASSID_%s, builtins._mt_%s,%d)",
getEtchTypeForBuiltin(b),classid, messagetype, getDimensionForBuiltin(b));
}
if (n.isStruct() || n.isExcept() || n.isEnumx())
return String.format(
"(etch_object*)etchvtor_custom_get(ETCHTYPEB_USER, get_dynamic_classid_unique(&CLASSID_%s), %s_valufact_get_static()->_mt_%s, %d)",
n.efqname(this).toUpperCase(), service.name().toString().toLowerCase(), n.efqname(this), type.dim());
if (n.isExtern())
{
Assertion.check(false,"extern type not supported for " + n );
}
else
{
Assertion.check(false,"unknown type " + n);
}
return "";
}
if (named instanceof Thrown) {
Thrown thrown = (Thrown) named;
Except e = (Except) thrown.getNamed();
return String.format("(etch_object*)etchvtor_custom_get( ETCHTYPEB_USER,get_dynamic_classid_unique(&%s), %s_valufact_get_static()->_mt_%s_%s,0)",
getClassIdVarName(thrown),getExcept(thrown).service().name().toString().toLowerCase(),getExcept(thrown).service().name().toString().toLowerCase(),thrown);
}
if (named instanceof Item)
return "(etch_object*)etchvtor_boolean_get( 0 )";
return "null";
}
private int getDimensionForBuiltin(Builtin b) {
if(b.bindingName().equals("etch_date"))
return 0;
if(b.bindingName().equals("etch_arraylist"))
return 1;
if(b.bindingName().equals("etch_hashtable"))
return 0;
if(b.bindingName().equals("etch_set"))
return 0;
return 0;
}
private String getEtchTypeForBuiltin(Builtin b) {
if(b.bindingName().equals("etch_date"))
return "ETCHTYPEB_PRIMITIVE";
if(b.bindingName().equals("etch_arraylist"))
return "ETCHTYPEB_ETCHLIST";
if(b.bindingName().equals("etch_hashtable"))
return "ETCHTYPEB_ETCHMAP";
if(b.bindingName().equals("etch_set"))
return "ETCHTYPEB_ETCHSET";
return "ETCHTYPEB_USER";
}
private String getMessageTypeBuiltin(Builtin b) {
if(b.bindingName().equals("etch_date"))
return "_etch_datetime";
if(b.bindingName().equals("etch_arraylist"))
return "_etch_list";
if(b.bindingName().equals("etch_hashtable"))
return "_etch_map";
if(b.bindingName().equals("etch_set"))
return "_etch_set";
return "NULL";
}
private String getClassIDBuiltin(Builtin b) {
if(b.bindingName().equals("etch_date"))
return "DATE";
if(b.bindingName().equals("etch_arraylist"))
return "ETCH_LIST";
if(b.bindingName().equals("etch_hashtable"))
return "ETCH_MAP";
if(b.bindingName().equals("etch_set"))
return "ETCH_SET";
return "NULL";
}
/**
* @param name
* @return the appropriate name for a getter method.
*/
public String getGetterName(Name name) {
String s = name.name;
return "get" + s.substring(0, 1).toUpperCase() + s.substring(1);
}
/**
* @param name
* @return the appropriate name for a setter method.
*/
public String getSetterName(Name name) {
String s = name.name;
return "set" + s.substring(0, 1).toUpperCase() + s.substring(1);
}
@Override
public void addDefaults(Service service) throws ParseException {
addBuiltin( service, newName( "List" ), "etch_arraylist", true );
addBuiltin( service, newName( "Map" ), "etch_hashtable", true );
addBuiltin( service, newName( "Set" ), "etch_set", true );
addBuiltin(service, newName("Datetime"), "etch_date", false);
}
public String getValidatorStringForParam(Parameter param) {
TypeRef type = param.type();
return getValidatorStringForParam(type);
}
public String getValidatorStringForParam(TypeRef type) {
switch (type.type().kind) {
case EtchGrammarConstants.BOOLEAN:
return "boolean";
case EtchGrammarConstants.BYTE:
return "byte";
case EtchGrammarConstants.INT:
return "int32";
case EtchGrammarConstants.SHORT:
return "int16";
case EtchGrammarConstants.DOUBLE:
return "double";
case EtchGrammarConstants.FLOAT:
return "float";
case EtchGrammarConstants.LONG:
return "int64";
case EtchGrammarConstants.STRING:
return "string";
}
// what should be the default here?
return "object";
}
public String getValidatorStringForParam(Message param) {
return getValidatorStringForParam(param.type());
}
public boolean isEnumParam(Parameter p) {
if (p.type() == null)
return false;
if (p.type().intf() == null)
return false;
if (p.type().getNamed(p.type().intf()) == null)
return false;
return p.type().getNamed(p.type().intf()).isEnumx();
}
public boolean isCustomType(Parameter param) {
return isCustomType(param.type());
}
public boolean isRefType(TypeRef param) {
if(param == null)
return true;
switch(param.type().kind) {
case EtchGrammarConstants.BOOLEAN:
case EtchGrammarConstants.DOUBLE:
case EtchGrammarConstants.FLOAT:
case EtchGrammarConstants.INT:
case EtchGrammarConstants.LONG:
case EtchGrammarConstants.ENUM:
case EtchGrammarConstants.DECIMAL:
case EtchGrammarConstants.SHORT:
return false;
default:
return true;
}
}
public boolean isCustomType(TypeRef param) {
switch (param.type().kind) {
case EtchGrammarConstants.BOOLEAN:
case EtchGrammarConstants.DOUBLE:
case EtchGrammarConstants.FLOAT:
case EtchGrammarConstants.INTEGER:
case EtchGrammarConstants.STRING:
case EtchGrammarConstants.LONG:
return false;
default:
return true;
}
}
public String getTypeName(Parameter pa) {
return pa.type().type().image;
}
public String getTypeName(Message pa) {
return pa.type().type().image;
}
public List<String> getUsedServiceNames(Service s) {
final List<String> ret = new LinkedList<String>();
IncludeTreeWalker walker = new IncludeTreeWalker(ret, s);
try {
s.treewalk(walker);
} catch (ParseException e) {
e.printStackTrace();
}
return walker.getList();
}
public boolean containsStructsOrMessages(Service s) {
return s.messages(false).hasNext() || s.structs(false).hasNext();
}
public String getClassIdVarName(Parameter p) {
Named<?> n = p.type().getNamed(p.type().intf());
return "CLASSID_" + n.efqname(this).toUpperCase();
}
public String getClassIdVarName(Thrown t) {
Except p = (Except) t.getNamed();
return "CLASSID_" + p.service().name().toString().toUpperCase() + "_"
+ p.name().toString().toUpperCase();
}
public Except getExcept(Thrown t) {
Except e = (Except) t.getNamed();
return e;
}
public String getClassIdVarName(Message n) {
Named<?> na = n.type().getNamed(n.type().intf());
return "CLASSID_" + na.efqname(this).toUpperCase();
}
public String getDefiningServiceNameOf(TypeRef type) {
Named<?> na = type.getNamed(type.intf());
return na.parent().name().name.toLowerCase();
}
@Override
public String getValidator(Named<?> named) {
return getValidator(null, named);
}
}