Search in sources :

Example 1 with PEnumValue

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

the class FastBinarySerializer method writeContainerEntry.

@SuppressWarnings("unchecked")
private int writeContainerEntry(LittleEndianBinaryWriter out, int typeid, PDescriptor descriptor, Object value) throws IOException {
    switch(typeid) {
        case VARINT:
            {
                if (value instanceof Boolean) {
                    return out.writeVarint(((Boolean) value ? 1 : 0));
                } else if (value instanceof Number) {
                    return out.writeZigzag(((Number) value).longValue());
                } else if (value instanceof PEnumValue) {
                    return out.writeZigzag(((PEnumValue) value).asInteger());
                } else {
                    throw new SerializerException("");
                }
            }
        case FIXED_64:
            {
                return out.writeDouble((Double) value);
            }
        case BINARY:
            {
                if (value instanceof CharSequence) {
                    byte[] bytes = ((String) value).getBytes(StandardCharsets.UTF_8);
                    int len = out.writeVarint(bytes.length);
                    out.write(bytes);
                    return len + bytes.length;
                } else if (value instanceof Binary) {
                    Binary bytes = (Binary) value;
                    int len = out.writeVarint(bytes.length());
                    bytes.write(out);
                    return len + bytes.length();
                } else {
                    throw new SerializerException("");
                }
            }
        case MESSAGE:
            {
                return writeMessage(out, (PMessage) value);
            }
        case COLLECTION:
            {
                if (value instanceof Map) {
                    Map<Object, Object> map = (Map<Object, Object>) value;
                    PMap<?, ?> desc = (PMap<?, ?>) descriptor;
                    int ktype = itemType(desc.keyDescriptor());
                    int vtype = itemType(desc.itemDescriptor());
                    int len = out.writeVarint(map.size() * 2);
                    len += out.writeVarint(ktype << 3 | vtype);
                    for (Map.Entry<Object, Object> entry : map.entrySet()) {
                        len += writeContainerEntry(out, ktype, desc.keyDescriptor(), entry.getKey());
                        len += writeContainerEntry(out, vtype, desc.itemDescriptor(), entry.getValue());
                    }
                    return len;
                } else if (value instanceof Collection) {
                    Collection<Object> coll = (Collection<Object>) value;
                    PContainer<?> desc = (PContainer<?>) descriptor;
                    int vtype = itemType(desc.itemDescriptor());
                    int len = out.writeVarint(coll.size());
                    len += out.writeVarint(vtype);
                    for (Object item : coll) {
                        len += writeContainerEntry(out, vtype, desc.itemDescriptor(), item);
                    }
                    return len;
                } else {
                    throw new SerializerException("");
                }
            }
        default:
            throw new SerializerException("");
    }
}
Also used : PEnumValue(net.morimekta.providence.PEnumValue) PMap(net.morimekta.providence.descriptor.PMap) PMessage(net.morimekta.providence.PMessage) PContainer(net.morimekta.providence.descriptor.PContainer) Collection(java.util.Collection) Binary(net.morimekta.util.Binary) Map(java.util.Map) PMap(net.morimekta.providence.descriptor.PMap)

Example 2 with PEnumValue

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

the class PrettySerializer method appendPrimitive.

private void appendPrimitive(IndentedPrintWriter writer, Object o) {
    if (o instanceof PEnumValue) {
        writer.print(((PEnumValue) o).asString());
    } else if (o instanceof CharSequence) {
        writer.print(Token.kLiteralDoubleQuote);
        writer.print(Strings.escape((CharSequence) o));
        writer.print(Token.kLiteralDoubleQuote);
    } else if (o instanceof Binary) {
        Binary b = (Binary) o;
        writer.append(Token.B64).append(Token.kParamsStart).append(b.toBase64()).append(Token.kParamsEnd);
    } else if (o instanceof Boolean) {
        writer.print(((Boolean) o).booleanValue());
    } else if (o instanceof Byte || o instanceof Short || o instanceof Integer || o instanceof Long) {
        writer.print(o.toString());
    } else if (o instanceof Double) {
        Double d = (Double) o;
        if (d.equals(((double) d.longValue()))) {
            // actually an integer or long value.
            writer.print(d.longValue());
        } else {
            writer.print(d.doubleValue());
        }
    } else {
        throw new IllegalArgumentException("Unknown primitive type class " + o.getClass().getSimpleName());
    }
}
Also used : PEnumValue(net.morimekta.providence.PEnumValue) Binary(net.morimekta.util.Binary)

