/** * */ package org.ebayopensource.turmeric.tools.codegen.fastserformat.protobuf.dotproto; import java.util.List; import org.ebayopensource.turmeric.tools.codegen.fastserformat.protobuf.model.ProtobufEnumEntry; import org.ebayopensource.turmeric.tools.codegen.fastserformat.protobuf.model.ProtobufEnumMessage; import org.ebayopensource.turmeric.tools.codegen.fastserformat.protobuf.model.ProtobufField; import org.ebayopensource.turmeric.tools.codegen.fastserformat.protobuf.model.ProtobufMessage; import org.ebayopensource.turmeric.tools.codegen.fastserformat.protobuf.model.ProtobufOption; import org.ebayopensource.turmeric.tools.codegen.fastserformat.protobuf.model.ProtobufOptionType; import org.ebayopensource.turmeric.tools.codegen.fastserformat.protobuf.model.ProtobufSchema; /** * @author rkulandaivel * */ public class ProtobufSchemaWriter { //Key words Constants public static final String PACKAGE = "package"; public static final String END_LINE = ";"; public static final String OPTION = "option"; public static final String EQUAL_SIGN = "="; public static final String MESSAGE = "message"; public static final String ENUM = "enum"; public static final String START_BLOCK = "{"; public static final String END_BLOCK = "}"; private ProtobufSchema m_schema = null; public ProtobufSchemaWriter( ProtobufSchema schema ){ m_schema = schema; } private ProtobufSchema getSchema(){ return m_schema; } /** * Writes the contents of the file. * Creates the file with following structure. * * <Package> * * <Compiler Options for JAVA> * * <Messages> * * @param formatter */ public void write( DotProtoFormatter formatter ){ //write package writePackage( formatter, getSchema() ); //Leave a line before options formatter.newLine(); //Write all java options writeOptions( formatter ); //Leave a line for messages formatter.newLine(); //Write all messages for(ProtobufMessage message : m_schema.getMessages() ){ writeMessage( formatter, message ); formatter.newLine(); } //write the metadata information formatter.newLine(); formatter.print( new String( m_schema.getMetadataBytes() ) ); } /** * Writes the package. * Writes as * package <Package value>; * * @param formatter * @param schema */ private void writePackage( DotProtoFormatter formatter , ProtobufSchema schema ){ formatter.print( PACKAGE ); formatter.print( schema.getDotprotoFilePackage() ); formatter.print( END_LINE ); } /** * Writes all the java options. * The format is * option <option_type> = "value"; * * Only for option type "optimize_for", the double quotes would not be generated. * * @param formatter */ private void writeOptions( DotProtoFormatter formatter ){ List<ProtobufOption> options = m_schema.getDotprotoOptions(); for( ProtobufOption option : options ){ //new line for each option formatter.newLine(); //print key word formatter.print( OPTION ); //print option type formatter.print( option.getOptionType().value() ); //equal sign formatter.print( EQUAL_SIGN ); //value //Only for optimize_for option surrounding single quotes is not necessary if( option.getOptionType() == ProtobufOptionType.OPTIMIZE_FOR ){ formatter.print( option.getOptionValue()); }else{ formatter.print( "\""+option.getOptionValue() +"\""); } //semi colan formatter.print( END_LINE ); } } /** * Writes the message. * The structure is * * //Comment line (one or more lines) * message <message_name>{ * * //field comment (one or more line) * <modifier> <fieldtype> <fieldname> = <sequencenumber>; (one or more fields) * } * * @param formatter * @param message */ private void writeMessage( DotProtoFormatter formatter , ProtobufMessage message){ //new line brefore starting new message formatter.newLine(); //print comments of message String comments = message.getMessageComments(); formatter.printComment(comments); //new line before starting message formatter.newLine(); formatter.print( MESSAGE ); //enum type handled separately if( !message.isEnumType() ){ //message name formatter.print( message.getMessageName() ); formatter.print( START_BLOCK ); for( ProtobufField field : message.getFields() ){ writeField( formatter, field ); } }else{ ProtobufEnumMessage enumMessage = (ProtobufEnumMessage)message ; formatter.print( enumMessage.getEnumMessageName() ); formatter.print( START_BLOCK ); writeEnumMessage( formatter, (ProtobufEnumMessage)message ); } formatter.newLine(); formatter.print( END_BLOCK ); } /** * Writes the enum block. * The method indents one level deeper for each message. * The structure is * * enum <enum_name>{ * <enum_value> = <seq_no>; (one or more entries) * } * * @param formatter * @param enumMessage */ public void writeEnumMessage( DotProtoFormatter formatter , ProtobufEnumMessage enumMessage){ formatter.newLine(); formatter.indent(); formatter.print( ENUM ); formatter.print( enumMessage.getMessageName() ); formatter.print( START_BLOCK ); for( ProtobufEnumEntry entry : enumMessage.getEnumEntries() ){ writeEnumEntry( formatter, entry ); } formatter.newLine(); formatter.print( END_BLOCK ); formatter.outdent(); } /** * Writes the enum entry. * The method indents one level deep for each entry. * * The structure is * * <fieldname> = <sequencenumber>; * * @param formatter * @param field */ private void writeEnumEntry( DotProtoFormatter formatter , ProtobufEnumEntry field){ //Create new line formatter.newLine(); //Increase Indentation formatter.indent(); //print the comments String comments = field.getFieldComments(); formatter.printComment(comments); //Create new line formatter.newLine(); //Print the field name formatter.print( field.getEnumValue() ); //Print the equals '=' sign formatter.print( EQUAL_SIGN ); //Print the sequence number formatter.print( field.getSequenceNumber() +""); //Print the semi colan formatter.print( END_LINE ); //Decrease Indentation formatter.outdent(); } /** * Writes the field. * The method indents one level deep for each field. * Structure is * * <modifier> <fieldtype> <fieldname> = <sequencenumber>; * * @param formatter * @param field */ private void writeField( DotProtoFormatter formatter , ProtobufField field){ //Create new line formatter.newLine(); //Increase Indentation formatter.indent(); //print the comments String comments = field.getFieldComments(); formatter.printComment(comments); //Create new line formatter.newLine(); //Print the modifier formatter.print( field.getFieldModifier().value() ); //Print the type name formatter.print( field.getProtobufTypeName() ); //Print the field name formatter.print( field.getConvertedFieldName() ); //Print the equals '=' sign formatter.print( EQUAL_SIGN ); //Print the sequence number formatter.print( field.getSequenceTagNumber() +""); //Print the semi colan formatter.print( END_LINE ); //Decrease Indentation formatter.outdent(); } }