package com.jsoniter.output;
import java.lang.reflect.Type;
import java.util.*;
class CodegenImplArray {
public static CodegenResult genArray(String cacheKey, Class clazz) {
Class compType = clazz.getComponentType();
if (compType.isArray()) {
throw new IllegalArgumentException("nested array not supported: " + clazz.getCanonicalName());
}
boolean isCollectionValueNullable = true;
if (cacheKey.endsWith("__value_not_nullable")) {
isCollectionValueNullable = false;
}
if (compType.isPrimitive()) {
isCollectionValueNullable = false;
}
CodegenResult ctx = new CodegenResult();
ctx.append("public static void encode_(java.lang.Object obj, com.jsoniter.output.JsonStream stream) throws java.io.IOException {");
ctx.append(String.format("%s[] arr = (%s[])obj;", compType.getCanonicalName(), compType.getCanonicalName()));
ctx.append("if (arr.length == 0) { return; }");
ctx.buffer('[');
ctx.append("int i = 0;");
ctx.append(String.format("%s e = arr[i++];", compType.getCanonicalName()));
if (isCollectionValueNullable) {
ctx.append("if (e == null) { stream.writeNull(); } else {");
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
ctx.append("}");
} else {
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
}
ctx.append("while (i < arr.length) {");
ctx.append("stream.write(',');");
ctx.append("e = arr[i++];");
if (isCollectionValueNullable) {
ctx.append("if (e == null) { stream.writeNull(); } else {");
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
ctx.append("}");
} else {
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
}
ctx.append("}");
ctx.buffer(']');
ctx.append("}");
return ctx;
}
public static CodegenResult genCollection(String cacheKey, Class clazz, Type[] typeArgs) {
Type compType = Object.class;
if (typeArgs.length == 0) {
// default to List<Object>
} else if (typeArgs.length == 1) {
compType = typeArgs[0];
} else {
throw new IllegalArgumentException(
"can not bind to generic collection without argument types, " +
"try syntax like TypeLiteral<List<Integer>>{}");
}
if (clazz == List.class) {
clazz = ArrayList.class;
} else if (clazz == Set.class) {
clazz = HashSet.class;
}
if (List.class.isAssignableFrom(clazz)) {
return genList(cacheKey, clazz, compType);
} else {
return genCollection(cacheKey, clazz, compType);
}
}
private static CodegenResult genList(String cacheKey, Class clazz, Type compType) {
boolean isCollectionValueNullable = true;
if (cacheKey.endsWith("__value_not_nullable")) {
isCollectionValueNullable = false;
}
CodegenResult ctx = new CodegenResult();
ctx.append("public static void encode_(java.lang.Object obj, com.jsoniter.output.JsonStream stream) throws java.io.IOException {");
ctx.append("java.util.List list = (java.util.List)obj;");
ctx.append("int size = list.size();");
ctx.append("if (size == 0) { return; }");
ctx.buffer('[');
ctx.append("java.lang.Object e = list.get(0);");
if (isCollectionValueNullable) {
ctx.append("if (e == null) { stream.writeNull(); } else {");
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
ctx.append("}");
} else {
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
}
ctx.append("for (int i = 1; i < size; i++) {");
ctx.append("stream.write(',');");
ctx.append("e = list.get(i);");
if (isCollectionValueNullable) {
ctx.append("if (e == null) { stream.writeNull(); } else {");
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
ctx.append("}");
} else {
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
}
ctx.append("}");
ctx.buffer(']');
ctx.append("}");
return ctx;
}
private static CodegenResult genCollection(String cacheKey, Class clazz, Type compType) {
boolean isCollectionValueNullable = true;
if (cacheKey.endsWith("__value_not_nullable")) {
isCollectionValueNullable = false;
}
CodegenResult ctx = new CodegenResult();
ctx.append("public static void encode_(java.lang.Object obj, com.jsoniter.output.JsonStream stream) throws java.io.IOException {");
ctx.append("java.util.Iterator iter = ((java.util.Collection)obj).iterator();");
ctx.append("if (!iter.hasNext()) { return; }");
ctx.buffer('[');
ctx.append("java.lang.Object e = iter.next();");
if (isCollectionValueNullable) {
ctx.append("if (e == null) { stream.writeNull(); } else {");
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
ctx.append("}");
} else {
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
}
ctx.append("while (iter.hasNext()) {");
ctx.append("stream.write(',');");
ctx.append("e = iter.next();");
if (isCollectionValueNullable) {
ctx.append("if (e == null) { stream.writeNull(); } else {");
CodegenImplNative.genWriteOp(ctx, "e", compType, true);
ctx.append("}");
} else {
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
}
ctx.append("}");
ctx.buffer(']');
ctx.append("}");
return ctx;
}
}