use of com.google.template.soy.soytree.MsgPluralNode in project closure-templates by google.
the class MsgUtils method buildMsgPartsForChildren.
// -----------------------------------------------------------------------------------------------
// Private helpers for building the list of message parts.
/**
* Builds the list of SoyMsgParts for all the children of a given parent node.
*
* @param parent Can be MsgNode, MsgPluralCaseNode, MsgPluralDefaultNode, MsgSelectCaseNode, or
* MsgSelectDefaultNode.
* @param msgNode The MsgNode containing 'parent'.
*/
private static ImmutableList<SoyMsgPart> buildMsgPartsForChildren(BlockNode parent, MsgNode msgNode) {
ImmutableList.Builder<SoyMsgPart> msgParts = ImmutableList.builder();
for (StandaloneNode child : parent.getChildren()) {
if (child instanceof RawTextNode) {
String rawText = ((RawTextNode) child).getRawText();
msgParts.add(SoyMsgRawTextPart.of(rawText));
} else if (child instanceof MsgPlaceholderNode) {
PlaceholderInfo placeholder = msgNode.getPlaceholder((MsgPlaceholderNode) child);
msgParts.add(new SoyMsgPlaceholderPart(placeholder.name(), placeholder.example()));
} else if (child instanceof MsgPluralNode) {
msgParts.add(buildMsgPartForPlural((MsgPluralNode) child, msgNode));
} else if (child instanceof MsgSelectNode) {
msgParts.add(buildMsgPartForSelect((MsgSelectNode) child, msgNode));
}
}
return msgParts.build();
}
use of com.google.template.soy.soytree.MsgPluralNode in project closure-templates by google.
the class MsgCompiler method putPluralPartIntoMap.
private void putPluralPartIntoMap(Expression mapExpression, MsgNode originalMsg, Map<String, Statement> placeholderNameToPutStatement, SoyMsgPluralPart plural) {
MsgPluralNode repPluralNode = originalMsg.getRepPluralNode(plural.getPluralVarName());
if (!placeholderNameToPutStatement.containsKey(plural.getPluralVarName())) {
Label reattachPoint = new Label();
Expression value = soyNodeCompiler.compileToInt(repPluralNode.getExpr(), reattachPoint);
placeholderNameToPutStatement.put(plural.getPluralVarName(), putToMap(mapExpression, plural.getPluralVarName(), value).labelStart(reattachPoint).withSourceLocation(repPluralNode.getSourceLocation()));
}
// Recursively visit plural cases
for (Case<SoyMsgPluralCaseSpec> caseOrDefault : plural.getCases()) {
putPlaceholdersIntoMap(mapExpression, originalMsg, caseOrDefault.parts(), placeholderNameToPutStatement);
}
}
use of com.google.template.soy.soytree.MsgPluralNode in project closure-templates by google.
the class MsgFuncGenerator method collectVarNameListAndToPyExprMap.
/**
* Private helper to process and collect all variables used within this msg node for code
* generation.
*
* @return A Map populated with all the variables used with in this message node, using {@link
* MsgPlaceholderInitialNode#genBasePhName}.
*/
private Map<PyExpr, PyExpr> collectVarNameListAndToPyExprMap() {
Map<PyExpr, PyExpr> nodePyVarToPyExprMap = new LinkedHashMap<>();
for (Map.Entry<String, MsgSubstUnitNode> entry : msgNode.getVarNameToRepNodeMap().entrySet()) {
MsgSubstUnitNode substUnitNode = entry.getValue();
PyExpr substPyExpr = null;
if (substUnitNode instanceof MsgPlaceholderNode) {
SoyNode phInitialNode = ((AbstractParentSoyNode<?>) substUnitNode).getChild(0);
if (phInitialNode instanceof PrintNode || phInitialNode instanceof CallNode || phInitialNode instanceof RawTextNode) {
substPyExpr = PyExprUtils.concatPyExprs(genPyExprsVisitor.exec(phInitialNode)).toPyString();
}
// when the placeholder is generated by HTML tags
if (phInitialNode instanceof MsgHtmlTagNode) {
substPyExpr = PyExprUtils.concatPyExprs(genPyExprsVisitor.execOnChildren((ParentSoyNode<?>) phInitialNode)).toPyString();
}
} else if (substUnitNode instanceof MsgPluralNode) {
// Translates {@link MsgPluralNode#pluralExpr} into a Python lookup expression.
// Note that {@code pluralExpr} represents the soy expression of the {@code plural} attr,
// i.e. the {@code $numDrafts} in {@code {plural $numDrafts}...{/plural}}.
substPyExpr = translateToPyExprVisitor.exec(((MsgPluralNode) substUnitNode).getExpr());
} else if (substUnitNode instanceof MsgSelectNode) {
substPyExpr = translateToPyExprVisitor.exec(((MsgSelectNode) substUnitNode).getExpr());
}
if (substPyExpr != null) {
nodePyVarToPyExprMap.put(new PyStringExpr("'" + entry.getKey() + "'"), substPyExpr);
}
}
return nodePyVarToPyExprMap;
}
use of com.google.template.soy.soytree.MsgPluralNode in project closure-templates by google.
the class MsgFuncGenerator method pyFuncForPluralMsg.
private PyStringExpr pyFuncForPluralMsg() {
SoyMsgPluralPart pluralPart = (SoyMsgPluralPart) msgParts.get(0);
MsgPluralNode pluralNode = msgNode.getRepPluralNode(pluralPart.getPluralVarName());
Map<PyExpr, PyExpr> nodePyVarToPyExprMap = collectVarNameListAndToPyExprMap();
Map<PyExpr, PyExpr> caseSpecStrToMsgTexts = new LinkedHashMap<>();
for (Case<SoyMsgPluralCaseSpec> pluralCase : pluralPart.getCases()) {
caseSpecStrToMsgTexts.put(new PyStringExpr("'" + pluralCase.spec() + "'"), new PyStringExpr("'" + processMsgPartsHelper(pluralCase.parts(), escaperForIcuSection) + "'"));
}
prepareFunc.addArg(msgId).addArg(PyExprUtils.convertMapToPyExpr(caseSpecStrToMsgTexts)).addArg(PyExprUtils.convertIterableToPyTupleExpr(nodePyVarToPyExprMap.keySet()));
// Translates {@link MsgPluralNode#pluralExpr} into a Python lookup expression.
// Note that pluralExpr represent the Soy expression inside the attributes of a plural tag.
PyExpr pluralPyExpr = translateToPyExprVisitor.exec(pluralNode.getExpr());
return renderFunc.addArg(prepareFunc.asPyExpr()).addArg(pluralPyExpr).addArg(PyExprUtils.convertMapToPyExpr(nodePyVarToPyExprMap)).asPyStringExpr();
}
use of com.google.template.soy.soytree.MsgPluralNode in project closure-templates by google.
the class TemplateParserTest method testParseMsgStmtWithPlural.
// -----------------------------------------------------------------------------------------------
// Tests for plural/select messages.
@Test
public void testParseMsgStmtWithPlural() throws Exception {
String templateBody = "{@param num_people : ?}{@param person : ?}{@param place : ?}\n" + " {msg desc=\"A sample plural message\"}\n" + " {plural $num_people offset=\"1\"}\n" + " {case 0}I see no one in {$place}.\n" + " {case 1}I see {$person} in {$place}.\n" + " {case 2}I see {$person} and one other person in {$place}.\n" + " {default}I see {$person} and {remainder($num_people)} " + "other people in {$place}.\n" + " {/plural}" + " {/msg}\n";
List<StandaloneNode> nodes = parseTemplateContent(templateBody, FAIL).getChildren();
assertEquals(1, nodes.size());
MsgNode mn = ((MsgFallbackGroupNode) nodes.get(0)).getChild(0);
assertEquals(1, mn.numChildren());
assertEquals("A sample plural message", mn.getDesc());
MsgPluralNode pn = (MsgPluralNode) mn.getChild(0);
assertEquals("$num_people", pn.getExpr().toSourceString());
assertEquals(1, pn.getOffset());
// 3 cases and default
assertEquals(4, pn.numChildren());
// Case 0
MsgPluralCaseNode cn0 = (MsgPluralCaseNode) pn.getChild(0);
assertEquals(3, cn0.numChildren());
assertEquals(0, cn0.getCaseNumber());
RawTextNode rtn01 = (RawTextNode) cn0.getChild(0);
assertEquals("I see no one in ", rtn01.getRawText());
MsgPlaceholderNode phn01 = (MsgPlaceholderNode) cn0.getChild(1);
assertEquals("{$place}", phn01.toSourceString());
RawTextNode rtn02 = (RawTextNode) cn0.getChild(2);
assertEquals(".", rtn02.getRawText());
// Case 1
MsgPluralCaseNode cn1 = (MsgPluralCaseNode) pn.getChild(1);
assertEquals(5, cn1.numChildren());
assertEquals(1, cn1.getCaseNumber());
RawTextNode rtn11 = (RawTextNode) cn1.getChild(0);
assertEquals("I see ", rtn11.getRawText());
MsgPlaceholderNode phn11 = (MsgPlaceholderNode) cn1.getChild(1);
assertEquals("{$person}", phn11.toSourceString());
RawTextNode rtn12 = (RawTextNode) cn1.getChild(2);
assertEquals(" in ", rtn12.getRawText());
MsgPlaceholderNode phn12 = (MsgPlaceholderNode) cn1.getChild(3);
assertEquals("{$place}", phn12.toSourceString());
RawTextNode rtn13 = (RawTextNode) cn1.getChild(4);
assertEquals(".", rtn13.getRawText());
// Case 2
MsgPluralCaseNode cn2 = (MsgPluralCaseNode) pn.getChild(2);
assertEquals(5, cn2.numChildren());
assertEquals(2, cn2.getCaseNumber());
RawTextNode rtn21 = (RawTextNode) cn2.getChild(0);
assertEquals("I see ", rtn21.getRawText());
MsgPlaceholderNode phn21 = (MsgPlaceholderNode) cn2.getChild(1);
assertEquals("{$person}", phn21.toSourceString());
RawTextNode rtn22 = (RawTextNode) cn2.getChild(2);
assertEquals(" and one other person in ", rtn22.getRawText());
MsgPlaceholderNode phn22 = (MsgPlaceholderNode) cn2.getChild(3);
assertEquals("{$place}", phn22.toSourceString());
RawTextNode rtn23 = (RawTextNode) cn2.getChild(4);
assertEquals(".", rtn23.getRawText());
// Default
MsgPluralDefaultNode dn = (MsgPluralDefaultNode) pn.getChild(3);
assertEquals(7, dn.numChildren());
RawTextNode rtnd1 = (RawTextNode) dn.getChild(0);
assertEquals("I see ", rtnd1.getRawText());
MsgPlaceholderNode phnd1 = (MsgPlaceholderNode) dn.getChild(1);
assertEquals("{$person}", phnd1.toSourceString());
RawTextNode rtnd2 = (RawTextNode) dn.getChild(2);
assertEquals(" and ", rtnd2.getRawText());
MsgPlaceholderNode phnd2 = (MsgPlaceholderNode) dn.getChild(3);
assertEquals("{$num_people - 1}", phnd2.toSourceString());
RawTextNode rtnd3 = (RawTextNode) dn.getChild(4);
assertEquals(" other people in ", rtnd3.getRawText());
MsgPlaceholderNode phnd3 = (MsgPlaceholderNode) dn.getChild(5);
assertEquals("{$place}", phnd3.toSourceString());
RawTextNode rtnd4 = (RawTextNode) dn.getChild(6);
assertEquals(".", rtnd4.getRawText());
}
Aggregations