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("");
}
}
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());
}
}
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());
}
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);
}
}
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;
}
}
Aggregations