package io.fathom.cloud.protobuf;
import io.fathom.cloud.protobuf.mapper.MessageMapper;
import io.fathom.cloud.protobuf.mapper.ProtobufWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.LinkedList;
import java.util.List;
import com.google.common.collect.Lists;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Message;
public class ProtobufYamlWriter implements ProtobufWriter {
final Writer out;
public ProtobufYamlWriter(Writer out) {
this.out = out;
}
public static void serialize(Message src, Writer out) throws IOException {
ProtobufYamlWriter writer = new ProtobufYamlWriter(out);
Descriptor descriptor = src.getDescriptorForType();
MessageMapper mapper = MessageMapper.getMessageMapper(descriptor);
mapper.write(src, writer);
}
public static void serialize(List<? extends Message> src, Writer out) throws IOException {
ProtobufYamlWriter writer = new ProtobufYamlWriter(out);
for (Message message : src) {
Descriptor descriptor = message.getDescriptorForType();
MessageMapper mapper = MessageMapper.getMessageMapper(descriptor);
mapper.write(message, writer);
}
}
enum State {
OBJECT, ARRAY
}
final LinkedList<State> stateStack = Lists.newLinkedList();
int indent;
String name;
@Override
public void beginObject() throws IOException {
if (name != null) {
writeIndent();
out.write(name);
out.write(":\n");
this.name = null;
} else {
writeIndent();
out.write("-\n");
}
indent++;
stateStack.push(State.OBJECT);
}
@Override
public void endObject() throws IOException {
State state = stateStack.pop();
if (state != State.OBJECT) {
throw new IllegalStateException();
}
indent--;
}
@Override
public void name(String name) throws IOException {
this.name = name;
}
@Override
public void beginArray() throws IOException {
if (name != null) {
writeIndent();
out.write(name);
out.write(":\n");
this.name = null;
}
indent++;
stateStack.push(State.ARRAY);
}
private void writeIndent() throws IOException {
for (int i = 0; i < indent; i++) {
out.write(" ");
}
}
@Override
public void endArray() throws IOException {
State state = stateStack.pop();
if (state != State.ARRAY) {
throw new IllegalStateException();
}
indent--;
}
@Override
public void value(boolean v) throws IOException {
writeValue(Boolean.toString(v));
}
@Override
public void value(long v) throws IOException {
writeValue(Long.toString(v));
}
@Override
public void value(double v) throws IOException {
writeValue(Double.toString(v));
}
@Override
public void value(String v) throws IOException {
if (v != null) {
writeValue(v);
}
}
private void writeValue(String v) throws IOException {
writeIndent();
State state = stateStack.peek();
if (state != null) {
switch (state) {
case OBJECT:
break;
case ARRAY:
out.write("- ");
break;
default:
throw new IllegalStateException();
}
}
if (name != null) {
out.write(name);
out.write(": ");
name = null;
}
out.write(v);
out.write("\n");
}
}