Search in sources :

Example 11 with PMessage

use of net.morimekta.providence.PMessage 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 PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class MessageFieldArgument method apply.

@Override
@SuppressWarnings("unchecked")
public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException {
    if (message.has(field)) {
        switch(field.getType()) {
            case BOOL:
                {
                    boolean value = message.get(field);
                    if (type == Types.BOOLEAN || type == Types.BIT) {
                        statement.setBoolean(position, value);
                    } else {
                        statement.setInt(position, value ? 1 : 0);
                    }
                    break;
                }
            case BYTE:
                {
                    statement.setByte(position, message.get(field));
                    break;
                }
            case I16:
                {
                    statement.setShort(position, message.get(field));
                    break;
                }
            case I32:
                {
                    if (type == Types.TIMESTAMP) {
                        Timestamp timestamp = new Timestamp(1000L * (int) message.get(field));
                        statement.setTimestamp(position, timestamp);
                    } else {
                        statement.setInt(position, message.get(field));
                    }
                    break;
                }
            case I64:
                {
                    if (type == Types.TIMESTAMP) {
                        Timestamp timestamp = new Timestamp(message.get(field));
                        statement.setTimestamp(position, timestamp);
                    } else {
                        statement.setLong(position, message.get(field));
                    }
                    break;
                }
            case DOUBLE:
                {
                    statement.setDouble(position, message.get(field));
                    break;
                }
            case STRING:
                {
                    statement.setString(position, message.get(field));
                    break;
                }
            case BINARY:
                {
                    Binary binary = message.get(field);
                    switch(type) {
                        case Types.BINARY:
                        case Types.VARBINARY:
                            {
                                statement.setBytes(position, binary.get());
                                break;
                            }
                        case Types.BLOB:
                            {
                                statement.setBlob(position, binary.getInputStream());
                                break;
                            }
                        case Types.CHAR:
                        case Types.VARCHAR:
                        case Types.NCHAR:
                        case Types.NVARCHAR:
                            {
                                statement.setString(position, binary.toBase64());
                                break;
                            }
                        default:
                            throw new SQLDataException("Unknown binary field type: " + type + " for " + field);
                    }
                    break;
                }
            case ENUM:
                {
                    PEnumValue value = message.get(field);
                    statement.setInt(position, value.asInteger());
                    break;
                }
            case MESSAGE:
                {
                    PMessage value = message.get(field);
                    switch(type) {
                        case Types.BINARY:
                        case Types.VARBINARY:
                            {
                                ByteArrayOutputStream out = new ByteArrayOutputStream();
                                try {
                                    BINARY.serialize(out, value);
                                    statement.setBytes(position, out.toByteArray());
                                } catch (IOException e) {
                                    throw new SQLDataException(e.getMessage(), e);
                                }
                                break;
                            }
                        case Types.BLOB:
                            {
                                ByteArrayOutputStream out = new ByteArrayOutputStream();
                                try {
                                    BINARY.serialize(out, value);
                                    statement.setBlob(position, new ByteArrayInputStream(out.toByteArray()));
                                } catch (IOException e) {
                                    throw new SQLDataException(e.getMessage(), e);
                                }
                                break;
                            }
                        case Types.CHAR:
                        case Types.VARCHAR:
                        case Types.NCHAR:
                        case Types.NVARCHAR:
                            {
                                StringWriter writer = new StringWriter();
                                try {
                                    JSON.serialize(new PrintWriter(writer), value);
                                    statement.setString(position, writer.getBuffer().toString());
                                } catch (IOException e) {
                                    throw new SQLDataException(e.getMessage(), e);
                                }
                                break;
                            }
                        case Types.CLOB:
                            {
                                StringWriter writer = new StringWriter();
                                try {
                                    JSON.serialize(new PrintWriter(writer), value);
                                    statement.setClob(position, new StringReader(writer.getBuffer().toString()));
                                } catch (IOException e) {
                                    throw new SQLDataException(e.getMessage(), e);
                                }
                                break;
                            }
                        default:
                            throw new SQLDataException("Unknown message field type: " + type + " for " + field);
                    }
                    break;
                }
            default:
                throw new SQLDataException("Unhandled field type in SQL: " + field);
        }
    } else {
        statement.setNull(position, type);
    }
}
Also used : SQLDataException(java.sql.SQLDataException) StringWriter(java.io.StringWriter) ByteArrayInputStream(java.io.ByteArrayInputStream) PMessage(net.morimekta.providence.PMessage) StringReader(java.io.StringReader) PEnumValue(net.morimekta.providence.PEnumValue) Binary(net.morimekta.util.Binary) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) Timestamp(java.sql.Timestamp) PrintWriter(java.io.PrintWriter)

