2014-08-05 20:18:04 +00:00
|
|
|
package com.moandjiezana.toml;
|
|
|
|
|
|
|
|
import java.util.ArrayDeque;
|
|
|
|
import java.util.Deque;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
class Results {
|
2014-08-12 15:38:23 +00:00
|
|
|
Set<String> tables = new HashSet<String>();
|
|
|
|
StringBuilder errors = new StringBuilder();
|
2014-08-05 20:18:04 +00:00
|
|
|
private Deque<Container> stack = new ArrayDeque<Container>();
|
|
|
|
|
2014-08-12 15:38:23 +00:00
|
|
|
Results() {
|
2014-08-05 20:18:04 +00:00
|
|
|
stack.push(new Container.Table());
|
|
|
|
}
|
|
|
|
|
2014-08-12 15:38:23 +00:00
|
|
|
void addValue(String key, Object value) {
|
2014-08-05 20:18:04 +00:00
|
|
|
Container currentTable = stack.peek();
|
|
|
|
if (currentTable.accepts(key)) {
|
|
|
|
currentTable.put(key, value);
|
|
|
|
} else {
|
|
|
|
errors.append("Key " + key + " is defined twice!\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-12 15:38:23 +00:00
|
|
|
void startTableArray(String tableName) {
|
2014-08-05 20:18:04 +00:00
|
|
|
while (stack.size() > 1) {
|
|
|
|
stack.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
String[] tableParts = tableName.split("\\.");
|
|
|
|
for (int i = 0; i < tableParts.length; i++) {
|
|
|
|
String tablePart = tableParts[i];
|
|
|
|
Container currentContainer = stack.peek();
|
|
|
|
|
|
|
|
if (currentContainer.get(tablePart) instanceof Container.TableArray) {
|
|
|
|
Container.TableArray currentTableArray = (Container.TableArray) currentContainer.get(tablePart);
|
|
|
|
stack.push(currentTableArray);
|
|
|
|
|
|
|
|
if (i == tableParts.length - 1) {
|
|
|
|
currentTableArray.put(tablePart, new Container.Table());
|
|
|
|
}
|
|
|
|
|
|
|
|
stack.push(currentTableArray.getCurrent());
|
|
|
|
currentContainer = stack.peek();
|
2014-08-12 10:53:18 +00:00
|
|
|
} else if (currentContainer.get(tablePart) instanceof Container.Table && i < tableParts.length - 1) {
|
2014-08-05 20:18:04 +00:00
|
|
|
Container nextTable = (Container) currentContainer.get(tablePart);
|
|
|
|
stack.push(nextTable);
|
|
|
|
} else if (currentContainer.accepts(tablePart)) {
|
|
|
|
Container newContainer = i == tableParts.length - 1 ? new Container.TableArray() : new Container.Table();
|
|
|
|
addValue(tablePart, newContainer);
|
|
|
|
stack.push(newContainer);
|
|
|
|
|
|
|
|
if (newContainer instanceof Container.TableArray) {
|
|
|
|
stack.push(((Container.TableArray) newContainer).getCurrent());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
errors.append("Duplicate key and table definitions for " + tableName + "!\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-12 15:38:23 +00:00
|
|
|
void startTables(String tableName) {
|
2014-08-05 20:18:04 +00:00
|
|
|
if (!tables.add(tableName)) {
|
|
|
|
errors.append("Table " + tableName + " defined twice!\n");
|
|
|
|
}
|
2014-12-15 13:58:19 +00:00
|
|
|
|
|
|
|
if (tableName.endsWith(".")) {
|
|
|
|
errors.append("Implicit table name cannot be empty: " + tableName);
|
|
|
|
}
|
2014-08-05 20:18:04 +00:00
|
|
|
|
|
|
|
while (stack.size() > 1) {
|
|
|
|
stack.pop();
|
|
|
|
}
|
|
|
|
|
2015-01-15 09:44:14 +00:00
|
|
|
Keys.Key[] tableParts = Keys.split(tableName);
|
2014-08-05 20:18:04 +00:00
|
|
|
for (int i = 0; i < tableParts.length; i++) {
|
2015-01-15 09:44:14 +00:00
|
|
|
String tablePart = tableParts[i].name;
|
2014-08-05 20:18:04 +00:00
|
|
|
Container currentContainer = stack.peek();
|
2014-08-12 10:53:18 +00:00
|
|
|
if (tablePart.isEmpty()) {
|
|
|
|
errors.append("Empty implicit table: " + tableName + "!\n");
|
|
|
|
} else if (currentContainer.get(tablePart) instanceof Container) {
|
2014-08-05 20:18:04 +00:00
|
|
|
Container nextTable = (Container) currentContainer.get(tablePart);
|
|
|
|
stack.push(nextTable);
|
|
|
|
if (stack.peek() instanceof Container.TableArray) {
|
|
|
|
stack.push(((Container.TableArray) stack.peek()).getCurrent());
|
|
|
|
}
|
|
|
|
} else if (currentContainer.accepts(tablePart)) {
|
|
|
|
startTable(tablePart);
|
|
|
|
} else {
|
|
|
|
errors.append("Duplicate key and table definitions for " + tableName + "!\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Warning: After this method has been called, this instance is no longer usable.
|
|
|
|
*/
|
2014-08-12 15:38:23 +00:00
|
|
|
Map<String, Object> consume() {
|
2014-08-05 20:18:04 +00:00
|
|
|
Container values = stack.getLast();
|
|
|
|
stack.clear();
|
|
|
|
|
|
|
|
return ((Container.Table) values).consume();
|
|
|
|
}
|
|
|
|
|
|
|
|
private Container startTable(String tableName) {
|
|
|
|
Container newTable = new Container.Table();
|
|
|
|
addValue(tableName, newTable);
|
|
|
|
stack.push(newTable);
|
|
|
|
|
|
|
|
return newTable;
|
|
|
|
}
|
|
|
|
}
|