use of net.morimekta.providence.serializer.pretty.Token in project providence by morimekta.
the class ConstParser method parseMessage.
/**
* Parse JSON object as a message.
*
* @param tokenizer The JSON tokenizer.
* @param type The message type.
* @param <Message> Message generic type.
* @param <Field> Message field type.
* @return The parsed message.
*/
private <Message extends PMessage<Message, Field>, Field extends PField> Message parseMessage(ThriftTokenizer tokenizer, PMessageDescriptor<Message, Field> type) throws IOException {
PMessageBuilder<Message, Field> builder = type.builder();
if (tokenizer.peek("checking for empty").isSymbol(Token.kMessageEnd)) {
tokenizer.next();
return builder.build();
}
while (true) {
Token token = tokenizer.expect("message field name", t -> t.isStringLiteral() || t.strEquals(ThriftTokenizer.kBlockCommentStart) || t.strEquals(ThriftTokenizer.kLineCommentStart));
if (token.strEquals(ThriftTokenizer.kLineCommentStart)) {
int c;
while ((c = tokenizer.read()) >= 0) {
if (c == '\n')
break;
}
continue;
} else if (token.strEquals(ThriftTokenizer.kBlockCommentStart)) {
int c;
while ((c = tokenizer.read()) >= 0) {
if (c == '*') {
c = tokenizer.read();
if (c == '/') {
break;
}
}
}
continue;
}
Field field = type.findFieldByName(token.decodeLiteral(true));
if (field == null) {
throw tokenizer.failure(token, "No such field in " + type.getQualifiedName() + ": " + token.decodeLiteral(true));
}
tokenizer.expectSymbol("message key-value sep", Token.kKeyValueSep);
builder.set(field.getId(), parseTypedValue(tokenizer.expect("parsing field value"), tokenizer, field.getDescriptor(), false));
token = tokenizer.peek("optional line sep or message end");
if (token.isSymbol(Token.kLineSep1) || token.isSymbol(Token.kLineSep2)) {
tokenizer.next();
token = tokenizer.peek("optional message end");
}
if (token.isSymbol(Token.kMessageEnd)) {
tokenizer.next();
break;
}
}
return builder.build();
}
use of net.morimekta.providence.serializer.pretty.Token in project providence by morimekta.
the class PrettySerializer method deserialize.
@Nonnull
@Override
public <Message extends PMessage<Message, Field>, Field extends PField> Message deserialize(@Nonnull InputStream input, @Nonnull PMessageDescriptor<Message, Field> descriptor) throws IOException {
Tokenizer tokenizer = new Tokenizer(input);
Token first = tokenizer.peek("start of message");
if (first.isSymbol(Token.kMessageStart)) {
tokenizer.next();
} else if (first.isQualifiedIdentifier()) {
if (first.asString().equals(descriptor.getQualifiedName())) {
// skip the name
tokenizer.next();
tokenizer.expectSymbol("message start after qualifier", Token.kMessageStart);
} else {
throw tokenizer.failure(first, "Expected qualifier " + descriptor.getQualifiedName() + " or message start, Got '" + first.asString() + "'");
}
} else {
throw tokenizer.failure(first, "Expected message start or qualifier, Got '" + first.asString() + "'");
}
return readMessage(tokenizer, descriptor, false);
}
use of net.morimekta.providence.serializer.pretty.Token in project providence by morimekta.
the class PrettySerializer method readMessage.
private <Message extends PMessage<Message, Field>, Field extends PField> Message readMessage(Tokenizer tokenizer, PMessageDescriptor<Message, Field> descriptor, boolean params) throws IOException {
PMessageBuilder<Message, Field> builder = descriptor.builder();
Token token = tokenizer.expect("message field or end");
for (; ; ) {
if (params) {
if (token.isSymbol(Token.kParamsEnd)) {
break;
}
} else if (token.isSymbol(Token.kMessageEnd)) {
break;
}
if (!token.isIdentifier()) {
throw new TokenizerException(token, "Expected field name, got '%s'", Strings.escape(token.asString())).setLine(tokenizer.getLine());
}
tokenizer.expectSymbol("field value separator", Token.kFieldValueSep);
PField field = descriptor.findFieldByName(token.asString());
if (field == null) {
consumeValue(tokenizer, tokenizer.expect("field value"));
} else {
builder.set(field.getId(), readFieldValue(tokenizer, tokenizer.expect("field value"), field.getDescriptor()));
}
token = tokenizer.expect("Message field or end");
if (token.isSymbol(Token.kLineSep1) || token.isSymbol(Token.kLineSep2)) {
token = tokenizer.expect("Message field or end");
}
}
return builder.build();
}
use of net.morimekta.providence.serializer.pretty.Token in project providence by morimekta.
the class PrettySerializer method deserialize.
@Nonnull
@Override
@SuppressWarnings("unchecked")
public <Message extends PMessage<Message, Field>, Field extends PField> PServiceCall<Message, Field> deserialize(@Nonnull InputStream input, @Nonnull PService service) throws IOException {
String methodName = null;
int sequence = 0;
PServiceCallType callType = null;
try {
// pretty printed service calls cannot be chained-serialized, so this should be totally safe.
Tokenizer tokenizer = new Tokenizer(input);
Token token = tokenizer.expect("Sequence or type");
if (token.isInteger()) {
sequence = (int) token.parseInteger();
tokenizer.expectSymbol("Sequence type sep", Token.kKeyValueSep);
token = tokenizer.expectIdentifier("Call Type");
}
callType = PServiceCallType.findByName(token.asString().toUpperCase(Locale.US));
if (callType == null) {
throw new TokenizerException(token, "No such call type %s", token.asString()).setLine(tokenizer.getLine()).setExceptionType(PApplicationExceptionType.INVALID_MESSAGE_TYPE);
}
token = tokenizer.expectIdentifier("method name");
methodName = token.asString();
PServiceMethod method = service.getMethod(methodName);
if (method == null) {
throw new TokenizerException(token, "no such method %s on service %s", methodName, service.getQualifiedName()).setLine(tokenizer.getLine()).setExceptionType(PApplicationExceptionType.UNKNOWN_METHOD);
}
tokenizer.expectSymbol("call params start", Token.kParamsStart);
Message message;
switch(callType) {
case CALL:
case ONEWAY:
message = (Message) readMessage(tokenizer, method.getRequestType(), true);
break;
case REPLY:
message = (Message) readMessage(tokenizer, method.getResponseType(), true);
break;
case EXCEPTION:
message = (Message) readMessage(tokenizer, PApplicationException.kDescriptor, true);
break;
default:
throw new IllegalStateException("Unreachable code reached");
}
return new PServiceCall<>(methodName, callType, sequence, message);
} catch (TokenizerException e) {
e.setCallType(callType).setSequenceNo(sequence).setMethodName(methodName);
throw e;
} catch (IOException e) {
throw new SerializerException(e, e.getMessage()).setCallType(callType).setSequenceNo(sequence).setMethodName(methodName);
}
}
use of net.morimekta.providence.serializer.pretty.Token in project providence by morimekta.
the class ProvidenceConfigUtilTest method validateConsume.
private void validateConsume(String content, ProvidenceConfigContext context) throws IOException {
if (context == null) {
context = new ProvidenceConfigContext();
}
Tokenizer tokenizer = tokenizer(content);
consumeValue(context, tokenizer, tokenizer.expect("consumed value"));
Token next = tokenizer.expect("after consuming");
assertThat(next, is(notNullValue()));
assertThat(next.asString(), is("__after__"));
}
Aggregations