in freemarker-docgen-core/src/main/java/org/freemarker/docgen/core/CJSONInterpreter.java [596:769]
private Map<String, Object> fetchMapInner(
Map<String, Object> map, char terminator, boolean forceStringValues)
throws EvaluationException {
int p2;
int mapP = p - 1;
skipWS();
if (terminator == 0x20) {
mapP = p;
}
// Key lookup
while (true) {
char c;
if (p < ln) {
c = tx.charAt(p);
if (c == terminator) {
return map;
}
if (c == ',') {
throw newSyntaxError(
"Key-value pair is missing before the comma.");
}
} else {
if (terminator == 0x20) {
return map;
} else {
throw newSyntaxError("Reached the end of the text, "
+ "but the map was not closed with "
+ TextUtil.jQuoteOrName(terminator) + ".",
mapP);
}
}
int keyP = p;
Object o1 = fetchExpression(false, true);
FunctionCall keyFunc;
if (o1 instanceof FunctionCall) {
keyFunc = (FunctionCall) o1;
try {
o1 = ee.evalFunctionCall(keyFunc, this);
} catch (Throwable e) {
throw newError("Failed to evaluate function "
+ TextUtil.jQuote(keyFunc.getName()) + ".",
keyP, e);
}
} else {
keyFunc = null;
}
c = skipSeparator(terminator, null, null);
if (c == ':') {
if (!(o1 instanceof String)) {
if (keyFunc != o1) {
throw newError(
"The key must be a String, but it is a(n) "
+ cjsonTypeNameOfValue(o1) + ".", keyP);
} else {
throw newError(
"You can't use the function here, "
+ "because it can't be evaluated "
+ "in this context.",
keyP);
}
}
if (p == ln) {
throw newSyntaxError(
"The key must be followed by a value because "
+ "colon was used.", keyP);
}
Object o2;
boolean done = false;
try {
Object nr;
try {
nr = ee.notify(
EvaluationEvent.ENTER_MAP_KEY,
this, (String) o1, null);
done = true;
} catch (Throwable e) {
throw newWrappedError(e, keyP);
}
if (nr == null) {
o2 = fetchExpression(forceStringValues, false);
map.put((String) o1, o2);
} else {
p2 = p;
skipExpression();
if (nr == EvaluationEnvironment.RETURN_FRAGMENT) {
map.put((String) o1,
new Fragment(tx, p2, p, fileName));
}
}
} finally {
if (done) {
try {
ee.notify(
EvaluationEvent.LEAVE_MAP_KEY,
this, (String) o1, null);
} catch (Throwable e) {
throw newWrappedError(e);
}
}
}
c = skipSeparator(terminator, null,
"Colon is for separating the key from the value, "
+ "and the value was alredy given previously.");
} else if (c == ',' || c == terminator || c == 0x20) {
if (keyFunc == null) {
if (o1 instanceof String) {
boolean done = false;
try {
Object nr;
try {
nr = ee.notify(
EvaluationEvent.ENTER_MAP_KEY,
this, (String) o1, null);
done = true;
} catch (Throwable e) {
throw newWrappedError(e, keyP);
}
if (nr == null
|| nr == EvaluationEnvironment
.RETURN_FRAGMENT) {
map.put((String) o1, Boolean.TRUE);
}
} finally {
if (done) {
try {
ee.notify(
EvaluationEvent.LEAVE_MAP_KEY,
this, (String) o1, null);
} catch (Throwable e) {
throw newWrappedError(e);
}
}
}
} else if (o1 instanceof Map) {
map.putAll((Map<String, Object>) o1);
} else {
throw newError(
"This expression should be either a string "
+ "or a map, but it is a(n) "
+ cjsonTypeNameOfValue(o1) + ".", keyP);
}
} else {
if (o1 instanceof Map) {
map.putAll((Map<String, Object>) o1);
} else {
if (keyFunc == o1) {
throw newError(
"You can't use the function here, "
+ "because it can't be evaluated "
+ "in this context.",
keyP);
} else {
throw newError(
"Function doesn't evalute to a map, but "
+ "to " + cjsonTypeNameOfValue(o1)
+ ", so it can't be merged into the map.",
keyP);
}
}
}
}
if (c == terminator) {
return map;
}
}
}