clear();
WodScanner scanner = WodScanner.wodScannerForDocument(_document);
DocumentWodBinding lastBinding = null;
DocumentWodElement element = null;
RulePosition tentativeElementName = null;
RulePosition savedRulePosition = null;
RulePosition savedRulePosition2 = null;
RulePosition savedRulePosition3 = null;
RulePosition lastRulePosition = null;
ForgivingStack<RulePosition> rulePositions = new ForgivingStack<RulePosition>();
// boolean stringLiteralIsABindingName = false;
RulePosition rulePosition;
while ((rulePosition = scanner.nextRulePosition()) != null) {
boolean whitespace = false;
boolean comment = false;
if (RulePosition.isRulePositionOfType(rulePosition, WhitespaceRule.class)) {
whitespace = true;
}
else if (RulePosition.isRulePositionOfType(rulePosition, ICommentRule.class)) {
comment = true;
if (lastBinding != null) {
String commentText = rulePosition._getTextWithoutException();
if (commentText != null && commentText.startsWith("//")) {
commentText = commentText.substring(2).trim();
if ("VALID".equalsIgnoreCase(commentText)) {
lastBinding.setValidate(false);
}
}
}
else {
String commentText = rulePosition._getTextWithoutException();
if (commentText != null && commentText.startsWith("//")) {
commentText = commentText.substring(2).trim();
if (commentText.toLowerCase().startsWith("inherit ")) {
String componentName = commentText.substring("inherit ".length()).trim();
try {
WodParserCache inheritCache = WodParserCache.parser(_wodFile.getProject(), componentName);
WodCacheEntry wodCacheEntry = inheritCache.getWodEntry();
IWodModel parentWodModel = wodCacheEntry.getModel();
for (IWodElement parentWodElement : parentWodModel.getElements()) {
SimpleWodElement inheritedWodElement = new SimpleWodElement(parentWodElement);
inheritedWodElement.setInherited(true);
addElement(inheritedWodElement);
}
}
catch (Throwable t) {
addParseProblem(element, "WOD inheritance of '" + componentName + "' failed: " + t.getMessage() + ".", rulePosition, false);
}
}
}
}
}
else if (RulePosition.isRulePositionOfType(rulePosition, ElementNameRule.class)) {
if (RulePosition.isOperatorOfType(lastRulePosition, OpenDefinitionWordDetector.class) || RulePosition.isOperatorOfType(lastRulePosition, EndAssignmentWordDetector.class)) {
savedRulePosition2 = rulePosition;
if (lastRulePosition != null && !RulePosition.isOperatorOfType(lastRulePosition, CloseDefinitionWordDetector.class)) {
tentativeElementName = rulePosition;
}
// leave old savedRulePosition
}
else {
if (lastRulePosition != null && !RulePosition.isOperatorOfType(lastRulePosition, CloseDefinitionWordDetector.class)) {
addParseProblem(element, "The element name '" + rulePosition._getTextWithoutException() + "' must start a WOD declaration", rulePosition, false);
}
savedRulePosition = rulePosition;
element = null;
}
}
else if (RulePosition.isOperatorOfType(rulePosition, ElementTypeOperatorWordDetector.class)) {
if (!RulePosition.isRulePositionOfType(lastRulePosition, ElementNameRule.class) && !RulePosition.isRulePositionOfType(lastRulePosition, BindingValueNamespaceRule.class)) {
addParseProblem(element, "A ':' can only appear after an element name or a binding value namespace.", rulePosition, false);
}
}
else if (RulePosition.isRulePositionOfType(rulePosition, ElementTypeRule.class)) {
if (tentativeElementName != null) {
addParseProblem(element, "The element name ' " + tentativeElementName._getTextWithoutException() + "' must start a WOD declaration", tentativeElementName, false);
tentativeElementName = null;
savedRulePosition = null;
}
else if (!RulePosition.isOperatorOfType(lastRulePosition, ElementTypeOperatorWordDetector.class)) {
addParseProblem(element, "The element type '" + rulePosition._getTextWithoutException() + "' can only appear after a ':'", rulePosition, false);
}
else {
rulePositions.clear();
element = new DocumentWodElement(savedRulePosition, rulePosition);
addElement(element);
savedRulePosition = null;
}
}
else if (RulePosition.isOperatorOfType(rulePosition, OpenDefinitionWordDetector.class)) {
if (!RulePosition.isRulePositionOfType(lastRulePosition, ElementTypeRule.class)) {
addParseProblem(element, "A '{' can only appear after an element type", rulePosition, false);
}
}
else if (RulePosition.isRulePositionOfType(rulePosition, WOOGNLRule.class)) {
boolean ognlIsValue = RulePosition.isOperatorOfType(lastRulePosition, AssignmentOperatorWordDetector.class);
boolean ognlIsName = !ognlIsValue && (RulePosition.isOperatorOfType(lastRulePosition, EndAssignmentWordDetector.class) || RulePosition.isOperatorOfType(lastRulePosition, OpenDefinitionWordDetector.class));
if (!ognlIsValue && !ognlIsName) {
addParseProblem(element, "The OGNL value " + rulePosition._getTextWithoutException() + " can only appear after a '{', '=', or ';'.", rulePosition, false);
savedRulePosition = null;
}
else if (ognlIsName) {
savedRulePosition = rulePosition;
}
else if (ognlIsValue) {
lastBinding = addBinding(element, savedRulePosition2, savedRulePosition, null, rulePosition, scanner);
savedRulePosition = null;
savedRulePosition2 = null;
savedRulePosition3 = null;
}
}
else if (RulePosition.isRulePositionOfType(rulePosition, StringLiteralRule.class)) {
boolean literalIsValue = RulePosition.isOperatorOfType(lastRulePosition, AssignmentOperatorWordDetector.class);
boolean literalIsName = !literalIsValue && (RulePosition.isOperatorOfType(rulePositions.peek(), EndAssignmentWordDetector.class) || RulePosition.isOperatorOfType(rulePositions.peek(), OpenDefinitionWordDetector.class));
if (!literalIsValue && !literalIsName) {
addParseProblem(element, "The string literal '" + rulePosition._getTextWithoutException() + "' can only appear after a '{', '=', or ';'.", rulePosition, false);
savedRulePosition = null;
}
else if (literalIsName) {
savedRulePosition = rulePosition;
}
else if (literalIsValue) {
lastBinding = addBinding(element, savedRulePosition2, savedRulePosition, null, rulePosition, scanner);
savedRulePosition = null;
savedRulePosition2 = null;
savedRulePosition3 = null;
}
tentativeElementName = null;
}
else if (RulePosition.isRulePositionOfType(rulePosition, BindingNameRule.class)) {
if (!RulePosition.isOperatorOfType(lastRulePosition, OpenDefinitionWordDetector.class) && !RulePosition.isOperatorOfType(lastRulePosition, EndAssignmentWordDetector.class) && !RulePosition.isOperatorOfType(lastRulePosition, ElementTypeOperatorWordDetector.class)) {
addParseProblem(element, "The binding name '" + rulePosition._getTextWithoutException() + "' can only appear after a '{' or a ';'", rulePosition, false);
}
savedRulePosition = rulePosition;
lastBinding = null;
}
else if (RulePosition.isOperatorOfType(rulePosition, AssignmentOperatorWordDetector.class)) {
if (!RulePosition.isRulePositionOfType(lastRulePosition, BindingNameRule.class) && !RulePosition.isRulePositionOfType(lastRulePosition, StringLiteralRule.class)) {
addParseProblem(element, "An '=' can only appear after a binding name", rulePosition, false);
}
}
else if (RulePosition.isRulePositionOfType(rulePosition, BindingValueNamespaceRule.class)) {
if (!RulePosition.isOperatorOfType(lastRulePosition, AssignmentOperatorWordDetector.class)) {
addParseProblem(element, "The binding value namespace '" + rulePosition._getTextWithoutException() + "' can only appear after an '='", rulePosition, false);
}
else {
savedRulePosition3 = rulePosition;
}
}
else if (RulePosition.isRulePositionOfType(rulePosition, BindingValueRule.class)) {
if (!RulePosition.isOperatorOfType(lastRulePosition, AssignmentOperatorWordDetector.class) && !(RulePosition.isOperatorOfType(lastRulePosition, ElementTypeOperatorWordDetector.class) && RulePosition.isRulePositionOfType(savedRulePosition3, BindingValueNamespaceRule.class))) {
addParseProblem(element, "The binding value '" + rulePosition._getTextWithoutException() + "' can only appear after an '=' or a 'xxx:'", rulePosition, false);
}
else {
lastBinding = addBinding(element, savedRulePosition2, savedRulePosition, savedRulePosition3, rulePosition, scanner);
}
savedRulePosition = null;
savedRulePosition2 = null;
savedRulePosition3 = null;
}
else if (RulePosition.isOperatorOfType(rulePosition, EndAssignmentWordDetector.class)) {
if (!RulePosition.isRulePositionOfType(lastRulePosition, BindingValueRule.class) && !RulePosition.isRulePositionOfType(lastRulePosition, StringLiteralRule.class) && !RulePosition.isRulePositionOfType(lastRulePosition, WOOGNLRule.class)) {
addParseProblem(element, "A ';' can only appear after a binding value", rulePosition, false);
}
}
else if (RulePosition.isOperatorOfType(rulePosition, CloseDefinitionWordDetector.class)) {
if (element != null) {
element.setEndOffset(rulePosition.getTokenOffset() + 1);
}
if (!RulePosition.isOperatorOfType(lastRulePosition, OpenDefinitionWordDetector.class) && !RulePosition.isOperatorOfType(lastRulePosition, EndAssignmentWordDetector.class) && !RulePosition.isRulePositionOfType(lastRulePosition, BindingValueRule.class) && !RulePosition.isRulePositionOfType(lastRulePosition, StringLiteralRule.class) && !RulePosition.isRulePositionOfType(lastRulePosition, WOOGNLRule.class)) {
addParseProblem(element, "A '}' can only appear after a ';' or a '{'", rulePosition, false);
}
else {
element = null;
}
lastBinding = null;
}
else {
addParseProblem(element, "'" + rulePosition._getTextWithoutException() + "' is an unknown keyword", rulePosition, false);
}
if (!whitespace && !comment) {
lastRulePosition = rulePosition;
rulePositions.push(rulePosition);