Example 3 with PEnumValue

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

the class ProvidenceConfigParser method parseFieldValue.

@SuppressWarnings("unchecked")
Object parseFieldValue(Token next, Tokenizer tokenizer, ProvidenceConfigContext context, PDescriptor descriptor, boolean requireEnumValue) throws IOException {
    try {
        switch(descriptor.getType()) {
            case BOOL:
                if (TRUE.equals(next.asString())) {
                    return true;
                } else if (FALSE.equals(next.asString())) {
                    return false;
                } else if (next.isReferenceIdentifier()) {
                    return resolve(context, next, tokenizer, descriptor);
                }
                break;
            case BYTE:
                if (next.isReferenceIdentifier()) {
                    return resolve(context, next, tokenizer, descriptor);
                } else if (next.isInteger()) {
                    return (byte) next.parseInteger();
                }
                break;
            case I16:
                if (next.isReferenceIdentifier()) {
                    return resolve(context, next, tokenizer, descriptor);
                } else if (next.isInteger()) {
                    return (short) next.parseInteger();
                }
                break;
            case I32:
                if (next.isReferenceIdentifier()) {
                    return resolve(context, next, tokenizer, descriptor);
                } else if (next.isInteger()) {
                    return (int) next.parseInteger();
                }
                break;
            case I64:
                if (next.isReferenceIdentifier()) {
                    return resolve(context, next, tokenizer, descriptor);
                } else if (next.isInteger()) {
                    return next.parseInteger();
                }
                break;
            case DOUBLE:
                if (next.isReferenceIdentifier()) {
                    return resolve(context, next, tokenizer, descriptor);
                } else if (next.isInteger() || next.isReal()) {
                    return next.parseDouble();
                }
                break;
            case STRING:
                if (next.isReferenceIdentifier()) {
                    return resolve(context, next, tokenizer, descriptor);
                } else if (next.isStringLiteral()) {
                    return next.decodeLiteral(strict);
                }
                break;
            case BINARY:
                if (Token.B64.equals(next.asString())) {
                    tokenizer.expectSymbol("binary data enclosing start", Token.kParamsStart);
                    return Binary.fromBase64(tokenizer.readBinary(Token.kParamsEnd));
                } else if (Token.HEX.equals(next.asString())) {
                    tokenizer.expectSymbol("binary data enclosing start", Token.kParamsStart);
                    return Binary.fromHexString(tokenizer.readBinary(Token.kParamsEnd));
                } else if (next.isReferenceIdentifier()) {
                    return resolve(context, next, tokenizer, descriptor);
                }
                break;
            case ENUM:
                {
                    PEnumDescriptor ed = (PEnumDescriptor) descriptor;
                    PEnumValue value;
                    String name = next.asString();
                    if (next.isInteger()) {
                        value = ed.findById((int) next.parseInteger());
                    } else if (next.isIdentifier()) {
                        value = ed.findByName(name);
                        if (value == null && context.containsReference(name)) {
                            value = resolve(context, next, tokenizer, ed);
                        }
                    } else if (next.isReferenceIdentifier()) {
                        value = resolve(context, next, tokenizer, descriptor);
                    } else {
                        break;
                    }
                    if (value == null && (strict || requireEnumValue)) {
                        PEnumValue option = null;
                        if (next.isIdentifier()) {
                            for (PEnumValue o : ed.getValues()) {
                                if (o.getName().equalsIgnoreCase(name)) {
                                    option = o;
                                    break;
                                }
                            }
                        }
                        if (option != null) {
                            throw new TokenizerException(next, "No such enum value '%s' for %s, did you mean '%s'?", name, ed.getQualifiedName(), option.getName()).setLine(tokenizer.getLine());
                        }
                        throw new TokenizerException(next, "No such enum value '%s' for %s.", name, ed.getQualifiedName()).setLine(tokenizer.getLine());
                    }
                    return value;
                }
            case MESSAGE:
                if (next.isReferenceIdentifier()) {
                    return resolve(context, next, tokenizer, descriptor);
                } else if (next.isSymbol(Token.kMessageStart)) {
                    return parseMessage(tokenizer, context, ((PMessageDescriptor) descriptor).builder());
                }
                break;
            case MAP:
                {
                    if (next.isReferenceIdentifier()) {
                        Map resolved;
                        try {
                            // Make sure the reference is to a map.
                            resolved = resolve(context, next, tokenizer, descriptor);
                        } catch (ClassCastException e) {
                            throw new TokenizerException(next, "Reference %s is not a map field ", next.asString()).setLine(tokenizer.getLine());
                        }
                        return resolved;
                    } else if (next.isSymbol(Token.kMessageStart)) {
                        return parseMapValue(tokenizer, context, (PMap) descriptor, new LinkedHashMap());
                    }
                    break;
                }
            case SET:
                {
                    if (next.isReferenceIdentifier()) {
                        return resolve(context, next, tokenizer, descriptor);
                    } else if (next.isSymbol(Token.kListStart)) {
                        @SuppressWarnings("unchecked") PSet<Object> ct = (PSet) descriptor;
                        Set<Object> value = new LinkedHashSet<>();
                        next = tokenizer.expect("set value or end");
                        while (!next.isSymbol(Token.kListEnd)) {
                            Object item = parseFieldValue(next, tokenizer, context, ct.itemDescriptor(), strict);
                            if (item != null) {
                                value.add(item);
                            }
                            // sets require separator, and allows separator after last.
                            if (tokenizer.expectSymbol("set separator or end", Token.kLineSep1, Token.kListEnd) == Token.kListEnd) {
                                break;
                            }
                            next = tokenizer.expect("set value or end");
                        }
                        return ct.builder().addAll(value).build();
                    }
                    break;
                }
            case LIST:
                {
                    if (next.isReferenceIdentifier()) {
                        return resolve(context, next, tokenizer, descriptor);
                    } else if (next.isSymbol(Token.kListStart)) {
                        @SuppressWarnings("unchecked") PList<Object> ct = (PList) descriptor;
                        PList.Builder<Object> builder = ct.builder();
                        next = tokenizer.expect("list value or end");
                        while (!next.isSymbol(Token.kListEnd)) {
                            Object item = parseFieldValue(next, tokenizer, context, ct.itemDescriptor(), strict);
                            if (item != null) {
                                builder.add(item);
                            }
                            // lists require separator, and allows separator after last.
                            if (tokenizer.expectSymbol("list separator or end", Token.kLineSep1, Token.kListEnd) == Token.kListEnd) {
                                break;
                            }
                            next = tokenizer.expect("list value or end");
                        }
                        return builder.build();
                    }
                    break;
                }
            default:
                {
                    throw new TokenizerException(next, descriptor.getType() + " not supported!").setLine(tokenizer.getLine());
                }
        }
    } catch (ProvidenceConfigException e) {
        throw new TokenizerException(next, e.getMessage()).setLine(tokenizer.getLine());
    }
    throw new TokenizerException(next, "Unhandled value \"%s\" for type %s", next.asString(), descriptor.getType()).setLine(tokenizer.getLine());
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PList(net.morimekta.providence.descriptor.PList) PEnumValue(net.morimekta.providence.PEnumValue) TokenizerException(net.morimekta.providence.serializer.pretty.TokenizerException) PEnumDescriptor(net.morimekta.providence.descriptor.PEnumDescriptor) ProvidenceConfigException(net.morimekta.providence.config.ProvidenceConfigException) LinkedHashMap(java.util.LinkedHashMap) PSet(net.morimekta.providence.descriptor.PSet) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) PMap(net.morimekta.providence.descriptor.PMap)

