MessageVisitor.java
package de.schegge.rosinante.generator;
import de.schegge.rosinante.parser.Node;
import de.schegge.rosinante.parser.Token;
import de.schegge.rosinante.parser.ast.Field;
import de.schegge.rosinante.parser.ast.FieldOption;
import de.schegge.rosinante.parser.ast.FieldOptions;
import de.schegge.rosinante.parser.ast.MessageBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import static de.schegge.rosinante.generator.FieldOptionsVisitor.MESSAGE_FIELD_OPTION_VISITOR;
public class MessageVisitor implements ProtoVisitor<MessagePatternWithContext, Void> {
private static final Logger logger = LoggerFactory.getLogger(MessageVisitor.class);
private static final NameVisitor NAME_VISITOR = new NameVisitor();
@Override
public Void visit(MessageBody messageBody, MessagePatternWithContext context) {
List<Node> children = messageBody.children();
children.subList(1, children.size() - 1).forEach(node -> node.accept(this, context));
return null;
}
@Override
public Void visit(Field field, MessagePatternWithContext context) {
context.pattern().addField(createFieldPattern(field, context));
return null;
}
public Void visit(FieldOption fieldOption, MessagePatternWithContext context) {
String name = fieldOption.get(0).toString();
Object constant = fieldOption.get(2).accept(ConstantVisitor.INSTANCE, null);
logger.debug("field option: name={}, value={}", name, constant);
return null;
}
@Override
public Void visit(FieldOptions fieldOptions, MessagePatternWithContext context) {
fieldOptions.childrenOfType(FieldOption.class).forEach(x -> x.accept(this, context));
return null;
}
private FieldPattern createFieldPattern(Field field, MessagePatternWithContext context) {
List<Node> children = field.children();
Node first = children.getFirst();
boolean repeated = first.getType() == Token.TokenType.REPEATED;
boolean optional = first.getType() == Token.TokenType.OPTIONAL;
int index = repeated || optional ? 1 : 0;
FieldType type = context.context().getType(children.get(index).toString());
int assignIndex = field.indexOf(field.firstChildOfType(Token.class, x1 -> x1.getType() == Token.TokenType.ASSIGN));
Node integerLiteral = children.get(assignIndex + 1);
String fieldName = children.get(index + 1).accept(NAME_VISITOR, null);
FieldPattern fieldPattern = new FieldPattern(fieldName, type, Integer.parseInt(integerLiteral.toString()), optional, repeated);
field.childrenOfType(FieldOptions.class).forEach(x -> x.accept(MESSAGE_FIELD_OPTION_VISITOR, fieldPattern));
return fieldPattern;
}
}