int lastPluralArgNumber = -1;
List<AlternateFormSelector> selectors = new ArrayList<AlternateFormSelector>();
// See if any parameter is tagged as a PluralCount or Select parameter.
for (int i = 0; i < numParams; ++i) {
PluralCount pluralCount = params[i].getAnnotation(PluralCount.class);
Select select = params[i].getAnnotation(Select.class);
if (pluralCount != null && select != null) {
throw error(logger, params[i].getName() + " cannot be both @PluralCount"
+ " and @Select");
}
AlternateFormSelector selector = null;
if (select != null) {
selector = new GenericSelector(logger, m, i, params);
seenSelect = true;
} else if (pluralCount != null) {
PluralFormSelector pluralSelector = new PluralFormSelector(logger, m, i,
params, locale);
selector = pluralSelector;
if (!seenPluralCount) {
// TODO(jat): what if we have different plural rules on the different
// forms?
resourceList.setPluralForms(key, pluralSelector.getPluralForms());
}
seenPluralCount = true;
lastPluralArgNumber = i;
}
if (selector != null) {
selectors.add(selector);
}
}
boolean[] seenFlags = new boolean[numParams];
final Parameters paramsAccessor = new ParametersImpl(params, seenFlags);
boolean isSafeHtml = m.getReturnType().getQualifiedSourceName().equals(
SAFE_HTML_FQCN);
String template = resourceEntry.getForm(null);
if (template == null) {
logger.log(TreeLogger.ERROR,"No default form for method " + m.getName()
+ "' in " + m.getEnclosingType() + " for locale " + locale, null);
throw new UnableToCompleteException();
}
// Generate code to format any lists
// TODO(jat): handle messages with different list formats in alternate forms
try {
for (TemplateChunk chunk : MessageFormatParser.parse(template)) {
if (chunk instanceof ArgumentChunk) {
ArgumentChunk argChunk = (ArgumentChunk) chunk;
if (argChunk.isList()) {
ListAccessor listAccessor = null;
int listArgNum = argChunk.getArgumentNumber();
JType listType = params[listArgNum].getType();
JClassType classType = listType.isInterface();
JType elemType = null;
if (classType != null) {
if ("java.util.List".equals(
classType.getErasedType().getQualifiedSourceName())) {
listAccessor = new ListAccessorList(listArgNum);
} else {
logger.log(TreeLogger.ERROR, "Parameters formatted as lists "
+ "must be declared as java.util.List or arrays in "
+ m.getEnclosingType().getSimpleSourceName() + "."
+ m.getName());
throw new UnableToCompleteException();
}
JParameterizedType paramType = classType.isParameterized();
if (paramType != null) {
elemType = paramType.getTypeArgs()[0];
} else {
elemType = classType.getOracle().getJavaLangObject();
}
} else {
JArrayType arrayType = listType.isArray();
if (arrayType != null) {
elemType = arrayType.getComponentType();
listAccessor = new ListAccessorArray(listArgNum);
}
}
generateListFormattingCode(logger, locale, argChunk,
elemType, isSafeHtml, listAccessor, paramsAccessor);
}
}
}
} catch (ParseException pe) {
throw error(logger, "Error parsing '" + template + "'", pe);
}
if (!seenPluralCount && !seenSelect
&& (m.getAnnotation(AlternateMessage.class) != null
|| m.getAnnotation(PluralText.class) != null)) {
logger.log(TreeLogger.WARN, "Unused @AlternateMessage or @PluralText on "
+ m.getEnclosingType().getSimpleSourceName() + "." + m.getName()
+ "; did you intend to mark a @Select or @PluralCount parameter?",
null);
}
Collection<String> resourceForms = resourceEntry.getForms();
if (seenPluralCount || seenSelect) {
paramsAccessor.enablePluralOffsets();
writer.println(m.getReturnType().getParameterizedQualifiedSourceName()
+ " returnVal = null;");
for (AlternateFormSelector selector : selectors) {
selector.generatePrepCode(writer);
}
// sort forms so that all exact-value forms come first
String[] forms = resourceForms.toArray(new String[resourceForms.size()]);
Arrays.sort(forms, new ExactValueComparator());
generateMessageSelectors(logger, m, locale, resourceEntry, selectors, paramsAccessor,
isSafeHtml, forms, lastPluralArgNumber);
for (AlternateFormSelector selector : selectors) {
selector.issueWarnings(logger, m, locale);
}
writer.println("if (returnVal != null) {");
writer.indent();
writer.println("return returnVal;");
writer.outdent();
writer.println("}");
}
writer.print("return ");
generateString(logger, locale, template, paramsAccessor, writer,
isSafeHtml, lastPluralArgNumber);
writer.println(";");
// Generate an error if any required parameter was not used somewhere.
for (int i = 0; i < numParams; ++i) {
if (!seenFlags[i]) {
Optional optional = params[i].getAnnotation(Optional.class);
Select select = params[i].getAnnotation(Select.class);
if (optional == null && select == null) {
throw error(logger, "Required argument " + i + " not present: "
+ template);
}
}