Example 13 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class MessageNamedArgumentFinder method find.

@Override
@SuppressWarnings("unchecked")
public Argument find(String name) {
    if (!prefix.isEmpty()) {
        if (name.startsWith(prefix)) {
            name = name.substring(prefix.length());
        } else {
            return null;
        }
    }
    String[] parts = name.split("[.]");
    PMessage leaf = message;
    PMessageDescriptor leafDescriptor = message.descriptor();
    for (int i = 0; i < parts.length - 1; ++i) {
        String part = parts[i];
        PField field = leafDescriptor.findFieldByName(part);
        if (field == null)
            return null;
        if (field.getType() != PType.MESSAGE) {
            throw new IllegalArgumentException("");
        }
        leafDescriptor = (PMessageDescriptor) field.getDescriptor();
        if (leaf != null) {
            leaf = (PMessage) leaf.get(field.getId());
        }
    }
    String leafName = parts[parts.length - 1];
    PField field = leafDescriptor.findFieldByName(leafName);
    if (field != null) {
        if (leaf != null) {
            return new MessageFieldArgument(leaf, field, getColumnType(field));
        }
        return new NullArgument(getColumnType(field));
    }
    return null;
}
Also used : PField(net.morimekta.providence.descriptor.PField) PMessage(net.morimekta.providence.PMessage) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) NullArgument(net.morimekta.providence.jdbi.v2.util.NullArgument)

Example 14 with PMessage

use of net.morimekta.providence.PMessage in project providence by morimekta.

the class FastBinarySerializer method readMessage.

@Nonnull
private <Message extends PMessage<Message, Field>, Field extends PField> Message readMessage(@Nonnull LittleEndianBinaryReader in, @Nonnull PMessageDescriptor<Message, Field> descriptor) throws IOException {
    int tag;
    PMessageBuilder<Message, Field> builder = descriptor.builder();
    while ((tag = in.readIntVarint()) != STOP) {
        int id = tag >>> 3;
        int type = tag & 0x07;
        Field field = descriptor.findFieldById(id);
        if (field != null) {
            Object value = readFieldValue(in, type, field.getDescriptor());
            builder.set(field.getId(), value);
        } else {
            readFieldValue(in, type, null);
        }
    }
    if (readStrict) {
        try {
            builder.validate();
        } catch (IllegalStateException e) {
            throw new SerializerException(e, e.getMessage());
        }
    }
    return builder.build();
}
Also used : PField(net.morimekta.providence.descriptor.PField) PMessage(net.morimekta.providence.PMessage) Nonnull(javax.annotation.Nonnull)

Example 15 with PMessage

use of net.morimekta.providence.PMessage 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)

Aggregations

PMessage (net.morimekta.providence.PMessage)31 PField (net.morimekta.providence.descriptor.PField)20 Nonnull (javax.annotation.Nonnull)7 TokenizerException (net.morimekta.providence.serializer.pretty.TokenizerException)7 IOException (java.io.IOException)6 PEnumValue (net.morimekta.providence.PEnumValue)6 PServiceCall (net.morimekta.providence.PServiceCall)6 PServiceCallType (net.morimekta.providence.PServiceCallType)6 Token (net.morimekta.providence.serializer.pretty.Token)6 Map (java.util.Map)5 PApplicationException (net.morimekta.providence.PApplicationException)5 PMessageDescriptor (net.morimekta.providence.descriptor.PMessageDescriptor)5 SerializerException (net.morimekta.providence.serializer.SerializerException)5 Binary (net.morimekta.util.Binary)5 ArrayList (java.util.ArrayList)4 PMessageBuilder (net.morimekta.providence.PMessageBuilder)4 PServiceMethod (net.morimekta.providence.descriptor.PServiceMethod)4 TMessage (org.apache.thrift.protocol.TMessage)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3