Search in sources :

Example 11 with Token

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();
}
Also used : PField(net.morimekta.providence.descriptor.PField) PMessage(net.morimekta.providence.PMessage) Token(net.morimekta.providence.serializer.pretty.Token) JsonToken(net.morimekta.util.json.JsonToken)

Example 12 with Token

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);
}
Also used : Token(net.morimekta.providence.serializer.pretty.Token) Tokenizer(net.morimekta.providence.serializer.pretty.Tokenizer) Nonnull(javax.annotation.Nonnull)

Example 13 with Token

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();
}
Also used : PField(net.morimekta.providence.descriptor.PField) PMessage(net.morimekta.providence.PMessage) PField(net.morimekta.providence.descriptor.PField) Token(net.morimekta.providence.serializer.pretty.Token) TokenizerException(net.morimekta.providence.serializer.pretty.TokenizerException)

Example 14 with Token

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);
    }
}
Also used : PMessage(net.morimekta.providence.PMessage) PServiceCallType(net.morimekta.providence.PServiceCallType) PServiceCall(net.morimekta.providence.PServiceCall) Token(net.morimekta.providence.serializer.pretty.Token) TokenizerException(net.morimekta.providence.serializer.pretty.TokenizerException) IOException(java.io.IOException) Tokenizer(net.morimekta.providence.serializer.pretty.Tokenizer) PServiceMethod(net.morimekta.providence.descriptor.PServiceMethod) Nonnull(javax.annotation.Nonnull)

Example 15 with Token

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__"));
}
Also used : Token(net.morimekta.providence.serializer.pretty.Token) Tokenizer(net.morimekta.providence.serializer.pretty.Tokenizer)

Aggregations

Token (net.morimekta.providence.serializer.pretty.Token)22 TokenizerException (net.morimekta.providence.serializer.pretty.TokenizerException)8 PMessage (net.morimekta.providence.PMessage)6 LinkedHashMap (java.util.LinkedHashMap)3 TreeSet (java.util.TreeSet)3 EnumType (net.morimekta.providence.model.EnumType)3 ServiceType (net.morimekta.providence.model.ServiceType)3 Tokenizer (net.morimekta.providence.serializer.pretty.Tokenizer)3 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 Map (java.util.Map)2 TreeMap (java.util.TreeMap)2 Nonnull (javax.annotation.Nonnull)2 PMessageBuilder (net.morimekta.providence.PMessageBuilder)2 PEnumDescriptor (net.morimekta.providence.descriptor.PEnumDescriptor)2 PField (net.morimekta.providence.descriptor.PField)2 PMessageDescriptor (net.morimekta.providence.descriptor.PMessageDescriptor)2 ConstType (net.morimekta.providence.model.ConstType)2 Declaration (net.morimekta.providence.model.Declaration)2