Example 4 with PEnumValue

use of net.morimekta.providence.PEnumValue 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 5 with PEnumValue

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

the class TProtocolSerializer method writeTypedValue.

private void writeTypedValue(Object item, PDescriptor type, TProtocol protocol) throws TException, SerializerException {
    switch(type.getType()) {
        case BOOL:
            protocol.writeBool((Boolean) item);
            break;
        case BYTE:
            protocol.writeByte((Byte) item);
            break;
        case I16:
            protocol.writeI16((Short) item);
            break;
        case I32:
            protocol.writeI32((Integer) item);
            break;
        case I64:
            protocol.writeI64((Long) item);
            break;
        case DOUBLE:
            protocol.writeDouble((Double) item);
            break;
        case STRING:
            protocol.writeString((String) item);
            break;
        case BINARY:
            protocol.writeBinary(((Binary) item).getByteBuffer());
            break;
        case ENUM:
            PEnumValue<?> value = (PEnumValue<?>) item;
            protocol.writeI32(value.asInteger());
            break;
        case MESSAGE:
            writeMessage((PMessage<?, ?>) item, protocol);
            break;
        case LIST:
            PList<?> lType = (PList<?>) type;
            List<?> list = (List<?>) item;
            TList listInfo = new TList(forType(lType.itemDescriptor().getType()), list.size());
            protocol.writeListBegin(listInfo);
            for (Object i : list) {
                writeTypedValue(i, lType.itemDescriptor(), protocol);
            }
            protocol.writeListEnd();
            break;
        case SET:
            PSet<?> sType = (PSet<?>) type;
            Set<?> set = (Set<?>) item;
            TSet setInfo = new TSet(forType(sType.itemDescriptor().getType()), set.size());
            protocol.writeSetBegin(setInfo);
            for (Object i : set) {
                writeTypedValue(i, sType.itemDescriptor(), protocol);
            }
            protocol.writeSetEnd();
            break;
        case MAP:
            PMap<?, ?> mType = (PMap<?, ?>) type;
            Map<?, ?> map = (Map<?, ?>) item;
            protocol.writeMapBegin(new TMap(forType(mType.keyDescriptor().getType()), forType(mType.itemDescriptor().getType()), map.size()));
            for (Map.Entry<?, ?> entry : map.entrySet()) {
                writeTypedValue(entry.getKey(), mType.keyDescriptor(), protocol);
                writeTypedValue(entry.getValue(), mType.itemDescriptor(), protocol);
            }
            protocol.writeMapEnd();
            break;
        default:
            break;
    }
}
Also used : TSet(org.apache.thrift.protocol.TSet) Set(java.util.Set) PSet(net.morimekta.providence.descriptor.PSet) PList(net.morimekta.providence.descriptor.PList) PEnumValue(net.morimekta.providence.PEnumValue) TSet(org.apache.thrift.protocol.TSet) PMap(net.morimekta.providence.descriptor.PMap) TMap(org.apache.thrift.protocol.TMap) TList(org.apache.thrift.protocol.TList) PSet(net.morimekta.providence.descriptor.PSet) TList(org.apache.thrift.protocol.TList) PList(net.morimekta.providence.descriptor.PList) List(java.util.List) Map(java.util.Map) PMap(net.morimekta.providence.descriptor.PMap) TMap(org.apache.thrift.protocol.TMap)

Aggregations

PEnumValue (net.morimekta.providence.PEnumValue)11 PMessage (net.morimekta.providence.PMessage)6 Binary (net.morimekta.util.Binary)6 Map (java.util.Map)5 List (java.util.List)3 Set (java.util.Set)3 PEnumDescriptor (net.morimekta.providence.descriptor.PEnumDescriptor)3 PMap (net.morimekta.providence.descriptor.PMap)3 PMessageDescriptor (net.morimekta.providence.descriptor.PMessageDescriptor)3 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2 PrintWriter (java.io.PrintWriter)2 StringReader (java.io.StringReader)2 StringWriter (java.io.StringWriter)2 Timestamp (java.sql.Timestamp)2 PMessageBuilder (net.morimekta.providence.PMessageBuilder)2 PField (net.morimekta.providence.descriptor.PField)2 PList (net.morimekta.providence.descriptor.PList)2 PSet (net.morimekta.providence.descriptor.PSet)2